Krita Source Code Documentation
Loading...
Searching...
No Matches
KoInvertColorTransformation.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2018 Iván Santa María <ghevan@gmail.com>
3 * SPDX-FileCopyrightText: 2006 Cyrille Berger <cberger@cberger.net>
4 * SPDX-FileCopyrightText: 2007 Emanuele Tamponi <emanuele@valinor.it>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7*/
8
9#ifndef KO_INVERT_COLOR_TRANSFORMATION_H
10#define KO_INVERT_COLOR_TRANSFORMATION_H
11
13
14#include "KoColorSpace.h"
15#include "KoColorSpaceMaths.h"
16
18
19#include <KoConfig.h>
20#ifdef HAVE_OPENEXR
21#include <half.h>
22#endif
24
25public:
26
28 : m_colorSpace(cs)
29 , m_psize(cs->pixelSize())
30 , m_chanCount(cs->channelCount())
31 {
32 // Only invert COLOR channels
33 const QList<KoChannelInfo *> channels = cs->channels();
34 for(quint8 i = 0; i < m_chanCount; i++){
35 if(channels.at(i)->channelType() == KoChannelInfo::COLOR)
36 m_channels.append(i);
37 }
38 }
39
40 template<typename T>
41 void transformI(const quint8 *src, quint8 *dst, qint32 nPixels) const {
42 T *m_rgba = (T*)(src);
43 T *m_dst = (T*)(dst);
44
45 while (nPixels--) {
46 for(quint8 i : m_channels){
47 m_dst[i] = KoColorSpaceMaths<T>::invert(m_rgba[i]);
48 }
49 m_rgba += m_chanCount;
50 m_dst += m_chanCount;
51 }
52
53 }
54
55 void transformGen(const quint8 *src, quint8 *dst, qint32 nPixels) const {
56 quint16 m_rgba[4];
57 while (nPixels--) {
58 m_colorSpace->toRgbA16(src, reinterpret_cast<quint8 *>(m_rgba), 1);
59 m_rgba[0] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[0];
60 m_rgba[1] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[1];
61 m_rgba[2] = KoColorSpaceMathsTraits<quint16>::max - m_rgba[2];
62 m_colorSpace->fromRgbA16(reinterpret_cast<quint8 *>(m_rgba), dst, 1);
63 src += m_psize;
64 dst += m_psize;
65 }
66 }
67
68 // Once CMYK and LAB 32 float are normalized, this inverts will invert properly
69// template<typename T>
70// void transformC(const quint8 *src, quint8 *dst, qint32 nPixels) const {
71// QVector<float> normChan(m_chanCount);
72
73// float *m_rgba;
74// float *m_dst = (float*)(dst);
75// while (nPixels--) {
76// m_colorSpace->normalisedChannelsValue(src, normChan);
77// for(quint8 i : m_channels){
78// normChan[i] = KoColorSpaceMaths<float>::invert(normChan[i]);
79// }
80// m_colorSpace->fromNormalisedChannelsValue(dst,normChan);
81// //m_rgba += m_psize;
82// src += m_psize;
83// dst += m_psize;
84// }
85// }
86
87protected:
89private:
91 quint32 m_psize;
92 quint32 m_chanCount;
93};
94
96public:
101
102 void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override {
103 transformI<quint8>(src,dst,nPixels);
104 }
105};
106
108public:
113
114 void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override {
115 transformI<quint16>(src,dst,nPixels);
116 }
117};
118
119#ifdef HAVE_OPENEXR
120class KoF16InvertColorTransformer : public KoInvertColorTransformationT {
121public:
122 KoF16InvertColorTransformer(const KoColorSpace* cs)
124 {
125 };
126
127 void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override {
128 transformI<half>(src,dst,nPixels);
129 }
130};
131#endif
132
134public:
139
140 void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override {
141 transformI<float>(src,dst,nPixels);
142 }
143};
144
146public:
151
152 void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override {
153 transformGen(src,dst,nPixels);
154 }
155};
156
157
159{
160public:
162 {
163 KoID id = cs->colorDepthId();
164 KoID modelId = cs->colorModelId();
165 if (id == Integer8BitsColorDepthID) {
166 return new KoU8InvertColorTransformer(cs);
167 } else if (id == Integer16BitsColorDepthID) {
168 return new KoU16InvertColorTransformer(cs);
169#ifdef HAVE_OPENEXR
170 } else if (id == Float16BitsColorDepthID) {
171 return new KoF16InvertColorTransformer(cs);
172#endif
173 } else {
174 if(modelId == LABAColorModelID || modelId == CMYKAColorModelID){
175 return new KoF32GenInvertColorTransformer(cs);
176 }
177 return new KoF32InvertColorTransformer(cs);
178 }
179 }
180};
181
182#endif
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
@ COLOR
The channel represents a color.
static _T invert(_T a)
virtual void toRgbA16(const quint8 *src, quint8 *dst, quint32 nPixels) const
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
virtual void fromRgbA16(const quint8 *src, quint8 *dst, quint32 nPixels) const
virtual KoID colorDepthId() const =0
virtual void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const =0
void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override
KoF32GenInvertColorTransformer(const KoColorSpace *cs)
void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override
KoF32InvertColorTransformer(const KoColorSpace *cs)
Definition KoID.h:30
void transformGen(const quint8 *src, quint8 *dst, qint32 nPixels) const
KoInvertColorTransformationT(const KoColorSpace *cs)
void transformI(const quint8 *src, quint8 *dst, qint32 nPixels) const
static KoColorTransformation * getTransformator(const KoColorSpace *cs)
KoU16InvertColorTransformer(const KoColorSpace *cs)
void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override
KoU8InvertColorTransformer(const KoColorSpace *cs)
void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override