libNeon
Loading...
Searching...
No Matches
color.hpp
Go to the documentation of this file.
1//
2// Created by spak on 6/4/21.
3//
4
5#ifndef NEO_COLOR_HPP
6#define NEO_COLOR_HPP
7
8#include <algorithm>
9#include <array>
10#include <cstdint>
11#include <mlab/bin_data.hpp>
12
13namespace neo {
14 struct rgb;
15 struct hsv;
16
17 namespace literals {
18 inline rgb operator ""_rgb(unsigned long long int);
19 }
20
21 struct keep_t {
22 };
23
24 static constexpr keep_t keep{};
25
26 template <class T>
27 struct maybe_update {
28 const bool update;
30
32
33 maybe_update(T value_);
34
35 void set(T &target) const;
36
37 template <class U>
38 void add(U &target) const;
39 };
40
41 [[nodiscard]] float srgb_to_linear(std::uint8_t v);
42 [[nodiscard]] std::uint8_t linear_to_srgb(float v);
43
47 struct rgb {
48 std::uint8_t r = 0;
49 std::uint8_t g = 0;
50 std::uint8_t b = 0;
51
52 rgb() = default;
53
54 explicit inline rgb(std::uint32_t rgb_);
55
56 inline rgb(std::uint8_t r_, std::uint8_t g_, std::uint8_t b_);
57
60
62 [[nodiscard]] inline rgb shift(maybe_update<signed> dr, maybe_update<signed> dg, maybe_update<signed> db) const;
63
64 inline rgb &shift(rgb delta, bool negate = false);
65 [[nodiscard]] inline rgb shift(rgb delta, bool negate = false) const;
66
67 rgb &blend(rgb target, float factor);
68 [[nodiscard]] inline rgb blend(rgb target, float factor) const;
69
70 [[nodiscard]] hsv to_hsv() const;
71
72 [[nodiscard]] std::array<float, 3> to_linear_rgb() const;
73 [[nodiscard]] static rgb from_linear_rgb(std::array<float, 3> const &linear_rgb);
74
75 [[nodiscard]] std::string to_string() const;
76 };
77
78 struct hsv {
79 float h = 0.f;
80 float s = 0.f;
81 float v = 0.f;
82
83 hsv() = default;
84
85 inline hsv(float h_, float s_, float v_);
86
87 hsv &clamp();
88
90 [[nodiscard]] inline hsv update(maybe_update<float> h_, maybe_update<float> s_, maybe_update<float> v_) const;
91
93 [[nodiscard]] inline hsv shift(maybe_update<float> dh, maybe_update<float> ds, maybe_update<float> dv) const;
94
95 inline hsv &shift(hsv delta, bool negate = false);
96 [[nodiscard]] inline hsv shift(hsv delta, bool negate = false) const;
97
98 [[nodiscard]] rgb to_rgb() const;
99 };
100
101}// namespace neo
102
103namespace neo {
104
105 rgb literals::operator ""_rgb(unsigned long long int c) {
106 return rgb{std::uint32_t(c)};
107 }
108
109 rgb::rgb(std::uint8_t r_, std::uint8_t g_, std::uint8_t b_) : r{r_}, g{g_}, b{b_} {}
110
111 rgb::rgb(std::uint32_t rgb_) : rgb{
112 std::uint8_t(0xff & (rgb_ >> 16)),
113 std::uint8_t(0xff & (rgb_ >> 8)),
114 std::uint8_t(0xff & rgb_)} {}
115
116
117 hsv::hsv(float h_, float s_, float v_) : h{h_}, s{s_}, v{v_} {}
118
119 template <class T>
120 maybe_update<T>::maybe_update(keep_t) : update{false}, value{} {}
121
122 template <class T>
123 maybe_update<T>::maybe_update(T value_) : update{true}, value{value_} {}
124
125 template <class T>
126 void maybe_update<T>::set(T &target) const {
127 if (update) {
128 target = value;
129 }
130 }
131
132 template <class T>
133 template <class U>
134 void maybe_update<T>::add(U &target) const {
135 if (update) {
136 if constexpr (not std::is_signed_v<U> and std::is_signed_v<T>) {
137 target = U(std::clamp(T(target + value),
138 T(std::numeric_limits<U>::lowest()),
139 T(std::numeric_limits<U>::max())));
140 } else {
141 target += value;
142 }
143 }
144 }
145
146 rgb &rgb::shift(rgb delta, bool negate) {
147 return negate ? shift(-delta.r, -delta.g, -delta.b) : shift(delta.r, delta.g, delta.b);
148 }
149
150 hsv &hsv::shift(hsv delta, bool negate) {
151 return negate ? shift(-delta.h, -delta.s, -delta.v) : shift(delta.h, delta.s, delta.v);
152 }
153
155 rgb retval = *this;
156 retval.update(r_, g_, b_);
157 return retval;
158 }
159
161 rgb retval = *this;
162 retval.shift(dr, dg, db);
163 return retval;
164 }
165
166 rgb rgb::shift(rgb delta, bool negate) const {
167 rgb retval = *this;
168 retval.shift(delta, negate);
169 return retval;
170 }
171
173 hsv retval = *this;
174 retval.update(h_, s_, v_);
175 return retval;
176 }
177
179 hsv retval = *this;
180 retval.shift(dh, ds, dv);
181 return retval;
182 }
183
184 hsv hsv::shift(hsv delta, bool negate) const {
185 hsv retval = *this;
186 retval.shift(delta, negate);
187 return retval;
188 }
189
190 rgb rgb::blend(rgb target, float factor) const {
191 rgb retval = *this;
192 retval.blend(target, factor);
193 return retval;
194 }
195
196}// namespace neo
197
198namespace mlab {
199 bin_data &operator<<(bin_data &o, neo::rgb c);
200 bin_stream &operator>>(bin_stream &i, neo::rgb &c);
201}// namespace mlab
202
203#endif//NEO_COLOR_HPP
Definition: any_fx.cpp:81
mlab::bin_stream & operator>>(mlab::bin_stream &s, neo::any_fx_config &fx_cfg)
Definition: any_fx.cpp:83
bin_data & operator<<(bin_data &o, neo::rgb c)
Definition: color.cpp:157
Definition: any_fx.cpp:7
std::uint8_t linear_to_srgb(float v)
Definition: color.cpp:22
float srgb_to_linear(std::uint8_t v)
Definition: color.cpp:17
static constexpr keep_t keep
Definition: color.hpp:24
Definition: color.hpp:78
float v
Definition: color.hpp:81
float s
Definition: color.hpp:80
hsv()=default
float h
Definition: color.hpp:79
rgb to_rgb() const
Definition: color.cpp:80
hsv & shift(maybe_update< float > dh, maybe_update< float > ds, maybe_update< float > dv)
Definition: color.cpp:137
hsv & clamp()
Definition: color.cpp:109
hsv & update(maybe_update< float > h_, maybe_update< float > s_, maybe_update< float > v_)
Definition: color.cpp:116
Definition: color.hpp:21
Definition: color.hpp:27
maybe_update(keep_t)
Definition: color.hpp:120
const bool update
Definition: color.hpp:28
T value
Definition: color.hpp:29
void set(T &target) const
Definition: color.hpp:126
void add(U &target) const
Definition: color.hpp:134
Definition: color.hpp:47
hsv to_hsv() const
Definition: color.cpp:53
rgb & blend(rgb target, float factor)
Definition: color.cpp:145
std::string to_string() const
Definition: color.cpp:28
std::array< float, 3 > to_linear_rgb() const
Definition: color.cpp:45
static rgb from_linear_rgb(std::array< float, 3 > const &linear_rgb)
Definition: color.cpp:49
rgb()=default
std::uint8_t r
Definition: color.hpp:48
std::uint8_t g
Definition: color.hpp:49
rgb & shift(maybe_update< signed > dr, maybe_update< signed > dg, maybe_update< signed > db)
Definition: color.cpp:130
rgb & update(maybe_update< std::uint8_t > r_, maybe_update< std::uint8_t > g_, maybe_update< std::uint8_t > b_)
Definition: color.cpp:123
std::uint8_t b
Definition: color.hpp:50