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