1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
5 // Copyright (C) 2018-2019 Intel Corporation
8 #ifndef OPENCV_GAPI_OWN_SATURATE_HPP
9 #define OPENCV_GAPI_OWN_SATURATE_HPP
14 #include <type_traits>
16 #include <opencv2/gapi/own/assert.hpp>
18 namespace cv { namespace gapi { namespace own {
19 //-----------------------------
21 // Numeric cast with saturation
23 //-----------------------------
25 template<typename DST, typename SRC>
26 static inline DST saturate(SRC x)
28 // only integral types please!
29 GAPI_DbgAssert(std::is_integral<DST>::value &&
30 std::is_integral<SRC>::value);
32 if (std::is_same<DST, SRC>::value)
33 return static_cast<DST>(x);
35 if (sizeof(DST) > sizeof(SRC))
36 return static_cast<DST>(x);
38 // compiler must recognize this saturation,
39 // so compile saturate<s16>(a + b) with adds
40 // instruction (e.g.: _mm_adds_epi16 if x86)
41 return x < std::numeric_limits<DST>::min()?
42 std::numeric_limits<DST>::min():
43 x > std::numeric_limits<DST>::max()?
44 std::numeric_limits<DST>::max():
48 // Note, that OpenCV rounds differently:
49 // - like std::round() for add, subtract
50 // - like std::rint() for multiply, divide
51 template<typename DST, typename SRC, typename R>
52 static inline DST saturate(SRC x, R round)
54 if (std::is_floating_point<DST>::value)
56 return static_cast<DST>(x);
58 else if (std::is_integral<SRC>::value)
60 GAPI_DbgAssert(std::is_integral<DST>::value &&
61 std::is_integral<SRC>::value);
62 return saturate<DST>(x);
66 GAPI_DbgAssert(std::is_integral<DST>::value &&
67 std::is_floating_point<SRC>::value);
69 // Suppress warning about convering x to floating-point
70 // Note that x is already floating-point at this point
71 #pragma warning(disable: 4244)
73 int ix = static_cast<int>(round(x));
75 #pragma warning(default: 4244)
77 return saturate<DST>(ix);
81 // explicit suffix 'd' for double type
82 inline double ceild(double x) { return std::ceil(x); }
83 inline double floord(double x) { return std::floor(x); }
84 inline double roundd(double x) { return std::round(x); }
85 inline double rintd(double x) { return std::rint(x); }
90 #endif /* OPENCV_GAPI_OWN_SATURATE_HPP */