1// Copyright (C) 2024 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 QCOLORTRANSFERGENERIC_P_H
5#define QCOLORTRANSFERGENERIC_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
20#include <cmath>
21
22QT_BEGIN_NAMESPACE
23
24// Defines the a generic transfer function for our HDR functions
25class QColorTransferGenericFunction
26{
27public:
28 using ConverterPtr = float (*)(float);
29 constexpr QColorTransferGenericFunction(ConverterPtr toLinear = nullptr, ConverterPtr fromLinear = nullptr) noexcept
30 : m_toLinear(toLinear), m_fromLinear(fromLinear)
31 {}
32
33 static QColorTransferGenericFunction hlg()
34 {
35 return QColorTransferGenericFunction(hlgToLinear, hlgFromLinear);
36 }
37 static QColorTransferGenericFunction pq()
38 {
39 return QColorTransferGenericFunction(pqToLinear, pqFromLinear);
40 }
41
42 float apply(float x) const
43 {
44 return m_toLinear(x);
45 }
46
47 float applyInverse(float x) const
48 {
49 return m_fromLinear(x);
50 }
51
52 bool operator==(const QColorTransferGenericFunction &o) const noexcept
53 {
54 return m_toLinear == o.m_toLinear && m_fromLinear == o.m_fromLinear;
55 }
56 bool operator!=(const QColorTransferGenericFunction &o) const noexcept
57 {
58 return m_toLinear != o.m_toLinear || m_fromLinear != o.m_fromLinear;
59 }
60
61private:
62 ConverterPtr m_toLinear = nullptr;
63 ConverterPtr m_fromLinear = nullptr;
64
65 // HLG from linear [0-12] -> [0-1]
66 static float hlgFromLinear(float x)
67 {
68 if (x > 1.f)
69 return m_hlg_a * std::log(x: x - m_hlg_b) + m_hlg_c;
70 return std::sqrt(x: x * 0.25f);
71 }
72
73 // HLG to linear [0-1] -> [0-12]
74 static float hlgToLinear(float x)
75 {
76 if (x < 0.5f)
77 return (x * x) * 4.f;
78 return std::exp(x: (x - m_hlg_c) / m_hlg_a) + m_hlg_b;
79 }
80
81 constexpr static float m_hlg_a = 0.17883277f;
82 constexpr static float m_hlg_b = 1.f - (4.f * m_hlg_a);
83 constexpr static float m_hlg_c = 0.55991073f; // 0.5 - a * ln(4 * a)
84
85 // PQ to linear [0-1] -> [0-64]
86 static float pqToLinear(float x)
87 {
88 x = std::pow(x: x, y: 1.f / m_pq_m2);
89 return std::pow(x: (m_pq_c1 - x) / (m_pq_c3 * x - m_pq_c2), y: (1.f / m_pq_m1)) * m_pq_f;
90 }
91
92 // PQ from linear [0-64] -> [0-1]
93 static float pqFromLinear(float x)
94 {
95 x = std::pow(x: x * (1.f / m_pq_f), y: m_pq_m1);
96 return std::pow(x: (m_pq_c1 + m_pq_c2 * x) / (1.f + m_pq_c3 * x), y: m_pq_m2);
97 }
98
99 constexpr static float m_pq_c1 = 107.f / 128.f; // c3 - c2 + 1
100 constexpr static float m_pq_c2 = 2413.f / 128.f;
101 constexpr static float m_pq_c3 = 2392.f / 128.f;
102 constexpr static float m_pq_m1 = 1305.f / 8192.f;
103 constexpr static float m_pq_m2 = 2523.f / 32.f;
104 constexpr static float m_pq_f = 64.f; // This might need to be set based on scene metadata
105};
106
107QT_END_NAMESPACE
108
109#endif // QCOLORTRANSFERGENERIC_P_H
110

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/gui/painting/qcolortransfergeneric_p.h