saturate.hpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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 Intel Corporation
  6. #ifndef OPENCV_GAPI_OWN_SATURATE_HPP
  7. #define OPENCV_GAPI_OWN_SATURATE_HPP
  8. #include <math.h>
  9. #include <limits>
  10. #include <opencv2/gapi/own/assert.hpp>
  11. #include <opencv2/gapi/util/type_traits.hpp>
  12. namespace cv { namespace gapi { namespace own {
  13. //-----------------------------
  14. //
  15. // Numeric cast with saturation
  16. //
  17. //-----------------------------
  18. template<typename DST, typename SRC,
  19. typename = cv::util::enable_if_t<!std::is_same<DST, SRC>::value &&
  20. std::is_integral<DST>::value &&
  21. std::is_integral<SRC>::value> >
  22. static CV_ALWAYS_INLINE DST saturate(SRC x)
  23. {
  24. if (sizeof(DST) > sizeof(SRC))
  25. return static_cast<DST>(x);
  26. // compiler must recognize this saturation,
  27. // so compile saturate<s16>(a + b) with adds
  28. // instruction (e.g.: _mm_adds_epi16 if x86)
  29. return x < std::numeric_limits<DST>::min()?
  30. std::numeric_limits<DST>::min():
  31. x > std::numeric_limits<DST>::max()?
  32. std::numeric_limits<DST>::max():
  33. static_cast<DST>(x);
  34. }
  35. template<typename T>
  36. static CV_ALWAYS_INLINE T saturate(T x)
  37. {
  38. return x;
  39. }
  40. template<typename DST, typename SRC, typename R,
  41. cv::util::enable_if_t<std::is_floating_point<DST>::value, bool> = true >
  42. static CV_ALWAYS_INLINE DST saturate(SRC x, R)
  43. {
  44. return static_cast<DST>(x);
  45. }
  46. template<typename DST, typename SRC, typename R,
  47. cv::util::enable_if_t<std::is_integral<DST>::value &&
  48. std::is_integral<SRC>::value , bool> = true >
  49. static CV_ALWAYS_INLINE DST saturate(SRC x, R)
  50. {
  51. return saturate<DST>(x);
  52. }
  53. // Note, that OpenCV rounds differently:
  54. // - like std::round() for add, subtract
  55. // - like std::rint() for multiply, divide
  56. template<typename DST, typename SRC, typename R,
  57. cv::util::enable_if_t<std::is_integral<DST>::value &&
  58. std::is_floating_point<SRC>::value, bool> = true >
  59. static CV_ALWAYS_INLINE DST saturate(SRC x, R round)
  60. {
  61. int ix = static_cast<int>(round(x));
  62. return saturate<DST>(ix);
  63. }
  64. // explicit suffix 'd' for double type
  65. inline double ceild(double x) { return ceil(x); }
  66. inline double floord(double x) { return floor(x); }
  67. inline double roundd(double x) { return round(x); }
  68. inline double rintd(double x) { return rint(x); }
  69. } //namespace own
  70. } //namespace gapi
  71. } //namespace cv
  72. #endif /* OPENCV_GAPI_OWN_SATURATE_HPP */