HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
sRGB.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2020-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
9#pragma once
10
11#include "../utility/module.hpp"
12#include "../geometry/module.hpp"
13#include "color.hpp"
14#include <cmath>
15#include <array>
16
17hi_warning_push();
18// C26426: Global initializer calls a non-constexpr function '...' (i.22).
19// std::pow() is not constexpr and needed to fill in the gamma conversion tables.
20hi_warning_ignore_msvc(26426);
21
22namespace hi { inline namespace v1 {
23
28 matrix3{0.41239080f, 0.35758434f, 0.18048079f, 0.21263901f, 0.71516868f, 0.07219232f, 0.01933082f, 0.11919478f, 0.95053215f};
29
34 3.24096994f,
35 -1.53738318f,
36 -0.49861076f,
37 -0.96924364f,
38 1.87596750f,
39 0.04155506f,
40 0.05563008f,
41 -0.20397696f,
42 1.05697151f};
43
50[[nodiscard]] inline float sRGB_linear_to_gamma(float u) noexcept
51{
52 if (u <= 0.0031308) {
53 return 12.92f * u;
54 } else {
55 return 1.055f * std::pow(u, 0.416f) - 0.055f;
56 }
57}
58
65[[nodiscard]] inline float sRGB_gamma_to_linear(float u) noexcept
66{
67 if (u <= 0.04045) {
68 return u / 12.92f;
69 } else {
70 return std::pow((u + 0.055f) / 1.055f, 2.4f);
71 }
72}
73
74namespace detail {
75
76[[nodiscard]] inline auto sRGB_linear16_to_gamma8_table_generator() noexcept
77{
79
80 for (int i = 0; i != 65536; ++i) {
81 r[i] = floor_cast<uint8_t>(
82 std::clamp(sRGB_linear_to_gamma(float16::from_uint16_t(narrow_cast<uint16_t>(i))), 0.0f, 1.0f) * 255.0f);
83 }
84
85 return r;
86}
87
88[[nodiscard]] inline auto sRGB_gamma8_to_linear16_table_generator() noexcept
89{
91
92 for (int i = 0; i != 256; ++i) {
93 r[i] = static_cast<float16>(sRGB_gamma_to_linear(i / 255.0f));
94 }
95
96 return r;
97}
98
99inline auto sRGB_linear16_to_gamma8_table = sRGB_linear16_to_gamma8_table_generator();
100inline auto sRGB_gamma8_to_linear16_table = sRGB_gamma8_to_linear16_table_generator();
101
102} // namespace detail
103
112[[nodiscard]] inline uint8_t sRGB_linear16_to_gamma8(float16 u) noexcept
113{
114 return detail::sRGB_linear16_to_gamma8_table[u.get()];
115}
116
125[[nodiscard]] inline float16 sRGB_gamma8_to_linear16(uint8_t u) noexcept
126{
127 return detail::sRGB_gamma8_to_linear16_table[u];
128}
129
139[[nodiscard]] inline color color_from_sRGB(
140 std::floating_point auto r,
141 std::floating_point auto g,
142 std::floating_point auto b,
143 std::floating_point auto a) noexcept
144{
145 return color{sRGB_gamma_to_linear(r), sRGB_gamma_to_linear(g), sRGB_gamma_to_linear(b), narrow_cast<float>(a)};
146}
147
157[[nodiscard]] inline color
158color_from_sRGB(std::integral auto r, std::integral auto g, std::integral auto b, std::integral auto a) noexcept
159{
160 hi_axiom_bounds(r, 0, 256);
161 hi_axiom_bounds(g, 0, 256);
162 hi_axiom_bounds(b, 0, 256);
163 hi_axiom_bounds(a, 0, 256);
164 return color_from_sRGB(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
165}
166
167[[nodiscard]] inline color color_from_sRGB(std::string_view str)
168{
169 auto tmp = std::string{str};
170
171 if (tmp.starts_with("#")) {
172 tmp = tmp.substr(1);
173 }
174 if (tmp.size() != 6 && tmp.size() != 8) {
175 throw parse_error(std::format("Expecting 6 or 8 hex-digit sRGB color string, got {}.", str));
176 }
177 if (tmp.size() == 6) {
178 tmp += "ff";
179 }
180
181 hilet packed = from_string<uint32_t>(tmp, 16);
182
183 hilet r = truncate<uint8_t>(packed >> 24);
184 hilet g = truncate<uint8_t>(packed >> 16);
185 hilet b = truncate<uint8_t>(packed >> 8);
186 hilet a = truncate<uint8_t>(packed);
187 return color_from_sRGB(r, g, b, a);
188}
189
190}} // namespace hi::v1
191
192hi_warning_pop();
Defined the color type.
#define hi_axiom_bounds(x,...)
Specify an axiom that the value is within bounds.
Definition assert.hpp:264
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
constexpr matrix3 XYZ_to_sRGB
Matrix to convert XYZ to sRGB.
Definition sRGB.hpp:33
float16 sRGB_gamma8_to_linear16(uint8_t u) noexcept
sRGB gamma to linear float-16 transfer function.
Definition sRGB.hpp:125
uint8_t sRGB_linear16_to_gamma8(float16 u) noexcept
sRGB linear float-16 to gamma transfer function.
Definition sRGB.hpp:112
color color_from_sRGB(std::floating_point auto r, std::floating_point auto g, std::floating_point auto b, std::floating_point auto a) noexcept
Convert gama corrected sRGB color to the linear color.
Definition sRGB.hpp:139
float sRGB_linear_to_gamma(float u) noexcept
sRGB linear to gamma transfer function.
Definition sRGB.hpp:50
constexpr matrix3 sRGB_to_XYZ
Matrix to convert sRGB to XYZ.
Definition sRGB.hpp:27
float sRGB_gamma_to_linear(float u) noexcept
sRGB gamma to linear transfer function.
Definition sRGB.hpp:65
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
This is a RGBA floating point color.
Definition color.hpp:44
A 2D or 3D homogenius matrix for transforming homogenious vectors and points.
Definition matrix.hpp:33
T pow(T... args)