nss: upgrade to release 3.73
[LibreOffice.git] / vcl / qa / cppunit / BitmapFilterTest.cxx
blob1f9e14d2ef9499bd56f08ec52f9761961c0f29d7
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 <test/bootstrapfixture.hxx>
12 #include <vcl/bitmap.hxx>
13 #include <vcl/bitmapaccess.hxx>
14 #include <bitmapwriteaccess.hxx>
16 #include <tools/stream.hxx>
17 #include <vcl/graphicfilter.hxx>
19 #include <vcl/BitmapBasicMorphologyFilter.hxx>
20 #include <vcl/BitmapFilterStackBlur.hxx>
21 #include <BitmapSymmetryCheck.hxx>
23 #include <chrono>
25 namespace
27 constexpr bool constWriteResultBitmap(false);
28 constexpr bool constEnablePerformanceTest(false);
30 class BitmapFilterTest : public test::BootstrapFixture
32 public:
33 BitmapFilterTest()
34 : test::BootstrapFixture(true, false)
38 void testBlurCorrectness();
39 void testBasicMorphology();
40 void testPerformance();
41 void testGenerateStripRanges();
43 CPPUNIT_TEST_SUITE(BitmapFilterTest);
44 CPPUNIT_TEST(testBlurCorrectness);
45 CPPUNIT_TEST(testBasicMorphology);
46 CPPUNIT_TEST(testPerformance);
47 CPPUNIT_TEST(testGenerateStripRanges);
48 CPPUNIT_TEST_SUITE_END();
50 private:
51 OUString getFullUrl(const OUString& sFileName)
53 return m_directories.getURLFromSrc("vcl/qa/cppunit/data/") + sFileName;
56 BitmapEx loadBitmap(const OUString& sFileName)
58 Graphic aGraphic;
59 const OUString aURL(getFullUrl(sFileName));
60 SvFileStream aFileStream(aURL, StreamMode::READ);
61 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
62 ErrCode aResult = rFilter.ImportGraphic(aGraphic, aURL, aFileStream);
63 CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, aResult);
64 return aGraphic.GetBitmapEx();
67 template <class BitmapT> // handle both Bitmap and BitmapEx
68 void savePNG(const OUString& sWhere, const BitmapT& rBmp)
70 SvFileStream aStream(sWhere, StreamMode::WRITE | StreamMode::TRUNC);
71 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
72 rFilter.compressAsPNG(BitmapEx(rBmp), aStream);
76 void BitmapFilterTest::testBlurCorrectness()
78 // Setup test bitmap
79 Size aSize(41, 31);
80 Bitmap aBitmap24Bit(aSize, 24);
82 ScanlineFormat scanlineFormat = ScanlineFormat::NONE;
83 sal_uInt16 nBPP = aBitmap24Bit.GetBitCount();
86 tools::Long aMargin1 = 1;
87 tools::Long aMargin2 = 3;
88 BitmapScopedWriteAccess aWriteAccess(aBitmap24Bit);
89 scanlineFormat = aWriteAccess->GetScanlineFormat();
90 aWriteAccess->Erase(COL_WHITE);
91 aWriteAccess->SetLineColor(COL_BLACK);
93 tools::Rectangle aRectangle1(aMargin1, aMargin1, aSize.Width() - 1 - aMargin1,
94 aSize.Height() - 1 - aMargin1);
96 tools::Rectangle aRectangle2(aMargin2, aMargin2, aSize.Width() - 1 - aMargin2,
97 aSize.Height() - 1 - aMargin2);
99 tools::Rectangle aRectangle3(aSize.Width() / 2, aSize.Height() / 2, aSize.Width() / 2,
100 aSize.Height() / 2);
102 aWriteAccess->DrawRect(aRectangle1);
103 aWriteAccess->DrawRect(aRectangle2);
104 aWriteAccess->DrawRect(aRectangle3);
107 if (constWriteResultBitmap)
109 savePNG("~/blurBefore.png", aBitmap24Bit);
112 // Perform blur
113 BitmapFilterStackBlur aBlurFilter(2);
114 aBitmap24Bit = aBlurFilter.filter(aBitmap24Bit);
116 // Check the result
118 if (constWriteResultBitmap)
120 savePNG("~/blurAfter.png", aBitmap24Bit);
123 // Check blurred bitmap parameters
124 CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(41), aBitmap24Bit.GetSizePixel().Width());
125 CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(31), aBitmap24Bit.GetSizePixel().Height());
127 CPPUNIT_ASSERT_EQUAL(nBPP, aBitmap24Bit.GetBitCount());
129 // Check that the bitmap is horizontally and vertically symmetrical
130 CPPUNIT_ASSERT(BitmapSymmetryCheck::check(aBitmap24Bit));
133 Bitmap::ScopedReadAccess aReadAccess(aBitmap24Bit);
134 CPPUNIT_ASSERT_EQUAL(scanlineFormat, aReadAccess->GetScanlineFormat());
138 void BitmapFilterTest::testBasicMorphology()
140 const BitmapEx aOrigBitmap = loadBitmap("testBasicMorphology.png");
141 const BitmapEx aRefBitmapDilated1 = loadBitmap("testBasicMorphologyDilated1.png");
142 const BitmapEx aRefBitmapDilated1Eroded1 = loadBitmap("testBasicMorphologyDilated1Eroded1.png");
143 const BitmapEx aRefBitmapDilated2 = loadBitmap("testBasicMorphologyDilated2.png");
144 const BitmapEx aRefBitmapDilated2Eroded1 = loadBitmap("testBasicMorphologyDilated2Eroded1.png");
146 BitmapEx aTransformBitmap = aOrigBitmap;
147 BitmapFilter::Filter(aTransformBitmap, BitmapDilateFilter(1));
148 if (constWriteResultBitmap)
149 savePNG("~/Dilated1.png", aTransformBitmap);
150 CPPUNIT_ASSERT_EQUAL(aRefBitmapDilated1.GetChecksum(), aTransformBitmap.GetChecksum());
151 BitmapFilter::Filter(aTransformBitmap, BitmapErodeFilter(1));
152 if (constWriteResultBitmap)
153 savePNG("~/Dilated1Eroded1.png", aTransformBitmap);
154 CPPUNIT_ASSERT_EQUAL(aRefBitmapDilated1Eroded1.GetChecksum(), aTransformBitmap.GetChecksum());
156 aTransformBitmap = aOrigBitmap;
157 BitmapFilter::Filter(aTransformBitmap, BitmapDilateFilter(2));
158 if (constWriteResultBitmap)
159 savePNG("~/Dilated2.png", aTransformBitmap);
160 CPPUNIT_ASSERT_EQUAL(aRefBitmapDilated2.GetChecksum(), aTransformBitmap.GetChecksum());
161 BitmapFilter::Filter(aTransformBitmap, BitmapErodeFilter(1));
162 if (constWriteResultBitmap)
163 savePNG("~/Dilated2Eroded1.png", aTransformBitmap);
164 CPPUNIT_ASSERT_EQUAL(aRefBitmapDilated2Eroded1.GetChecksum(), aTransformBitmap.GetChecksum());
167 void BitmapFilterTest::testPerformance()
169 if (!constEnablePerformanceTest)
170 return;
172 Size aSize(4000, 3000); // A rather common picture size
174 // Prepare bitmap
175 Bitmap aBigBitmap(aSize, 24);
177 tools::Long aMargin = 500;
178 BitmapScopedWriteAccess aWriteAccess(aBigBitmap);
179 aWriteAccess->Erase(COL_WHITE);
180 aWriteAccess->SetLineColor(COL_BLACK);
181 aWriteAccess->SetFillColor(COL_BLACK);
182 tools::Rectangle aRectangle(aMargin, aMargin, aSize.Width() - 1 - aMargin,
183 aSize.Height() - 1 - aMargin);
185 aWriteAccess->DrawRect(aRectangle);
188 int nIterations = 10;
189 auto start = std::chrono::high_resolution_clock::now();
190 Bitmap aResult;
191 for (int i = 0; i < nIterations; i++)
193 BitmapFilterStackBlur aBlurFilter(250);
194 aResult = aBlurFilter.filter(aBigBitmap);
196 auto end = std::chrono::high_resolution_clock::now();
197 auto elapsed = (end - start) / nIterations;
199 if (constWriteResultBitmap)
201 std::unique_ptr<SvFileStream> pStream(
202 new SvFileStream("~/BlurBigPerformance.png", StreamMode::WRITE | StreamMode::TRUNC));
203 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
204 rFilter.compressAsPNG(BitmapEx(aResult), *pStream);
206 pStream.reset(new SvFileStream("~/BlurBigPerformance.txt", StreamMode::WRITE));
207 pStream->WriteOString("Blur average time: ");
208 pStream->WriteOString(OString::number(
209 std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count()));
210 pStream->WriteOString("\n");
214 void BitmapFilterTest::testGenerateStripRanges()
217 constexpr tools::Long nFirstIndex = 0;
218 constexpr tools::Long nLastIndex = 100;
219 constexpr tools::Long nStripSize = 32;
221 std::vector<std::tuple<tools::Long, tools::Long, bool>> aRanges;
223 vcl::bitmap::generateStripRanges<nStripSize>(
224 nFirstIndex, nLastIndex,
225 [&](tools::Long const nStart, tools::Long const nEnd, bool const bLast) {
226 aRanges.emplace_back(nStart, nEnd, bLast);
229 CPPUNIT_ASSERT_EQUAL(size_t(4), aRanges.size());
231 CPPUNIT_ASSERT_EQUAL(tools::Long(0), std::get<0>(aRanges[0]));
232 CPPUNIT_ASSERT_EQUAL(tools::Long(31), std::get<1>(aRanges[0]));
233 CPPUNIT_ASSERT_EQUAL(false, std::get<2>(aRanges[0]));
235 CPPUNIT_ASSERT_EQUAL(tools::Long(32), std::get<0>(aRanges[1]));
236 CPPUNIT_ASSERT_EQUAL(tools::Long(63), std::get<1>(aRanges[1]));
237 CPPUNIT_ASSERT_EQUAL(false, std::get<2>(aRanges[1]));
239 CPPUNIT_ASSERT_EQUAL(tools::Long(64), std::get<0>(aRanges[2]));
240 CPPUNIT_ASSERT_EQUAL(tools::Long(95), std::get<1>(aRanges[2]));
241 CPPUNIT_ASSERT_EQUAL(false, std::get<2>(aRanges[2]));
243 CPPUNIT_ASSERT_EQUAL(tools::Long(96), std::get<0>(aRanges[3]));
244 CPPUNIT_ASSERT_EQUAL(tools::Long(100), std::get<1>(aRanges[3]));
245 CPPUNIT_ASSERT_EQUAL(true, std::get<2>(aRanges[3]));
249 constexpr tools::Long nFirstIndex = 0;
250 constexpr tools::Long nLastIndex = 95;
251 constexpr tools::Long nStripSize = 32;
253 std::vector<std::tuple<tools::Long, tools::Long, bool>> aRanges;
255 vcl::bitmap::generateStripRanges<nStripSize>(
256 nFirstIndex, nLastIndex,
257 [&](tools::Long const nStart, tools::Long const nEnd, bool const bLast) {
258 aRanges.emplace_back(nStart, nEnd, bLast);
261 CPPUNIT_ASSERT_EQUAL(size_t(3), aRanges.size());
263 CPPUNIT_ASSERT_EQUAL(tools::Long(0), std::get<0>(aRanges[0]));
264 CPPUNIT_ASSERT_EQUAL(tools::Long(31), std::get<1>(aRanges[0]));
265 CPPUNIT_ASSERT_EQUAL(false, std::get<2>(aRanges[0]));
267 CPPUNIT_ASSERT_EQUAL(tools::Long(32), std::get<0>(aRanges[1]));
268 CPPUNIT_ASSERT_EQUAL(tools::Long(63), std::get<1>(aRanges[1]));
269 CPPUNIT_ASSERT_EQUAL(false, std::get<2>(aRanges[1]));
271 CPPUNIT_ASSERT_EQUAL(tools::Long(64), std::get<0>(aRanges[2]));
272 CPPUNIT_ASSERT_EQUAL(tools::Long(95), std::get<1>(aRanges[2]));
273 CPPUNIT_ASSERT_EQUAL(true, std::get<2>(aRanges[2]));
277 } // namespace
279 CPPUNIT_TEST_SUITE_REGISTRATION(BitmapFilterTest);
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */