Perceptual Color

helperconversion.h
1// SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR MIT
3
4#ifndef HELPERCONVERSION_H
5#define HELPERCONVERSION_H
6
7#include "helperqttypes.h"
8#include "lchdouble.h"
9#include <lcms2.h>
10#include <qcolor.h>
11#include <qglobal.h>
12#include <type_traits>
13
14#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
15#include <qtmetamacros.h>
16#endif
17
18/** @internal
19 *
20 * @file
21 *
22 * Provides type conversions. */
23
24namespace PerceptualColor
25{
26
27Q_NAMESPACE
28
29/** @brief Identifiers for color models. */
30enum class ColorModel {
31 CielabD50, /**< Cielab color space using a D50 illuminant.
32 Lightness: [0, 100].<br/>
33 a: unbound.<br/>
34 b: unbound. */
35 CielchD50, /**< Cielch color space using a D50 illuminant.
36 Lightness: [0, 100].<br/>
37 Chroma: unbound.<br/>
38 Hue: [0, 360[. */
39 Hsl360_1_1, /**< A HSL color space.
40 Hue: [0, 360[.<br/>
41 Saturation: [0, 1].<br/>
42 Lightness: [0, 1]. */
43 Hwb360_1_1, /**< A HWB color space.
44 Hue: [0, 360[.<br/>
45 Whiteness: [0, 1].<br/>
46 Blackness: [0, 1]. */
47 Invalid, /**< Represents invalid data. */
48 OklabD65, /**< Oklab color space, which by definition always and
49 exclusively uses a D65 illuminant.
50
51 Lightness: [0, 1].<br/>
52 a: unbound.<br/>
53 b: unbound. */
54 OklchD65, /**< Oklch color space, which by definition always and
55 exclusively uses a D65 illuminant.
56
57 Lightness: [0, 1].<br/>
58 Chroma: unbound.<br/>
59 Hue: [0, 360[. */
60 Rgb1, /**< An Rgb color space.
61 R: [0, 1].<br/>
62 G: [0, 1].<br/>
63 B: [0, 1]. */
64 XyzD50, /**< Xyz color space using a D50 illuminant.
65 X: unbound.<br/>
66 Y: [0, 1]. Diffuse white has a luminance (Y) of 1.0<br/>
67 Z: unbound. */
68 XyzD65 /**< Xzy color space using a D65 illuminant.
69 X: unbound.<br/>
70 Y: [0, 1]. Diffuse white has a luminance (Y) of 1.0<br/>
71 Z: unbound. */
72};
73Q_ENUM_NS(ColorModel)
74
75#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
76uint qHash(const ColorModel t, uint seed = 0); // clazy:exclude=qt6-qhash-signature
77#endif
78
79/** @internal
80 *
81 * @brief Converts from <tt>[0, 1]</tt> to <tt>[0, 255]</tt>.
82 *
83 * @param original A value on a scale <tt>[0, 1]</tt>.
84 *
85 * @returns Value converted to the scale <tt>[0, 255]</tt>, applying correct
86 * rounding. Out-of-range values are bound to the valid range. */
87template<typename T>
88[[nodiscard]] constexpr quint8 fromFloatingToEightBit(const T &original)
89{
90 static_assert( //
91 std::is_floating_point<T>::value, //
92 "Template fromFloatingToEightBit() only works with floating point types");
93 const int rounded = qRound(original * 255);
94 const auto bounded = qBound<int>(0, rounded, 255);
95 return static_cast<quint8>(bounded);
96}
97
98/** @internal
99 *
100 * @brief Like <tt>QColor::fromRgbF</tt> but for all floating point types.
101 *
102 * @param red Red component. Range: <tt>[0, 1]</tt>
103 * @param green See above.
104 * @param blue See above.
105 * @returns A corresponding <tt>QColor</tt> object. */
106template<typename T>
107[[nodiscard]] QColor qColorFromRgbDouble(T red, T green, T blue)
108{
109 static_assert( //
110 std::is_floating_point<T>::value, //
111 "Template fromFloatingToEightBit() only works with floating point types");
112 return QColor::fromRgbF(static_cast<QColorFloatType>(red), //
113 static_cast<QColorFloatType>(green), //
114 static_cast<QColorFloatType>(blue));
115}
116
117[[nodiscard]] cmsCIELab toCmsLab(const cmsCIELCh &value);
118
119[[nodiscard]] cmsCIELCh toCmsLch(const LchDouble &value);
120
121[[nodiscard]] LchDouble toLchDouble(const cmsCIELCh &value);
122
123[[nodiscard]] LchDouble toLchDouble(const cmsCIELab &value);
124
125/** @internal
126 *
127 * @brief White point D65 for 2°-observer.
128 *
129 * According to
130 * <a href="https://en.wikipedia.org/w/index.php?title=Illuminant_D65&oldid=1100467073#Definition">
131 * Wikipedia</a>:
132 *
133 * > “Using the standard 2° observer […] of D65 […] Normalizing for
134 * > relative luminance (i.e. set Y=100), the XYZ tristimulus
135 * > values are:<br/>
136 * > X = 95.047<br/>
137 * > Y = 100<br/>
138 * > Z = 108.883”
139 *
140 * Normalizing this to Y = 1 as expected by LittleCMS, gives this value. */
141// TODO xxx This seems to be not longer used!?
142constexpr cmsCIEXYZ whitePointD65TwoDegree{0.95047, 1.00000, 1.08883};
143
144} // namespace PerceptualColor
145
146#endif // HELPERCONVERSION_H
The namespace of this library.
ColorModel
Identifiers for color models.
@ OklabD65
Oklab color space, which by definition always and exclusively uses a D65 illuminant.
@ XyzD50
Xyz color space using a D50 illuminant.
@ CielabD50
Cielab color space using a D50 illuminant.
@ OklchD65
Oklch color space, which by definition always and exclusively uses a D65 illuminant.
@ Hsl360_1_1
A HSL color space.
@ Invalid
Represents invalid data.
@ XyzD65
Xzy color space using a D65 illuminant.
@ Rgb1
An Rgb color space.
@ CielchD50
Cielch color space using a D50 illuminant.
@ Hwb360_1_1
A HWB color space.
QColor fromRgbF(float r, float g, float b, float a)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 24 2024 11:48:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.