Krita Source Code Documentation
Loading...
Searching...
No Matches
KoConvolutionOpImpl< _CSTrait > Class Template Reference

#include <KoConvolutionOpImpl.h>

+ Inheritance diagram for KoConvolutionOpImpl< _CSTrait >:

Public Member Functions

void convolveColors (const quint8 *const *colors, const qreal *kernelValues, quint8 *dst, qreal factor, qreal offset, qint32 nPixels, const QBitArray &channelFlags) const override
 
 KoConvolutionOpImpl ()
 
 ~KoConvolutionOpImpl () override
 
- Public Member Functions inherited from KoConvolutionOp
virtual ~KoConvolutionOp ()
 

Private Types

typedef _CSTrait::channels_type channels_type
 
typedef KoColorSpaceMathsTraits< typename_CSTrait::channels_type >::compositetype compositetype
 

Detailed Description

template<class _CSTrait>
class KoConvolutionOpImpl< _CSTrait >

Definition at line 17 of file KoConvolutionOpImpl.h.

Member Typedef Documentation

◆ channels_type

template<class _CSTrait >
typedef _CSTrait::channels_type KoConvolutionOpImpl< _CSTrait >::channels_type
private

Definition at line 20 of file KoConvolutionOpImpl.h.

◆ compositetype

template<class _CSTrait >
typedef KoColorSpaceMathsTraits<typename_CSTrait::channels_type>::compositetype KoConvolutionOpImpl< _CSTrait >::compositetype
private

Definition at line 19 of file KoConvolutionOpImpl.h.

Constructor & Destructor Documentation

◆ KoConvolutionOpImpl()

template<class _CSTrait >
KoConvolutionOpImpl< _CSTrait >::KoConvolutionOpImpl ( )
inline

Definition at line 23 of file KoConvolutionOpImpl.h.

23{ }

◆ ~KoConvolutionOpImpl()

template<class _CSTrait >
KoConvolutionOpImpl< _CSTrait >::~KoConvolutionOpImpl ( )
inlineoverride

Definition at line 25 of file KoConvolutionOpImpl.h.

25{ }

Member Function Documentation

◆ convolveColors()

template<class _CSTrait >
void KoConvolutionOpImpl< _CSTrait >::convolveColors ( const quint8 *const * colors,
const qreal * kernelValues,
quint8 * dst,
qreal factor,
qreal offset,
qint32 nPixels,
const QBitArray & channelFlags ) const
inlineoverridevirtual

Calculates a weighted average of the pixels, mentioned in colors using weight values from kernelValues

Note: It behaves in a quite unclear way, when at least one pixel is fully transparent. There are three cases: Case A) None of the pixels is fully transparent.

  • Every color channel AND alpha channel of dst stores a sum of the corresponding channels from colors, divided by factor and incremented by offset Case B) At least one pixel of colors is transparent and factor stores a weight of the kernel (sum of it's items).
  • Every color channel of dst stores a sum of the corresponding channels from non-transparent pixels, divided by a weight of non-transparent pixels and incremented by offset.
  • Alpha channel of dst stores a sum of the corresponding channels from non-transparent pixels, divided by a weight of all the pixels (equals to factor) and incremented by offset. Case C) At least one pixel of colors is transparent and factor is set to an arbitrary value.
  • Every color channel of dst stores a sum of the corresponding channels from non-transparent pixels, divided by a "scaled down factor" and incremented by offset. "Scaled down factor" is calculated in the following way:
                             [weight of non-transparent pixels]
    
    scaledDownFactor = factor * -------------------------------— [weight of all the pixels]
  • Alpha channel of dst stores a sum of the corresponding channels from non-transparent pixels, divided by unscaled factor and incremented by offset.

Implements KoConvolutionOp.

Definition at line 63 of file KoConvolutionOpImpl.h.

63 {
64
65 // Create and initialize to 0 the array of totals
66 qreal totals[_CSTrait::channels_nb];
67
68 qreal totalWeight = 0;
69 qreal totalWeightTransparent = 0;
70
71 memset(totals, 0, sizeof(qreal) * _CSTrait::channels_nb);
72
73 for (; nPixels--; colors++, kernelValues++) {
74 qreal weight = *kernelValues;
75 const channels_type* color = _CSTrait::nativeArray(*colors);
76 if (weight != 0) {
77 if (_CSTrait::opacityU8(*colors) == 0) {
78 totalWeightTransparent += weight;
79 } else {
80 for (uint i = 0; i < _CSTrait::channels_nb; i++) {
81 totals[i] += color[i] * weight;
82 }
83 }
84 totalWeight += weight;
85 }
86 }
87
88 typename _CSTrait::channels_type* dstColor = _CSTrait::nativeArray(dst);
89
90 bool allChannels = channelFlags.isEmpty();
91 Q_ASSERT(allChannels || channelFlags.size() == (int)_CSTrait::channels_nb);
92 if (totalWeightTransparent == 0) {
93 // Case A)
94 for (uint i = 0; i < _CSTrait::channels_nb; i++) {
95 if (allChannels || channelFlags.testBit(i)) {
96 compositetype v = totals[i] / factor + offset;
99 }
100 }
101 } else if (totalWeightTransparent != totalWeight) {
102 if (totalWeight == factor) {
103 // Case B)
104 qint64 a = (totalWeight - totalWeightTransparent);
105 for (uint i = 0; i < _CSTrait::channels_nb; i++) {
106 if (allChannels || channelFlags.testBit(i)) {
107 if (i == (uint)_CSTrait::alpha_pos) {
108 compositetype v = totals[i] / totalWeight + offset;
111 } else {
112 compositetype v = totals[i] / a + offset;
115 }
116 }
117 }
118 } else {
119 // Case C)
120 qreal a = qreal(totalWeight) / (factor * (totalWeight - totalWeightTransparent)); // use qreal as it easily saturate
121 for (uint i = 0; i < _CSTrait::channels_nb; i++) {
122 if (allChannels || channelFlags.testBit(i)) {
123 if (i == (uint)_CSTrait::alpha_pos) {
124 compositetype v = totals[i] / factor + offset;
127 } else {
128 compositetype v = (compositetype)(totals[i] * a + offset);
131 }
132 }
133 }
134 }
135 }
136
137 }
qreal v
unsigned int uint
_CSTrait::channels_type channels_type
KoColorSpaceMathsTraits< typename_CSTrait::channels_type >::compositetype compositetype
#define CLAMP(x, l, h)

References CLAMP, and v.


The documentation for this class was generated from the following file: