Krita Source Code Documentation
Loading...
Searching...
No Matches
LcmsRGBP2020PQColorSpaceTransformation.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef LCMSRGBP2020PQCOLORSPACETRANSFORMATION_H
8#define LCMSRGBP2020PQCOLORSPACETRANSFORMATION_H
9
10#include "KoAlwaysInline.h"
12#include "KoColorSpaceMaths.h"
16
19#ifdef HAVE_OPENEXR
21#endif
23
24
25namespace
26{
27
28template <class T>
29struct DstTraitsForSource {
30 typedef KoRgbF32Traits result;
31};
32
36#ifdef HAVE_OPENEXR
37template <>
38struct DstTraitsForSource<KoBgrU16Traits> {
39 typedef KoRgbF16Traits result;
40};
41
42template <>
43struct DstTraitsForSource<KoBgrU8Traits> {
44 typedef KoRgbF16Traits result;
45};
46#endif
47
48template <typename src_channel_type,
49 typename dst_channel_type>
50struct RemoveSmpte2048Policy {
51 static ALWAYS_INLINE dst_channel_type process(src_channel_type value, float refWhite) {
52 return
56 value), refWhite));
57 }
58
59 static ALWAYS_INLINE double getRefWhite(const KoColorSpace *src, const KoColorSpace *target) {
60 Q_UNUSED(target)
61 if (!src || !src->profile()) return 203.0;
62 return src->profile()->hdrReferenceWhite().value_or(203.0);
63 }
64};
65
66template <typename src_channel_type,
67 typename dst_channel_type>
68struct ApplySmpte2048Policy {
69 static ALWAYS_INLINE dst_channel_type process(src_channel_type value, float refWhite) {
70 return
74 value), refWhite));
75 }
76
77 static ALWAYS_INLINE double getRefWhite(const KoColorSpace *src, const KoColorSpace *target) {
78 Q_UNUSED(src)
79 if (!target || !target->profile()) return 203.0;
80 return target->profile()->hdrReferenceWhite().value_or(203.0);
81 }
82};
83
84template <typename src_channel_type,
85 typename dst_channel_type>
86struct NoopPolicy {
87 static ALWAYS_INLINE dst_channel_type process(src_channel_type value, float refWhite) {
88 Q_UNUSED(refWhite)
90 }
91
92 static ALWAYS_INLINE double getRefWhite(const KoColorSpace *src, const KoColorSpace *target) {
93 Q_UNUSED(src)
94 Q_UNUSED(target)
95 return 203.0;
96 }
97};
98
99}
100
101template<typename SrcCSTraits,
102 typename DstCSTraits,
103 template<typename, typename> class Policy>
105{
107 const KoColorSpace* dstCs,
109 ConversionFlags conversionFlags)
111 dstCs,
114 {
115 }
116
117 void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override {
118 KIS_ASSERT(src != dst);
119
120 const typename SrcCSTraits::Pixel *srcPixel = reinterpret_cast<const typename SrcCSTraits::Pixel*>(src);
121 typename DstCSTraits::Pixel *dstPixel = reinterpret_cast<typename DstCSTraits::Pixel*>(dst);
122
123 typedef typename SrcCSTraits::channels_type src_channel_type;
124 typedef typename DstCSTraits::channels_type dst_channel_type;
125 typedef Policy<src_channel_type, dst_channel_type> ConcretePolicy;
126
127 const double refWhite = ConcretePolicy::getRefWhite(srcColorSpace(), dstColorSpace());
128
129 for (int i = 0; i < nPixels; i++) {
130 dstPixel->red = ConcretePolicy::process(srcPixel->red, refWhite);
131 dstPixel->green = ConcretePolicy::process(srcPixel->green, refWhite);
132 dstPixel->blue = ConcretePolicy::process(srcPixel->blue, refWhite);
133 dstPixel->alpha =
135 srcPixel->alpha);
136
137 srcPixel++;
138 dstPixel++;
139 }
140 }
141
142};
143
144template<class ParentColorSpace, class DstColorSpaceTraits = typename DstTraitsForSource<typename ParentColorSpace::ColorSpaceTraits>::result>
146{
147public:
148 LcmsFromRGBP2020PQTransformationFactory(const QString &targetProfileName, const QString &linearProfileName)
150 colorDepthIdForChannelType<typename ParentColorSpace::ColorSpaceTraits::channels_type>().id(),
151 targetProfileName,
152 RGBAColorModelID.id(),
153 colorDepthIdForChannelType<typename DstColorSpaceTraits::channels_type>().id(),
154 linearProfileName)
155 {
156 }
157
159 const KoColorSpace* dstColorSpace,
161 KoColorConversionTransformation::ConversionFlags conversionFlags) const override
162 {
163 return new ApplyRgbShaper<
164 typename ParentColorSpace::ColorSpaceTraits,
165 DstColorSpaceTraits,
166 RemoveSmpte2048Policy>(srcColorSpace,
167 dstColorSpace,
168 renderingIntent,
169 conversionFlags);
170 }
171};
172
173template<class ParentColorSpace, class DstColorSpaceTraits = typename DstTraitsForSource<typename ParentColorSpace::ColorSpaceTraits>::result>
175{
176public:
177 LcmsToRGBP2020PQTransformationFactory(const QString &targetProfileName, const QString &linearProfileName)
179 colorDepthIdForChannelType<typename DstColorSpaceTraits::channels_type>().id(),
180 linearProfileName,
181 RGBAColorModelID.id(),
182 colorDepthIdForChannelType<typename ParentColorSpace::ColorSpaceTraits::channels_type>().id(),
183 targetProfileName)
184 {
185 }
186
188 const KoColorSpace* dstColorSpace,
190 KoColorConversionTransformation::ConversionFlags conversionFlags) const override
191 {
192 return new ApplyRgbShaper<
193 DstColorSpaceTraits,
194 typename ParentColorSpace::ColorSpaceTraits,
195 ApplySmpte2048Policy>(srcColorSpace,
196 dstColorSpace,
197 renderingIntent,
198 conversionFlags);
199 }
200};
201
202template<class ParentColorSpace, class DstColorSpaceTraits>
204{
205public:
206 LcmsScaleRGBP2020PQTransformationFactory(const QString &targetProfileName)
208 colorDepthIdForChannelType<typename ParentColorSpace::ColorSpaceTraits::channels_type>().id(),
209 targetProfileName,
210 RGBAColorModelID.id(),
211 colorDepthIdForChannelType<typename DstColorSpaceTraits::channels_type>().id(),
212 targetProfileName)
213 {
215 }
216
218 const KoColorSpace* dstColorSpace,
220 KoColorConversionTransformation::ConversionFlags conversionFlags) const override
221 {
222 return new ApplyRgbShaper<
223 typename ParentColorSpace::ColorSpaceTraits,
224 DstColorSpaceTraits,
225 NoopPolicy>(srcColorSpace,
226 dstColorSpace,
227 renderingIntent,
228 conversionFlags);
229 }
230};
231
232#endif // LCMSRGBP2020PQCOLORSPACETRANSFORMATION_H
float value(const T *src, size_t ch)
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
#define ALWAYS_INLINE
KoID colorDepthIdForChannelType()
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
ALWAYS_INLINE float applySmpte2048Curve(float x, float refWhite=203.0) noexcept
ALWAYS_INLINE float removeSmpte2048Curve(float x, float refWhite=203.0) noexcept
static _Tdst scaleToA(_T a)
KoColorConversionTransformation * createColorTransformation(const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const override
LcmsFromRGBP2020PQTransformationFactory(const QString &targetProfileName, const QString &linearProfileName)
KoColorConversionTransformation * createColorTransformation(const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const override
LcmsScaleRGBP2020PQTransformationFactory(const QString &targetProfileName)
LcmsToRGBP2020PQTransformationFactory(const QString &targetProfileName, const QString &linearProfileName)
KoColorConversionTransformation * createColorTransformation(const KoColorSpace *srcColorSpace, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const override
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override
ApplyRgbShaper(const KoColorSpace *srcCs, const KoColorSpace *dstCs, Intent renderingIntent, ConversionFlags conversionFlags)