diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-01-11 10:42:23 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-01-11 10:42:23 +0100 |
commit | da40d2558e3de30914f4c181cceb66937c6f1124 (patch) | |
tree | 7ebc2980b02117b6b9264ad2beabb07e02db8faf /vcl | |
parent | cd9a016116e07e6ac08dcdd3b08b3d070469cedc (diff) |
Remove BitmapFilterStackBlur, which is unused...
...ever since it got introduced with 28c61871e876e6a2cac47439f768504b1a4c94a0
"vcl: stack blur implementation + basic test & performance test"
Change-Id: I78672cf74c24930df92121baecb9886df4382036
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/CppunitTest_vcl_bitmap_test.mk | 1 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/qa/cppunit/BitmapFilterTest.cxx | 175 | ||||
-rw-r--r-- | vcl/source/bitmap/BitmapFilterStackBlur.cxx | 581 |
4 files changed, 0 insertions, 758 deletions
diff --git a/vcl/CppunitTest_vcl_bitmap_test.mk b/vcl/CppunitTest_vcl_bitmap_test.mk index 290d167675b1..a65ddb349767 100644 --- a/vcl/CppunitTest_vcl_bitmap_test.mk +++ b/vcl/CppunitTest_vcl_bitmap_test.mk @@ -11,7 +11,6 @@ $(eval $(call gb_CppunitTest_CppunitTest,vcl_bitmap_test)) $(eval $(call gb_CppunitTest_add_exception_objects,vcl_bitmap_test, \ vcl/qa/cppunit/BitmapTest \ - vcl/qa/cppunit/BitmapFilterTest \ )) $(eval $(call gb_CppunitTest_use_externals,vcl_bitmap_test,\ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index f7572329a939..961bb0593e73 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -317,7 +317,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/bitmap/bitmapscalesuper \ vcl/source/bitmap/BitmapScaleConvolution \ vcl/source/bitmap/BitmapSymmetryCheck \ - vcl/source/bitmap/BitmapFilterStackBlur \ vcl/source/bitmap/BitmapProcessor \ vcl/source/bitmap/BitmapTools \ vcl/source/bitmap/checksum \ diff --git a/vcl/qa/cppunit/BitmapFilterTest.cxx b/vcl/qa/cppunit/BitmapFilterTest.cxx deleted file mode 100644 index ade5acbc6271..000000000000 --- a/vcl/qa/cppunit/BitmapFilterTest.cxx +++ /dev/null @@ -1,175 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include <cppunit/TestAssert.h> -#include <cppunit/TestFixture.h> -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/plugin/TestPlugIn.h> - -#include <vcl/bitmap.hxx> -#include <vcl/bmpacc.hxx> - -#include <tools/stream.hxx> -#include <vcl/graphicfilter.hxx> - -#include <vcl/BitmapFilterStackBlur.hxx> -#include "BitmapSymmetryCheck.hxx" - -#include <chrono> - -namespace -{ - -const bool constWriteResultBitmap(false); -const bool constEnablePerformanceTest(false); - -class BitmapFilterTest : public CppUnit::TestFixture -{ - - void testBlurCorrectness(); - void testPerformance(); - - CPPUNIT_TEST_SUITE(BitmapFilterTest); - CPPUNIT_TEST(testBlurCorrectness); - CPPUNIT_TEST(testPerformance); - CPPUNIT_TEST_SUITE_END(); -}; - -void BitmapFilterTest::testBlurCorrectness() -{ - // Setup test bitmap - Size aSize(41, 31); - Bitmap aBitmap24Bit(aSize, 24); - - sal_uLong nScanlineFormat = 0; - sal_uInt16 nBPP = aBitmap24Bit.GetBitCount(); - - { - long aMargin1 = 1; - long aMargin2 = 3; - Bitmap::ScopedWriteAccess aWriteAccess(aBitmap24Bit); - nScanlineFormat = aWriteAccess->GetScanlineFormat(); - aWriteAccess->Erase(COL_WHITE); - aWriteAccess->SetLineColor(COL_BLACK); - - Rectangle aRectangle1( - aMargin1, - aMargin1, - aSize.Width() - 1 - aMargin1, - aSize.Height() - 1 - aMargin1); - - Rectangle aRectangle2( - aMargin2, - aMargin2, - aSize.Width() - 1 - aMargin2, - aSize.Height() - 1 - aMargin2); - - Rectangle aRectangle3( - aSize.Width() / 2, - aSize.Height() / 2, - aSize.Width() / 2, - aSize.Height() / 2); - - aWriteAccess->DrawRect(aRectangle1); - aWriteAccess->DrawRect(aRectangle2); - aWriteAccess->DrawRect(aRectangle3); - } - - if (constWriteResultBitmap) - { - SvFileStream aStream(OUString("~/blurBefore.png"), StreamMode::WRITE | StreamMode::TRUNC); - GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); - rFilter.compressAsPNG(aBitmap24Bit, aStream, 1); - } - - // Perform blur - BitmapFilterStackBlur aBlurFilter(2); - aBlurFilter.filter(aBitmap24Bit); - - // Check the result - - if (constWriteResultBitmap) - { - SvFileStream aStream(OUString("~/blurAfter.png"), StreamMode::WRITE | StreamMode::TRUNC); - GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); - rFilter.compressAsPNG(aBitmap24Bit, aStream, 1); - } - - // Check blurred bitmap parameters - CPPUNIT_ASSERT_EQUAL(static_cast<long>(45), aBitmap24Bit.GetSizePixel().Width()); - CPPUNIT_ASSERT_EQUAL(static_cast<long>(35), aBitmap24Bit.GetSizePixel().Height()); - - CPPUNIT_ASSERT_EQUAL(nBPP, aBitmap24Bit.GetBitCount()); - - // Check that the bitmap is horizontally and vertically symmetrical - BitmapSymmetryCheck symmetryCheck; - CPPUNIT_ASSERT(BitmapSymmetryCheck::check(aBitmap24Bit)); - - { - Bitmap::ScopedReadAccess aReadAccess(aBitmap24Bit); - CPPUNIT_ASSERT_EQUAL(nScanlineFormat, aReadAccess->GetScanlineFormat()); - } -} - -void BitmapFilterTest::testPerformance() -{ - if (!constEnablePerformanceTest) - return; - - Size aSize(4000, 3000); // A rather common picture size - - // Prepare bitmap - Bitmap aBigBitmap(aSize, 24); - { - long aMargin = 500; - Bitmap::ScopedWriteAccess aWriteAccess(aBigBitmap); - aWriteAccess->Erase(COL_WHITE); - aWriteAccess->SetLineColor(COL_BLACK); - aWriteAccess->SetFillColor(COL_BLACK); - Rectangle aRectangle( - aMargin, - aMargin, - aSize.Width() - 1 - aMargin, - aSize.Height() - 1 - aMargin); - - aWriteAccess->DrawRect(aRectangle); - } - - int nIterations = 10; - auto start = std::chrono::high_resolution_clock::now(); - for (int i = 0; i < nIterations; i++) - { - { - BitmapFilterStackBlur aBlurFilter(250, false); // don't extend the image - aBlurFilter.filter(aBigBitmap); - } - } - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed = (end - start) / nIterations; - - if (constWriteResultBitmap) - { - std::unique_ptr<SvFileStream> pStream( - new SvFileStream(OUString("~/BlurBigPerformance.png"), StreamMode::WRITE | StreamMode::TRUNC)); - GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); - rFilter.compressAsPNG(aBigBitmap, *pStream, 1); - - pStream.reset( - new SvFileStream(OUString("~/BlurBigPerformance.txt"), StreamMode::WRITE)); - pStream->WriteOString(OString("Blur average time: ")); - pStream->WriteOString(OString::number(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count())); - pStream->WriteOString(OString("\n")); - } -} - -} // namespace - -CPPUNIT_TEST_SUITE_REGISTRATION(BitmapFilterTest); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/bitmap/BitmapFilterStackBlur.cxx b/vcl/source/bitmap/BitmapFilterStackBlur.cxx deleted file mode 100644 index a2664b702e7c..000000000000 --- a/vcl/source/bitmap/BitmapFilterStackBlur.cxx +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - */ - -#include <vcl/BitmapFilterStackBlur.hxx> -#include <vcl/bmpacc.hxx> - -namespace -{ - -static const sal_Int16 constMultiplyTable[255] = -{ - 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, - 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, - 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, - 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, - 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, - 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, - 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, - 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, - 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, - 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, - 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, - 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, - 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, - 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, - 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, - 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259 -}; - -static const sal_Int16 constShiftTable[255] = -{ - 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, - 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 -}; - -class BlurSharedData -{ -public: - long mnRadius; - long mnComponentWidth; - long mnColorChannels; - long mnDiv; - std::vector<sal_uInt8> maStackBuffer; - std::vector<long> maPositionTable; - std::vector<long> maWeightTable; - - std::vector<long> mnSumVector; - std::vector<long> mnInSumVector; - std::vector<long> mnOutSumVector; - - BlurSharedData(long aRadius, long nComponentWidth, long nColorChannels) - : mnRadius(aRadius) - , mnComponentWidth(nComponentWidth) - , mnColorChannels(nColorChannels) - , mnDiv(aRadius + aRadius + 1) - , maStackBuffer(mnDiv * mnComponentWidth) - , maPositionTable(mnDiv) - , maWeightTable(mnDiv) - , mnSumVector(mnColorChannels) - , mnInSumVector(mnColorChannels) - , mnOutSumVector(mnColorChannels) - { - } - - void calculateWeightAndPositions(long nLastIndex) - { - for (long i = 0; i < mnDiv; i++) - { - maPositionTable[i] = std::min(nLastIndex, std::max(0L, i - mnRadius)); - maWeightTable[i] = mnRadius + 1 - std::abs(i - mnRadius); - } - } - - long getMultiplyValue() - { - return static_cast<long>(constMultiplyTable[mnRadius]); - } - - long getShiftValue() - { - return static_cast<long>(constShiftTable[mnRadius]); - } -}; - -struct SumFunction24 -{ - static inline void add(long*& pValue1, long nConstant) - { - pValue1[0] += nConstant; - pValue1[1] += nConstant; - pValue1[2] += nConstant; - } - - static inline void set(long*& pValue1, long nConstant) - { - pValue1[0] = nConstant; - pValue1[1] = nConstant; - pValue1[2] = nConstant; - } - - static inline void add(long*& pValue1, sal_uInt8*& pValue2) - { - pValue1[0] += pValue2[0]; - pValue1[1] += pValue2[1]; - pValue1[2] += pValue2[2]; - } - - static inline void add(long*& pValue1, long*& pValue2) - { - pValue1[0] += pValue2[0]; - pValue1[1] += pValue2[1]; - pValue1[2] += pValue2[2]; - } - - static inline void sub(long*& pValue1, sal_uInt8*& pValue2) - { - pValue1[0] -= pValue2[0]; - pValue1[1] -= pValue2[1]; - pValue1[2] -= pValue2[2]; - } - - static inline void sub(long*& pValue1, long*& pValue2) - { - pValue1[0] -= pValue2[0]; - pValue1[1] -= pValue2[1]; - pValue1[2] -= pValue2[2]; - } - - static inline void assignPtr(sal_uInt8*& pValue1, sal_uInt8*& pValue2) - { - pValue1[0] = pValue2[0]; - pValue1[1] = pValue2[1]; - pValue1[2] = pValue2[2]; - } - - static inline void assignMulAndShr(sal_uInt8*& result, long*& sum, long multiply, long shift) - { - result[0] = (multiply * sum[0]) >> shift; - result[1] = (multiply * sum[1]) >> shift; - result[2] = (multiply * sum[2]) >> shift; - } -}; - -struct SumFunction8 -{ - static inline void add(long*& pValue1, long nConstant) - { - pValue1[0] += nConstant; - } - - static inline void set(long*& pValue1, long nConstant) - { - pValue1[0] = nConstant; - } - - static inline void add(long*& pValue1, sal_uInt8*& pValue2) - { - pValue1[0] += pValue2[0]; - } - - static inline void add(long*& pValue1, long*& pValue2) - { - pValue1[0] += pValue2[0]; - } - - static inline void sub(long*& pValue1, sal_uInt8*& pValue2) - { - pValue1[0] -= pValue2[0]; - } - - static inline void sub(long*& pValue1, long*& pValue2) - { - pValue1[0] -= pValue2[0]; - } - - static inline void assignPtr(sal_uInt8*& pValue1, sal_uInt8*& pValue2) - { - pValue1[0] = pValue2[0]; - } - - static inline void assignMulAndShr(sal_uInt8*& result, long*& sum, long multiply, long shift) - { - result[0] = (multiply * sum[0]) >> shift; - } -}; - -template<typename SumFunction> -void stackBlurHorizontal( - BitmapReadAccess* pReadAccess, - BitmapWriteAccess* pWriteAccess, - BlurSharedData& rShared) -{ - long nWidth = pReadAccess->Width(); - long nHeight = pReadAccess->Height(); - - sal_uInt8* pStack = rShared.maStackBuffer.data(); - sal_uInt8* pStackPtr; - - long nLastIndexX = nWidth - 1; - - long nMultiplyValue = rShared.getMultiplyValue(); - long nShiftValue = rShared.getShiftValue(); - - long nRadius = rShared.mnRadius; - long nComponentWidth = rShared.mnComponentWidth; - long nDiv = rShared.mnDiv; - - Scanline pSourcePointer; - Scanline pDestinationPointer; - - long nXPosition; - long nStackIndex; - long nStackIndexStart; - long nWeight; - - long* nSum = rShared.mnSumVector.data(); - long* nInSum = rShared.mnInSumVector.data(); - long* nOutSum = rShared.mnOutSumVector.data(); - - rShared.calculateWeightAndPositions(nLastIndexX); - long* pPositionPointer = rShared.maPositionTable.data(); - long* pWeightPointer = rShared.maWeightTable.data(); - - for (long y = 0; y < nHeight; y++) - { - SumFunction::set(nSum, 0L); - SumFunction::set(nInSum, 0L); - SumFunction::set(nOutSum, 0L); - - for (long i = 0; i < nDiv; i++) - { - pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]); - - pStackPtr = &pStack[nComponentWidth * i]; - - SumFunction::assignPtr(pStackPtr, pSourcePointer); - - nWeight = pWeightPointer[i]; - - SumFunction::add(nSum, pSourcePointer[0] * nWeight); - - if (i - nRadius > 0) - { - SumFunction::add(nInSum, pSourcePointer); - } - else - { - SumFunction::add(nOutSum, pSourcePointer); - } - } - - nStackIndex = nRadius; - nXPosition = std::min(nRadius, nLastIndexX); - - pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth * nXPosition; - - for (long x = 0; x < nWidth; x++) - { - pDestinationPointer = pWriteAccess->GetScanline(y) + nComponentWidth * x; - - SumFunction::assignMulAndShr(pDestinationPointer, nSum, nMultiplyValue, nShiftValue); - - SumFunction::sub(nSum, nOutSum); - - nStackIndexStart = nStackIndex + nDiv - nRadius; - if (nStackIndexStart >= nDiv) - { - nStackIndexStart -= nDiv; - } - pStackPtr = &pStack[nComponentWidth * nStackIndexStart]; - - SumFunction::sub(nOutSum, pStackPtr); - - if (nXPosition < nLastIndexX) - { - nXPosition++; - pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth * nXPosition; - } - - SumFunction::assignPtr(pStackPtr, pSourcePointer); - - SumFunction::add(nInSum, pSourcePointer); - - SumFunction::add(nSum, nInSum); - - nStackIndex++; - if (nStackIndex >= nDiv) - { - nStackIndex = 0; - } - - pStackPtr = &pStack[nStackIndex * nComponentWidth]; - - SumFunction::add(nOutSum, pStackPtr); - SumFunction::sub(nInSum, pStackPtr); - } - } -} - -template<typename SumFunction> -void stackBlurVertical( - BitmapReadAccess* pReadAccess, - BitmapWriteAccess* pWriteAccess, - BlurSharedData& rShared) -{ - long nWidth = pReadAccess->Width(); - long nHeight = pReadAccess->Height(); - - sal_uInt8* pStack = rShared.maStackBuffer.data(); - sal_uInt8* pStackPtr; - - long nLastIndexY = nHeight - 1; - - long nMultiplyValue = rShared.getMultiplyValue(); - long nShiftValue = rShared.getShiftValue(); - - long nRadius = rShared.mnRadius; - long nComponentWidth = rShared.mnComponentWidth; - long nDiv = rShared.mnDiv; - - Scanline pSourcePointer; - Scanline pDestinationPointer; - - long nYPosition; - long nStackIndex; - long nStackIndexStart; - long nWeight; - - long* nSum = rShared.mnSumVector.data(); - long* nInSum = rShared.mnInSumVector.data(); - long* nOutSum = rShared.mnOutSumVector.data(); - - rShared.calculateWeightAndPositions(nLastIndexY); - long* pPositionPointer = rShared.maPositionTable.data(); - long* pWeightPointer = rShared.maWeightTable.data(); - - for (long x = 0; x < nWidth; x++) - { - SumFunction::set(nSum, 0L); - SumFunction::set(nInSum, 0L); - SumFunction::set(nOutSum, 0L); - - for (long i = 0; i < nDiv; i++) - { - pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]); - - pStackPtr = &pStack[nComponentWidth * i]; - - SumFunction::assignPtr(pStackPtr, pSourcePointer); - - nWeight = pWeightPointer[i]; - - SumFunction::add(nSum, pSourcePointer[0] * nWeight); - - if (i - nRadius > 0) - { - SumFunction::add(nInSum, pSourcePointer); - } - else - { - SumFunction::add(nOutSum, pSourcePointer); - } - } - - nStackIndex = nRadius; - nYPosition = std::min(nRadius, nLastIndexY); - - pSourcePointer = pReadAccess->GetScanline(nYPosition) + nComponentWidth * x; - - for (long y = 0; y < nHeight; y++) - { - pDestinationPointer = pWriteAccess->GetScanline(y) + nComponentWidth * x; - - SumFunction::assignMulAndShr(pDestinationPointer, nSum, nMultiplyValue, nShiftValue); - - SumFunction::sub(nSum, nOutSum); - - - nStackIndexStart = nStackIndex + nDiv - nRadius; - if (nStackIndexStart >= nDiv) - { - nStackIndexStart -= nDiv; - } - pStackPtr = &pStack[nComponentWidth * nStackIndexStart]; - - SumFunction::sub(nOutSum, pStackPtr); - - if (nYPosition < nLastIndexY) - { - nYPosition++; - pSourcePointer = pReadAccess->GetScanline(nYPosition) + nComponentWidth * x; - } - - SumFunction::assignPtr(pStackPtr, pSourcePointer); - - SumFunction::add(nInSum, pSourcePointer); - - SumFunction::add(nSum, nInSum); - - nStackIndex++; - if (nStackIndex >= nDiv) - { - nStackIndex = 0; - } - - pStackPtr = &pStack[nStackIndex * nComponentWidth]; - - SumFunction::add(nOutSum, pStackPtr); - - SumFunction::sub(nInSum, pStackPtr); - } - } -} - -void stackBlur24(Bitmap& rBitmap, sal_Int32 nRadius, sal_Int32 nComponentWidth) -{ - // Limit radius - nRadius = std::min<sal_Int32>(254, std::max<sal_Int32>(2, nRadius)); - const long nColorChannels = 3; // 3 color channel - BlurSharedData aData(nRadius, nComponentWidth, nColorChannels); - - { - Bitmap::ScopedReadAccess pReadAccess(rBitmap); - Bitmap::ScopedWriteAccess pWriteAccess(rBitmap); - - stackBlurHorizontal<SumFunction24>(pReadAccess.get(), pWriteAccess.get(), aData); - } - - { - Bitmap::ScopedReadAccess pReadAccess(rBitmap); - Bitmap::ScopedWriteAccess pWriteAccess(rBitmap); - - stackBlurVertical<SumFunction24>(pReadAccess.get(), pWriteAccess.get(), aData); - } -} - -void stackBlur8(Bitmap& rBitmap, sal_Int32 nRadius, sal_Int32 nComponentWidth) -{ - // Limit radius - nRadius = std::min<sal_Int32>(254, std::max<sal_Int32>(2, nRadius)); - const long nColorChannels = 1; // 1 color channel - BlurSharedData aData(nRadius, nComponentWidth, nColorChannels); - - { - Bitmap::ScopedReadAccess pReadAccess(rBitmap); - Bitmap::ScopedWriteAccess pWriteAccess(rBitmap); - - stackBlurHorizontal<SumFunction8>(pReadAccess.get(), pWriteAccess.get(), aData); - } - - { - Bitmap::ScopedReadAccess pReadAccess(rBitmap); - Bitmap::ScopedWriteAccess pWriteAccess(rBitmap); - - stackBlurVertical<SumFunction8>(pReadAccess.get(), pWriteAccess.get(), aData); - } -} - -void centerExtendBitmap(Bitmap& rBitmap, sal_Int32 nExtendSize, Color aColor) -{ - const Size& rSize = rBitmap.GetSizePixel(); - const Size aNewSize(rSize.Width() + nExtendSize * 2, - rSize.Height() + nExtendSize * 2); - - Bitmap aNewBitmap(aNewSize, rBitmap.GetBitCount()); - - { - Bitmap::ScopedReadAccess pReadAccess(rBitmap); - Bitmap::ScopedWriteAccess pWriteAccess(aNewBitmap); - - long nWidthBorder = nExtendSize + rSize.Width(); - long nHeightBorder = nExtendSize + rSize.Height(); - - for (long y = 0; y < aNewSize.Height(); y++) - { - for (long x = 0; x < aNewSize.Width(); x++) - { - if (y < nExtendSize || y >= nHeightBorder - || x < nExtendSize || x >= nWidthBorder) - { - pWriteAccess->SetPixel(y, x, aColor); - } - else - { - pWriteAccess->SetPixel(y, x, pReadAccess->GetPixel(y - nExtendSize, x - nExtendSize)); - } - } - } - } - rBitmap = aNewBitmap; -} - -} // end anonymous namespace - -/** - * Implementation of stack blur - a fast Gaussian blur approximation. - * nRadius - blur radious, valid values are between 2 and 254 - * bExtend - extend the bitmap in all directions by the radius - * - * Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> - * (http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html) - * - * Additionally references and implementations: - * - Blur.js by Jacob Kelley - * (http://www.blurjs.com) - * - BlurEffectForAndroidDesign by Nicolas Pomepuy - * (https://github.com/PomepuyN/BlurEffectForAndroidDesign) - * - StackBluriOS by Thomas Landspurg - * (https://github.com/tomsoft1/StackBluriOS) - * - stackblur.cpp by Benjamin Yates - * (https://gist.github.com/benjamin9999/3809142) - * - stack blur in fog 2D graphic library by Petr Kobalicek - * (https://code.google.com/p/fog/) - * - */ -BitmapFilterStackBlur::BitmapFilterStackBlur(sal_Int32 nRadius, bool bExtend) - : mnRadius(nRadius) - , mbExtend(bExtend) -{} - -BitmapFilterStackBlur::~BitmapFilterStackBlur() -{} - -bool BitmapFilterStackBlur::filter(Bitmap& rBitmap) -{ - sal_uLong nScanlineFormat; - { - Bitmap::ScopedReadAccess pReadAccess(rBitmap); - nScanlineFormat = pReadAccess->GetScanlineFormat(); - } - - if (nScanlineFormat == BMP_FORMAT_24BIT_TC_RGB || - nScanlineFormat == BMP_FORMAT_24BIT_TC_BGR || - nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK) - { - int nComponentWidth = (nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK) ? 4 : 3; - - if (mbExtend) - { - centerExtendBitmap(rBitmap, mnRadius, COL_WHITE); - } - - stackBlur24(rBitmap, mnRadius, nComponentWidth); - } - else if (nScanlineFormat == BMP_FORMAT_8BIT_PAL) - { - int nComponentWidth = 1; - - if (mbExtend) - { - centerExtendBitmap(rBitmap, mnRadius, COL_WHITE); - } - - stackBlur8(rBitmap, mnRadius, nComponentWidth); - } - - return true; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |