diff --git a/libs/pigment/KoColorSpaceAbstract.h b/libs/pigment/KoColorSpaceAbstract.h --- a/libs/pigment/KoColorSpaceAbstract.h +++ b/libs/pigment/KoColorSpaceAbstract.h @@ -35,7 +35,6 @@ #include "KoConvolutionOpImpl.h" #include "KoInvertColorTransformation.h" - /** * This in an implementation of KoColorSpace which can be used as a base for colorspaces with as many * different channels of the same type. @@ -137,7 +136,7 @@ } KoColorTransformation* createInvertTransformation() const override { - return new KoInvertColorTransformation(this); + return KoInvertColorTransformation::getTransformator(this); } KoColorTransformation *createDarkenAdjustment(qint32 shade, bool compensate, qreal compensation) const override { diff --git a/libs/pigment/KoInvertColorTransformation.h b/libs/pigment/KoInvertColorTransformation.h --- a/libs/pigment/KoInvertColorTransformation.h +++ b/libs/pigment/KoInvertColorTransformation.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2018 Iván Santa María * Copyright (c) 2006 Cyrille Berger * Copyright (c) 2007 Emanuele Tamponi * @@ -23,15 +24,45 @@ #include "KoColorTransformation.h" -class KoInvertColorTransformation : public KoColorTransformation -{ +#include "KoColorSpace.h" +#include "KoColorSpaceMaths.h" + +#include "KoColorModelStandardIds.h" + + +class KoInvertColorTransformationT : public KoColorTransformation { public: - KoInvertColorTransformation(const KoColorSpace* cs) : m_colorSpace(cs), m_psize(cs->pixelSize()) { + KoInvertColorTransformationT(const KoColorSpace* cs) + : m_colorSpace(cs) + , m_psize(cs->pixelSize()) + , m_chanCount(cs->channelCount()) + { + // Only invert COLOR channels + QList channels = cs->channels(); + for(quint8 i = 0; i < m_chanCount; i++){ + if(channels.at(i)->channelType() == KoChannelInfo::COLOR) + m_channels.append(i); + } } - void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { + template + void transformI(const quint8 *src, quint8 *dst, qint32 nPixels) const { + T *m_rgba = (T*)(src); + T *m_dst = (T*)(dst); + + while (nPixels--) { + for(quint8 i : m_channels){ + m_dst[i] = KoColorSpaceMaths::invert(m_rgba[i]); + } + m_rgba += m_chanCount; + m_dst += m_chanCount; + } + + } + + void transformGen(const quint8 *src, quint8 *dst, qint32 nPixels) const { quint16 m_rgba[4]; while (nPixels--) { m_colorSpace->toRgbA16(src, reinterpret_cast(m_rgba), 1); @@ -42,14 +73,116 @@ src += m_psize; dst += m_psize; } - } -private: + // Once CMYK and LAB 32 float are normalized, this inverts will invert properly +// template +// void transformC(const quint8 *src, quint8 *dst, qint32 nPixels) const { +// QVector normChan(m_chanCount); + +// float *m_rgba; +// float *m_dst = (float*)(dst); +// while (nPixels--) { +// m_colorSpace->normalisedChannelsValue(src, normChan); +// for(quint8 i : m_channels){ +// normChan[i] = KoColorSpaceMaths::invert(normChan[i]); +// } +// m_colorSpace->fromNormalisedChannelsValue(dst,normChan); +// //m_rgba += m_psize; +// src += m_psize; +// dst += m_psize; +// } +// } +protected: + QList m_channels; +private: const KoColorSpace* m_colorSpace; quint32 m_psize; + quint32 m_chanCount; +}; + +class KoU8InvertColorTransformer : public KoInvertColorTransformationT { +public: + KoU8InvertColorTransformer(const KoColorSpace* cs) + : KoInvertColorTransformationT(cs) + { + }; + + void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { + transformI(src,dst,nPixels); + } +}; + +class KoU16InvertColorTransformer : public KoInvertColorTransformationT { +public: + KoU16InvertColorTransformer(const KoColorSpace* cs) + : KoInvertColorTransformationT(cs) + { + }; + + void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { + transformI(src,dst,nPixels); + } }; +class KoF16InvertColorTransformer : public KoInvertColorTransformationT { +public: + KoF16InvertColorTransformer(const KoColorSpace* cs) + : KoInvertColorTransformationT(cs) + { + }; + + void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { + transformI(src,dst,nPixels); + } +}; + +class KoF32InvertColorTransformer : public KoInvertColorTransformationT { +public: + KoF32InvertColorTransformer(const KoColorSpace* cs) + : KoInvertColorTransformationT(cs) + { + }; + + void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { + transformI(src,dst,nPixels); + } +}; + +class KoF32GenInvertColorTransformer : public KoInvertColorTransformationT { +public: + KoF32GenInvertColorTransformer(const KoColorSpace* cs) + : KoInvertColorTransformationT(cs) + { + }; + + void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { + transformGen(src,dst,nPixels); + } +}; + + +class KoInvertColorTransformation +{ +public: + static KoColorTransformation* getTransformator(const KoColorSpace *cs) + { + KoID id = cs->colorDepthId(); + KoID modelId = cs->colorModelId(); + if (id == Integer8BitsColorDepthID) { + return new KoU8InvertColorTransformer(cs); + } else if (id == Integer16BitsColorDepthID) { + return new KoU16InvertColorTransformer(cs); + } else if (id == Float16BitsColorDepthID) { + return new KoF16InvertColorTransformer(cs); + } else { + if(modelId == LABAColorModelID || modelId == CMYKAColorModelID){ + return new KoF32GenInvertColorTransformer(cs); + } + return new KoF32InvertColorTransformer(cs); + } + } +}; #endif diff --git a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h --- a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h +++ b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h @@ -36,8 +36,6 @@ return false; } - KoColorTransformation *createInvertTransformation() const override; - KoID colorModelId() const override { return RGBAColorModelID; diff --git a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp --- a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp +++ b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp @@ -34,33 +34,6 @@ #define downscale(quantum) (quantum) //((unsigned char) ((quantum)/257UL)) #define upscale(value) (value) // ((quint8) (257UL*(value))) -class KoRgbU8InvertColorTransformation : public KoColorTransformation -{ - -public: - - KoRgbU8InvertColorTransformation(const KoColorSpace *cs) : m_psize(cs->pixelSize()) - { - } - - void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override - { - while (nPixels--) { - dst[0] = KoColorSpaceMathsTraits::max - src[0]; - dst[1] = KoColorSpaceMathsTraits::max - src[1]; - dst[2] = KoColorSpaceMathsTraits::max - src[2]; - dst[3] = src[3]; - - src += m_psize; - dst += m_psize; - } - - } - -private: - quint32 m_psize; -}; - RgbU8ColorSpace::RgbU8ColorSpace(const QString &name, KoColorProfile *p) : LcmsColorSpace(colorSpaceId(), name, TYPE_BGRA_8, cmsSigRgbData, p) { @@ -78,11 +51,6 @@ addCompositeOp(new RgbCompositeOpBumpmap(this)); } -KoColorTransformation *RgbU8ColorSpace::createInvertTransformation() const -{ - return new KoRgbU8InvertColorTransformation(this); -} - KoColorSpace *RgbU8ColorSpace::clone() const { return new RgbU8ColorSpace(name(), profile()->clone());