EstervQrCode 1.1.1
Library for qr code manipulation
fast_math.hpp
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_CORE_FAST_MATH_HPP
46 #define OPENCV_CORE_FAST_MATH_HPP
47 
48 #include "opencv2/core/cvdef.h"
49 
52 
53 /****************************************************************************************\
54 * fast math *
55 \****************************************************************************************/
56 
57 #ifdef __cplusplus
58 # include <cmath>
59 #else
60 # ifdef __BORLANDC__
61 # include <fastmath.h>
62 # else
63 # include <math.h>
64 # endif
65 #endif
66 
67 #if defined(__CUDACC__)
68  // nothing, intrinsics/asm code is not supported
69 #else
70  #if ((defined _MSC_VER && defined _M_X64) \
71  || (defined __GNUC__ && defined __SSE2__)) \
72  && !defined(OPENCV_SKIP_INCLUDE_EMMINTRIN_H)
73  #include <emmintrin.h>
74  #endif
75 
76  #if defined __PPC64__ && defined __GNUC__ && defined _ARCH_PWR8 \
77  && !defined(OPENCV_SKIP_INCLUDE_ALTIVEC_H)
78  #include <altivec.h>
79  #undef vector
80  #undef bool
81  #undef pixel
82  #endif
83 
84  #if defined(CV_INLINE_ROUND_FLT)
85  // user-specified version
86  // CV_INLINE_ROUND_DBL should be defined too
87  #elif defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__ || defined __ARM_NEON) && !defined __SOFTFP__
88  // 1. general scheme
89  #define ARM_ROUND(_value, _asm_string) \
90  int res; \
91  float temp; \
92  CV_UNUSED(temp); \
93  __asm__(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \
94  return res
95  // 2. version for double
96  #ifdef __clang__
97  #define CV_INLINE_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]")
98  #else
99  #define CV_INLINE_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]")
100  #endif
101  // 3. version for float
102  #define CV_INLINE_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]")
103  #elif defined __PPC64__ && defined __GNUC__ && defined _ARCH_PWR8
104  // P8 and newer machines can convert fp32/64 to int quickly.
105  #define CV_INLINE_ROUND_DBL(value) \
106  int out; \
107  double temp; \
108  __asm__( "fctiw %[temp],%[in]\n\tmfvsrwz %[out],%[temp]\n\t" : [out] "=r" (out), [temp] "=d" (temp) : [in] "d" ((double)(value)) : ); \
109  return out;
110 
111  // FP32 also works with FP64 routine above
112  #define CV_INLINE_ROUND_FLT(value) CV_INLINE_ROUND_DBL(value)
113  #endif
114 
115  #ifdef CV_INLINE_ISINF_FLT
116  // user-specified version
117  // CV_INLINE_ISINF_DBL should be defined too
118  #elif defined __PPC64__ && defined _ARCH_PWR9 && defined(scalar_test_data_class)
119  #define CV_INLINE_ISINF_DBL(value) return scalar_test_data_class(value, 0x30);
120  #define CV_INLINE_ISINF_FLT(value) CV_INLINE_ISINF_DBL(value)
121  #endif
122 
123  #ifdef CV_INLINE_ISNAN_FLT
124  // user-specified version
125  // CV_INLINE_ISNAN_DBL should be defined too
126  #elif defined __PPC64__ && defined _ARCH_PWR9 && defined(scalar_test_data_class)
127  #define CV_INLINE_ISNAN_DBL(value) return scalar_test_data_class(value, 0x40);
128  #define CV_INLINE_ISNAN_FLT(value) CV_INLINE_ISNAN_DBL(value)
129  #endif
130 
131  #if !defined(OPENCV_USE_FASTMATH_BUILTINS) \
132  && ( \
133  defined(__x86_64__) || defined(__i686__) \
134  || defined(__arm__) \
135  || defined(__PPC64__) \
136  )
137  /* Let builtin C math functions when available. Dedicated hardware is available to
138  round and convert FP values. */
139  #define OPENCV_USE_FASTMATH_BUILTINS 1
140  #endif
141 
142  /* Enable builtin math functions if possible, desired, and available.
143  Note, not all math functions inline equally. E.g lrint will not inline
144  without the -fno-math-errno option. */
145  #if defined(CV_ICC)
146  // nothing
147  #elif defined(OPENCV_USE_FASTMATH_BUILTINS) && OPENCV_USE_FASTMATH_BUILTINS
148  #if defined(__clang__)
149  #define CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
150  #if !defined(CV_INLINE_ISNAN_DBL) && __has_builtin(__builtin_isnan)
151  #define CV_INLINE_ISNAN_DBL(value) return __builtin_isnan(value);
152  #endif
153  #if !defined(CV_INLINE_ISNAN_FLT) && __has_builtin(__builtin_isnan)
154  #define CV_INLINE_ISNAN_FLT(value) return __builtin_isnan(value);
155  #endif
156  #if !defined(CV_INLINE_ISINF_DBL) && __has_builtin(__builtin_isinf)
157  #define CV_INLINE_ISINF_DBL(value) return __builtin_isinf(value);
158  #endif
159  #if !defined(CV_INLINE_ISINF_FLT) && __has_builtin(__builtin_isinf)
160  #define CV_INLINE_ISINF_FLT(value) return __builtin_isinf(value);
161  #endif
162  #elif defined(__GNUC__)
163  #define CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS
164  #if !defined(CV_INLINE_ISNAN_DBL)
165  #define CV_INLINE_ISNAN_DBL(value) return __builtin_isnan(value);
166  #endif
167  #if !defined(CV_INLINE_ISNAN_FLT)
168  #define CV_INLINE_ISNAN_FLT(value) return __builtin_isnanf(value);
169  #endif
170  #if !defined(CV_INLINE_ISINF_DBL)
171  #define CV_INLINE_ISINF_DBL(value) return __builtin_isinf(value);
172  #endif
173  #if !defined(CV_INLINE_ISINF_FLT)
174  #define CV_INLINE_ISINF_FLT(value) return __builtin_isinff(value);
175  #endif
176  #elif defined(_MSC_VER)
177  #if !defined(CV_INLINE_ISNAN_DBL)
178  #define CV_INLINE_ISNAN_DBL(value) return isnan(value);
179  #endif
180  #if !defined(CV_INLINE_ISNAN_FLT)
181  #define CV_INLINE_ISNAN_FLT(value) return isnan(value);
182  #endif
183  #if !defined(CV_INLINE_ISINF_DBL)
184  #define CV_INLINE_ISINF_DBL(value) return isinf(value);
185  #endif
186  #if !defined(CV_INLINE_ISINF_FLT)
187  #define CV_INLINE_ISINF_FLT(value) return isinf(value);
188  #endif
189  #endif
190  #endif
191 
192 #endif // defined(__CUDACC__)
193 
199 CV_INLINE int
200 cvRound( double value )
201 {
202 #if defined CV_INLINE_ROUND_DBL
203  CV_INLINE_ROUND_DBL(value);
204 #elif ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __SSE2__)) && !defined(__CUDACC__)
205  __m128d t = _mm_set_sd( value );
206  return _mm_cvtsd_si32(t);
207 #elif defined _MSC_VER && defined _M_IX86
208  int t;
209  __asm
210  {
211  fld value;
212  fistp t;
213  }
214  return t;
215 #elif defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
216  defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
217  return (int)__builtin_lrint(value);
218 #else
219  return (int)lrint(value);
220 #endif
221 }
222 
223 
231 CV_INLINE int cvFloor( double value )
232 {
233 #if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
234  defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
235  return (int)__builtin_floor(value);
236 #elif defined __loongarch64
237  int i;
238  double tmp;
239  __asm__ ("ftintrm.l.d %[tmp], %[in] \n\t"
240  "movfr2gr.d %[i], %[tmp] \n\t"
241  : [i] "=r" (i), [tmp] "=f" (tmp)
242  : [in] "f" (value)
243  :);
244  return i;
245 #else
246  int i = (int)value;
247  return i - (i > value);
248 #endif
249 }
250 
258 CV_INLINE int cvCeil( double value )
259 {
260 #if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
261  defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
262  return (int)__builtin_ceil(value);
263 #elif defined __loongarch64
264  int i;
265  double tmp;
266  __asm__ ("ftintrp.l.d %[tmp], %[in] \n\t"
267  "movfr2gr.d %[i], %[tmp] \n\t"
268  : [i] "=r" (i), [tmp] "=f" (tmp)
269  : [in] "f" (value)
270  :);
271  return i;
272 #else
273  int i = (int)value;
274  return i + (i < value);
275 #endif
276 }
277 
284 CV_INLINE int cvIsNaN( double value )
285 {
286 #if defined CV_INLINE_ISNAN_DBL
287  CV_INLINE_ISNAN_DBL(value);
288 #else
289  Cv64suf ieee754;
290  ieee754.f = value;
291  return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
292  ((unsigned)ieee754.u != 0) > 0x7ff00000;
293 #endif
294 }
295 
302 CV_INLINE int cvIsInf( double value )
303 {
304 #if defined CV_INLINE_ISINF_DBL
305  CV_INLINE_ISINF_DBL(value);
306 #elif defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__PPC64__) || defined(__loongarch64)
307  Cv64suf ieee754;
308  ieee754.f = value;
309  return (ieee754.u & 0x7fffffffffffffff) ==
310  0x7ff0000000000000;
311 #else
312  Cv64suf ieee754;
313  ieee754.f = value;
314  return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
315  (unsigned)ieee754.u == 0;
316 #endif
317 }
318 
319 #ifdef __cplusplus
320 
322 CV_INLINE int cvRound(float value)
323 {
324 #if defined CV_INLINE_ROUND_FLT
325  CV_INLINE_ROUND_FLT(value);
326 #elif ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __SSE2__)) && !defined(__CUDACC__)
327  __m128 t = _mm_set_ss( value );
328  return _mm_cvtss_si32(t);
329 #elif defined _MSC_VER && defined _M_IX86
330  int t;
331  __asm
332  {
333  fld value;
334  fistp t;
335  }
336  return t;
337 #elif defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
338  defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
339  return (int)__builtin_lrintf(value);
340 #else
341  return (int)lrintf(value);
342 #endif
343 }
344 
346 CV_INLINE int cvRound( int value )
347 {
348  return value;
349 }
350 
352 CV_INLINE int cvFloor( float value )
353 {
354 #if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
355  defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
356  return (int)__builtin_floorf(value);
357 #elif defined __loongarch__
358  int i;
359  float tmp;
360  __asm__ ("ftintrm.w.s %[tmp], %[in] \n\t"
361  "movfr2gr.s %[i], %[tmp] \n\t"
362  : [i] "=r" (i), [tmp] "=f" (tmp)
363  : [in] "f" (value)
364  :);
365  return i;
366 #else
367  int i = (int)value;
368  return i - (i > value);
369 #endif
370 }
371 
373 CV_INLINE int cvFloor( int value )
374 {
375  return value;
376 }
377 
379 CV_INLINE int cvCeil( float value )
380 {
381 #if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
382  defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
383  return (int)__builtin_ceilf(value);
384 #elif defined __loongarch__
385  int i;
386  float tmp;
387  __asm__ ("ftintrp.w.s %[tmp], %[in] \n\t"
388  "movfr2gr.s %[i], %[tmp] \n\t"
389  : [i] "=r" (i), [tmp] "=f" (tmp)
390  : [in] "f" (value)
391  :);
392  return i;
393 #else
394  int i = (int)value;
395  return i + (i < value);
396 #endif
397 }
398 
400 CV_INLINE int cvCeil( int value )
401 {
402  return value;
403 }
404 
406 CV_INLINE int cvIsNaN( float value )
407 {
408 #if defined CV_INLINE_ISNAN_FLT
409  CV_INLINE_ISNAN_FLT(value);
410 #else
411  Cv32suf ieee754;
412  ieee754.f = value;
413  return (ieee754.u & 0x7fffffff) > 0x7f800000;
414 #endif
415 }
416 
418 CV_INLINE int cvIsInf( float value )
419 {
420 #if defined CV_INLINE_ISINF_FLT
421  CV_INLINE_ISINF_FLT(value);
422 #else
423  Cv32suf ieee754;
424  ieee754.f = value;
425  return (ieee754.u & 0x7fffffff) == 0x7f800000;
426 #endif
427 }
428 
429 #endif // __cplusplus
430 
432 
433 #endif
int CvScalar value
Definition: core_c.h:720
CV_INLINE int cvIsNaN(double value)
Determines if the argument is Not A Number.
Definition: fast_math.hpp:284
CV_INLINE int cvIsInf(double value)
Determines if the argument is Infinity.
Definition: fast_math.hpp:302
CV_INLINE int cvRound(double value)
Rounds floating-point number to the nearest integer.
Definition: fast_math.hpp:200
CV_INLINE int cvCeil(double value)
Rounds floating-point number to the nearest integer not smaller than the original.
Definition: fast_math.hpp:258
CV_INLINE int cvFloor(double value)
Rounds floating-point number to the nearest integer not larger than the original.
Definition: fast_math.hpp:231
#define CV_INLINE
Definition: cvdef.h:218
Definition: cvdef.h:402
unsigned u
Definition: cvdef.h:404
float f
Definition: cvdef.h:405
Definition: cvdef.h:410
double f
Definition: cvdef.h:413
uint64 u
Definition: cvdef.h:412