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