Krita Source Code Documentation
Loading...
Searching...
No Matches
KoCompositeOpBase.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#ifndef KOCOMPOSITEOP_BASE_H_
8#define KOCOMPOSITEOP_BASE_H_
9
10#include <KoCompositeOp.h>
11#include <KoColorSpaceMaths.h>
12
31template<class _CSTraits, class _compositeOp>
33{
34 typedef typename _CSTraits::channels_type channels_type;
35 static const qint32 channels_nb = _CSTraits::channels_nb;
36 static const qint32 alpha_pos = _CSTraits::alpha_pos;
37 static const qint32 pixel_size = _CSTraits::pixelSize;
38
39public:
40 KoCompositeOpBase(const KoColorSpace* cs, const QString& id, const QString& category)
41 : KoCompositeOp(cs, id, category) { }
42
44
45 void composite(const KoCompositeOp::ParameterInfo& params) const override {
46
47 const QBitArray& flags = params.channelFlags.isEmpty() ? QBitArray(channels_nb,true) : params.channelFlags;
48 bool allChannelFlags = params.channelFlags.isEmpty() || params.channelFlags == QBitArray(channels_nb,true);
49 bool alphaLocked = (alpha_pos != -1) && !flags.testBit(alpha_pos);
50 bool useMask = params.maskRowStart != 0;
51
52 if(useMask) {
53 if(alphaLocked) {
54 if(allChannelFlags) { genericComposite<true,true,true> (params, flags); }
55 else { genericComposite<true,true,false>(params, flags); }
56 }
57 else {
58 if(allChannelFlags) { genericComposite<true,false,true> (params, flags); }
59 else { genericComposite<true,false,false>(params, flags); }
60 }
61 }
62 else {
63 if(alphaLocked) {
64 if(allChannelFlags) { genericComposite<false,true,true> (params, flags); }
65 else { genericComposite<false,true,false>(params, flags); }
66 }
67 else {
68 if(allChannelFlags) { genericComposite<false,false,true> (params, flags); }
69 else { genericComposite<false,false,false>(params, flags); }
70 }
71 }
72 }
73
74private:
75 template<bool useMask, bool alphaLocked, bool allChannelFlags>
76 void genericComposite(const KoCompositeOp::ParameterInfo& params, const QBitArray& channelFlags) const {
77
78 using namespace Arithmetic;
79
80 qint32 srcInc = (params.srcRowStride == 0) ? 0 : channels_nb;
81 channels_type opacity = scale<channels_type>(params.opacity);
82 quint8* dstRowStart = params.dstRowStart;
83 const quint8* srcRowStart = params.srcRowStart;
84 const quint8* maskRowStart = params.maskRowStart;
85
86 for (qint32 r=0; r<params.rows; ++r) {
87 const channels_type* src = reinterpret_cast<const channels_type*>(srcRowStart);
88 channels_type* dst = reinterpret_cast<channels_type*>(dstRowStart);
89 const quint8* mask = maskRowStart;
90
91 for (qint32 c=0; c<params.cols; ++c) {
92 channels_type srcAlpha = (alpha_pos == -1) ? unitValue<channels_type>() : src[alpha_pos];
93 channels_type dstAlpha = (alpha_pos == -1) ? unitValue<channels_type>() : dst[alpha_pos];
94 channels_type mskAlpha = useMask ? scale<channels_type>(*mask) : unitValue<channels_type>();
95
96 if (!allChannelFlags && dstAlpha == zeroValue<channels_type>()) {
97 memset(reinterpret_cast<quint8*>(dst), 0, pixel_size);
98 }
99
100 channels_type newDstAlpha = _compositeOp::template composeColorChannels<alphaLocked,allChannelFlags>(
101 src, srcAlpha, dst, dstAlpha, mskAlpha, opacity, channelFlags
102 );
103
104 if(alpha_pos != -1)
105 dst[alpha_pos] = alphaLocked ? dstAlpha : newDstAlpha;
106
107 src += srcInc;
108 dst += channels_nb;
109
110 if(useMask)
111 ++mask;
112 }
113
114 srcRowStart += params.srcRowStride;
115 dstRowStart += params.dstRowStride;
116 maskRowStart += params.maskRowStride;
117 }
118 }
119};
120
121#endif // KOCOMPOSITEOP_BASE_H_
void composite(const KoCompositeOp::ParameterInfo &params) const override
KoCompositeOpBase(const KoColorSpace *cs, const QString &id, const QString &category)
static const qint32 alpha_pos
static const qint32 channels_nb
void genericComposite(const KoCompositeOp::ParameterInfo &params, const QBitArray &channelFlags) const
_CSTraits::channels_type channels_type
static const qint32 pixel_size
void composite(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, float opacity, const QBitArray &channelFlags=QBitArray()) const