include/vcl/BitmapArithmeticBlendFilter.hxx | 14 + svgio/source/svgreader/svgfecompositenode.cxx | 6 vcl/qa/cppunit/BitmapFilterTest.cxx | 182 ++++++++++++++++++---- vcl/source/bitmap/BitmapArithmeticBlendFilter.cxx | 41 ++-- 4 files changed, 183 insertions(+), 60 deletions(-)
New commits: commit 5b54f68599d9a9b6f4d21fd8c0cdac746ea71ecb Author: Chris Sherlock <chris.sherloc...@gmail.com> AuthorDate: Sat Sep 14 02:22:28 2024 +1000 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Fri Sep 20 22:53:17 2024 +0200 vcl: migrate BitmapArithmeticBlendFilter to use BitmapFilter class Change-Id: I524b8c87747b79a8698cce4bd092493ffc9c1235 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173350 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/vcl/BitmapArithmeticBlendFilter.hxx b/include/vcl/BitmapArithmeticBlendFilter.hxx index 6f936c0822bc..e63f838e65f4 100644 --- a/include/vcl/BitmapArithmeticBlendFilter.hxx +++ b/include/vcl/BitmapArithmeticBlendFilter.hxx @@ -11,19 +11,23 @@ #ifndef INCLUDED_VCL_BITMAPARITHMETICBLENDFILTER_HXX #define INCLUDED_VCL_BITMAPARITHMETICBLENDFILTER_HXX -#include <vcl/bitmapex.hxx> +#include <vcl/BitmapFilter.hxx> -class VCL_DLLPUBLIC BitmapArithmeticBlendFilter +class VCL_DLLPUBLIC BitmapArithmeticBlendFilter final : public BitmapFilter { private: - BitmapEx maBitmapEx; BitmapEx maBitmapEx2; + double mnK1; + double mnK2; + double mnK3; + double mnK4; public: - BitmapArithmeticBlendFilter(BitmapEx const& rBmpEx, BitmapEx const& rBmpEx2); + BitmapArithmeticBlendFilter(BitmapEx const& rBmpEx2, double nK1, double nK2, double nK3, + double nK4); ~BitmapArithmeticBlendFilter(); - BitmapEx execute(double aK1, double aK2, double aK3, double aK4); + BitmapEx execute(BitmapEx const& rBitmapEx) const; }; #endif diff --git a/svgio/source/svgreader/svgfecompositenode.cxx b/svgio/source/svgreader/svgfecompositenode.cxx index 0dea908847f6..9d9b1b2616f2 100644 --- a/svgio/source/svgreader/svgfecompositenode.cxx +++ b/svgio/source/svgreader/svgfecompositenode.cxx @@ -256,9 +256,9 @@ void SvgFeCompositeNode::apply(drawinglayer::primitive2d::Primitive2DContainer& aBaseRange.getHeight(), aBaseRange.getWidth() * aBaseRange.getHeight()); } - BitmapArithmeticBlendFilter aArithmeticFilter(aBmpEx, aBmpEx2); - BitmapEx aResBmpEx = aArithmeticFilter.execute(maK1.getNumber(), maK2.getNumber(), - maK3.getNumber(), maK4.getNumber()); + BitmapArithmeticBlendFilter aArithmeticFilter(aBmpEx2, maK1.getNumber(), maK2.getNumber(), + maK3.getNumber(), maK4.getNumber()); + BitmapEx aResBmpEx = aArithmeticFilter.execute(aBmpEx); const drawinglayer::primitive2d::Primitive2DReference xRef( new drawinglayer::primitive2d::BitmapPrimitive2D( diff --git a/vcl/qa/cppunit/BitmapFilterTest.cxx b/vcl/qa/cppunit/BitmapFilterTest.cxx index 099720a1569d..c34b121e4959 100644 --- a/vcl/qa/cppunit/BitmapFilterTest.cxx +++ b/vcl/qa/cppunit/BitmapFilterTest.cxx @@ -612,91 +612,207 @@ void BitmapFilterTest::testArithmeticBlendFilter() // same color { - BitmapArithmeticBlendFilter* pArithmeticFilter - = new BitmapArithmeticBlendFilter(aRedBitmapEx, aRedBitmapEx); - BitmapEx aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 0); + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 0, 0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(1, 0, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 1, 0, 0, 0)); CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 1, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 1, 0, 0)); CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 1, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 0, 1, 0)); CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 1); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 0, 0, 1)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xFF, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0.5, 0, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0.5, 0, 0, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0.5, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 0.5, 0, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0.5, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 0, 0.5, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 0.5); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aRedBitmapEx, 0, 0, 0, 0.5)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); } // Different colors { - BitmapArithmeticBlendFilter* pArithmeticFilter - = new BitmapArithmeticBlendFilter(aRedBitmapEx, aGreenBitmapEx); - BitmapEx aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 0); + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 0, 0, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(1, 0, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aGreenBitmapEx, 1, 0, 0, 0)); CPPUNIT_ASSERT_EQUAL(COL_BLACK, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 1, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 1, 0, 0)); CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 1, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 0, 1, 0)); CPPUNIT_ASSERT_EQUAL(COL_GREEN, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 1); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 0, 0, 1)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xFF, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0.5, 0, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aGreenBitmapEx, 0.5, 0, 0, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0x00, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0.5, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 0.5, 0, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0.5, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 0, 0.5, 0)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0x00, 0x81, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 0.5); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aGreenBitmapEx, 0, 0, 0, 0.5)); CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); } // transparent { - BitmapArithmeticBlendFilter* pArithmeticFilter - = new BitmapArithmeticBlendFilter(aRedBitmapEx, aTransparentBitmapEx); - BitmapEx aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 0); + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 0, 0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(1, 0, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 1, 0, 0, 0)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 1, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 1, 0, 0)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 1, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 0, 1, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xFF, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 1); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 0, 0, 1)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xFF, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0.5, 0, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0.5, 0, 0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0.5, 0, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 0.5, 0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0x00, 0x00), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0.5, 0); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 0, 0.5, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); - aResBitmapEx = pArithmeticFilter->execute(0, 0, 0, 0.5); + } + + { + BitmapEx aResBitmapEx(aRedBitmapEx); + BitmapFilter::Filter(aResBitmapEx, + BitmapArithmeticBlendFilter(aTransparentBitmapEx, 0, 0, 0, 0.5)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x7F, 0xFF, 0xFF, 0xFF), aResBitmapEx.GetPixelColor(0, 0)); } diff --git a/vcl/source/bitmap/BitmapArithmeticBlendFilter.cxx b/vcl/source/bitmap/BitmapArithmeticBlendFilter.cxx index d46b7bc9bd74..8f88fac58e60 100644 --- a/vcl/source/bitmap/BitmapArithmeticBlendFilter.cxx +++ b/vcl/source/bitmap/BitmapArithmeticBlendFilter.cxx @@ -13,31 +13,34 @@ #include <vcl/BitmapWriteAccess.hxx> #include <vcl/BitmapTools.hxx> -BitmapArithmeticBlendFilter::BitmapArithmeticBlendFilter(BitmapEx const& rBitmapEx, - BitmapEx const& rBitmapEx2) - : maBitmapEx(rBitmapEx) - , maBitmapEx2(rBitmapEx2) +BitmapArithmeticBlendFilter::BitmapArithmeticBlendFilter(BitmapEx const& rBitmapEx2, double nK1, + double nK2, double nK3, double nK4) + : maBitmapEx2(rBitmapEx2) + , mnK1(nK1) + , mnK2(nK2) + , mnK3(nK3) + , mnK4(nK4) { } BitmapArithmeticBlendFilter::~BitmapArithmeticBlendFilter() {} -static sal_uInt8 lcl_calculate(sal_uInt8 aColor, sal_uInt8 aColor2, double aK1, double aK2, - double aK3, double aK4) +static sal_uInt8 lcl_calculate(sal_uInt8 cColor, sal_uInt8 cColor2, double nK1, double nK2, + double nK3, double nK4) { - const double i1 = aColor / 255.0; - const double i2 = aColor2 / 255.0; - const double result = aK1 * i1 * i2 + aK2 * i1 + aK3 * i2 + aK4; + const double i1 = cColor / 255.0; + const double i2 = cColor2 / 255.0; + const double result = nK1 * i1 * i2 + nK2 * i1 + nK3 * i2 + nK4; return std::clamp(result, 0.0, 1.0) * 255.0; } -BitmapEx BitmapArithmeticBlendFilter::execute(double aK1, double aK2, double aK3, double aK4) +BitmapEx BitmapArithmeticBlendFilter::execute(BitmapEx const& rBitmapEx) const { - if (maBitmapEx.IsEmpty() || maBitmapEx2.IsEmpty()) + if (rBitmapEx.IsEmpty() || maBitmapEx2.IsEmpty()) return BitmapEx(); - Size aSize = maBitmapEx.GetBitmap().GetSizePixel(); + Size aSize = rBitmapEx.GetBitmap().GetSizePixel(); Size aSize2 = maBitmapEx2.GetBitmap().GetSizePixel(); sal_Int32 nHeight = std::min(aSize.getHeight(), aSize2.getHeight()); sal_Int32 nWidth = std::min(aSize.getWidth(), aSize2.getWidth()); @@ -48,18 +51,18 @@ BitmapEx BitmapArithmeticBlendFilter::execute(double aK1, double aK2, double aK3 BitmapScopedWriteAccess pWriteAccess(aDstBitmap); BitmapScopedWriteAccess pAlphaWriteAccess(aDstAlpha); - for (tools::Long y(0); y < nHeight; ++y) + for (tools::Long y = 0; y < nHeight; ++y) { Scanline pScanline = pWriteAccess->GetScanline(y); Scanline pScanAlpha = pAlphaWriteAccess->GetScanline(y); - for (tools::Long x(0); x < nWidth; ++x) + for (tools::Long x = 0; x < nWidth; ++x) { - BitmapColor i1 = vcl::bitmap::premultiply(maBitmapEx.GetPixelColor(x, y)); + BitmapColor i1 = vcl::bitmap::premultiply(rBitmapEx.GetPixelColor(x, y)); BitmapColor i2 = vcl::bitmap::premultiply(maBitmapEx2.GetPixelColor(x, y)); - sal_uInt8 r(lcl_calculate(i1.GetRed(), i2.GetRed(), aK1, aK2, aK3, aK4)); - sal_uInt8 g(lcl_calculate(i1.GetGreen(), i2.GetGreen(), aK1, aK2, aK3, aK4)); - sal_uInt8 b(lcl_calculate(i1.GetBlue(), i2.GetBlue(), aK1, aK2, aK3, aK4)); - sal_uInt8 a(lcl_calculate(i1.GetAlpha(), i2.GetAlpha(), aK1, aK2, aK3, aK4)); + sal_uInt8 r(lcl_calculate(i1.GetRed(), i2.GetRed(), mnK1, mnK2, mnK3, mnK4)); + sal_uInt8 g(lcl_calculate(i1.GetGreen(), i2.GetGreen(), mnK1, mnK2, mnK3, mnK4)); + sal_uInt8 b(lcl_calculate(i1.GetBlue(), i2.GetBlue(), mnK1, mnK2, mnK3, mnK4)); + sal_uInt8 a(lcl_calculate(i1.GetAlpha(), i2.GetAlpha(), mnK1, mnK2, mnK3, mnK4)); pWriteAccess->SetPixelOnData( pScanline, x, vcl::bitmap::unpremultiply(BitmapColor(ColorAlpha, r, g, b, a)));