1 #pragma once
2
3 #include <algorithm>
4 #include <limits>
5 #include <cmath>
6 #include <cstdint>
7 #include <array>
8
9 namespace rtengine
10 {
11
12 constexpr int MAXVAL = 0xffff;
13 constexpr float MAXVALF = static_cast<float>(MAXVAL); // float version of MAXVAL
14 constexpr double MAXVALD = static_cast<double>(MAXVAL); // double version of MAXVAL
15
16 constexpr double RT_PI = 3.14159265358979323846; // pi
17 constexpr double RT_PI_2 = 1.57079632679489661923; // pi/2
18 constexpr double RT_PI_180 = 0.017453292519943295769; // pi/180
19 constexpr double RT_1_PI = 0.31830988618379067154; // 1/pi
20 constexpr double RT_2_PI = 0.63661977236758134308; // 2/pi
21 constexpr double RT_SQRT1_2 = 0.70710678118654752440; // 1/sqrt(2)
22
23 constexpr double RT_INFINITY = std::numeric_limits<double>::infinity();
24 constexpr double RT_NAN = std::numeric_limits<double>::quiet_NaN();
25
26 constexpr float RT_PI_F = RT_PI;
27 constexpr float RT_PI_F_2 = RT_PI_2;
28 constexpr float RT_PI_F_180 = RT_PI_180;
29 constexpr float RT_1_PI_F = RT_1_PI;
30 constexpr float RT_2_PI_F = RT_2_PI;
31
32 constexpr float RT_INFINITY_F = std::numeric_limits<float>::infinity();
33 constexpr float RT_NAN_F = std::numeric_limits<float>::quiet_NaN();
34
35 template<typename T>
SQR(T x)36 constexpr T SQR(T x)
37 {
38 return x * x;
39 }
40
41 template<typename T>
pow4(T x)42 constexpr T pow4(T x)
43 {
44 return SQR(SQR(x));
45 }
46
47 template<typename T>
min(const T & a)48 constexpr const T& min(const T& a)
49 {
50 return a;
51 }
52
53 template<typename T>
min(const T & a,const T & b)54 constexpr const T& min(const T& a, const T& b)
55 {
56 return b < a ? b : a;
57 }
58
59 template<typename T, typename... ARGS>
min(const T & a,const T & b,const ARGS &...args)60 constexpr const T& min(const T& a, const T& b, const ARGS&... args)
61 {
62 return min(min(a, b), min(args...));
63 }
64
65 template<typename T>
max(const T & a)66 constexpr const T& max(const T& a)
67 {
68 return a;
69 }
70
71 template<typename T>
max(const T & a,const T & b)72 constexpr const T& max(const T& a, const T& b)
73 {
74 return a < b ? b : a;
75 }
76
77 template<typename T, typename... ARGS>
max(const T & a,const T & b,const ARGS &...args)78 constexpr const T& max(const T& a, const T& b, const ARGS&... args)
79 {
80 return max(max(a, b), max(args...));
81 }
82
83 template<typename T>
LIM(const T & val,const T & low,const T & high)84 constexpr const T& LIM(const T& val, const T& low, const T& high)
85 {
86 return max(low, min(val, high));
87 }
88
89 template<typename T>
LIM01(const T & a)90 constexpr T LIM01(const T& a)
91 {
92 return max(T(0), min(a, T(1)));
93 }
94
95 template<typename T>
CLIP(const T & a)96 constexpr T CLIP(const T& a)
97 {
98 return LIM(a, static_cast<T>(0), static_cast<T>(MAXVAL));
99 }
100
101 template <typename T>
SGN(const T & a)102 constexpr T SGN(const T& a)
103 {
104 // returns -1 for a < 0, 0 for a = 0 and +1 for a > 0
105 return (T(0) < a) - (a < T(0));
106 }
107
108 template<typename T>
intp(T a,T b,T c)109 constexpr T intp(T a, T b, T c)
110 {
111 // calculate a * b + (1 - a) * c
112 // following is valid:
113 // intp(a, b+x, c+x) = intp(a, b, c) + x
114 // intp(a, b*x, c*x) = intp(a, b, c) * x
115 return a * (b - c) + c;
116 }
117
118 template<typename T>
norm1(const T & x,const T & y)119 inline T norm1(const T& x, const T& y)
120 {
121 return std::abs(x) + std::abs(y);
122 }
123
124 template<typename T>
norm2(const T & x,const T & y)125 inline T norm2(const T& x, const T& y)
126 {
127 return std::sqrt(x * x + y * y);
128 }
129
130 template< typename T >
norminf(const T & x,const T & y)131 inline T norminf(const T& x, const T& y)
132 {
133 return max(std::abs(x), std::abs(y));
134 }
135
float2uint16range(float d)136 constexpr int float2uint16range(float d)
137 {
138 // clips input to [0;65535] and rounds
139 return CLIP(d) + 0.5f;
140 }
141
uint16ToUint8Rounded(std::uint16_t i)142 constexpr std::uint8_t uint16ToUint8Rounded(std::uint16_t i)
143 {
144 return ((i + 128) - ((i + 128) >> 8)) >> 8;
145 }
146
147 template <typename T>
148 constexpr bool OOG(const T &val, const T &high=T(MAXVAL))
149 {
150 return (val < T(0)) || (val > high);
151 }
152
153 template <typename T>
setUnlessOOG(T & out,const T & val)154 void setUnlessOOG(T &out, const T &val)
155 {
156 if (!OOG(out)) {
157 out = val;
158 }
159 }
160
161
162 template <typename T>
invertMatrix(const std::array<std::array<T,3>,3> & in,std::array<std::array<T,3>,3> & out)163 bool invertMatrix(const std::array<std::array<T, 3>, 3> &in, std::array<std::array<T, 3>, 3> &out)
164 {
165 const T res00 = in[1][1] * in[2][2] - in[2][1] * in[1][2];
166 const T res10 = in[2][0] * in[1][2] - in[1][0] * in[2][2];
167 const T res20 = in[1][0] * in[2][1] - in[2][0] * in[1][1];
168
169 const T det = in[0][0] * res00 + in[0][1] * res10 + in[0][2] * res20;
170
171 if (std::abs(det) < 1.0e-10) {
172 return false;
173 }
174
175 out[0][0] = res00 / det;
176 out[0][1] = (in[2][1] * in[0][2] - in[0][1] * in[2][2]) / det;
177 out[0][2] = (in[0][1] * in[1][2] - in[1][1] * in[0][2]) / det;
178 out[1][0] = res10 / det;
179 out[1][1] = (in[0][0] * in[2][2] - in[2][0] * in[0][2]) / det;
180 out[1][2] = (in[1][0] * in[0][2] - in[0][0] * in[1][2]) / det;
181 out[2][0] = res20 / det;
182 out[2][1] = (in[2][0] * in[0][1] - in[0][0] * in[2][1]) / det;
183 out[2][2] = (in[0][0] * in[1][1] - in[1][0] * in[0][1]) / det;
184
185 return true;
186 }
187
188
189 template <typename T>
dotProduct(const std::array<std::array<T,3>,3> & a,const std::array<std::array<T,3>,3> & b)190 std::array<std::array<T, 3>, 3> dotProduct(const std::array<std::array<T, 3>, 3> &a, const std::array<std::array<T, 3>, 3> &b)
191 {
192 std::array<std::array<T, 3>, 3> res;
193
194 for (int i = 0; i < 3; ++i) {
195 for (int j = 0; j < 3; ++j) {
196 res[i][j] = 0;
197
198 for (int k = 0; k < 3; ++k) {
199 res[i][j] += a[i][k] * b[k][j];
200 }
201 }
202 }
203
204 return res;
205 }
206
207
208 template <typename T>
dotProduct(const std::array<std::array<T,3>,3> & a,const std::array<T,3> & b)209 std::array<T, 3> dotProduct(const std::array<std::array<T, 3>, 3> &a, const std::array<T, 3> &b)
210 {
211 std::array<T, 3> res;
212
213 for (int i = 0; i < 3; ++i) {
214 res[i] = 0;
215 for (int k = 0; k < 3; ++k) {
216 res[i] += a[i][k] * b[k];
217 }
218 }
219
220 return res;
221 }
222
223
224 template <typename T>
lin2log(T x,T base)225 T lin2log(T x, T base)
226 {
227 constexpr T one(1);
228 return std::log(x * (base - one) + one) / std::log(base);
229 }
230
231
232 template <typename T>
log2lin(T x,T base)233 T log2lin(T x, T base)
234 {
235 constexpr T one(1);
236 return (std::pow(base, x) - one) / (base - one);
237 }
238
239 }
240
241