1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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>
26 #include <vcl/skia/SkiaHelper.hxx>
27 #include <vcl/BitmapMonochromeFilter.hxx>
29 #include <bitmapwriteaccess.hxx>
32 #include <salinst.hxx>
33 #include <bitmap/Octree.hxx>
37 class BitmapTest
: public CppUnit::TestFixture
41 void testMonochrome();
42 void testN4Greyscale();
43 void testN8Greyscale();
46 void testGreyPalette();
47 void testCustom8BitPalette();
51 void testEmptyAccess();
53 CPPUNIT_TEST_SUITE(BitmapTest
);
54 CPPUNIT_TEST(testCreation
);
55 CPPUNIT_TEST(testEmpty
);
56 CPPUNIT_TEST(testMonochrome
);
57 CPPUNIT_TEST(testConvert
);
58 CPPUNIT_TEST(testN4Greyscale
);
59 CPPUNIT_TEST(testN8Greyscale
);
60 CPPUNIT_TEST(testCRC
);
61 CPPUNIT_TEST(testGreyPalette
);
62 CPPUNIT_TEST(testCustom8BitPalette
);
63 CPPUNIT_TEST(testErase
);
64 CPPUNIT_TEST(testBitmap32
);
65 CPPUNIT_TEST(testOctree
);
66 CPPUNIT_TEST(testEmptyAccess
);
67 CPPUNIT_TEST_SUITE_END();
70 void assertColorsAreSimilar(int maxDifference
, const std::string
& message
,
71 const BitmapColor
& expected
, const BitmapColor
& actual
)
73 // Check that the two colors match or are reasonably similar.
74 if (expected
== actual
)
76 if (abs(expected
.GetRed() - actual
.GetRed()) <= maxDifference
77 && abs(expected
.GetGreen() - actual
.GetGreen()) <= maxDifference
78 && abs(expected
.GetBlue() - actual
.GetBlue()) <= maxDifference
79 && abs(expected
.GetAlpha() - actual
.GetAlpha()) <= maxDifference
)
83 CPPUNIT_ASSERT_EQUAL_MESSAGE(message
, expected
, actual
);
86 void BitmapTest::testCreation()
90 Size aSize
= aBmp
.GetSizePixel();
91 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<tools::Long
>(0), aSize
.Width());
92 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<tools::Long
>(0), aSize
.Height());
93 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp
.GetPrefSize());
94 CPPUNIT_ASSERT_MESSAGE("Not empty", aBmp
.IsEmpty());
95 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16
>(0),
97 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(1), aBmp
.GetColorCount());
98 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong
>(0),
103 Bitmap
aBmp(Size(10, 10), 1);
104 Size aSize
= aBmp
.GetSizePixel();
105 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<tools::Long
>(10), aSize
.Width());
106 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<tools::Long
>(10), aSize
.Height());
107 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp
.GetPrefSize());
108 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp
.IsEmpty());
109 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16
>(1),
111 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(2), aBmp
.GetColorCount());
112 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong
>(12),
113 aBmp
.GetSizeBytes());
117 Bitmap
aBmp(Size(10, 10), 4);
118 Size aSize
= aBmp
.GetSizePixel();
119 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<tools::Long
>(10), aSize
.Width());
120 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<tools::Long
>(10), aSize
.Height());
121 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp
.GetPrefSize());
122 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp
.IsEmpty());
123 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16
>(4),
125 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(16), aBmp
.GetColorCount());
126 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong
>(50),
127 aBmp
.GetSizeBytes());
131 Bitmap
aBmp(Size(10, 10), 8);
132 Size aSize
= aBmp
.GetSizePixel();
133 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<tools::Long
>(10), aSize
.Width());
134 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<tools::Long
>(10), aSize
.Height());
135 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp
.GetPrefSize());
136 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp
.IsEmpty());
137 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16
>(8),
139 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(256), aBmp
.GetColorCount());
140 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong
>(100),
141 aBmp
.GetSizeBytes());
145 Bitmap
aBmp(Size(10, 10), 24);
146 Size aSize
= aBmp
.GetSizePixel();
147 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<tools::Long
>(10), aSize
.Width());
148 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<tools::Long
>(10), aSize
.Height());
149 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp
.GetPrefSize());
150 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp
.IsEmpty());
151 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", static_cast<sal_uInt16
>(24),
153 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(16777216),
154 aBmp
.GetColorCount());
155 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", static_cast<sal_uLong
>(300),
156 aBmp
.GetSizeBytes());
159 // Check backend capabilities and return from the test successfully
160 // if the backend doesn't support 32-bit bitmap
161 auto pBackendCapabilities
= ImplGetSVData()->mpDefInst
->GetBackendCapabilities();
162 if (pBackendCapabilities
->mbSupportsBitmap32
)
164 Bitmap
aBmp(Size(10, 10), 32);
165 Size aSize
= aBmp
.GetSizePixel();
166 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong width", static_cast<tools::Long
>(10), aSize
.Width());
167 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong height", static_cast<tools::Long
>(10), aSize
.Height());
168 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong pref size", Size(), aBmp
.GetPrefSize());
169 CPPUNIT_ASSERT_MESSAGE("Empty bitmap", !aBmp
.IsEmpty());
171 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong bit count", sal_uInt16(32), aBmp
.GetBitCount());
172 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong color count", sal_Int64(4294967296ull),
173 aBmp
.GetColorCount());
174 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong byte size", sal_uLong(400), aBmp
.GetSizeBytes());
178 void BitmapTest::testEmpty()
180 Bitmap
aBitmap(Size(10, 10), 8);
181 aBitmap
.Erase(COL_LIGHTGRAYBLUE
);
183 CPPUNIT_ASSERT(!aBitmap
.IsEmpty());
186 CPPUNIT_ASSERT(aBitmap
.IsEmpty());
189 Bitmap
createTestBitmap()
191 Bitmap
aBmp(Size(4, 4), 24);
192 BitmapWriteAccess
aBmpAccess(aBmp
);
195 aBmpAccess
.SetPixel(0, 0, BitmapColor(COL_BLACK
));
196 aBmpAccess
.SetPixel(0, 1, BitmapColor(COL_BLUE
));
197 aBmpAccess
.SetPixel(0, 2, BitmapColor(COL_GREEN
));
198 aBmpAccess
.SetPixel(0, 3, BitmapColor(COL_CYAN
));
201 aBmpAccess
.SetPixel(1, 0, BitmapColor(COL_RED
));
202 aBmpAccess
.SetPixel(1, 1, BitmapColor(COL_MAGENTA
));
203 aBmpAccess
.SetPixel(1, 2, BitmapColor(COL_BROWN
));
204 aBmpAccess
.SetPixel(1, 3, BitmapColor(COL_GRAY
));
207 aBmpAccess
.SetPixel(2, 0, BitmapColor(COL_LIGHTGRAY
));
208 aBmpAccess
.SetPixel(2, 1, BitmapColor(COL_LIGHTBLUE
));
209 aBmpAccess
.SetPixel(2, 2, BitmapColor(COL_LIGHTGREEN
));
210 aBmpAccess
.SetPixel(2, 3, BitmapColor(COL_LIGHTCYAN
));
213 aBmpAccess
.SetPixel(3, 0, BitmapColor(COL_LIGHTRED
));
214 aBmpAccess
.SetPixel(3, 1, BitmapColor(COL_LIGHTMAGENTA
));
215 aBmpAccess
.SetPixel(3, 2, BitmapColor(COL_YELLOW
));
216 aBmpAccess
.SetPixel(3, 3, BitmapColor(COL_WHITE
));
221 void BitmapTest::testMonochrome()
223 Bitmap aBmp
= createTestBitmap();
225 BitmapEx
aBmpEx(aBmp
);
226 BitmapFilter::Filter(aBmpEx
, BitmapMonochromeFilter(63));
227 aBmp
= aBmpEx
.GetBitmap();
228 BitmapReadAccess
aBmpReadAccess(aBmp
);
230 CPPUNIT_ASSERT_EQUAL_MESSAGE("Black pixel wrong monochrome value", BitmapColor(COL_BLACK
),
231 aBmpReadAccess
.GetColor(0, 0));
232 CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue pixel wrong monochrome value", BitmapColor(COL_BLACK
),
233 aBmpReadAccess
.GetColor(0, 1));
234 CPPUNIT_ASSERT_EQUAL_MESSAGE("Green pixel wrong monochrome value", BitmapColor(COL_WHITE
),
235 aBmpReadAccess
.GetColor(0, 2));
236 CPPUNIT_ASSERT_EQUAL_MESSAGE("Cyan pixel wrong monochrome value", BitmapColor(COL_WHITE
),
237 aBmpReadAccess
.GetColor(0, 3));
238 CPPUNIT_ASSERT_EQUAL_MESSAGE("Red pixel wrong monochrome value", BitmapColor(COL_BLACK
),
239 aBmpReadAccess
.GetColor(1, 0));
240 CPPUNIT_ASSERT_EQUAL_MESSAGE("Magenta pixel wrong monochrome value", BitmapColor(COL_BLACK
),
241 aBmpReadAccess
.GetColor(1, 1));
242 CPPUNIT_ASSERT_EQUAL_MESSAGE("Brown pixel wrong monochrome value", BitmapColor(COL_WHITE
),
243 aBmpReadAccess
.GetColor(1, 2));
244 CPPUNIT_ASSERT_EQUAL_MESSAGE("Gray pixel wrong monochrome value", BitmapColor(COL_WHITE
),
245 aBmpReadAccess
.GetColor(1, 3));
246 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light gray pixel wrong monochrome value", BitmapColor(COL_WHITE
),
247 aBmpReadAccess
.GetColor(2, 0));
248 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light blue pixel wrong monochrome value", BitmapColor(COL_BLACK
),
249 aBmpReadAccess
.GetColor(2, 1));
250 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light green pixel wrong monochrome value", BitmapColor(COL_WHITE
),
251 aBmpReadAccess
.GetColor(2, 2));
252 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light cyan pixel wrong monochrome value", BitmapColor(COL_WHITE
),
253 aBmpReadAccess
.GetColor(2, 3));
254 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light red pixel wrong monochrome value", BitmapColor(COL_WHITE
),
255 aBmpReadAccess
.GetColor(3, 0));
256 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light magenta pixel wrong monochrome value",
257 BitmapColor(COL_WHITE
), aBmpReadAccess
.GetColor(3, 1));
258 CPPUNIT_ASSERT_EQUAL_MESSAGE("Yellow pixel wrong monochrome value", BitmapColor(COL_WHITE
),
259 aBmpReadAccess
.GetColor(3, 2));
260 CPPUNIT_ASSERT_EQUAL_MESSAGE("White pixel wrong monochrome value", BitmapColor(COL_WHITE
),
261 aBmpReadAccess
.GetColor(3, 3));
264 void BitmapTest::testN4Greyscale()
266 Bitmap aBmp
= createTestBitmap();
267 BitmapPalette aGreyscalePalette
= Bitmap::GetGreyPalette(16);
269 aBmp
.Convert(BmpConversion::N4BitGreys
);
270 BitmapReadAccess
aBmpReadAccess(aBmp
);
272 CPPUNIT_ASSERT_EQUAL_MESSAGE("Black pixel wrong 8-bit greyscale value", aGreyscalePalette
[0],
273 aBmpReadAccess
.GetColor(0, 0));
274 CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue pixel wrong 8-bit greyscale value", aGreyscalePalette
[0],
275 aBmpReadAccess
.GetColor(0, 1));
276 CPPUNIT_ASSERT_EQUAL_MESSAGE("Green pixel wrong 8-bit greyscale value", aGreyscalePalette
[4],
277 aBmpReadAccess
.GetColor(0, 2));
278 CPPUNIT_ASSERT_EQUAL_MESSAGE("Cyan pixel wrong 8-bit greyscale value", aGreyscalePalette
[5],
279 aBmpReadAccess
.GetColor(0, 3));
280 CPPUNIT_ASSERT_EQUAL_MESSAGE("Red pixel wrong 8-bit greyscale value", aGreyscalePalette
[2],
281 aBmpReadAccess
.GetColor(1, 0));
282 CPPUNIT_ASSERT_EQUAL_MESSAGE("Magenta pixel wrong 8-bit greyscale value", aGreyscalePalette
[3],
283 aBmpReadAccess
.GetColor(1, 1));
284 CPPUNIT_ASSERT_EQUAL_MESSAGE("Brown pixel wrong 8-bit greyscale value", aGreyscalePalette
[7],
285 aBmpReadAccess
.GetColor(1, 2));
286 CPPUNIT_ASSERT_EQUAL_MESSAGE("Gray pixel wrong 8-bit greyscale value", aGreyscalePalette
[8],
287 aBmpReadAccess
.GetColor(1, 3));
288 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light gray pixel wrong 8-bit greyscale value",
289 aGreyscalePalette
[12], aBmpReadAccess
.GetColor(2, 0));
290 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light blue pixel wrong 8-bit greyscale value",
291 aGreyscalePalette
[1], aBmpReadAccess
.GetColor(2, 1));
292 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light green pixel wrong 8-bit greyscale value",
293 aGreyscalePalette
[9], aBmpReadAccess
.GetColor(2, 2));
294 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light cyan pixel wrong 8-bit greyscale value",
295 aGreyscalePalette
[11], aBmpReadAccess
.GetColor(2, 3));
296 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light red pixel wrong 8-bit greyscale value",
297 aGreyscalePalette
[4], aBmpReadAccess
.GetColor(3, 0));
298 CPPUNIT_ASSERT_EQUAL_MESSAGE("Light magenta pixel wrong 8-bit greyscale value",
299 aGreyscalePalette
[6], aBmpReadAccess
.GetColor(3, 1));
300 CPPUNIT_ASSERT_EQUAL_MESSAGE("Yellow pixel wrong 8-bit greyscale value", aGreyscalePalette
[14],
301 aBmpReadAccess
.GetColor(3, 2));
302 CPPUNIT_ASSERT_EQUAL_MESSAGE("White pixel wrong 8-bit greyscale value", aGreyscalePalette
[15],
303 aBmpReadAccess
.GetColor(3, 3));
306 void BitmapTest::testN8Greyscale()
308 Bitmap aBmp
= createTestBitmap();
309 BitmapPalette aGreyscalePalette
= Bitmap::GetGreyPalette(256);
311 aBmp
.Convert(BmpConversion::N8BitGreys
);
312 BitmapReadAccess
aBmpReadAccess(aBmp
);
314 assertColorsAreSimilar(1, "Black pixel wrong 8-bit greyscale value", aGreyscalePalette
[0],
315 aBmpReadAccess
.GetColor(0, 0));
316 assertColorsAreSimilar(1, "Blue pixel wrong 8-bit greyscale value", aGreyscalePalette
[14],
317 aBmpReadAccess
.GetColor(0, 1));
318 assertColorsAreSimilar(1, "Green pixel wrong 8-bit greyscale value", aGreyscalePalette
[75],
319 aBmpReadAccess
.GetColor(0, 2));
320 assertColorsAreSimilar(1, "Cyan pixel wrong 8-bit greyscale value", aGreyscalePalette
[89],
321 aBmpReadAccess
.GetColor(0, 3));
322 assertColorsAreSimilar(1, "Red pixel wrong 8-bit greyscale value", aGreyscalePalette
[38],
323 aBmpReadAccess
.GetColor(1, 0));
324 assertColorsAreSimilar(1, "Magenta pixel wrong 8-bit greyscale value", aGreyscalePalette
[52],
325 aBmpReadAccess
.GetColor(1, 1));
326 assertColorsAreSimilar(1, "Brown pixel wrong 8-bit greyscale value", aGreyscalePalette
[114],
327 aBmpReadAccess
.GetColor(1, 2));
328 assertColorsAreSimilar(1, "Gray pixel wrong 8-bit greyscale value", aGreyscalePalette
[128],
329 aBmpReadAccess
.GetColor(1, 3));
330 assertColorsAreSimilar(1, "Light gray pixel wrong 8-bit greyscale value",
331 aGreyscalePalette
[192], aBmpReadAccess
.GetColor(2, 0));
332 assertColorsAreSimilar(1, "Light blue pixel wrong 8-bit greyscale value", aGreyscalePalette
[27],
333 aBmpReadAccess
.GetColor(2, 1));
334 assertColorsAreSimilar(1, "Light green pixel wrong 8-bit greyscale value",
335 aGreyscalePalette
[150], aBmpReadAccess
.GetColor(2, 2));
336 assertColorsAreSimilar(1, "Light cyan pixel wrong 8-bit greyscale value",
337 aGreyscalePalette
[178], aBmpReadAccess
.GetColor(2, 3));
338 assertColorsAreSimilar(1, "Light red pixel wrong 8-bit greyscale value", aGreyscalePalette
[76],
339 aBmpReadAccess
.GetColor(3, 0));
340 assertColorsAreSimilar(1, "Light magenta pixel wrong 8-bit greyscale value",
341 aGreyscalePalette
[104], aBmpReadAccess
.GetColor(3, 1));
342 assertColorsAreSimilar(1, "Yellow pixel wrong 8-bit greyscale value", aGreyscalePalette
[227],
343 aBmpReadAccess
.GetColor(3, 2));
344 assertColorsAreSimilar(1, "White pixel wrong 8-bit greyscale value", aGreyscalePalette
[255],
345 aBmpReadAccess
.GetColor(3, 3));
348 void BitmapTest::testConvert()
350 Bitmap
aBitmap(Size(10, 10), 8);
352 aBitmap
.Erase(COL_LIGHTGRAYBLUE
);
354 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(8), aBitmap
.GetBitCount());
356 Bitmap::ScopedReadAccess
pReadAccess(aBitmap
);
357 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(8), pReadAccess
->GetBitCount());
358 #if defined MACOSX || defined IOS
359 //it would be nice to find and change the stride for quartz to be the same as everyone else
360 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32
>(10), pReadAccess
->GetScanlineSize());
362 if (!SkiaHelper::isVCLSkiaEnabled())
363 #if HAVE_FEATURE_OPENGL
364 if (!OpenGLHelper::isVCLOpenGLEnabled())
366 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32
>(12), pReadAccess
->GetScanlineSize());
368 CPPUNIT_ASSERT(pReadAccess
->HasPalette());
369 const BitmapColor
& rColor
= pReadAccess
->GetPaletteColor(pReadAccess
->GetPixelIndex(1, 1));
370 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(rColor
.GetRed()));
371 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(rColor
.GetGreen()));
372 CPPUNIT_ASSERT_EQUAL(sal_Int32(255), sal_Int32(rColor
.GetBlue()));
375 aBitmap
.Convert(BmpConversion::N24Bit
);
377 CPPUNIT_ASSERT_EQUAL(sal_uInt16(24), aBitmap
.GetBitCount());
379 Bitmap::ScopedReadAccess
pReadAccess(aBitmap
);
380 // 24 bit Bitmap on SVP backend can now use 24bit RGB everywhere.
381 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(24), pReadAccess
->GetBitCount());
383 if (SkiaHelper::isVCLSkiaEnabled()) // aligned to 4 bytes
384 CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess
->GetScanlineSize());
386 #if HAVE_FEATURE_OPENGL
387 if (OpenGLHelper::isVCLOpenGLEnabled())
388 CPPUNIT_ASSERT_EQUAL(sal_uInt32(30), pReadAccess
->GetScanlineSize());
391 #if defined LINUX || defined FREEBSD
393 CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess
->GetScanlineSize());
395 #elif defined(_WIN32)
397 // GDI Scanlines padded to DWORD multiples, it seems
398 CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess
->GetScanlineSize());
402 CPPUNIT_ASSERT_EQUAL(sal_uInt32(30), pReadAccess
->GetScanlineSize());
406 CPPUNIT_ASSERT(!pReadAccess
->HasPalette());
407 Color aColor
= pReadAccess
->GetPixel(0, 0);
408 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(aColor
.GetRed()));
409 CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(aColor
.GetGreen()));
410 CPPUNIT_ASSERT_EQUAL(sal_Int32(255), sal_Int32(aColor
.GetBlue()));
414 typedef std::unordered_map
<sal_uInt64
, const char*> CRCHash
;
416 void checkAndInsert(CRCHash
& rHash
, sal_uInt64 nCRC
, const char* pLocation
)
418 auto it
= rHash
.find(nCRC
);
419 if (it
!= rHash
.end())
421 OStringBuffer
aBuf("CRC collision between ");
422 aBuf
.append(pLocation
);
423 aBuf
.append(" and ");
424 aBuf
.append(it
->second
);
425 aBuf
.append(" hash is 0x");
426 aBuf
.append(static_cast<sal_Int64
>(nCRC
), 16);
427 CPPUNIT_FAIL(aBuf
.toString().getStr());
429 rHash
[nCRC
] = pLocation
;
432 void checkAndInsert(CRCHash
& rHash
, Bitmap
const& rBmp
, const char* pLocation
)
434 checkAndInsert(rHash
, rBmp
.GetChecksum(), pLocation
);
437 Bitmap
getAsBitmap(VclPtr
<OutputDevice
> const& pOut
)
439 return pOut
->GetBitmap(Point(), pOut
->GetOutputSizePixel());
442 void BitmapTest::testCRC()
446 Bitmap
aBitmap(Size(1023, 759), 24, nullptr);
447 aBitmap
.Erase(COL_BLACK
);
448 checkAndInsert(aCRCs
, aBitmap
, "black bitmap");
450 checkAndInsert(aCRCs
, aBitmap
, "white bitmap");
452 ScopedVclPtrInstance
<VirtualDevice
> aVDev
;
453 aVDev
->SetBackground(Wallpaper(COL_WHITE
));
454 aVDev
->SetOutputSizePixel(Size(1023, 759));
456 #if 0 // disabled for now - oddly breaks on OS/X - but why ?
457 Bitmap aWhiteCheck
= getAsBitmap(aVDev
);
458 CPPUNIT_ASSERT(aCRCs
.find(aWhiteCheck
.GetChecksum()) != aCRCs
.end());
461 // a 1x1 black & white checkerboard
462 aVDev
->DrawCheckered(Point(), aVDev
->GetOutputSizePixel(), 1, Color(0, 0, 1));
463 Bitmap aChecker
= getAsBitmap(aVDev
);
464 checkAndInsert(aCRCs
, aChecker
, "checkerboard");
466 checkAndInsert(aCRCs
, aChecker
, "inverted checkerboard");
469 void BitmapTest::testGreyPalette()
472 BitmapPalette aPalette
= Bitmap::GetGreyPalette(2);
473 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries", static_cast<sal_uInt16
>(2),
474 aPalette
.GetEntryCount());
475 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette
[0]);
476 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 2 wrong", BitmapColor(255, 255, 255), aPalette
[1]);
480 BitmapPalette aPalette
= Bitmap::GetGreyPalette(4);
481 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries", static_cast<sal_uInt16
>(4),
482 aPalette
.GetEntryCount());
483 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette
[0]);
484 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 2 wrong", BitmapColor(85, 85, 85), aPalette
[1]);
485 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 3 wrong", BitmapColor(170, 170, 170), aPalette
[2]);
486 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 4 wrong", BitmapColor(255, 255, 255), aPalette
[3]);
490 BitmapPalette aPalette
= Bitmap::GetGreyPalette(16);
491 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries", static_cast<sal_uInt16
>(16),
492 aPalette
.GetEntryCount());
493 // this is a *real* specific number of greys, incremented in units of 17 so may
494 // as well test them all...
495 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette
[0]);
496 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 2 wrong", BitmapColor(17, 17, 17), aPalette
[1]);
497 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 3 wrong", BitmapColor(34, 34, 34), aPalette
[2]);
498 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 4 wrong", BitmapColor(51, 51, 51), aPalette
[3]);
499 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 5 wrong", BitmapColor(68, 68, 68), aPalette
[4]);
500 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 6 wrong", BitmapColor(85, 85, 85), aPalette
[5]);
501 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 7 wrong", BitmapColor(102, 102, 102), aPalette
[6]);
502 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 8 wrong", BitmapColor(119, 119, 119), aPalette
[7]);
503 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 9 wrong", BitmapColor(136, 136, 136), aPalette
[8]);
504 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 10 wrong", BitmapColor(153, 153, 153), aPalette
[9]);
505 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 11 wrong", BitmapColor(170, 170, 170), aPalette
[10]);
506 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 12 wrong", BitmapColor(187, 187, 187), aPalette
[11]);
507 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 13 wrong", BitmapColor(204, 204, 204), aPalette
[12]);
508 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 14 wrong", BitmapColor(221, 221, 221), aPalette
[13]);
509 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 15 wrong", BitmapColor(238, 238, 238), aPalette
[14]);
510 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 16 wrong", BitmapColor(255, 255, 255), aPalette
[15]);
514 BitmapPalette aPalette
= Bitmap::GetGreyPalette(256);
515 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of palette entries",
516 static_cast<sal_uInt16
>(256), aPalette
.GetEntryCount());
517 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 1 wrong", BitmapColor(0, 0, 0), aPalette
[0]);
518 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 127 wrong", BitmapColor(127, 127, 127), aPalette
[127]);
519 CPPUNIT_ASSERT_EQUAL_MESSAGE("Entry 255 wrong", BitmapColor(255, 255, 255), aPalette
[255]);
523 void BitmapTest::testCustom8BitPalette()
525 BitmapPalette aCustomPalette
;
526 aCustomPalette
.SetEntryCount(256);
527 for (sal_uInt16 i
= 0; i
< 256; i
++)
529 aCustomPalette
[i
] = BitmapColor(sal_uInt8(i
), sal_uInt8(0xCC), sal_uInt8(0x22));
531 Bitmap
aBitmap(Size(3, 2), 8, &aCustomPalette
);
534 BitmapScopedWriteAccess
pAccess(aBitmap
);
535 pAccess
->SetPixelIndex(0, 0, 0);
536 pAccess
->SetPixelIndex(0, 1, 1);
537 pAccess
->SetPixelIndex(0, 2, 2);
539 pAccess
->SetPixelIndex(1, 0, 253);
540 pAccess
->SetPixelIndex(1, 1, 254);
541 pAccess
->SetPixelIndex(1, 2, 255);
545 Bitmap::ScopedReadAccess
pAccess(aBitmap
);
546 CPPUNIT_ASSERT_EQUAL(0, int(pAccess
->GetPixelIndex(0, 0)));
547 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0xCC, 0x22), pAccess
->GetColor(0, 0));
549 CPPUNIT_ASSERT_EQUAL(1, int(pAccess
->GetPixelIndex(0, 1)));
550 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x01, 0xCC, 0x22), pAccess
->GetColor(0, 1));
552 CPPUNIT_ASSERT_EQUAL(2, int(pAccess
->GetPixelIndex(0, 2)));
553 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x02, 0xCC, 0x22), pAccess
->GetColor(0, 2));
555 CPPUNIT_ASSERT_EQUAL(253, int(pAccess
->GetPixelIndex(1, 0)));
556 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFD, 0xCC, 0x22), pAccess
->GetColor(1, 0));
558 CPPUNIT_ASSERT_EQUAL(254, int(pAccess
->GetPixelIndex(1, 1)));
559 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFE, 0xCC, 0x22), pAccess
->GetColor(1, 1));
561 CPPUNIT_ASSERT_EQUAL(255, int(pAccess
->GetPixelIndex(1, 2)));
562 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xCC, 0x22), pAccess
->GetColor(1, 2));
566 void BitmapTest::testErase()
568 Bitmap
aBitmap(Size(3, 3), 24);
570 BitmapScopedWriteAccess
pWriteAccess(aBitmap
);
571 pWriteAccess
->Erase(Color(0x11, 0x22, 0x33));
574 Bitmap::ScopedReadAccess
pReadAccess(aBitmap
);
575 BitmapColor
aColor(pReadAccess
->GetPixel(0, 0));
576 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x11, 0x22, 0x33, 0x00), aColor
);
580 void BitmapTest::testBitmap32()
582 // Check backend capabilities and return from the test successfully
583 // if the backend doesn't support 32-bit bitmap
584 auto pBackendCapabilities
= ImplGetSVData()->mpDefInst
->GetBackendCapabilities();
585 if (!pBackendCapabilities
->mbSupportsBitmap32
)
588 Bitmap
aBitmap(Size(3, 3), 32);
590 BitmapScopedWriteAccess
pWriteAccess(aBitmap
);
591 pWriteAccess
->Erase(Color(0xFF, 0x11, 0x22, 0x33));
592 pWriteAccess
->SetPixel(1, 1, BitmapColor(0x44, 0xFF, 0xBB, 0x00));
593 pWriteAccess
->SetPixel(2, 2, BitmapColor(0x99, 0x77, 0x66, 0x55));
596 Bitmap::ScopedReadAccess
pReadAccess(aBitmap
);
597 BitmapColor aColor
= pReadAccess
->GetPixel(0, 0);
598 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x00, 0xFF), aColor
);
600 aColor
= pReadAccess
->GetPixel(1, 1);
601 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x44, 0xFF, 0xBB, 0x00), aColor
);
603 aColor
= pReadAccess
->GetPixel(2, 2);
604 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x99, 0x77, 0x66, 0x55), aColor
);
608 void BitmapTest::testOctree()
610 Size
aSize(1000, 100);
611 Bitmap
aBitmap(aSize
, 24);
613 BitmapScopedWriteAccess
pWriteAccess(aBitmap
);
614 for (tools::Long y
= 0; y
< aSize
.Height(); ++y
)
616 for (tools::Long x
= 0; x
< aSize
.Width(); ++x
)
618 double fPercent
= double(x
) / double(aSize
.Width());
619 pWriteAccess
->SetPixel(y
, x
,
620 BitmapColor(255.0 * fPercent
, 64.0 + (128.0 * fPercent
),
621 255.0 - 255.0 * fPercent
));
628 Bitmap::ScopedReadAccess
pAccess(aBitmap
);
629 Octree
aOctree(*pAccess
, 1);
630 auto aBitmapPalette
= aOctree
.GetPalette();
631 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), aBitmapPalette
.GetEntryCount());
632 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7e, 0x7f, 0x7f), aBitmapPalette
[0]);
637 Bitmap::ScopedReadAccess
pAccess(aBitmap
);
638 Octree
aOctree(*pAccess
, 4);
639 auto aBitmapPalette
= aOctree
.GetPalette();
640 CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), aBitmapPalette
.GetEntryCount());
641 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7f, 0x7f, 0x7f), aBitmapPalette
[0]);
642 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x3e, 0x5f, 0xbf), aBitmapPalette
[1]);
643 CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7f, 0x80, 0x7f), aBitmapPalette
[2]);
644 CPPUNIT_ASSERT_EQUAL(BitmapColor(0xbe, 0x9f, 0x3f), aBitmapPalette
[3]);
648 // Reduce to 256 color
649 Bitmap::ScopedReadAccess
pAccess(aBitmap
);
650 Octree
aOctree(*pAccess
, 256);
651 auto aBitmapPalette
= aOctree
.GetPalette();
652 CPPUNIT_ASSERT_EQUAL(sal_uInt16(74), aBitmapPalette
.GetEntryCount());
656 void BitmapTest::testEmptyAccess()
659 BitmapInfoAccess
access(empty
);
660 CPPUNIT_ASSERT_EQUAL(tools::Long(0), access
.Width());
661 CPPUNIT_ASSERT_EQUAL(tools::Long(0), access
.Height());
666 CPPUNIT_TEST_SUITE_REGISTRATION(BitmapTest
);
668 CPPUNIT_PLUGIN_IMPLEMENT();
670 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */