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
281typedef 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
305typedef union Cv32suf
306{
307    int i;
308    unsigned u;
309    float f;
310}
311Cv32suf;
312
313typedef union Cv64suf
314{
315    int64 i;
316    uint64 u;
317    double f;
318}
319Cv64suf;
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 */
363CV_INLINE int
364cvRound( 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 */
402CV_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 */
425CV_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. */
447CV_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. */
461CV_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 */
472CV_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 */
503CV_INLINE int cvRound( int value )
504{
505    return value;
506}
507
508/** @overload */
509CV_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 */
526CV_INLINE int cvFloor( int value )
527{
528    return value;
529}
530
531/** @overload */
532CV_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 */
549CV_INLINE int cvCeil( int value )
550{
551    return value;
552}
553
554/** @overload */
555CV_INLINE int cvIsNaN( float value )
556{
557    Cv32suf ieee754;
558    ieee754.f = value;
559    return (ieee754.u & 0x7fffffff) > 0x7f800000;
560}
561
562/** @overload */
563CV_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
572namespace 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 */
601template<typename _Tp> static inline _Tp saturate_cast(uchar v)    { return _Tp(v); }
602/** @overload */
603template<typename _Tp> static inline _Tp saturate_cast(schar v)    { return _Tp(v); }
604/** @overload */
605template<typename _Tp> static inline _Tp saturate_cast(ushort v)   { return _Tp(v); }
606/** @overload */
607template<typename _Tp> static inline _Tp saturate_cast(short v)    { return _Tp(v); }
608/** @overload */
609template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
610/** @overload */
611template<typename _Tp> static inline _Tp saturate_cast(int v)      { return _Tp(v); }
612/** @overload */
613template<typename _Tp> static inline _Tp saturate_cast(float v)    { return _Tp(v); }
614/** @overload */
615template<typename _Tp> static inline _Tp saturate_cast(double v)   { return _Tp(v); }
616/** @overload */
617template<typename _Tp> static inline _Tp saturate_cast(int64 v)    { return _Tp(v); }
618/** @overload */
619template<typename _Tp> static inline _Tp saturate_cast(uint64 v)   { return _Tp(v); }
620
621//! @cond IGNORED
622
623template<> inline uchar saturate_cast<uchar>(schar v)        { return (uchar)std::max((int)v, 0); }
624template<> inline uchar saturate_cast<uchar>(ushort v)       { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
625template<> inline uchar saturate_cast<uchar>(int v)          { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
626template<> inline uchar saturate_cast<uchar>(short v)        { return saturate_cast<uchar>((int)v); }
627template<> inline uchar saturate_cast<uchar>(unsigned v)     { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
628template<> inline uchar saturate_cast<uchar>(float v)        { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
629template<> inline uchar saturate_cast<uchar>(double v)       { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
630template<> inline uchar saturate_cast<uchar>(int64 v)        { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
631template<> inline uchar saturate_cast<uchar>(uint64 v)       { return (uchar)std::min(v, (uint64)UCHAR_MAX); }
632
633template<> inline schar saturate_cast<schar>(uchar v)        { return (schar)std::min((int)v, SCHAR_MAX); }
634template<> inline schar saturate_cast<schar>(ushort v)       { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
635template<> inline schar saturate_cast<schar>(int v)          { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
636template<> inline schar saturate_cast<schar>(short v)        { return saturate_cast<schar>((int)v); }
637template<> inline schar saturate_cast<schar>(unsigned v)     { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
638template<> inline schar saturate_cast<schar>(float v)        { int iv = cvRound(v); return saturate_cast<schar>(iv); }
639template<> inline schar saturate_cast<schar>(double v)       { int iv = cvRound(v); return saturate_cast<schar>(iv); }
640template<> inline schar saturate_cast<schar>(int64 v)        { return (schar)((uint64)((int64)v-SCHAR_MIN) <= (uint64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
641template<> inline schar saturate_cast<schar>(uint64 v)       { return (schar)std::min(v, (uint64)SCHAR_MAX); }
642
643template<> inline ushort saturate_cast<ushort>(schar v)      { return (ushort)std::max((int)v, 0); }
644template<> inline ushort saturate_cast<ushort>(short v)      { return (ushort)std::max((int)v, 0); }
645template<> inline ushort saturate_cast<ushort>(int v)        { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
646template<> inline ushort saturate_cast<ushort>(unsigned v)   { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
647template<> inline ushort saturate_cast<ushort>(float v)      { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
648template<> inline ushort saturate_cast<ushort>(double v)     { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
649template<> inline ushort saturate_cast<ushort>(int64 v)      { return (ushort)((uint64)v <= (uint64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
650template<> inline ushort saturate_cast<ushort>(uint64 v)     { return (ushort)std::min(v, (uint64)USHRT_MAX); }
651
652template<> inline short saturate_cast<short>(ushort v)       { return (short)std::min((int)v, SHRT_MAX); }
653template<> inline short saturate_cast<short>(int v)          { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
654template<> inline short saturate_cast<short>(unsigned v)     { return (short)std::min(v, (unsigned)SHRT_MAX); }
655template<> inline short saturate_cast<short>(float v)        { int iv = cvRound(v); return saturate_cast<short>(iv); }
656template<> inline short saturate_cast<short>(double v)       { int iv = cvRound(v); return saturate_cast<short>(iv); }
657template<> inline short saturate_cast<short>(int64 v)        { return (short)((uint64)((int64)v - SHRT_MIN) <= (uint64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
658template<> inline short saturate_cast<short>(uint64 v)       { return (short)std::min(v, (uint64)SHRT_MAX); }
659
660template<> inline int saturate_cast<int>(float v)            { return cvRound(v); }
661template<> 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.
664template<> inline unsigned saturate_cast<unsigned>(float v)  { return cvRound(v); }
665template<> 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