Get the style color and number just once
[LibreOffice.git] / vcl / source / bitmap / BitmapArithmeticBlendFilter.cxx
blobc63d7d23d8cc400a3847d6b4138973e6b5787348
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/.
9 */
11 #include <comphelper/diagnose_ex.hxx>
13 #include <vcl/bitmap/BitmapArithmeticBlendFilter.hxx>
14 #include <vcl/BitmapWriteAccess.hxx>
15 #include <vcl/BitmapTools.hxx>
17 BitmapArithmeticBlendFilter::BitmapArithmeticBlendFilter(BitmapEx const& rBitmapEx2, double nK1,
18 double nK2, double nK3, double nK4)
19 : maBitmapEx2(rBitmapEx2)
20 , mnK1(nK1)
21 , mnK2(nK2)
22 , mnK3(nK3)
23 , mnK4(nK4)
27 BitmapArithmeticBlendFilter::~BitmapArithmeticBlendFilter() {}
29 static sal_uInt8 lcl_calculate(const sal_uInt8 cColor, const sal_uInt8 cColor2, const double nK1,
30 const double nK2, const double nK3, const double nK4)
32 const double i1 = cColor / 255.0;
33 const double i2 = cColor2 / 255.0;
34 const double result = nK1 * i1 * i2 + nK2 * i1 + nK3 * i2 + nK4;
36 return std::clamp(result, 0.0, 1.0) * 255.0;
39 BitmapEx BitmapArithmeticBlendFilter::execute(BitmapEx const& rBitmapEx) const
41 if (rBitmapEx.IsEmpty() || maBitmapEx2.IsEmpty())
42 return BitmapEx();
44 const Size aSize = rBitmapEx.GetBitmap().GetSizePixel();
45 const Size aSize2 = maBitmapEx2.GetBitmap().GetSizePixel();
46 const sal_Int32 nHeight = std::min(aSize.getHeight(), aSize2.getHeight());
47 const sal_Int32 nWidth = std::min(aSize.getWidth(), aSize2.getWidth());
49 Bitmap aDstBitmap(Size(nWidth, nHeight), vcl::PixelFormat::N24_BPP);
50 Bitmap aDstAlpha(AlphaMask(Size(nWidth, nHeight)).GetBitmap());
52 BitmapScopedWriteAccess pWriteAccess(aDstBitmap);
53 BitmapScopedWriteAccess pAlphaWriteAccess(aDstAlpha);
55 for (tools::Long y = 0; y < nHeight; ++y)
57 Scanline pScanline = pWriteAccess->GetScanline(y);
58 Scanline pScanAlpha = pAlphaWriteAccess->GetScanline(y);
60 for (tools::Long x = 0; x < nWidth; ++x)
62 const BitmapColor i1 = vcl::bitmap::premultiply(rBitmapEx.GetPixelColor(x, y));
63 const BitmapColor i2 = vcl::bitmap::premultiply(maBitmapEx2.GetPixelColor(x, y));
65 const sal_uInt8 r(lcl_calculate(i1.GetRed(), i2.GetRed(), mnK1, mnK2, mnK3, mnK4));
66 const sal_uInt8 g(lcl_calculate(i1.GetGreen(), i2.GetGreen(), mnK1, mnK2, mnK3, mnK4));
67 const sal_uInt8 b(lcl_calculate(i1.GetBlue(), i2.GetBlue(), mnK1, mnK2, mnK3, mnK4));
68 const sal_uInt8 a(lcl_calculate(i1.GetAlpha(), i2.GetAlpha(), mnK1, mnK2, mnK3, mnK4));
70 pWriteAccess->SetPixelOnData(
71 pScanline, x, vcl::bitmap::unpremultiply(BitmapColor(ColorAlpha, r, g, b, a)));
72 pAlphaWriteAccess->SetPixelOnData(pScanAlpha, x, BitmapColor(a));
76 pWriteAccess.reset();
77 pAlphaWriteAccess.reset();
79 return BitmapEx(aDstBitmap, AlphaMask(aDstAlpha));
82 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */