Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcolortransferfunction_p.h
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCOLORTRANSFERFUNCTION_P_H
5#define QCOLORTRANSFERFUNCTION_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/private/qtguiglobal_p.h>
19#include <QtCore/QFlags>
20
21#include <cmath>
22
24
25// Defines a ICC parametric curve type 4
27{
28public:
30 : m_a(1.0f), m_b(0.0f), m_c(1.0f), m_d(0.0f), m_e(0.0f), m_f(0.0f), m_g(1.0f)
31 , m_flags(Hints(Hint::Calculated) | Hint::IsGamma | Hint::IsIdentity)
32 { }
33
34 QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g) noexcept
35 : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags()
36 { }
37
38 bool isGamma() const
39 {
40 updateHints();
41 return m_flags & Hint::IsGamma;
42 }
43 bool isIdentity() const
44 {
45 updateHints();
46 return m_flags & Hint::IsIdentity;
47 }
48 bool isSRgb() const
49 {
50 updateHints();
51 return m_flags & Hint::IsSRgb;
52 }
53
54 float apply(float x) const
55 {
56 if (x < m_d)
57 return m_c * x + m_f;
58 float t = std::pow(m_a * x + m_b, m_g);
59 if (std::isfinite(t))
60 return t + m_e;
61 if (t > 0.f)
62 return 1.f;
63 else
64 return 0.f;
65 }
66
68 {
69 float a, b, c, d, e, f, g;
70
71 d = m_c * m_d + m_f;
72
73 if (std::isnormal(m_c)) {
74 c = 1.0f / m_c;
75 f = -m_f / m_c;
76 } else {
77 c = 0.0f;
78 f = 0.0f;
79 }
80
81 bool valid_abeg = std::isnormal(m_a) && std::isnormal(m_g);
82 if (valid_abeg)
83 a = std::pow(1.0f / m_a, m_g);
84 if (valid_abeg && !std::isfinite(a))
85 valid_abeg = false;
86 if (valid_abeg) {
87 b = -a * m_e;
88 e = -m_b / m_a;
89 g = 1.0f / m_g;
90 } else {
91 a = 0.0f;
92 b = 0.0f;
93 e = 1.0f;
94 g = 1.0f;
95 }
96
97 return QColorTransferFunction(a, b, c, d, e, f, g);
98 }
99
100 // A few predefined curves:
102 {
103 return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma,
105 (paramCompare(gamma, 1.0f) ? Hint::IsIdentity : Hint::NoHint));
106 }
108 {
109 return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f,
111 }
113 {
114 return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f,
115 Hints(Hint::Calculated));
116 }
118 {
119 return paramCompare(m_a, o.m_a) && paramCompare(m_b, o.m_b)
120 && paramCompare(m_c, o.m_c) && paramCompare(m_d, o.m_d)
121 && paramCompare(m_e, o.m_e) && paramCompare(m_f, o.m_f)
122 && paramCompare(m_g, o.m_g);
123 }
124 friend inline bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2);
125 friend inline bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2);
126
127 float m_a;
128 float m_b;
129 float m_c;
130 float m_d;
131 float m_e;
132 float m_f;
133 float m_g;
134
135 enum class Hint : quint32 {
136 NoHint = 0,
137 Calculated = 1,
138 IsGamma = 2,
139 IsIdentity = 4,
140 IsSRgb = 8
141 };
142
144
145private:
146 QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g, Hints flags) noexcept
147 : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(flags)
148 { }
149 static inline bool paramCompare(float p1, float p2)
150 {
151 // Much fuzzier than fuzzy compare.
152 // It tries match parameters that has been passed through a 8.8
153 // fixed point form.
154 return (qAbs(p1 - p2) <= (1.0f / 512.0f));
155 }
156
157 void updateHints() const
158 {
159 if (m_flags & Hint::Calculated)
160 return;
161 // We do not consider the case with m_d = 1.0f linear or simple,
162 // since it wouldn't be linear for applyExtended().
163 bool simple = paramCompare(m_a, 1.0f) && paramCompare(m_b, 0.0f)
164 && paramCompare(m_d, 0.0f)
165 && paramCompare(m_e, 0.0f);
166 if (simple) {
167 m_flags |= Hint::IsGamma;
168 if (qFuzzyCompare(m_g, 1.0f))
169 m_flags |= Hint::IsIdentity;
170 } else {
171 if (*this == fromSRgb())
172 m_flags |= Hint::IsSRgb;
173 }
174 m_flags |= Hint::Calculated;
175 }
176
177 mutable Hints m_flags;
178};
179
180Q_DECLARE_OPERATORS_FOR_FLAGS(QColorTransferFunction::Hints);
181
183{
184 return f1.matches(f2);
185}
187{
188 return !f1.matches(f2);
189}
190
192
193#endif // QCOLORTRANSFERFUNCTION_P_H
Q_DECLARE_FLAGS(Hints, Hint)
QColorTransferFunction inverted() const
friend bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2)
QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g) noexcept
static QColorTransferFunction fromGamma(float gamma)
bool matches(const QColorTransferFunction &o) const
friend bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2)
static QColorTransferFunction fromProPhotoRgb()
static QColorTransferFunction fromSRgb()
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2)
bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2)
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLfloat GLfloat f
GLbitfield flags
GLboolean GLboolean g
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
unsigned int quint32
Definition qtypes.h:50