00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _KO_COLORSPACE_TRAITS_H_
00021 #define _KO_COLORSPACE_TRAITS_H_
00022
00023 #include <QtCore/QVector>
00024
00025 #include "KoColorSpaceConstants.h"
00026 #include "KoColorSpaceMaths.h"
00027 #include "DebugPigment.h"
00028
00041 template<typename _channels_type_, int _channels_nb_, int _alpha_pos_>
00042 struct KoColorSpaceTrait {
00044 typedef _channels_type_ channels_type;
00046 static const quint32 channels_nb = _channels_nb_;
00049 static const qint32 alpha_pos = _alpha_pos_;
00051 static const int depth = KoColorSpaceMathsTraits<_channels_type_>::bits;
00055 static const quint32 pixelSize = channels_nb * sizeof(channels_type);
00059 inline static quint8 opacityU8(const quint8 * U8_pixel) {
00060 if (alpha_pos < 0) return OPACITY_OPAQUE_U8;
00061 channels_type c = nativeArray(U8_pixel)[alpha_pos];
00062 return KoColorSpaceMaths<channels_type, quint8>::scaleToA(c);
00063 }
00064 inline static qreal opacityF(const quint8 * U8_pixel) {
00065 if (alpha_pos < 0) return OPACITY_OPAQUE_F;
00066 channels_type c = nativeArray(U8_pixel)[alpha_pos];
00067 return KoColorSpaceMaths<channels_type, qreal>::scaleToA(c);
00068 }
00072 inline static void setOpacity(quint8 * pixels, quint8 alpha, qint32 nPixels) {
00073 if (alpha_pos < 0) return;
00074 qint32 psize = pixelSize;
00075 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(alpha);
00076 for (; nPixels > 0; --nPixels, pixels += psize) {
00077 nativeArray(pixels)[alpha_pos] = valpha;
00078 }
00079 }
00080 inline static void setOpacity(quint8 * pixels, qreal alpha, qint32 nPixels) {
00081 if (alpha_pos < 0) return;
00082 qint32 psize = pixelSize;
00083 channels_type valpha = KoColorSpaceMaths<qreal, channels_type>::scaleToA(alpha);
00084 for (; nPixels > 0; --nPixels, pixels += psize) {
00085 nativeArray(pixels)[alpha_pos] = valpha;
00086 }
00087 }
00091 inline static const channels_type* nativeArray(const quint8 * a) {
00092 return reinterpret_cast<const channels_type*>(a);
00093 }
00097 inline static channels_type* nativeArray(quint8 * a) {
00098 return reinterpret_cast< channels_type*>(a);
00099 }
00103 inline static quint8* allocate(quint32 nPixels) {
00104 return new quint8[ nPixels * pixelSize ];
00105 }
00106 inline static void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) {
00107 const channels_type* src = nativeArray(srcPixel);
00108 channels_type* dst = nativeArray(dstPixel);
00109 for (uint i = 0; i < channels_nb; i++) {
00110 if (i != channelIndex) {
00111 dst[i] = 0;
00112 } else {
00113 dst[i] = src[i];
00114 }
00115 }
00116 }
00117 inline static QString channelValueText(const quint8 *pixel, quint32 channelIndex) {
00118 if (channelIndex > channels_nb) return QString("Error");
00119 channels_type c = nativeArray(pixel)[channelIndex];
00120 return QString().setNum(c);
00121 }
00122
00123 inline static QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) {
00124 if (channelIndex > channels_nb) return QString("Error");
00125 channels_type c = nativeArray(pixel)[channelIndex];
00126 return QString().setNum(100. *((qreal)c) / KoColorSpaceMathsTraits< channels_type>::unitValue);
00127 }
00128
00129 inline static void normalisedChannelsValue(const quint8 *pixel, QVector<float> &channels) {
00130 Q_ASSERT((int)channels.count() == (int)channels_nb);
00131 channels_type c;
00132 for (uint i = 0; i < channels_nb; i++) {
00133 c = nativeArray(pixel)[i];
00134 channels[i] = ((qreal)c) / KoColorSpaceMathsTraits<channels_type>::unitValue;
00135 }
00136 }
00137
00138 inline static void fromNormalisedChannelsValue(quint8 *pixel, const QVector<float> &values) {
00139 Q_ASSERT((int)values.count() == (int)channels_nb);
00140 channels_type c;
00141 for (uint i = 0; i < channels_nb; i++) {
00142 c = (channels_type)
00143 ((float)KoColorSpaceMathsTraits<channels_type>::unitValue * values[i]);
00144 nativeArray(pixel)[i] = c;
00145 }
00146 }
00147 inline static void multiplyAlpha(quint8 * pixels, quint8 alpha, qint32 nPixels) {
00148 if (alpha_pos < 0) return;
00149
00150 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(alpha);
00151
00152 for (; nPixels > 0; --nPixels, pixels += pixelSize) {
00153 channels_type* alphapixel = nativeArray(pixels) + alpha_pos;
00154 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha);
00155 }
00156 }
00157
00158 inline static void applyAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) {
00159 if (alpha_pos < 0) return;
00160
00161 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++alpha) {
00162 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(*alpha);
00163 channels_type* alphapixel = nativeArray(pixels) + alpha_pos;
00164 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha);
00165 }
00166 }
00167
00168 inline static void applyInverseAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) {
00169 if (alpha_pos < 0) return;
00170
00171 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++alpha) {
00172 channels_type valpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(OPACITY_OPAQUE_U8 - *alpha);
00173 channels_type* alphapixel = nativeArray(pixels) + alpha_pos;
00174 *alphapixel = KoColorSpaceMaths<channels_type>::multiply(*alphapixel, valpha);
00175 }
00176 }
00177
00178 };
00179
00192 template<typename _channels_type_>
00193 struct KoLabTraits : public KoColorSpaceTrait<_channels_type_, 4, 3> {
00194 typedef _channels_type_ channels_type;
00195 typedef KoColorSpaceTrait<_channels_type_, 4, 3> parent;
00196 static const qint32 L_pos = 0;
00197 static const qint32 a_pos = 1;
00198 static const qint32 b_pos = 2;
00199
00203 struct Pixel {
00204 channels_type L;
00205 channels_type a;
00206 channels_type b;
00207 channels_type alpha;
00208 };
00209
00211 inline static channels_type L(quint8* data) {
00212 channels_type* d = parent::nativeArray(data);
00213 return d[L_pos];
00214 }
00216 inline static void setL(quint8* data, channels_type nv) {
00217 channels_type* d = parent::nativeArray(data);
00218 d[L_pos] = nv;
00219 }
00221 inline static channels_type a(quint8* data) {
00222 channels_type* d = parent::nativeArray(data);
00223 return d[a_pos];
00224 }
00226 inline static void setA(quint8* data, channels_type nv) {
00227 channels_type* d = parent::nativeArray(data);
00228 d[a_pos] = nv;
00229 }
00231 inline static channels_type b(quint8* data) {
00232 channels_type* d = parent::nativeArray(data);
00233 return d[b_pos];
00234 }
00236 inline static void setB(quint8* data, channels_type nv) {
00237 channels_type* d = parent::nativeArray(data);
00238 d[b_pos] = nv;
00239 }
00240 };
00241
00246 struct KoLabU16Traits : public KoLabTraits<quint16> {
00247 };
00248
00252 template<typename _channels_type_>
00253 struct KoRgbTraits : public KoColorSpaceTrait<_channels_type_, 4, 3> {
00254 typedef _channels_type_ channels_type;
00255 typedef KoColorSpaceTrait<_channels_type_, 4, 3> parent;
00256 static const qint32 red_pos = 2;
00257 static const qint32 green_pos = 1;
00258 static const qint32 blue_pos = 0;
00262 struct Pixel {
00263 channels_type blue;
00264 channels_type green;
00265 channels_type red;
00266 channels_type alpha;
00267 };
00268
00270 inline static channels_type red(quint8* data) {
00271 channels_type* d = parent::nativeArray(data);
00272 return d[red_pos];
00273 }
00275 inline static void setRed(quint8* data, channels_type nv) {
00276 channels_type* d = parent::nativeArray(data);
00277 d[red_pos] = nv;
00278 }
00280 inline static channels_type green(quint8* data) {
00281 channels_type* d = parent::nativeArray(data);
00282 return d[green_pos];
00283 }
00285 inline static void setGreen(quint8* data, channels_type nv) {
00286 channels_type* d = parent::nativeArray(data);
00287 d[green_pos] = nv;
00288 }
00290 inline static channels_type blue(quint8* data) {
00291 channels_type* d = parent::nativeArray(data);
00292 return d[blue_pos];
00293 }
00295 inline static void setBlue(quint8* data, channels_type nv) {
00296 channels_type* d = parent::nativeArray(data);
00297 d[blue_pos] = nv;
00298 }
00299 };
00300
00301
00305 struct KoRgbU8Traits : public KoRgbTraits<quint8> {
00306 };
00307
00313 struct KoRgbU16Traits : public KoRgbTraits<quint16> {
00314 };
00315
00319 template<typename _channels_type_>
00320 struct KoXyzTraits : public KoColorSpaceTrait<_channels_type_, 4, 3> {
00321 typedef _channels_type_ channels_type;
00322 static const qint32 x_pos = 0;
00323 static const qint32 y_pos = 1;
00324 static const qint32 z_pos = 2;
00325
00329 struct Pixel {
00330 channels_type X;
00331 channels_type Y;
00332 channels_type Z;
00333 channels_type alpha;
00334 };
00335 };
00336
00340 template<typename _channels_type_>
00341 struct KoCmykTraits : public KoColorSpaceTrait<_channels_type_, 5, 4> {
00342 typedef _channels_type_ channels_type;
00343 static const qint32 c_pos = 0;
00344 static const qint32 m_pos = 1;
00345 static const qint32 y_pos = 2;
00346 static const qint32 k_pos = 3;
00347
00351 struct Pixel {
00352 channels_type cyan;
00353 channels_type magenta;
00354 channels_type yellow;
00355 channels_type black;
00356 channels_type alpha;
00357 };
00358 };
00359
00360
00361
00362
00363 #endif