Home | History | Annotate | Download | only in hal
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                          License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
     15 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
     16 // Copyright (C) 2015, Itseez Inc., all rights reserved.
     17 // Third party copyrights are property of their respective owners.
     18 //
     19 // Redistribution and use in source and binary forms, with or without modification,
     20 // are permitted provided that the following conditions are met:
     21 //
     22 //   * Redistribution's of source code must retain the above copyright notice,
     23 //     this list of conditions and the following disclaimer.
     24 //
     25 //   * Redistribution's in binary form must reproduce the above copyright notice,
     26 //     this list of conditions and the following disclaimer in the documentation
     27 //     and/or other materials provided with the distribution.
     28 //
     29 //   * The name of the copyright holders may not be used to endorse or promote products
     30 //     derived from this software without specific prior written permission.
     31 //
     32 // This software is provided by the copyright holders and contributors "as is" and
     33 // any express or implied warranties, including, but not limited to, the implied
     34 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     35 // In no event shall the Intel Corporation or contributors be liable for any direct,
     36 // indirect, incidental, special, exemplary, or consequential damages
     37 // (including, but not limited to, procurement of substitute goods or services;
     38 // loss of use, data, or profits; or business interruption) however caused
     39 // and on any theory of liability, whether in contract, strict liability,
     40 // or tort (including negligence or otherwise) arising in any way out of
     41 // the use of this software, even if advised of the possibility of such damage.
     42 //
     43 //M*/
     44 
     45 #ifndef __OPENCV_DEF_H__
     46 #define __OPENCV_DEF_H__
     47 
     48 #if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER && _MSC_VER > 1300
     49 #  define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */
     50 #endif
     51 
     52 #include <limits.h>
     53 
     54 #if defined __ICL
     55 #  define CV_ICC   __ICL
     56 #elif defined __ICC
     57 #  define CV_ICC   __ICC
     58 #elif defined __ECL
     59 #  define CV_ICC   __ECL
     60 #elif defined __ECC
     61 #  define CV_ICC   __ECC
     62 #elif defined __INTEL_COMPILER
     63 #  define CV_ICC   __INTEL_COMPILER
     64 #endif
     65 
     66 #ifndef CV_INLINE
     67 #  if defined __cplusplus
     68 #    define CV_INLINE static inline
     69 #  elif defined _MSC_VER
     70 #    define CV_INLINE __inline
     71 #  else
     72 #    define CV_INLINE static
     73 #  endif
     74 #endif
     75 
     76 #if defined CV_ICC && !defined CV_ENABLE_UNROLLED
     77 #  define CV_ENABLE_UNROLLED 0
     78 #else
     79 #  define CV_ENABLE_UNROLLED 1
     80 #endif
     81 
     82 #ifdef __GNUC__
     83 #  define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
     84 #elif defined _MSC_VER
     85 #  define CV_DECL_ALIGNED(x) __declspec(align(x))
     86 #else
     87 #  define CV_DECL_ALIGNED(x)
     88 #endif
     89 
     90 /* CPU features and intrinsics support */
     91 #define CV_CPU_NONE             0
     92 #define CV_CPU_MMX              1
     93 #define CV_CPU_SSE              2
     94 #define CV_CPU_SSE2             3
     95 #define CV_CPU_SSE3             4
     96 #define CV_CPU_SSSE3            5
     97 #define CV_CPU_SSE4_1           6
     98 #define CV_CPU_SSE4_2           7
     99 #define CV_CPU_POPCNT           8
    100 
    101 #define CV_CPU_AVX              10
    102 #define CV_CPU_AVX2             11
    103 #define CV_CPU_FMA3             12
    104 
    105 #define CV_CPU_AVX_512F         13
    106 #define CV_CPU_AVX_512BW        14
    107 #define CV_CPU_AVX_512CD        15
    108 #define CV_CPU_AVX_512DQ        16
    109 #define CV_CPU_AVX_512ER        17
    110 #define CV_CPU_AVX_512IFMA512   18
    111 #define CV_CPU_AVX_512PF        19
    112 #define CV_CPU_AVX_512VBMI      20
    113 #define CV_CPU_AVX_512VL        21
    114 
    115 #define CV_CPU_NEON   100
    116 
    117 // when adding to this list remember to update the enum in core/utility.cpp
    118 #define CV_HARDWARE_MAX_FEATURE 255
    119 
    120 // do not include SSE/AVX/NEON headers for NVCC compiler
    121 #ifndef __CUDACC__
    122 
    123 #if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
    124 #  include <emmintrin.h>
    125 #  define CV_MMX 1
    126 #  define CV_SSE 1
    127 #  define CV_SSE2 1
    128 #  if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
    129 #    include <pmmintrin.h>
    130 #    define CV_SSE3 1
    131 #  endif
    132 #  if defined __SSSE3__  || (defined _MSC_VER && _MSC_VER >= 1500)
    133 #    include <tmmintrin.h>
    134 #    define CV_SSSE3 1
    135 #  endif
    136 #  if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500)
    137 #    include <smmintrin.h>
    138 #    define CV_SSE4_1 1
    139 #  endif
    140 #  if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500)
    141 #    include <nmmintrin.h>
    142 #    define CV_SSE4_2 1
    143 #  endif
    144 #  if defined __POPCNT__ || (defined _MSC_VER && _MSC_VER >= 1500)
    145 #    ifdef _MSC_VER
    146 #      include <nmmintrin.h>
    147 #    else
    148 #      include <popcntintrin.h>
    149 #    endif
    150 #    define CV_POPCNT 1
    151 #  endif
    152 #  if defined __AVX__ || (defined _MSC_VER && _MSC_VER >= 1600 && 0)
    153 // MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX
    154 // See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32
    155 #    include <immintrin.h>
    156 #    define CV_AVX 1
    157 #    if defined(_XCR_XFEATURE_ENABLED_MASK)
    158 #      define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
    159 #    else
    160 #      define __xgetbv() 0
    161 #    endif
    162 #  endif
    163 #  if defined __AVX2__ || (defined _MSC_VER && _MSC_VER >= 1800 && 0)
    164 #    include <immintrin.h>
    165 #    define CV_AVX2 1
    166 #    if defined __FMA__
    167 #      define CV_FMA3 1
    168 #    endif
    169 #  endif
    170 #endif
    171 
    172 #if (defined WIN32 || defined _WIN32) && defined(_M_ARM)
    173 # include <Intrin.h>
    174 # include "arm_neon.h"
    175 # define CV_NEON 1
    176 # define CPU_HAS_NEON_FEATURE (true)
    177 #elif defined(__ARM_NEON__) || (defined (__ARM_NEON) && defined(__aarch64__))
    178 #  include <arm_neon.h>
    179 #  define CV_NEON 1
    180 #endif
    181 
    182 #if defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__)
    183 #  define CV_VFP 1
    184 #endif
    185 
    186 #endif // __CUDACC__
    187 
    188 #ifndef CV_POPCNT
    189 #define CV_POPCNT 0
    190 #endif
    191 #ifndef CV_MMX
    192 #  define CV_MMX 0
    193 #endif
    194 #ifndef CV_SSE
    195 #  define CV_SSE 0
    196 #endif
    197 #ifndef CV_SSE2
    198 #  define CV_SSE2 0
    199 #endif
    200 #ifndef CV_SSE3
    201 #  define CV_SSE3 0
    202 #endif
    203 #ifndef CV_SSSE3
    204 #  define CV_SSSE3 0
    205 #endif
    206 #ifndef CV_SSE4_1
    207 #  define CV_SSE4_1 0
    208 #endif
    209 #ifndef CV_SSE4_2
    210 #  define CV_SSE4_2 0
    211 #endif
    212 #ifndef CV_AVX
    213 #  define CV_AVX 0
    214 #endif
    215 #ifndef CV_AVX2
    216 #  define CV_AVX2 0
    217 #endif
    218 #ifndef CV_FMA3
    219 #  define CV_FMA3 0
    220 #endif
    221 #ifndef CV_AVX_512F
    222 #  define CV_AVX_512F 0
    223 #endif
    224 #ifndef CV_AVX_512BW
    225 #  define CV_AVX_512BW 0
    226 #endif
    227 #ifndef CV_AVX_512CD
    228 #  define CV_AVX_512CD 0
    229 #endif
    230 #ifndef CV_AVX_512DQ
    231 #  define CV_AVX_512DQ 0
    232 #endif
    233 #ifndef CV_AVX_512ER
    234 #  define CV_AVX_512ER 0
    235 #endif
    236 #ifndef CV_AVX_512IFMA512
    237 #  define CV_AVX_512IFMA512 0
    238 #endif
    239 #ifndef CV_AVX_512PF
    240 #  define CV_AVX_512PF 0
    241 #endif
    242 #ifndef CV_AVX_512VBMI
    243 #  define CV_AVX_512VBMI 0
    244 #endif
    245 #ifndef CV_AVX_512VL
    246 #  define CV_AVX_512VL 0
    247 #endif
    248 
    249 #ifndef CV_NEON
    250 #  define CV_NEON 0
    251 #endif
    252 
    253 #ifndef CV_VFP
    254 #  define CV_VFP 0
    255 #endif
    256 
    257 /* primitive types */
    258 /*
    259   schar  - signed 1 byte integer
    260   uchar  - unsigned 1 byte integer
    261   short  - signed 2 byte integer
    262   ushort - unsigned 2 byte integer
    263   int    - signed 4 byte integer
    264   uint   - unsigned 4 byte integer
    265   int64  - signed 8 byte integer
    266   uint64 - unsigned 8 byte integer
    267 */
    268 
    269 #if !defined _MSC_VER && !defined __BORLANDC__
    270 #  if defined __cplusplus && __cplusplus >= 201103L
    271 #    include <cstdint>
    272      typedef std::uint32_t uint;
    273 #  else
    274 #    include <stdint.h>
    275      typedef uint32_t uint;
    276 #  endif
    277 #else
    278    typedef unsigned uint;
    279 #endif
    280 
    281 typedef signed char schar;
    282 
    283 #ifndef __IPL_H__
    284    typedef unsigned char uchar;
    285    typedef unsigned short ushort;
    286 #endif
    287 
    288 #if defined _MSC_VER || defined __BORLANDC__
    289    typedef __int64 int64;
    290    typedef unsigned __int64 uint64;
    291 #  define CV_BIG_INT(n)   n##I64
    292 #  define CV_BIG_UINT(n)  n##UI64
    293 #else
    294    typedef int64_t int64;
    295    typedef uint64_t uint64;
    296 #  define CV_BIG_INT(n)   n##LL
    297 #  define CV_BIG_UINT(n)  n##ULL
    298 #endif
    299 
    300 /* fundamental constants */
    301 #define CV_PI   3.1415926535897932384626433832795
    302 #define CV_2PI 6.283185307179586476925286766559
    303 #define CV_LOG2 0.69314718055994530941723212145818
    304 
    305 typedef union Cv32suf
    306 {
    307     int i;
    308     unsigned u;
    309     float f;
    310 }
    311 Cv32suf;
    312 
    313 typedef union Cv64suf
    314 {
    315     int64 i;
    316     uint64 u;
    317     double f;
    318 }
    319 Cv64suf;
    320 
    321 
    322 /****************************************************************************************\
    323 *                                      fast math                                         *
    324 \****************************************************************************************/
    325 
    326 #if defined __BORLANDC__
    327 #  include <fastmath.h>
    328 #elif defined __cplusplus
    329 #  include <cmath>
    330 #else
    331 #  include <math.h>
    332 #endif
    333 
    334 #ifdef HAVE_TEGRA_OPTIMIZATION
    335 #  include "tegra_round.hpp"
    336 #endif
    337 
    338 //! @addtogroup core_utils
    339 //! @{
    340 
    341 #if CV_VFP
    342     // 1. general scheme
    343     #define ARM_ROUND(_value, _asm_string) \
    344         int res; \
    345         float temp; \
    346         asm(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \
    347         return res
    348     // 2. version for double
    349     #ifdef __clang__
    350         #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]")
    351     #else
    352         #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]")
    353     #endif
    354     // 3. version for float
    355     #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]")
    356 #endif // CV_VFP
    357 
    358 /** @brief Rounds floating-point number to the nearest integer
    359 
    360  @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
    361  result is not defined.
    362  */
    363 CV_INLINE int
    364 cvRound( double value )
    365 {
    366 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \
    367     && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
    368     __m128d t = _mm_set_sd( value );
    369     return _mm_cvtsd_si32(t);
    370 #elif defined _MSC_VER && defined _M_IX86
    371     int t;
    372     __asm
    373     {
    374         fld value;
    375         fistp t;
    376     }
    377     return t;
    378 #elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \
    379         defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION
    380     TEGRA_ROUND_DBL(value);
    381 #elif defined CV_ICC || defined __GNUC__
    382 # if CV_VFP
    383     ARM_ROUND_DBL(value);
    384 # else
    385     return (int)lrint(value);
    386 # endif
    387 #else
    388     /* it's ok if round does not comply with IEEE754 standard;
    389        the tests should allow +/-1 difference when the tested functions use round */
    390     return (int)(value + (value >= 0 ? 0.5 : -0.5));
    391 #endif
    392 }
    393 
    394 
    395 /** @brief Rounds floating-point number to the nearest integer not larger than the original.
    396 
    397  The function computes an integer i such that:
    398  \f[i \le \texttt{value} < i+1\f]
    399  @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
    400  result is not defined.
    401  */
    402 CV_INLINE int cvFloor( double value )
    403 {
    404 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
    405     __m128d t = _mm_set_sd( value );
    406     int i = _mm_cvtsd_si32(t);
    407     return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i)));
    408 #elif defined __GNUC__
    409     int i = (int)value;
    410     return i - (i > value);
    411 #else
    412     int i = cvRound(value);
    413     float diff = (float)(value - i);
    414     return i - (diff < 0);
    415 #endif
    416 }
    417 
    418 /** @brief Rounds floating-point number to the nearest integer not larger than the original.
    419 
    420  The function computes an integer i such that:
    421  \f[i \le \texttt{value} < i+1\f]
    422  @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
    423  result is not defined.
    424  */
    425 CV_INLINE int cvCeil( double value )
    426 {
    427 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
    428     __m128d t = _mm_set_sd( value );
    429     int i = _mm_cvtsd_si32(t);
    430     return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t));
    431 #elif defined __GNUC__
    432     int i = (int)value;
    433     return i + (i < value);
    434 #else
    435     int i = cvRound(value);
    436     float diff = (float)(i - value);
    437     return i + (diff < 0);
    438 #endif
    439 }
    440 
    441 /** @brief Determines if the argument is Not A Number.
    442 
    443  @param value The input floating-point value
    444 
    445  The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0
    446  otherwise. */
    447 CV_INLINE int cvIsNaN( double value )
    448 {
    449     Cv64suf ieee754;
    450     ieee754.f = value;
    451     return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
    452            ((unsigned)ieee754.u != 0) > 0x7ff00000;
    453 }
    454 
    455 /** @brief Determines if the argument is Infinity.
    456 
    457  @param value The input floating-point value
    458 
    459  The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard)
    460  and 0 otherwise. */
    461 CV_INLINE int cvIsInf( double value )
    462 {
    463     Cv64suf ieee754;
    464     ieee754.f = value;
    465     return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
    466             (unsigned)ieee754.u == 0;
    467 }
    468 
    469 #ifdef __cplusplus
    470 
    471 /** @overload */
    472 CV_INLINE int cvRound(float value)
    473 {
    474 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && \
    475       defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
    476     __m128 t = _mm_set_ss( value );
    477     return _mm_cvtss_si32(t);
    478 #elif defined _MSC_VER && defined _M_IX86
    479     int t;
    480     __asm
    481     {
    482         fld value;
    483         fistp t;
    484     }
    485     return t;
    486 #elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \
    487         defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION
    488     TEGRA_ROUND_FLT(value);
    489 #elif defined CV_ICC || defined __GNUC__
    490 # if CV_VFP
    491     ARM_ROUND_FLT(value);
    492 # else
    493     return (int)lrintf(value);
    494 # endif
    495 #else
    496     /* it's ok if round does not comply with IEEE754 standard;
    497      the tests should allow +/-1 difference when the tested functions use round */
    498     return (int)(value + (value >= 0 ? 0.5f : -0.5f));
    499 #endif
    500 }
    501 
    502 /** @overload */
    503 CV_INLINE int cvRound( int value )
    504 {
    505     return value;
    506 }
    507 
    508 /** @overload */
    509 CV_INLINE int cvFloor( float value )
    510 {
    511 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
    512     __m128 t = _mm_set_ss( value );
    513     int i = _mm_cvtss_si32(t);
    514     return i - _mm_movemask_ps(_mm_cmplt_ss(t, _mm_cvtsi32_ss(t,i)));
    515 #elif defined __GNUC__
    516     int i = (int)value;
    517     return i - (i > value);
    518 #else
    519     int i = cvRound(value);
    520     float diff = (float)(value - i);
    521     return i - (diff < 0);
    522 #endif
    523 }
    524 
    525 /** @overload */
    526 CV_INLINE int cvFloor( int value )
    527 {
    528     return value;
    529 }
    530 
    531 /** @overload */
    532 CV_INLINE int cvCeil( float value )
    533 {
    534 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
    535     __m128 t = _mm_set_ss( value );
    536     int i = _mm_cvtss_si32(t);
    537     return i + _mm_movemask_ps(_mm_cmplt_ss(_mm_cvtsi32_ss(t,i), t));
    538 #elif defined __GNUC__
    539     int i = (int)value;
    540     return i + (i < value);
    541 #else
    542     int i = cvRound(value);
    543     float diff = (float)(i - value);
    544     return i + (diff < 0);
    545 #endif
    546 }
    547 
    548 /** @overload */
    549 CV_INLINE int cvCeil( int value )
    550 {
    551     return value;
    552 }
    553 
    554 /** @overload */
    555 CV_INLINE int cvIsNaN( float value )
    556 {
    557     Cv32suf ieee754;
    558     ieee754.f = value;
    559     return (ieee754.u & 0x7fffffff) > 0x7f800000;
    560 }
    561 
    562 /** @overload */
    563 CV_INLINE int cvIsInf( float value )
    564 {
    565     Cv32suf ieee754;
    566     ieee754.f = value;
    567     return (ieee754.u & 0x7fffffff) == 0x7f800000;
    568 }
    569 
    570 #include <algorithm>
    571 
    572 namespace cv
    573 {
    574 
    575 /////////////// saturate_cast (used in image & signal processing) ///////////////////
    576 
    577 /**
    578  Template function for accurate conversion from one primitive type to another.
    579 
    580  The functions saturate_cast resemble the standard C++ cast operations, such as static_cast\<T\>()
    581  and others. They perform an efficient and accurate conversion from one primitive type to another
    582  (see the introduction chapter). saturate in the name means that when the input value v is out of the
    583  range of the target type, the result is not formed just by taking low bits of the input, but instead
    584  the value is clipped. For example:
    585  @code
    586  uchar a = saturate_cast<uchar>(-100); // a = 0 (UCHAR_MIN)
    587  short b = saturate_cast<short>(33333.33333); // b = 32767 (SHRT_MAX)
    588  @endcode
    589  Such clipping is done when the target type is unsigned char , signed char , unsigned short or
    590  signed short . For 32-bit integers, no clipping is done.
    591 
    592  When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit),
    593  the floating-point value is first rounded to the nearest integer and then clipped if needed (when
    594  the target type is 8- or 16-bit).
    595 
    596  This operation is used in the simplest or most complex image processing functions in OpenCV.
    597 
    598  @param v Function parameter.
    599  @sa add, subtract, multiply, divide, Mat::convertTo
    600  */
    601 template<typename _Tp> static inline _Tp saturate_cast(uchar v)    { return _Tp(v); }
    602 /** @overload */
    603 template<typename _Tp> static inline _Tp saturate_cast(schar v)    { return _Tp(v); }
    604 /** @overload */
    605 template<typename _Tp> static inline _Tp saturate_cast(ushort v)   { return _Tp(v); }
    606 /** @overload */
    607 template<typename _Tp> static inline _Tp saturate_cast(short v)    { return _Tp(v); }
    608 /** @overload */
    609 template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
    610 /** @overload */
    611 template<typename _Tp> static inline _Tp saturate_cast(int v)      { return _Tp(v); }
    612 /** @overload */
    613 template<typename _Tp> static inline _Tp saturate_cast(float v)    { return _Tp(v); }
    614 /** @overload */
    615 template<typename _Tp> static inline _Tp saturate_cast(double v)   { return _Tp(v); }
    616 /** @overload */
    617 template<typename _Tp> static inline _Tp saturate_cast(int64 v)    { return _Tp(v); }
    618 /** @overload */
    619 template<typename _Tp> static inline _Tp saturate_cast(uint64 v)   { return _Tp(v); }
    620 
    621 //! @cond IGNORED
    622 
    623 template<> inline uchar saturate_cast<uchar>(schar v)        { return (uchar)std::max((int)v, 0); }
    624 template<> inline uchar saturate_cast<uchar>(ushort v)       { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
    625 template<> inline uchar saturate_cast<uchar>(int v)          { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
    626 template<> inline uchar saturate_cast<uchar>(short v)        { return saturate_cast<uchar>((int)v); }
    627 template<> inline uchar saturate_cast<uchar>(unsigned v)     { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
    628 template<> inline uchar saturate_cast<uchar>(float v)        { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
    629 template<> inline uchar saturate_cast<uchar>(double v)       { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
    630 template<> inline uchar saturate_cast<uchar>(int64 v)        { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
    631 template<> inline uchar saturate_cast<uchar>(uint64 v)       { return (uchar)std::min(v, (uint64)UCHAR_MAX); }
    632 
    633 template<> inline schar saturate_cast<schar>(uchar v)        { return (schar)std::min((int)v, SCHAR_MAX); }
    634 template<> inline schar saturate_cast<schar>(ushort v)       { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
    635 template<> inline schar saturate_cast<schar>(int v)          { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
    636 template<> inline schar saturate_cast<schar>(short v)        { return saturate_cast<schar>((int)v); }
    637 template<> inline schar saturate_cast<schar>(unsigned v)     { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
    638 template<> inline schar saturate_cast<schar>(float v)        { int iv = cvRound(v); return saturate_cast<schar>(iv); }
    639 template<> inline schar saturate_cast<schar>(double v)       { int iv = cvRound(v); return saturate_cast<schar>(iv); }
    640 template<> inline schar saturate_cast<schar>(int64 v)        { return (schar)((uint64)((int64)v-SCHAR_MIN) <= (uint64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
    641 template<> inline schar saturate_cast<schar>(uint64 v)       { return (schar)std::min(v, (uint64)SCHAR_MAX); }
    642 
    643 template<> inline ushort saturate_cast<ushort>(schar v)      { return (ushort)std::max((int)v, 0); }
    644 template<> inline ushort saturate_cast<ushort>(short v)      { return (ushort)std::max((int)v, 0); }
    645 template<> inline ushort saturate_cast<ushort>(int v)        { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
    646 template<> inline ushort saturate_cast<ushort>(unsigned v)   { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
    647 template<> inline ushort saturate_cast<ushort>(float v)      { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
    648 template<> inline ushort saturate_cast<ushort>(double v)     { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
    649 template<> inline ushort saturate_cast<ushort>(int64 v)      { return (ushort)((uint64)v <= (uint64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
    650 template<> inline ushort saturate_cast<ushort>(uint64 v)     { return (ushort)std::min(v, (uint64)USHRT_MAX); }
    651 
    652 template<> inline short saturate_cast<short>(ushort v)       { return (short)std::min((int)v, SHRT_MAX); }
    653 template<> inline short saturate_cast<short>(int v)          { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
    654 template<> inline short saturate_cast<short>(unsigned v)     { return (short)std::min(v, (unsigned)SHRT_MAX); }
    655 template<> inline short saturate_cast<short>(float v)        { int iv = cvRound(v); return saturate_cast<short>(iv); }
    656 template<> inline short saturate_cast<short>(double v)       { int iv = cvRound(v); return saturate_cast<short>(iv); }
    657 template<> inline short saturate_cast<short>(int64 v)        { return (short)((uint64)((int64)v - SHRT_MIN) <= (uint64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
    658 template<> inline short saturate_cast<short>(uint64 v)       { return (short)std::min(v, (uint64)SHRT_MAX); }
    659 
    660 template<> inline int saturate_cast<int>(float v)            { return cvRound(v); }
    661 template<> inline int saturate_cast<int>(double v)           { return cvRound(v); }
    662 
    663 // we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
    664 template<> inline unsigned saturate_cast<unsigned>(float v)  { return cvRound(v); }
    665 template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
    666 
    667 //! @endcond
    668 
    669 }
    670 
    671 #endif // __cplusplus
    672 
    673 //! @} core_utils
    674 
    675 #endif //__OPENCV_HAL_H__
    676