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
cvRound(double value)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  */
cvFloor(double value)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  */
cvCeil(double value)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. */
cvIsNaN(double value)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. */
cvIsInf(double value)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 */
cvRound(float value)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 */
cvRound(int value)503 CV_INLINE int cvRound( int value )
504 {
505     return value;
506 }
507 
508 /** @overload */
cvFloor(float value)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 */
cvFloor(int value)526 CV_INLINE int cvFloor( int value )
527 {
528     return value;
529 }
530 
531 /** @overload */
cvCeil(float value)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 */
cvCeil(int value)549 CV_INLINE int cvCeil( int value )
550 {
551     return value;
552 }
553 
554 /** @overload */
cvIsNaN(float value)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 */
cvIsInf(float value)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  */
saturate_cast(uchar v)601 template<typename _Tp> static inline _Tp saturate_cast(uchar v)    { return _Tp(v); }
602 /** @overload */
saturate_cast(schar v)603 template<typename _Tp> static inline _Tp saturate_cast(schar v)    { return _Tp(v); }
604 /** @overload */
saturate_cast(ushort v)605 template<typename _Tp> static inline _Tp saturate_cast(ushort v)   { return _Tp(v); }
606 /** @overload */
saturate_cast(short v)607 template<typename _Tp> static inline _Tp saturate_cast(short v)    { return _Tp(v); }
608 /** @overload */
saturate_cast(unsigned v)609 template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
610 /** @overload */
saturate_cast(int v)611 template<typename _Tp> static inline _Tp saturate_cast(int v)      { return _Tp(v); }
612 /** @overload */
saturate_cast(float v)613 template<typename _Tp> static inline _Tp saturate_cast(float v)    { return _Tp(v); }
614 /** @overload */
saturate_cast(double v)615 template<typename _Tp> static inline _Tp saturate_cast(double v)   { return _Tp(v); }
616 /** @overload */
saturate_cast(int64 v)617 template<typename _Tp> static inline _Tp saturate_cast(int64 v)    { return _Tp(v); }
618 /** @overload */
saturate_cast(uint64 v)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