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