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