Changeset View
Changeset View
Standalone View
Standalone View
libs/pigment/KoInvertColorTransformation.h
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * Copyright (c) 2018 Iván Santa María <ghevan@gmail.com> | ||||
2 | * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> | 3 | * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> | ||
3 | * Copyright (c) 2007 Emanuele Tamponi <emanuele@valinor.it> | 4 | * Copyright (c) 2007 Emanuele Tamponi <emanuele@valinor.it> | ||
4 | * | 5 | * | ||
5 | * This library is free software; you can redistribute it and/or | 6 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | 7 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | 8 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | 9 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | 10 | * | ||
10 | * This library is distributed in the hope that it will be useful, | 11 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | 14 | * Lesser General Public License for more details. | ||
14 | * | 15 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public License | 16 | * You should have received a copy of the GNU Lesser General Public License | ||
16 | * along with this library; see the file COPYING.LIB. If not, write to | 17 | * along with this library; see the file COPYING.LIB. If not, write to | ||
17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | 19 | * Boston, MA 02110-1301, USA. | ||
19 | */ | 20 | */ | ||
20 | 21 | | |||
21 | #ifndef KO_INVERT_COLOR_TRANSFORMATION_H | 22 | #ifndef KO_INVERT_COLOR_TRANSFORMATION_H | ||
22 | #define KO_INVERT_COLOR_TRANSFORMATION_H | 23 | #define KO_INVERT_COLOR_TRANSFORMATION_H | ||
23 | 24 | | |||
24 | #include "KoColorTransformation.h" | 25 | #include "KoColorTransformation.h" | ||
25 | 26 | | |||
26 | class KoInvertColorTransformation : public KoColorTransformation | 27 | #include "KoColorSpace.h" | ||
27 | { | 28 | #include "KoColorSpaceMaths.h" | ||
29 | | ||||
30 | #include "KoColorModelStandardIds.h" | ||||
31 | | ||||
32 | | ||||
33 | class KoInvertColorTransformationT : public KoColorTransformation { | ||||
28 | 34 | | |||
29 | public: | 35 | public: | ||
30 | 36 | | |||
31 | KoInvertColorTransformation(const KoColorSpace* cs) : m_colorSpace(cs), m_psize(cs->pixelSize()) { | 37 | KoInvertColorTransformationT(const KoColorSpace* cs) | ||
38 | : m_colorSpace(cs) | ||||
39 | , m_psize(cs->pixelSize()) | ||||
40 | , m_chanCount(cs->channelCount()) | ||||
41 | { | ||||
42 | // Only invert COLOR channels | ||||
43 | QList<KoChannelInfo *> channels = cs->channels(); | ||||
44 | for(quint8 i = 0; i < m_chanCount; i++){ | ||||
45 | if(channels.at(i)->channelType() == KoChannelInfo::COLOR) | ||||
46 | m_channels.append(i); | ||||
47 | } | ||||
32 | } | 48 | } | ||
33 | 49 | | |||
34 | void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { | 50 | template<typename T> | ||
51 | void transformI(const quint8 *src, quint8 *dst, qint32 nPixels) const { | ||||
52 | T *m_rgba = (T*)(src); | ||||
53 | T *m_dst = (T*)(dst); | ||||
54 | | ||||
55 | while (nPixels--) { | ||||
56 | for(quint8 i : m_channels){ | ||||
57 | m_dst[i] = KoColorSpaceMaths<T>::invert(m_rgba[i]); | ||||
58 | } | ||||
59 | m_rgba += m_chanCount; | ||||
60 | m_dst += m_chanCount; | ||||
61 | } | ||||
62 | | ||||
63 | } | ||||
64 | | ||||
65 | void transformGen(const quint8 *src, quint8 *dst, qint32 nPixels) const { | ||||
35 | quint16 m_rgba[4]; | 66 | quint16 m_rgba[4]; | ||
36 | while (nPixels--) { | 67 | while (nPixels--) { | ||
37 | m_colorSpace->toRgbA16(src, reinterpret_cast<quint8 *>(m_rgba), 1); | 68 | m_colorSpace->toRgbA16(src, reinterpret_cast<quint8 *>(m_rgba), 1); | ||
38 | m_rgba[0] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[0]; | 69 | m_rgba[0] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[0]; | ||
39 | m_rgba[1] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[1]; | 70 | m_rgba[1] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[1]; | ||
40 | m_rgba[2] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[2]; | 71 | m_rgba[2] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[2]; | ||
41 | m_colorSpace->fromRgbA16(reinterpret_cast<quint8 *>(m_rgba), dst, 1); | 72 | m_colorSpace->fromRgbA16(reinterpret_cast<quint8 *>(m_rgba), dst, 1); | ||
42 | src += m_psize; | 73 | src += m_psize; | ||
43 | dst += m_psize; | 74 | dst += m_psize; | ||
44 | } | 75 | } | ||
45 | | ||||
46 | } | 76 | } | ||
47 | 77 | | |||
48 | private: | 78 | // Once CMYK and LAB 32 float are normalized, this inverts will invert properly | ||
79 | // template<typename T> | ||||
80 | // void transformC(const quint8 *src, quint8 *dst, qint32 nPixels) const { | ||||
81 | // QVector<float> normChan(m_chanCount); | ||||
82 | | ||||
83 | // float *m_rgba; | ||||
84 | // float *m_dst = (float*)(dst); | ||||
85 | // while (nPixels--) { | ||||
86 | // m_colorSpace->normalisedChannelsValue(src, normChan); | ||||
87 | // for(quint8 i : m_channels){ | ||||
88 | // normChan[i] = KoColorSpaceMaths<float>::invert(normChan[i]); | ||||
89 | // } | ||||
90 | // m_colorSpace->fromNormalisedChannelsValue(dst,normChan); | ||||
91 | // //m_rgba += m_psize; | ||||
92 | // src += m_psize; | ||||
93 | // dst += m_psize; | ||||
94 | // } | ||||
95 | // } | ||||
49 | 96 | | |||
97 | protected: | ||||
98 | QList<quint8> m_channels; | ||||
99 | private: | ||||
50 | const KoColorSpace* m_colorSpace; | 100 | const KoColorSpace* m_colorSpace; | ||
51 | quint32 m_psize; | 101 | quint32 m_psize; | ||
102 | quint32 m_chanCount; | ||||
103 | }; | ||||
104 | | ||||
105 | class KoU8InvertColorTransformer : public KoInvertColorTransformationT { | ||||
106 | public: | ||||
107 | KoU8InvertColorTransformer(const KoColorSpace* cs) | ||||
108 | : KoInvertColorTransformationT(cs) | ||||
109 | { | ||||
110 | }; | ||||
111 | | ||||
112 | void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { | ||||
113 | transformI<quint8>(src,dst,nPixels); | ||||
114 | } | ||||
115 | }; | ||||
116 | | ||||
117 | class KoU16InvertColorTransformer : public KoInvertColorTransformationT { | ||||
118 | public: | ||||
119 | KoU16InvertColorTransformer(const KoColorSpace* cs) | ||||
120 | : KoInvertColorTransformationT(cs) | ||||
121 | { | ||||
122 | }; | ||||
123 | | ||||
124 | void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { | ||||
125 | transformI<quint16>(src,dst,nPixels); | ||||
126 | } | ||||
52 | }; | 127 | }; | ||
53 | 128 | | |||
129 | class KoF16InvertColorTransformer : public KoInvertColorTransformationT { | ||||
130 | public: | ||||
131 | KoF16InvertColorTransformer(const KoColorSpace* cs) | ||||
132 | : KoInvertColorTransformationT(cs) | ||||
133 | { | ||||
134 | }; | ||||
135 | | ||||
136 | void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { | ||||
137 | transformI<half>(src,dst,nPixels); | ||||
138 | } | ||||
139 | }; | ||||
140 | | ||||
141 | class KoF32InvertColorTransformer : public KoInvertColorTransformationT { | ||||
142 | public: | ||||
143 | KoF32InvertColorTransformer(const KoColorSpace* cs) | ||||
144 | : KoInvertColorTransformationT(cs) | ||||
145 | { | ||||
146 | }; | ||||
147 | | ||||
148 | void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { | ||||
149 | transformI<float>(src,dst,nPixels); | ||||
150 | } | ||||
151 | }; | ||||
152 | | ||||
153 | class KoF32GenInvertColorTransformer : public KoInvertColorTransformationT { | ||||
154 | public: | ||||
155 | KoF32GenInvertColorTransformer(const KoColorSpace* cs) | ||||
156 | : KoInvertColorTransformationT(cs) | ||||
157 | { | ||||
158 | }; | ||||
159 | | ||||
160 | void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override { | ||||
161 | transformGen(src,dst,nPixels); | ||||
162 | } | ||||
163 | }; | ||||
164 | | ||||
165 | | ||||
166 | class KoInvertColorTransformation | ||||
167 | { | ||||
168 | public: | ||||
169 | static KoColorTransformation* getTransformator(const KoColorSpace *cs) | ||||
170 | { | ||||
171 | KoID id = cs->colorDepthId(); | ||||
172 | KoID modelId = cs->colorModelId(); | ||||
173 | if (id == Integer8BitsColorDepthID) { | ||||
174 | return new KoU8InvertColorTransformer(cs); | ||||
175 | } else if (id == Integer16BitsColorDepthID) { | ||||
176 | return new KoU16InvertColorTransformer(cs); | ||||
177 | } else if (id == Float16BitsColorDepthID) { | ||||
178 | return new KoF16InvertColorTransformer(cs); | ||||
179 | } else { | ||||
180 | if(modelId == LABAColorModelID || modelId == CMYKAColorModelID){ | ||||
181 | return new KoF32GenInvertColorTransformer(cs); | ||||
182 | } | ||||
183 | return new KoF32InvertColorTransformer(cs); | ||||
184 | } | ||||
185 | } | ||||
186 | }; | ||||
54 | 187 | | |||
55 | #endif | 188 | #endif |