Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / include / opencv2 / gapi / own / saturate.hpp
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.
4 //
5 // Copyright (C) 2018-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_OWN_SATURATE_HPP
9 #define OPENCV_GAPI_OWN_SATURATE_HPP
10
11 #include <cmath>
12
13 #include <limits>
14 #include <type_traits>
15
16 #include <opencv2/gapi/own/assert.hpp>
17
18 namespace cv { namespace gapi { namespace own {
19 //-----------------------------
20 //
21 // Numeric cast with saturation
22 //
23 //-----------------------------
24
25 template<typename DST, typename SRC>
26 static inline DST saturate(SRC x)
27 {
28     // only integral types please!
29     GAPI_DbgAssert(std::is_integral<DST>::value &&
30                    std::is_integral<SRC>::value);
31
32     if (std::is_same<DST, SRC>::value)
33         return static_cast<DST>(x);
34
35     if (sizeof(DST) > sizeof(SRC))
36         return static_cast<DST>(x);
37
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():
45            static_cast<DST>(x);
46 }
47
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)
53 {
54     if (std::is_floating_point<DST>::value)
55     {
56         return static_cast<DST>(x);
57     }
58     else if (std::is_integral<SRC>::value)
59     {
60         GAPI_DbgAssert(std::is_integral<DST>::value &&
61                        std::is_integral<SRC>::value);
62         return saturate<DST>(x);
63     }
64     else
65     {
66         GAPI_DbgAssert(std::is_integral<DST>::value &&
67                  std::is_floating_point<SRC>::value);
68 #ifdef _WIN32
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)
72 #endif
73         int ix = static_cast<int>(round(x));
74 #ifdef _WIN32
75 #pragma warning(default: 4244)
76 #endif
77         return saturate<DST>(ix);
78     }
79 }
80
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); }
86
87 } //namespace own
88 } //namespace gapi
89 } //namespace cv
90 #endif /* OPENCV_GAPI_OWN_SATURATE_HPP */