diff options
Diffstat (limited to 'src/gui/painting/qcolortransferfunction_p.h')
-rw-r--r-- | src/gui/painting/qcolortransferfunction_p.h | 116 |
1 files changed, 53 insertions, 63 deletions
diff --git a/src/gui/painting/qcolortransferfunction_p.h b/src/gui/painting/qcolortransferfunction_p.h index 0575dbd888..484cc69114 100644 --- a/src/gui/painting/qcolortransferfunction_p.h +++ b/src/gui/painting/qcolortransferfunction_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QCOLORTRANSFERFUNCTION_P_H #define QCOLORTRANSFERFUNCTION_P_H @@ -52,44 +16,52 @@ // #include <QtGui/private/qtguiglobal_p.h> +#include <QtCore/QFlags> #include <cmath> QT_BEGIN_NAMESPACE // Defines a ICC parametric curve type 4 -class Q_GUI_EXPORT QColorTransferFunction +class QColorTransferFunction { public: QColorTransferFunction() noexcept - : 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), m_flags(0) + : 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) + , m_flags(Hints(Hint::Calculated) | Hint::IsGamma | Hint::IsIdentity) { } + QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g) noexcept - : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(0) + : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags() { } bool isGamma() const { updateHints(); - return m_flags & quint32(Hints::IsGamma); + return m_flags & Hint::IsGamma; } - bool isLinear() const + bool isIdentity() const { updateHints(); - return m_flags & quint32(Hints::IsLinear); + return m_flags & Hint::IsIdentity; } bool isSRgb() const { updateHints(); - return m_flags & quint32(Hints::IsSRgb); + return m_flags & Hint::IsSRgb; } float apply(float x) const { if (x < m_d) return m_c * x + m_f; + float t = std::pow(m_a * x + m_b, m_g); + if (std::isfinite(t)) + return t + m_e; + if (t > 0.f) + return 1.f; else - return std::pow(m_a * x + m_b, m_g) + m_e; + return 0.f; } QColorTransferFunction inverted() const @@ -98,7 +70,7 @@ public: d = m_c * m_d + m_f; - if (!qFuzzyIsNull(m_c)) { + if (std::isnormal(m_c)) { c = 1.0f / m_c; f = -m_f / m_c; } else { @@ -106,8 +78,12 @@ public: f = 0.0f; } - if (!qFuzzyIsNull(m_a) && !qFuzzyIsNull(m_g)) { + bool valid_abeg = std::isnormal(m_a) && std::isnormal(m_g); + if (valid_abeg) a = std::pow(1.0f / m_a, m_g); + if (valid_abeg && !std::isfinite(a)) + valid_abeg = false; + if (valid_abeg) { b = -a * m_e; e = -m_b / m_a; g = 1.0f / m_g; @@ -124,15 +100,19 @@ public: // A few predefined curves: static QColorTransferFunction fromGamma(float gamma) { - return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma); + return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma, + Hints(Hint::Calculated) | Hint::IsGamma | + (paramCompare(gamma, 1.0f) ? Hint::IsIdentity : Hint::NoHint)); } static QColorTransferFunction fromSRgb() { - return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f); + return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f, + Hints(Hint::Calculated) | Hint::IsSRgb); } static QColorTransferFunction fromProPhotoRgb() { - return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f); + return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f, + Hints(Hint::Calculated)); } bool matches(const QColorTransferFunction &o) const { @@ -152,7 +132,20 @@ public: float m_f; float m_g; + enum class Hint : quint32 { + NoHint = 0, + Calculated = 1, + IsGamma = 2, + IsIdentity = 4, + IsSRgb = 8 + }; + + Q_DECLARE_FLAGS(Hints, Hint); + private: + QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g, Hints flags) noexcept + : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(flags) + { } static inline bool paramCompare(float p1, float p2) { // Much fuzzier than fuzzy compare. @@ -163,7 +156,7 @@ private: void updateHints() const { - if (m_flags & quint32(Hints::Calculated)) + if (m_flags & Hint::Calculated) return; // We do not consider the case with m_d = 1.0f linear or simple, // since it wouldn't be linear for applyExtended(). @@ -171,24 +164,21 @@ private: && paramCompare(m_d, 0.0f) && paramCompare(m_e, 0.0f); if (simple) { - m_flags |= quint32(Hints::IsGamma); + m_flags |= Hint::IsGamma; if (qFuzzyCompare(m_g, 1.0f)) - m_flags |= quint32(Hints::IsLinear); + m_flags |= Hint::IsIdentity; } else { if (*this == fromSRgb()) - m_flags |= quint32(Hints::IsSRgb); + m_flags |= Hint::IsSRgb; } - m_flags |= quint32(Hints::Calculated); + m_flags |= Hint::Calculated; } - enum class Hints : quint32 { - Calculated = 1, - IsGamma = 2, - IsLinear = 4, - IsSRgb = 8 - }; - mutable quint32 m_flags; + + mutable Hints m_flags; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QColorTransferFunction::Hints); + inline bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2) { return f1.matches(f2); |