8#ifndef KOMIXCOLORSOPIMPL_H
9#define KOMIXCOLORSOPIMPL_H
24 std::enable_if_t<!std::numeric_limits<T>::is_integer, T> divisor) {
25 return dividend / divisor;
30 std::enable_if_t<std::numeric_limits<T>::is_integer, T> divisor) {
31 return (dividend + divisor / 2) / divisor;
36template<
class _CSTrait>
46 void mixColors(
const quint8 *
const* colors,
const qint16 *weights,
int nColors, quint8 *dst,
int weightSum = 255)
const override {
50 void mixColors(
const quint8 *colors,
const qint16 *weights,
int nColors, quint8 *dst,
int weightSum = 255)
const override {
54 void mixColors(
const quint8 *
const* colors,
int nColors, quint8 *dst)
const override {
58 void mixColors(
const quint8 *colors,
int nColors, quint8 *dst)
const override {
62 void mixTwoColorArrays(
const quint8* colorsA,
const quint8* colorsB,
int nColors, qreal weight, quint8* dst)
const override {
63 const quint8* pixelA = colorsA;
64 const quint8* pixelB = colorsB;
65 weight = qBound(0.0, weight, 1.0);
66 for (
int i = 0; i < nColors; i++) {
67 const quint8* colors[2];
71 weights[1] = qRound(weight * 255.0);
72 weights[0] = 255 - weights[1];
75 pixelA += _CSTrait::pixelSize;
76 pixelB += _CSTrait::pixelSize;
77 dst += _CSTrait::pixelSize;
81 void mixArrayWithColor(
const quint8* colorArray,
const quint8* color,
int nColors, qreal weight, quint8* dst)
const override {
82 const quint8* pixelA = colorArray;
83 weight = qBound(0.0, weight, 1.0);
84 for (
int i = 0; i < nColors; i++) {
85 const quint8* colors[2];
89 weights[1] = qRound(weight * 255.0);
90 weights[0] = 255 - weights[1];
93 pixelA += _CSTrait::pixelSize;
94 dst += _CSTrait::pixelSize;
198 qint64 m_numPixels = 0;
210 std::numeric_limits<mix_type>::max() /
pow2(
mix_type(MathsTraits::unitValue));
212 if (m_numPixels > maxSaneNumPixels) {
213 qWarning() <<
"SANITY CHECK FAILED: KoMixColorOp got too many pixels to mix, the containing type may overflow";
214 qWarning() <<
" " <<
ppVar(m_numPixels);
215 qWarning() <<
" " <<
ppVar(maxSaneNumPixels);
228 for (
int i = 0; i < (int)_CSTrait::channels_nb; i++) {
229 if (i != _CSTrait::alpha_pos) {
233 if (
v > MathsTraits::max) {
234 v = MathsTraits::max;
236 if (
v < MathsTraits::min) {
237 v = MathsTraits::min;
243 if (_CSTrait::alpha_pos != -1) {
246 if (
v > MathsTraits::max) {
247 v = MathsTraits::max;
249 if (
v < MathsTraits::min) {
250 v = MathsTraits::min;
252 dstColor[ _CSTrait::alpha_pos ] =
v;
255 memset(dst, 0,
sizeof(
channels_type) * _CSTrait::channels_nb);
259 template<
class AbstractSource,
class WeightsWrapper>
264 m_numPixels += nColors;
271 if (_CSTrait::alpha_pos != -1) {
272 alphaTimesWeight = color[_CSTrait::alpha_pos];
274 alphaTimesWeight = MathsTraits::unitValue;
279 for (
int i = 0; i < (int)_CSTrait::channels_nb; i++) {
280 if (i != _CSTrait::alpha_pos) {
281 totals[i] += color[i] * alphaTimesWeight;
299 template<
class AbstractSource,
class WeightsWrapper>
308template<
class _CSTrait>
316 void accumulate(
const quint8 *data,
const qint16 *weights,
int weightSum,
int nPixels)
override
328 result.computeMixedColor(data);
333 return result.currentWeightsSum();
340template<
class _CSTrait>
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
static T safeDivideWithRound(T dividend, std::enable_if_t<!std::numeric_limits< T >::is_integer, T > divisor)
mix_type totals[_CSTrait::channels_nb]
void accumulateColors(AbstractSource source, WeightsWrapper weightsWrapper, int nColors)
void computeMixedColor(quint8 *dst)
qint64 currentWeightsSum() const
typename _CSTrait::channels_type channels_type
typename KoColorSpaceMathsTraits< channels_type >::mixtype mix_type
qint64 currentWeightsSum() const override
void computeMixedColor(quint8 *data) override
void accumulateAverage(const quint8 *data, int nPixels) override
void accumulate(const quint8 *data, const qint16 *weights, int weightSum, int nPixels) override
void mixColorsImpl(AbstractSource source, WeightsWrapper weightsWrapper, int nColors, quint8 *dst) const
void mixArrayWithColor(const quint8 *colorArray, const quint8 *color, int nColors, qreal weight, quint8 *dst) const override
Mixer * createMixer() const override
void mixColors(const quint8 *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum=255) const override
~KoMixColorsOpImpl() override
void mixColors(const quint8 *const *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum=255) const override
void mixColors(const quint8 *const *colors, int nColors, quint8 *dst) const override
void mixColors(const quint8 *colors, int nColors, quint8 *dst) const override
void mixTwoColorArrays(const quint8 *colorsA, const quint8 *colorsB, int nColors, qreal weight, quint8 *dst) const override
const quint8 * getPixel() const
ArrayOfPointers(const quint8 *const *colors)
const quint8 *const * m_colors
int normalizeFactor() const
void premultiplyAlphaWithWeight(mixtype &) const
KoColorSpaceMathsTraits< typename_CSTrait::channels_type >::mixtype mixtype
NoWeightsSurrogate(int numPixels)
PointerToArray(const quint8 *colors, int pixelSize)
const quint8 * getPixel() const
int normalizeFactor() const
WeightsWrapper(const qint16 *weights, int weightSum)
void premultiplyAlphaWithWeight(mixtype &alpha) const
KoColorSpaceMathsTraits< typename_CSTrait::channels_type >::mixtype mixtype