// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // // Copyright (C) 2018 Intel Corporation #ifndef OPENCV_GAPI_OWN_SATURATE_HPP #define OPENCV_GAPI_OWN_SATURATE_HPP #include #include #include #include namespace cv { namespace gapi { namespace own { //----------------------------- // // Numeric cast with saturation // //----------------------------- template::value && std::is_integral::value && std::is_integral::value> > static CV_ALWAYS_INLINE DST saturate(SRC x) { if (sizeof(DST) > sizeof(SRC)) return static_cast(x); // compiler must recognize this saturation, // so compile saturate(a + b) with adds // instruction (e.g.: _mm_adds_epi16 if x86) return x < std::numeric_limits::min()? std::numeric_limits::min(): x > std::numeric_limits::max()? std::numeric_limits::max(): static_cast(x); } template static CV_ALWAYS_INLINE T saturate(T x) { return x; } template::value, bool> = true > static CV_ALWAYS_INLINE DST saturate(SRC x, R) { return static_cast(x); } template::value && std::is_integral::value , bool> = true > static CV_ALWAYS_INLINE DST saturate(SRC x, R) { return saturate(x); } // Note, that OpenCV rounds differently: // - like std::round() for add, subtract // - like std::rint() for multiply, divide template::value && std::is_floating_point::value, bool> = true > static CV_ALWAYS_INLINE DST saturate(SRC x, R round) { int ix = static_cast(round(x)); return saturate(ix); } // explicit suffix 'd' for double type inline double ceild(double x) { return ceil(x); } inline double floord(double x) { return floor(x); } inline double roundd(double x) { return round(x); } inline double rintd(double x) { return rint(x); } } //namespace own } //namespace gapi } //namespace cv #endif /* OPENCV_GAPI_OWN_SATURATE_HPP */