Warning, file /office/calligra/libs/pigment/KoColorSpaceAbstract.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 KOCOLORSPACEABSTRACT_H 0022 #define KOCOLORSPACEABSTRACT_H 0023 0024 #include <QBitArray> 0025 #include <klocalizedstring.h> 0026 0027 #include <KoColorSpace.h> 0028 #include <KoColorProfile.h> 0029 #include <KoColorSpaceMaths.h> 0030 #include <KoColorSpaceRegistry.h> 0031 #include "KoFallBackColorTransformation.h" 0032 #include "KoLabDarkenColorTransformation.h" 0033 #include "KoMixColorsOpImpl.h" 0034 0035 #include "KoConvolutionOpImpl.h" 0036 #include "KoInvertColorTransformation.h" 0037 0038 0039 /** 0040 * This in an implementation of KoColorSpace which can be used as a base for colorspaces with as many 0041 * different channels of the same type. 0042 * 0043 * The template parameters must be a class which inherits KoColorSpaceTrait (or a class with the same signature). 0044 * 0045 * SOMETYPE is the type of the channel for instance (quint8, quint32...), 0046 * SOMENBOFCHANNELS is the number of channels including the alpha channel 0047 * SOMEALPHAPOS is the position of the alpha channel in the pixel (can be equal to -1 if no alpha channel). 0048 */ 0049 template<class _CSTrait> 0050 class KoColorSpaceAbstract : public KoColorSpace 0051 { 0052 public: 0053 KoColorSpaceAbstract(const QString &id, const QString &name) : 0054 KoColorSpace(id, name, new KoMixColorsOpImpl< _CSTrait>(), new KoConvolutionOpImpl< _CSTrait>()) { 0055 } 0056 0057 quint32 colorChannelCount() const override { 0058 if (_CSTrait::alpha_pos == -1) 0059 return _CSTrait::channels_nb; 0060 else 0061 return _CSTrait::channels_nb - 1; 0062 } 0063 0064 quint32 channelCount() const override { 0065 return _CSTrait::channels_nb; 0066 } 0067 0068 quint32 pixelSize() const override { 0069 return _CSTrait::pixelSize; 0070 } 0071 0072 QString channelValueText(const quint8 *pixel, quint32 channelIndex) const override { 0073 return _CSTrait::channelValueText(pixel, channelIndex); 0074 } 0075 0076 QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) const override { 0077 return _CSTrait::normalisedChannelValueText(pixel, channelIndex); 0078 } 0079 0080 void normalisedChannelsValue(const quint8 *pixel, QVector<qreal> &channels) const override { 0081 return _CSTrait::normalisedChannelsValue(pixel, channels); 0082 } 0083 0084 void fromNormalisedChannelsValue(quint8 *pixel, const QVector<qreal> &values) const override { 0085 return _CSTrait::fromNormalisedChannelsValue(pixel, values); 0086 } 0087 0088 quint8 scaleToU8(const quint8 * srcPixel, qint32 channelIndex) const override { 0089 typename _CSTrait::channels_type c = _CSTrait::nativeArray(srcPixel)[channelIndex]; 0090 return KoColorSpaceMaths<typename _CSTrait::channels_type, quint8>::scaleToA(c); 0091 } 0092 0093 void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) const override { 0094 _CSTrait::singleChannelPixel(dstPixel, srcPixel, channelIndex); 0095 } 0096 0097 quint8 opacityU8(const quint8 * U8_pixel) const override { 0098 return _CSTrait::opacityU8(U8_pixel); 0099 } 0100 0101 qreal opacityF(const quint8 * U8_pixel) const override { 0102 return _CSTrait::opacityF(U8_pixel); 0103 } 0104 0105 void setOpacity(quint8 * pixels, quint8 alpha, qint32 nPixels) const override { 0106 _CSTrait::setOpacity(pixels, alpha, nPixels); 0107 } 0108 0109 void setOpacity(quint8 * pixels, qreal alpha, qint32 nPixels) const override { 0110 _CSTrait::setOpacity(pixels, alpha, nPixels); 0111 } 0112 0113 void multiplyAlpha(quint8 * pixels, quint8 alpha, qint32 nPixels) const override { 0114 _CSTrait::multiplyAlpha(pixels, alpha, nPixels); 0115 } 0116 0117 void applyAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) const override { 0118 _CSTrait::applyAlphaU8Mask(pixels, alpha, nPixels); 0119 } 0120 0121 void applyInverseAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) const override { 0122 _CSTrait::applyInverseAlphaU8Mask(pixels, alpha, nPixels); 0123 } 0124 0125 void applyAlphaNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) const override { 0126 _CSTrait::applyAlphaNormedFloatMask(pixels, alpha, nPixels); 0127 } 0128 0129 void applyInverseNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) const override { 0130 _CSTrait::applyInverseAlphaNormedFloatMask(pixels, alpha, nPixels); 0131 } 0132 0133 quint8 intensity8(const quint8 * src) const override { 0134 QColor c; 0135 const_cast<KoColorSpaceAbstract<_CSTrait> *>(this)->toQColor(src, &c); 0136 return static_cast<quint8>((c.red() * 0.30 + c.green() * 0.59 + c.blue() * 0.11) + 0.5); 0137 } 0138 0139 KoColorTransformation* createInvertTransformation() const override { 0140 return new KoInvertColorTransformation(this); 0141 } 0142 0143 KoColorTransformation *createDarkenAdjustment(qint32 shade, bool compensate, qreal compensation) const override { 0144 return new KoFallBackColorTransformation(this, KoColorSpaceRegistry::instance()->lab16(""), new KoLabDarkenColorTransformation<quint16>(shade, compensate, compensation, KoColorSpaceRegistry::instance()->lab16(""))); 0145 } 0146 0147 bool convertPixelsTo(const quint8 *src, 0148 quint8 *dst, const KoColorSpace *dstColorSpace, 0149 quint32 numPixels, 0150 KoColorConversionTransformation::Intent renderingIntent, 0151 KoColorConversionTransformation::ConversionFlags conversionFlags) const override 0152 { 0153 0154 // check whether we have the same profile and color model, but only a different bit 0155 // depth; in that case we don't convert as such, but scale 0156 bool scaleOnly = false; 0157 0158 // Note: getting the id() is really, really expensive, so only do that if 0159 // we are sure there is a difference between the colorspaces 0160 if (!(*this == *dstColorSpace)) { 0161 scaleOnly = dstColorSpace->colorModelId().id() == colorModelId().id() && 0162 dstColorSpace->colorDepthId().id() != colorDepthId().id() && 0163 dstColorSpace->profile()->name() == profile()->name(); 0164 } 0165 0166 if (scaleOnly && dynamic_cast<const KoColorSpaceAbstract*>(dstColorSpace)) { 0167 typedef typename _CSTrait::channels_type channels_type; 0168 0169 switch(dstColorSpace->channels().at(0)->channelValueType()) 0170 { 0171 case KoChannelInfo::UINT8: 0172 scalePixels<_CSTrait::pixelSize, 1, channels_type, quint8>(src, dst, numPixels); 0173 return true; 0174 // case KoChannelInfo::INT8: 0175 // scalePixels<_CSTrait::pixelSize, 1, channels_type, qint8>(src, dst, numPixels); 0176 // return true; 0177 case KoChannelInfo::UINT16: 0178 scalePixels<_CSTrait::pixelSize, 2, channels_type, quint16>(src, dst, numPixels); 0179 return true; 0180 case KoChannelInfo::INT16: 0181 scalePixels<_CSTrait::pixelSize, 2, channels_type, qint16>(src, dst, numPixels); 0182 return true; 0183 case KoChannelInfo::UINT32: 0184 scalePixels<_CSTrait::pixelSize, 4, channels_type, quint32>(src, dst, numPixels); 0185 return true; 0186 default: 0187 break; 0188 } 0189 } 0190 0191 return KoColorSpace::convertPixelsTo(src, dst, dstColorSpace, numPixels, renderingIntent, conversionFlags); 0192 } 0193 0194 private: 0195 template<int srcPixelSize, int dstChannelSize, class TSrcChannel, class TDstChannel> 0196 void scalePixels(const quint8* src, quint8* dst, quint32 numPixels) const { 0197 qint32 dstPixelSize = dstChannelSize * _CSTrait::channels_nb; 0198 0199 for(quint32 i=0; i<numPixels; ++i) { 0200 const TSrcChannel* srcPixel = reinterpret_cast<const TSrcChannel*>(src + i * srcPixelSize); 0201 TDstChannel* dstPixel = reinterpret_cast<TDstChannel*>(dst + i * dstPixelSize); 0202 0203 for(quint32 c=0; c<_CSTrait::channels_nb; ++c) 0204 dstPixel[c] = Arithmetic::scale<TDstChannel>(srcPixel[c]); 0205 } 0206 } 0207 }; 0208 0209 #endif // KOCOLORSPACEABSTRACT_H