libs/pigment

KoColorSpaceTraits.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright (c) 2006-2007 Cyrille Berger <cberger@cberger.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this library; see the file COPYING.LIB.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
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