#ifndef _MYMATH_ #define _MYMATH_ #include #include namespace rtengine { static const int MAXVAL = 0xffff; static const float MAXVALF = float(MAXVAL); // float version of MAXVAL static const double MAXVALD = double(MAXVAL); // double version of MAXVAL template inline _Tp SQR (_Tp x) { // return std::pow(x,2); Slower than: return x * x; } template inline const _Tp& min(const _Tp& a, const _Tp& b) { return std::min(a, b); } template inline const _Tp& max(const _Tp& a, const _Tp& b) { return std::max(a, b); } template inline const _Tp& LIM(const _Tp& a, const _Tp& b, const _Tp& c) { return std::max(b, std::min(a, c)); } template inline _Tp LIM01(const _Tp& a) { return std::max(_Tp(0), std::min(a, _Tp(1))); } template inline _Tp CLIP(const _Tp& a) { return LIM(a, static_cast<_Tp>(0), static_cast<_Tp>(MAXVAL)); } template inline const _Tp& min(const _Tp& a, const _Tp& b, const _Tp& c) { return std::min(c, std::min(a, b)); } template inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c) { return std::max(c, std::max(a, b)); } template inline const _Tp& min(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) { return std::min(d, std::min(c, std::min(a, b))); } template inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) { return std::max(d, std::max(c, std::max(a, b))); } template inline _Tp intp(_Tp a, _Tp b, _Tp c) { // calculate a * b + (1 - a) * c // following is valid: // intp(a, b+x, c+x) = intp(a, b, c) + x // intp(a, b*x, c*x) = intp(a, b, c) * x return a * (b - c) + c; } template inline T norm1(const T& x, const T& y) { return std::abs(x) + std::abs(y); } template inline T norm2(const T& x, const T& y) { return std::sqrt(x * x + y * y); } template< typename T > inline T norminf(const T& x, const T& y) { return std::max(std::abs(x), std::abs(y)); } inline int float2uint16range(float d) // clips input to [0;65535] and rounds { d = CLIP(d); // clip to [0;65535] #ifdef __SSE2__ // this only works in IEEE 754 maths. For simplicity I restricted it to SSE2. We can enhance it later, but we have to take care of endianness then. d += 12582912.f; return reinterpret_cast(d); #else // fall back to slow std::round() return std::round(d); #endif } } #endif