Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include <cppunit/TestAssert.h>
11 : #include <cppunit/TestFixture.h>
12 : #include <cppunit/extensions/HelperMacros.h>
13 : #include <cppunit/plugin/TestPlugIn.h>
14 :
15 : #include <vcl/bitmap.hxx>
16 : #include <vcl/bmpacc.hxx>
17 :
18 : #include <tools/stream.hxx>
19 : #include <vcl/graphicfilter.hxx>
20 :
21 : #include <vcl/BitmapFilterStackBlur.hxx>
22 : #include "BitmapSymmetryCheck.hxx"
23 :
24 : #include <chrono>
25 :
26 : namespace
27 : {
28 :
29 : const bool constWriteResultBitmap(false);
30 : const bool constEnablePerformanceTest(false);
31 :
32 6 : class BitmapFilterTest : public CppUnit::TestFixture
33 : {
34 :
35 : void testBlurCorrectness();
36 : void testPerformance();
37 :
38 2 : CPPUNIT_TEST_SUITE(BitmapFilterTest);
39 1 : CPPUNIT_TEST(testBlurCorrectness);
40 1 : CPPUNIT_TEST(testPerformance);
41 5 : CPPUNIT_TEST_SUITE_END();
42 : };
43 :
44 1 : void BitmapFilterTest::testBlurCorrectness()
45 : {
46 : // Setup test bitmap
47 1 : Size aSize(41, 31);
48 1 : Bitmap aBitmap24Bit(aSize, 24);
49 :
50 1 : sal_uLong nScanlineFormat = 0;
51 1 : sal_uInt16 nBPP = aBitmap24Bit.GetBitCount();
52 :
53 : {
54 1 : long aMargin1 = 1;
55 1 : long aMargin2 = 3;
56 1 : Bitmap::ScopedWriteAccess aWriteAccess(aBitmap24Bit);
57 1 : nScanlineFormat = aWriteAccess->GetScanlineFormat();
58 1 : aWriteAccess->Erase(COL_WHITE);
59 1 : aWriteAccess->SetLineColor(COL_BLACK);
60 :
61 : Rectangle aRectangle1(
62 : aMargin1,
63 : aMargin1,
64 1 : aSize.Width() - 1 - aMargin1,
65 2 : aSize.Height() - 1 - aMargin1);
66 :
67 : Rectangle aRectangle2(
68 : aMargin2,
69 : aMargin2,
70 1 : aSize.Width() - 1 - aMargin2,
71 2 : aSize.Height() - 1 - aMargin2);
72 :
73 : Rectangle aRectangle3(
74 1 : aSize.Width() / 2,
75 1 : aSize.Height() / 2,
76 1 : aSize.Width() / 2,
77 4 : aSize.Height() / 2);
78 :
79 1 : aWriteAccess->DrawRect(aRectangle1);
80 1 : aWriteAccess->DrawRect(aRectangle2);
81 1 : aWriteAccess->DrawRect(aRectangle3);
82 : }
83 :
84 : if (constWriteResultBitmap)
85 : {
86 : SvFileStream aStream(OUString("~/blurBefore.png"), StreamMode::WRITE | StreamMode::TRUNC);
87 : GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
88 : rFilter.compressAsPNG(aBitmap24Bit, aStream, 1);
89 : }
90 :
91 : // Perform blur
92 2 : BitmapFilterStackBlur aBlurFilter(2);
93 1 : aBlurFilter.filter(aBitmap24Bit);
94 :
95 : // Check the result
96 :
97 : if (constWriteResultBitmap)
98 : {
99 : SvFileStream aStream(OUString("~/blurAfter.png"), StreamMode::WRITE | StreamMode::TRUNC);
100 : GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
101 : rFilter.compressAsPNG(aBitmap24Bit, aStream, 1);
102 : }
103 :
104 : // Check blurred bitmap parameters
105 1 : CPPUNIT_ASSERT_EQUAL(static_cast<long>(45), aBitmap24Bit.GetSizePixel().Width());
106 1 : CPPUNIT_ASSERT_EQUAL(static_cast<long>(35), aBitmap24Bit.GetSizePixel().Height());
107 :
108 1 : CPPUNIT_ASSERT_EQUAL(nBPP, aBitmap24Bit.GetBitCount());
109 :
110 : // Check that the bitmap is horizontally and vertically symmetrical
111 2 : BitmapSymmetryCheck symmetryCheck;
112 1 : CPPUNIT_ASSERT(symmetryCheck.check(aBitmap24Bit));
113 :
114 : {
115 1 : Bitmap::ScopedReadAccess aReadAccess(aBitmap24Bit);
116 1 : CPPUNIT_ASSERT_EQUAL(nScanlineFormat, aReadAccess->GetScanlineFormat());
117 1 : }
118 1 : }
119 :
120 1 : void BitmapFilterTest::testPerformance()
121 : {
122 : if (!constEnablePerformanceTest)
123 1 : return;
124 :
125 : Size aSize(4000, 3000); // A rather common picture size
126 :
127 : // Prepare bitmap
128 : Bitmap aBigBitmap(aSize, 24);
129 : {
130 : long aMargin = 500;
131 : Bitmap::ScopedWriteAccess aWriteAccess(aBigBitmap);
132 : aWriteAccess->Erase(COL_WHITE);
133 : aWriteAccess->SetLineColor(COL_BLACK);
134 : aWriteAccess->SetFillColor(COL_BLACK);
135 : Rectangle aRectangle(
136 : aMargin,
137 : aMargin,
138 : aSize.Width() - 1 - aMargin,
139 : aSize.Height() - 1 - aMargin);
140 :
141 : aWriteAccess->DrawRect(aRectangle);
142 : }
143 :
144 : int nIterations = 10;
145 : auto start = std::chrono::high_resolution_clock::now();
146 : for (int i = 0; i < nIterations; i++)
147 : {
148 : {
149 : BitmapFilterStackBlur aBlurFilter(250, false); // don't extend the image
150 : aBlurFilter.filter(aBigBitmap);
151 : }
152 : }
153 : auto end = std::chrono::high_resolution_clock::now();
154 : auto elapsed = (end - start) / nIterations;
155 :
156 : if (constWriteResultBitmap)
157 : {
158 : std::unique_ptr<SvFileStream> pStream(
159 : new SvFileStream(OUString("~/BlurBigPerformance.png"), StreamMode::WRITE | StreamMode::TRUNC));
160 : GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
161 : rFilter.compressAsPNG(aBigBitmap, *pStream, 1);
162 :
163 : pStream.reset(
164 : new SvFileStream(OUString("~/BlurBigPerformance.txt"), StreamMode::WRITE));
165 : pStream->WriteOString(OString("Blur average time: "));
166 : pStream->WriteOString(OString::number(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count()));
167 : pStream->WriteOString(OString("\n"));
168 : }
169 : }
170 :
171 : } // namespace
172 :
173 3 : CPPUNIT_TEST_SUITE_REGISTRATION(BitmapFilterTest);
174 :
175 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|