Warning, file /office/calligra/libs/pigment/KoMixColorsOpImpl.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> 0003 * Copyright (c) 2007 Emanuele Tamponi <emanuele@valinor.it> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #ifndef KOMIXCOLORSOPIMPL_H 0022 #define KOMIXCOLORSOPIMPL_H 0023 0024 #include "KoMixColorsOp.h" 0025 0026 template<class _CSTrait> 0027 class KoMixColorsOpImpl : public KoMixColorsOp 0028 { 0029 public: 0030 KoMixColorsOpImpl() { 0031 } 0032 ~KoMixColorsOpImpl() override { } 0033 void mixColors(const quint8 * const* colors, const qint16 *weights, quint32 nColors, quint8 *dst) const override { 0034 mixColorsImpl(ArrayOfPointers(colors), weights, nColors, dst); 0035 } 0036 0037 void mixColors(const quint8 *colors, const qint16 *weights, quint32 nColors, quint8 *dst) const override { 0038 mixColorsImpl(PointerToArray(colors, _CSTrait::pixelSize), weights, nColors, dst); 0039 } 0040 0041 private: 0042 struct ArrayOfPointers { 0043 ArrayOfPointers(const quint8 * const* colors) 0044 : m_colors(colors) 0045 { 0046 } 0047 0048 const quint8* getPixel() const { 0049 return *m_colors; 0050 } 0051 0052 void nextPixel() { 0053 m_colors++; 0054 } 0055 0056 private: 0057 const quint8 * const * m_colors; 0058 }; 0059 0060 struct PointerToArray { 0061 PointerToArray(const quint8 *colors, int pixelSize) 0062 : m_colors(colors), 0063 m_pixelSize(pixelSize) 0064 { 0065 } 0066 0067 const quint8* getPixel() const { 0068 return m_colors; 0069 } 0070 0071 void nextPixel() { 0072 m_colors += m_pixelSize; 0073 } 0074 0075 private: 0076 const quint8 *m_colors; 0077 const int m_pixelSize; 0078 }; 0079 0080 0081 template<class AbstractSource> 0082 void mixColorsImpl(AbstractSource source, const qint16 *weights, quint32 nColors, quint8 *dst) const { 0083 // Create and initialize to 0 the array of totals 0084 typename KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::compositetype totals[_CSTrait::channels_nb]; 0085 typename KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::compositetype totalAlpha = 0; 0086 0087 memset(totals, 0, sizeof(totals)); 0088 0089 // Compute the total for each channel by summing each colors multiplied by the weightlabcache 0090 0091 while (nColors--) { 0092 const typename _CSTrait::channels_type* color = _CSTrait::nativeArray(source.getPixel()); 0093 typename KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::compositetype alphaTimesWeight; 0094 0095 if (_CSTrait::alpha_pos != -1) { 0096 alphaTimesWeight = color[_CSTrait::alpha_pos]; 0097 } else { 0098 alphaTimesWeight = KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::unitValue; 0099 } 0100 0101 alphaTimesWeight *= *weights; 0102 0103 for (int i = 0; i < (int)_CSTrait::channels_nb; i++) { 0104 if (i != _CSTrait::alpha_pos) { 0105 totals[i] += color[i] * alphaTimesWeight; 0106 } 0107 } 0108 0109 totalAlpha += alphaTimesWeight; 0110 source.nextPixel(); 0111 weights++; 0112 } 0113 0114 // set totalAlpha to the minimum between its value and the unit value of the channels 0115 const int sumOfWeights = 255; 0116 0117 if (totalAlpha > KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::unitValue * sumOfWeights) { 0118 totalAlpha = KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::unitValue * sumOfWeights; 0119 } 0120 0121 typename _CSTrait::channels_type* dstColor = _CSTrait::nativeArray(dst); 0122 0123 if (totalAlpha > 0) { 0124 0125 for (int i = 0; i < (int)_CSTrait::channels_nb; i++) { 0126 if (i != _CSTrait::alpha_pos) { 0127 0128 typename KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::compositetype v = totals[i] / totalAlpha; 0129 0130 if (v > KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::max) { 0131 v = KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::max; 0132 } 0133 if (v < KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::min) { 0134 v = KoColorSpaceMathsTraits<typename _CSTrait::channels_type>::min; 0135 } 0136 dstColor[ i ] = v; 0137 } 0138 } 0139 0140 if (_CSTrait::alpha_pos != -1) { 0141 dstColor[ _CSTrait::alpha_pos ] = totalAlpha / sumOfWeights; 0142 } 0143 } else { 0144 memset(dst, 0, sizeof(typename _CSTrait::channels_type) * _CSTrait::channels_nb); 0145 } 0146 } 0147 }; 0148 0149 #endif