1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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
)
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())
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
));
77 pAlphaWriteAccess
.reset();
79 return BitmapEx(aDstBitmap
, AlphaMask(aDstAlpha
));
82 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */