Warning, file /office/calligra/libs/pigment/KoColorSpaceTraits.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-2007 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public License 0015 * along with this library; see the file COPYING.LIB. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #ifndef _KO_COLORSPACE_TRAITS_H_ 0021 #define _KO_COLORSPACE_TRAITS_H_ 0022 0023 #include <QVector> 0024 0025 #include "KoColorSpaceConstants.h" 0026 #include "KoColorSpaceMaths.h" 0027 #include "DebugPigment.h" 0028 0029 /** 0030 * This class is the base class to define the main characteristics of a colorspace 0031 * which inherits KoColorSpaceAbstract. 0032 * 0033 * - _channels_type_ is the type of the value use for each channel, for example quint8 for 8bits per channel 0034 * color spaces, or quint16 for 16bits integer per channel, float for 32bits per channel 0035 * floating point color spaces 0036 * - _channels_nb_ is the total number of channels in an image (for example RGB is 3 but RGBA is four) 0037 * - _alpha_pos_ is the position of the alpha channel among the channels, if there is no alpha channel, 0038 * then _alpha_pos_ is set to -1 0039 * 0040 * For instance a colorspace of three color channels and alpha channel in 16bits, 0041 * will be defined as KoColorSpaceTrait\<quint16, 4, 3\>. The same without the alpha 0042 * channel is KoColorSpaceTrait\<quint16,3,-1\> 0043 * 0044 */ 0045 template<typename _channels_type_, int _channels_nb_, int _alpha_pos_> 0046 struct KoColorSpaceTrait { 0047 0048 /// the type of the value of the channels of this color space 0049 typedef _channels_type_ channels_type; 0050 0051 /// the number of channels in this color space 0052 static const quint32 channels_nb = _channels_nb_; 0053 0054 /// the position of the alpha channel in the channels of the pixel (or -1 if no alpha 0055 /// channel. 0056 static const qint32 alpha_pos = _alpha_pos_; 0057 0058 /// the number of bit for each channel 0059 static const int depth = KoColorSpaceMathsTraits<_channels_type_>::bits; 0060 0061 /** 0062 * @return the size in byte of one pixel 0063 */ 0064 static const quint32 pixelSize = channels_nb * sizeof(channels_type); 0065 0066 /** 0067 * @return the value of the alpha channel for this pixel in the 0..255 range 0068 */ 0069 inline static quint8 opacityU8(const quint8 * U8_pixel) { 0070 if (alpha_pos < 0) return OPACITY_OPAQUE_U8; 0071 channels_type c = nativeArray(U8_pixel)[alpha_pos]; 0072 return KoColorSpaceMaths<channels_type, quint8>::scaleToA(c); 0073 } 0074 0075 inline static qreal opacityF(const quint8 * U8_pixel) { 0076 if (alpha_pos < 0) return OPACITY_OPAQUE_F; 0077 channels_type c = nativeArray(U8_pixel)[alpha_pos]; 0078 return KoColorSpaceMaths<channels_type, qreal>::scaleToA(c); 0079 } 0080 0081 /** 0082 * Set the alpha channel for this pixel from a value in the 0..255 range 0083 */ 0084 inline static void setOpacity(quint8 * pixels, quint8 alpha, qint32 nPixels) { 0085 if (alpha_pos < 0) return; 0086 qint32 psize = pixelSize; 0087 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(alpha); 0088 for (; nPixels > 0; --nPixels, pixels += psize) { 0089 nativeArray(pixels)[alpha_pos] = valpha; 0090 } 0091 } 0092 0093 inline static void setOpacity(quint8 * pixels, qreal alpha, qint32 nPixels) { 0094 if (alpha_pos < 0) return; 0095 qint32 psize = pixelSize; 0096 channels_type valpha = KoColorSpaceMaths<qreal, channels_type>::scaleToA(alpha); 0097 for (; nPixels > 0; --nPixels, pixels += psize) { 0098 nativeArray(pixels)[alpha_pos] = valpha; 0099 } 0100 } 0101 0102 /** 0103 * Convenient function for transforming a quint8* array in a pointer of the native channels type 0104 */ 0105 inline static const channels_type* nativeArray(const quint8 * a) { 0106 return reinterpret_cast<const channels_type*>(a); 0107 } 0108 0109 /** 0110 * Convenient function for transforming a quint8* array in a pointer of the native channels type 0111 */ 0112 inline static channels_type* nativeArray(quint8 * a) { 0113 return reinterpret_cast< channels_type*>(a); 0114 } 0115 0116 /** 0117 * Allocate nPixels pixels for this colorspace. 0118 */ 0119 inline static quint8* allocate(quint32 nPixels) { 0120 return new quint8[ nPixels * pixelSize ]; 0121 } 0122 0123 inline static void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) { 0124 const channels_type* src = nativeArray(srcPixel); 0125 channels_type* dst = nativeArray(dstPixel); 0126 for (uint i = 0; i < channels_nb; i++) { 0127 if (i != channelIndex) { 0128 dst[i] = 0; 0129 } else { 0130 dst[i] = src[i]; 0131 } 0132 } 0133 } 0134 0135 inline static QString channelValueText(const quint8 *pixel, quint32 channelIndex) { 0136 if (channelIndex > channels_nb) return QString("Error"); 0137 channels_type c = nativeArray(pixel)[channelIndex]; 0138 return QString().setNum(c); 0139 } 0140 0141 inline static QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) { 0142 if (channelIndex > channels_nb) return QString("Error"); 0143 channels_type c = nativeArray(pixel)[channelIndex]; 0144 return QString().setNum(100. *((qreal)c) / KoColorSpaceMathsTraits< channels_type>::unitValue); 0145 } 0146 0147 inline static void normalisedChannelsValue(const quint8 *pixel, QVector<qreal> &channels) { 0148 Q_ASSERT((int)channels.count() == (int)channels_nb); 0149 channels_type c; 0150 for (uint i = 0; i < channels_nb; i++) { 0151 c = nativeArray(pixel)[i]; 0152 channels[i] = ((qreal)c) / KoColorSpaceMathsTraits<channels_type>::unitValue; 0153 } 0154 } 0155 0156 inline static void fromNormalisedChannelsValue(quint8 *pixel, const QVector<qreal> &values) { 0157 Q_ASSERT((int)values.count() == (int)channels_nb); 0158 channels_type c; 0159 for (uint i = 0; i < channels_nb; i++) { 0160 c = (channels_type) 0161 ((float)KoColorSpaceMathsTraits<channels_type>::unitValue * values[i]); 0162 nativeArray(pixel)[i] = c; 0163 } 0164 } 0165 inline static void multiplyAlpha(quint8 * pixels, quint8 alpha, qint32 nPixels) { 0166 if (alpha_pos < 0) return; 0167 0168 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(alpha); 0169 0170 for (; nPixels > 0; --nPixels, pixels += pixelSize) { 0171 channels_type* alphapixel = nativeArray(pixels) + alpha_pos; 0172 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha); 0173 } 0174 } 0175 0176 inline static void applyAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) { 0177 if (alpha_pos < 0) return; 0178 0179 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++alpha) { 0180 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(*alpha); 0181 channels_type* alphapixel = nativeArray(pixels) + alpha_pos; 0182 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha); 0183 } 0184 } 0185 0186 inline static void applyInverseAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) { 0187 if (alpha_pos < 0) return; 0188 0189 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++alpha) { 0190 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(OPACITY_OPAQUE_U8 - *alpha); 0191 channels_type* alphapixel = nativeArray(pixels) + alpha_pos; 0192 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha); 0193 } 0194 } 0195 0196 inline static void applyAlphaNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) { 0197 if (alpha_pos < 0) return; 0198 0199 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++alpha) { 0200 channels_type valpha = channels_type(KoColorSpaceMathsTraits<channels_type>::unitValue * (*alpha)); 0201 channels_type* alphapixel = nativeArray(pixels) + alpha_pos; 0202 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha); 0203 } 0204 } 0205 0206 inline static void applyInverseAlphaNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) { 0207 if (alpha_pos < 0) return; 0208 0209 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++alpha) { 0210 channels_type valpha = channels_type(KoColorSpaceMathsTraits<channels_type>::unitValue * (1.0f - *alpha)); 0211 channels_type* alphapixel = nativeArray(pixels) + alpha_pos; 0212 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha); 0213 } 0214 } 0215 }; 0216 0217 #include "KoRgbColorSpaceTraits.h" 0218 #include "KoBgrColorSpaceTraits.h" 0219 #include "KoGrayColorSpaceTraits.h" 0220 #include "KoLabColorSpaceTraits.h" 0221 #include "KoXyzColorSpaceTraits.h" 0222 #include "KoYcbcrColorSpaceTraits.h" 0223 #include "KoCmykColorSpaceTraits.h" 0224 0225 #endif