next: drop HAVE_TEGRA_OPTIMIZATION/TADP
[platform/upstream/opencv.git] / modules / core / include / opencv2 / core / private.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 // Third party copyrights are property of their respective owners.
17 //
18 // Redistribution and use in source and binary forms, with or without modification,
19 // are permitted provided that the following conditions are met:
20 //
21 //   * Redistribution's of source code must retain the above copyright notice,
22 //     this list of conditions and the following disclaimer.
23 //
24 //   * Redistribution's in binary form must reproduce the above copyright notice,
25 //     this list of conditions and the following disclaimer in the documentation
26 //     and/or other materials provided with the distribution.
27 //
28 //   * The name of the copyright holders may not be used to endorse or promote products
29 //     derived from this software without specific prior written permission.
30 //
31 // This software is provided by the copyright holders and contributors "as is" and
32 // any express or implied warranties, including, but not limited to, the implied
33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
34 // In no event shall the Intel Corporation or contributors be liable for any direct,
35 // indirect, incidental, special, exemplary, or consequential damages
36 // (including, but not limited to, procurement of substitute goods or services;
37 // loss of use, data, or profits; or business interruption) however caused
38 // and on any theory of liability, whether in contract, strict liability,
39 // or tort (including negligence or otherwise) arising in any way out of
40 // the use of this software, even if advised of the possibility of such damage.
41 //
42 //M*/
43
44 #ifndef OPENCV_CORE_PRIVATE_HPP
45 #define OPENCV_CORE_PRIVATE_HPP
46
47 #ifndef __OPENCV_BUILD
48 #  error this is a private header which should not be used from outside of the OpenCV library
49 #endif
50
51 #include "opencv2/core.hpp"
52 #include "cvconfig.h"
53
54 #include <opencv2/core/utils/trace.hpp>
55
56 #ifdef HAVE_EIGEN
57 #  if defined __GNUC__ && defined __APPLE__
58 #    pragma GCC diagnostic ignored "-Wshadow"
59 #  endif
60 #  include <Eigen/Core>
61 #  include "opencv2/core/eigen.hpp"
62 #endif
63
64 //! @cond IGNORED
65
66 namespace cv
67 {
68     class BlockedRange
69     {
70     public:
71         BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
72         BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
73         int begin() const { return _begin; }
74         int end() const { return _end; }
75         int grainsize() const { return _grainsize; }
76
77     protected:
78         int _begin, _end, _grainsize;
79     };
80
81     template<typename Body> static inline
82     void parallel_for( const BlockedRange& range, const Body& body )
83     {
84         body(range);
85     }
86     typedef std::vector<Rect> ConcurrentRectVector;
87
88     class Split {};
89
90     template<typename Body> static inline
91     void parallel_reduce( const BlockedRange& range, Body& body )
92     {
93         body(range);
94     }
95
96     // Returns a static string if there is a parallel framework,
97     // NULL otherwise.
98     CV_EXPORTS const char* currentParallelFramework();
99 } //namespace cv
100
101 /****************************************************************************************\
102 *                                  Common declarations                                   *
103 \****************************************************************************************/
104
105 /* the alignment of all the allocated buffers */
106 #define  CV_MALLOC_ALIGN    64
107
108 /* IEEE754 constants and macros */
109 #define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
110 #define  CV_TOGGLE_DBL(x) ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))
111
112 static inline void* cvAlignPtr( const void* ptr, int align = 32 )
113 {
114     CV_DbgAssert ( (align & (align-1)) == 0 );
115     return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
116 }
117
118 static inline int cvAlign( int size, int align )
119 {
120     CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX );
121     return (size + align - 1) & -align;
122 }
123
124 #ifdef IPL_DEPTH_8U
125 static inline cv::Size cvGetMatSize( const CvMat* mat )
126 {
127     return cv::Size(mat->cols, mat->rows);
128 }
129 #endif
130
131 namespace cv
132 {
133 CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
134
135 //! Allocate all memory buffers which will not be freed, ease filtering memcheck issues
136 template <typename T>
137 T* allocSingleton(size_t count) { return static_cast<T*>(fastMalloc(sizeof(T) * count)); }
138 }
139
140 #if 1 // TODO: Remove in OpenCV 4.x
141
142 // property implementation macros
143
144 #define CV_IMPL_PROPERTY_RO(type, name, member) \
145     inline type get##name() const { return member; }
146
147 #define CV_HELP_IMPL_PROPERTY(r_type, w_type, name, member) \
148     CV_IMPL_PROPERTY_RO(r_type, name, member) \
149     inline void set##name(w_type val) { member = val; }
150
151 #define CV_HELP_WRAP_PROPERTY(r_type, w_type, name, internal_name, internal_obj) \
152     r_type get##name() const { return internal_obj.get##internal_name(); } \
153     void set##name(w_type val) { internal_obj.set##internal_name(val); }
154
155 #define CV_IMPL_PROPERTY(type, name, member) CV_HELP_IMPL_PROPERTY(type, type, name, member)
156 #define CV_IMPL_PROPERTY_S(type, name, member) CV_HELP_IMPL_PROPERTY(type, const type &, name, member)
157
158 #define CV_WRAP_PROPERTY(type, name, internal_name, internal_obj)  CV_HELP_WRAP_PROPERTY(type, type, name, internal_name, internal_obj)
159 #define CV_WRAP_PROPERTY_S(type, name, internal_name, internal_obj) CV_HELP_WRAP_PROPERTY(type, const type &, name, internal_name, internal_obj)
160
161 #define CV_WRAP_SAME_PROPERTY(type, name, internal_obj) CV_WRAP_PROPERTY(type, name, name, internal_obj)
162 #define CV_WRAP_SAME_PROPERTY_S(type, name, internal_obj) CV_WRAP_PROPERTY_S(type, name, name, internal_obj)
163
164 #endif
165
166 /****************************************************************************************\
167 *                     Structures and macros for integration with IPP                     *
168 \****************************************************************************************/
169
170 // Temporary disabled named IPP region. Accuracy
171 #define IPP_DISABLE_PYRAMIDS_UP         1 // Different results
172 #define IPP_DISABLE_PYRAMIDS_DOWN       1 // Different results
173 #define IPP_DISABLE_PYRAMIDS_BUILD      1 // Different results
174 #define IPP_DISABLE_WARPAFFINE          1 // Different results
175 #define IPP_DISABLE_WARPPERSPECTIVE     1 // Different results
176 #define IPP_DISABLE_REMAP               1 // Different results
177 #define IPP_DISABLE_YUV_RGB             1 // accuracy difference
178 #define IPP_DISABLE_RGB_YUV             1 // breaks OCL accuracy tests
179 #define IPP_DISABLE_RGB_HSV             1 // breaks OCL accuracy tests
180 #define IPP_DISABLE_RGB_LAB             1 // breaks OCL accuracy tests
181 #define IPP_DISABLE_LAB_RGB             1 // breaks OCL accuracy tests
182 #define IPP_DISABLE_RGB_XYZ             1 // big accuracy difference
183 #define IPP_DISABLE_XYZ_RGB             1 // big accuracy difference
184 #define IPP_DISABLE_HAAR                1 // improper integration/results
185 #define IPP_DISABLE_HOUGH               1 // improper integration/results
186
187 // Temporary disabled named IPP region. Performance
188 #define IPP_DISABLE_PERF_COPYMAKE       1 // performance variations
189 #define IPP_DISABLE_PERF_LUT            1 // there are no performance benefits (PR #2653)
190 #define IPP_DISABLE_PERF_TRUE_DIST_MT   1 // cv::distanceTransform OpenCV MT performance is better
191 #define IPP_DISABLE_PERF_CANNY_MT       1 // cv::Canny OpenCV MT performance is better
192
193 #ifdef HAVE_IPP
194 #include "ippversion.h"
195 #ifndef IPP_VERSION_UPDATE // prior to 7.1
196 #define IPP_VERSION_UPDATE 0
197 #endif
198
199 #define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)
200
201 #ifdef HAVE_IPP_ICV
202 #define ICV_BASE
203 #if IPP_VERSION_X100 >= 201700
204 #include "ippicv.h"
205 #else
206 #include "ipp.h"
207 #endif
208 #else
209 #include "ipp.h"
210 #endif
211 #ifdef HAVE_IPP_IW
212 #  if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
213 #  pragma GCC diagnostic push
214 #  pragma GCC diagnostic ignored "-Wsuggest-override"
215 #  endif
216 #include "iw++/iw.hpp"
217 #include "iw/iw_ll.h"
218 #  if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
219 #  pragma GCC diagnostic pop
220 #  endif
221 #endif
222
223 #if IPP_VERSION_X100 >= 201700
224 #define CV_IPP_MALLOC(SIZE) ippMalloc_L(SIZE)
225 #else
226 #define CV_IPP_MALLOC(SIZE) ippMalloc((int)SIZE)
227 #endif
228
229 #define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
230
231 #if IPP_VERSION_X100 >= 201700
232 #define ippCPUID_AVX512_SKX (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ)
233 #define ippCPUID_AVX512_KNL (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512PF|ippCPUID_AVX512ER)
234 #else
235 #define ippCPUID_AVX512_SKX 0xFFFFFFFF
236 #define ippCPUID_AVX512_KNL 0xFFFFFFFF
237 #endif
238
239 namespace cv
240 {
241 namespace ipp
242 {
243 CV_EXPORTS   unsigned long long getIppTopFeatures(); // Returns top major enabled IPP feature flag
244 }
245 }
246
247 static inline IppiSize ippiSize(size_t width, size_t height)
248 {
249     IppiSize size = { (int)width, (int)height };
250     return size;
251 }
252
253 static inline IppiSize ippiSize(const cv::Size & _size)
254 {
255     IppiSize size = { _size.width, _size.height };
256     return size;
257 }
258
259 #if IPP_VERSION_X100 >= 201700
260 static inline IppiSizeL ippiSizeL(size_t width, size_t height)
261 {
262     IppiSizeL size = { (IppSizeL)width, (IppSizeL)height };
263     return size;
264 }
265
266 static inline IppiSizeL ippiSizeL(const cv::Size & _size)
267 {
268     IppiSizeL size = { _size.width, _size.height };
269     return size;
270 }
271 #endif
272
273 static inline IppiPoint ippiPoint(const cv::Point & _point)
274 {
275     IppiPoint point = { _point.x, _point.y };
276     return point;
277 }
278
279 static inline IppiPoint ippiPoint(int x, int y)
280 {
281     IppiPoint point = { x, y };
282     return point;
283 }
284
285 static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
286 {
287     return borderTypeNI == cv::BORDER_CONSTANT    ? ippBorderConst   :
288            borderTypeNI == cv::BORDER_TRANSPARENT ? ippBorderTransp  :
289            borderTypeNI == cv::BORDER_REPLICATE   ? ippBorderRepl    :
290            borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror  :
291            (IppiBorderType)-1;
292 }
293
294 static inline IppiMaskSize ippiGetMaskSize(int kx, int ky)
295 {
296     return (kx == 1 && ky == 3) ? ippMskSize1x3 :
297            (kx == 1 && ky == 5) ? ippMskSize1x5 :
298            (kx == 3 && ky == 1) ? ippMskSize3x1 :
299            (kx == 3 && ky == 3) ? ippMskSize3x3 :
300            (kx == 5 && ky == 1) ? ippMskSize5x1 :
301            (kx == 5 && ky == 5) ? ippMskSize5x5 :
302            (IppiMaskSize)-1;
303 }
304
305 static inline IppDataType ippiGetDataType(int depth)
306 {
307     depth = CV_MAT_DEPTH(depth);
308     return depth == CV_8U ? ipp8u :
309         depth == CV_8S ? ipp8s :
310         depth == CV_16U ? ipp16u :
311         depth == CV_16S ? ipp16s :
312         depth == CV_32S ? ipp32s :
313         depth == CV_32F ? ipp32f :
314         depth == CV_64F ? ipp64f :
315         (IppDataType)-1;
316 }
317
318 static inline int ippiSuggestThreadsNum(size_t width, size_t height, size_t elemSize, double multiplier)
319 {
320     int threads = cv::getNumThreads();
321     if(threads > 1 && height >= 64)
322     {
323         size_t opMemory = (int)(width*height*elemSize*multiplier);
324         int l2cache = 0;
325 #if IPP_VERSION_X100 >= 201700
326         ippGetL2CacheSize(&l2cache);
327 #endif
328         if(!l2cache)
329             l2cache = 1 << 18;
330
331         return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
332     }
333     return 1;
334 }
335
336 static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier)
337 {
338     return ippiSuggestThreadsNum(image.cols, image.rows, image.elemSize(), multiplier);
339 }
340
341 #ifdef HAVE_IPP_IW
342 static inline bool ippiCheckAnchor(int x, int y, int kernelWidth, int kernelHeight)
343 {
344     if(x != ((kernelWidth-1)/2) || y != ((kernelHeight-1)/2))
345         return 0;
346     else
347         return 1;
348 }
349
350 static inline ::ipp::IwiSize ippiGetSize(const cv::Size & size)
351 {
352     return ::ipp::IwiSize((IwSize)size.width, (IwSize)size.height);
353 }
354
355 static inline IwiDerivativeType ippiGetDerivType(int dx, int dy, bool nvert)
356 {
357     return (dx == 1 && dy == 0) ? ((nvert)?iwiDerivNVerFirst:iwiDerivVerFirst) :
358            (dx == 0 && dy == 1) ? iwiDerivHorFirst :
359            (dx == 2 && dy == 0) ? iwiDerivVerSecond :
360            (dx == 0 && dy == 2) ? iwiDerivHorSecond :
361            (IwiDerivativeType)-1;
362 }
363
364 static inline void ippiGetImage(const cv::Mat &src, ::ipp::IwiImage &dst)
365 {
366     ::ipp::IwiBorderSize inMemBorder;
367     if(src.isSubmatrix()) // already have physical border
368     {
369         cv::Size  origSize;
370         cv::Point offset;
371         src.locateROI(origSize, offset);
372
373         inMemBorder.left   = (IwSize)offset.x;
374         inMemBorder.top    = (IwSize)offset.y;
375         inMemBorder.right  = (IwSize)(origSize.width - src.cols - offset.x);
376         inMemBorder.bottom = (IwSize)(origSize.height - src.rows - offset.y);
377     }
378
379     dst.Init(ippiSize(src.size()), ippiGetDataType(src.depth()), src.channels(), inMemBorder, (void*)src.ptr(), src.step);
380 }
381
382 static inline ::ipp::IwiImage ippiGetImage(const cv::Mat &src)
383 {
384     ::ipp::IwiImage image;
385     ippiGetImage(src, image);
386     return image;
387 }
388
389 static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorderType, ipp::IwiBorderSize &borderSize)
390 {
391     int            inMemFlags = 0;
392     IppiBorderType border     = ippiGetBorderType(ocvBorderType & ~cv::BORDER_ISOLATED);
393     if((int)border == -1)
394         return (IppiBorderType)0;
395
396     if(!(ocvBorderType & cv::BORDER_ISOLATED))
397     {
398         if(image.m_inMemSize.left)
399         {
400             if(image.m_inMemSize.left >= borderSize.left)
401                 inMemFlags |= ippBorderInMemLeft;
402             else
403                 return (IppiBorderType)0;
404         }
405         else
406             borderSize.left = 0;
407         if(image.m_inMemSize.top)
408         {
409             if(image.m_inMemSize.top >= borderSize.top)
410                 inMemFlags |= ippBorderInMemTop;
411             else
412                 return (IppiBorderType)0;
413         }
414         else
415             borderSize.top = 0;
416         if(image.m_inMemSize.right)
417         {
418             if(image.m_inMemSize.right >= borderSize.right)
419                 inMemFlags |= ippBorderInMemRight;
420             else
421                 return (IppiBorderType)0;
422         }
423         else
424             borderSize.right = 0;
425         if(image.m_inMemSize.bottom)
426         {
427             if(image.m_inMemSize.bottom >= borderSize.bottom)
428                 inMemFlags |= ippBorderInMemBottom;
429             else
430                 return (IppiBorderType)0;
431         }
432         else
433             borderSize.bottom = 0;
434     }
435     else
436         borderSize.left = borderSize.right = borderSize.top = borderSize.bottom = 0;
437
438     return (IppiBorderType)(border|inMemFlags);
439 }
440
441 static inline ::ipp::IwValueFloat ippiGetValue(const cv::Scalar &scalar)
442 {
443     return ::ipp::IwValueFloat(scalar[0], scalar[1], scalar[2], scalar[3]);
444 }
445
446 static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
447 {
448     return ippiSuggestThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, multiplier);
449 }
450 #endif
451
452 // IPP temporary buffer helper
453 template<typename T>
454 class IppAutoBuffer
455 {
456 public:
457     IppAutoBuffer() { m_size = 0; m_pBuffer = NULL; }
458     explicit IppAutoBuffer(size_t size) { m_size = 0; m_pBuffer = NULL; allocate(size); }
459     ~IppAutoBuffer() { deallocate(); }
460     T* allocate(size_t size)   { if(m_size < size) { deallocate(); m_pBuffer = (T*)CV_IPP_MALLOC(size); m_size = size; } return m_pBuffer; }
461     void deallocate() { if(m_pBuffer) { ippFree(m_pBuffer); m_pBuffer = NULL; } m_size = 0; }
462     inline T* get() { return (T*)m_pBuffer;}
463     inline operator T* () { return (T*)m_pBuffer;}
464     inline operator const T* () const { return (const T*)m_pBuffer;}
465 private:
466     // Disable copy operations
467     IppAutoBuffer(IppAutoBuffer &) {}
468     IppAutoBuffer& operator =(const IppAutoBuffer &) {return *this;}
469
470     size_t m_size;
471     T*     m_pBuffer;
472 };
473
474 // Extracts border interpolation type without flags
475 #if IPP_VERSION_X100 >= 201700
476 #define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF|((((BORDER)&ippBorderInMem) == ippBorderInMem)?ippBorderInMem:0));
477 #else
478 #define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF);
479 #endif
480
481 #else
482 #define IPP_VERSION_X100 0
483 #endif
484
485 #if defined HAVE_IPP
486 #if IPP_VERSION_X100 >= 900
487 #define IPP_INITIALIZER(FEAT)                           \
488 {                                                       \
489     if(FEAT)                                            \
490         ippSetCpuFeatures(FEAT);                        \
491     else                                                \
492         ippInit();                                      \
493 }
494 #elif IPP_VERSION_X100 >= 800
495 #define IPP_INITIALIZER(FEAT)                           \
496 {                                                       \
497     ippInit();                                          \
498 }
499 #else
500 #define IPP_INITIALIZER(FEAT)                           \
501 {                                                       \
502     ippStaticInit();                                    \
503 }
504 #endif
505
506 #ifdef CVAPI_EXPORTS
507 #define IPP_INITIALIZER_AUTO                            \
508 struct __IppInitializer__                               \
509 {                                                       \
510     __IppInitializer__()                                \
511     {IPP_INITIALIZER(cv::ipp::getIppFeatures())}        \
512 };                                                      \
513 static struct __IppInitializer__ __ipp_initializer__;
514 #else
515 #define IPP_INITIALIZER_AUTO
516 #endif
517 #else
518 #define IPP_INITIALIZER
519 #define IPP_INITIALIZER_AUTO
520 #endif
521
522 #define CV_IPP_CHECK_COND (cv::ipp::useIPP())
523 #define CV_IPP_CHECK() if(CV_IPP_CHECK_COND)
524
525 #ifdef HAVE_IPP
526
527 #ifdef CV_IPP_RUN_VERBOSE
528 #define CV_IPP_RUN_(condition, func, ...)                                   \
529     {                                                                       \
530         if (cv::ipp::useIPP() && (condition) && (func))                     \
531         {                                                                   \
532             printf("%s: IPP implementation is running\n", CV_Func);         \
533             fflush(stdout);                                                 \
534             CV_IMPL_ADD(CV_IMPL_IPP);                                       \
535             return __VA_ARGS__;                                             \
536         }                                                                   \
537         else                                                                \
538         {                                                                   \
539             printf("%s: Plain implementation is running\n", CV_Func);       \
540             fflush(stdout);                                                 \
541         }                                                                   \
542     }
543 #elif defined CV_IPP_RUN_ASSERT
544 #define CV_IPP_RUN_(condition, func, ...)                                   \
545     {                                                                       \
546         if (cv::ipp::useIPP() && (condition))                               \
547         {                                                                   \
548             CV__TRACE_REGION_("IPP:" #func, CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP) \
549             if(func)                                                        \
550             {                                                               \
551                 CV_IMPL_ADD(CV_IMPL_IPP);                                   \
552             }                                                               \
553             else                                                            \
554             {                                                               \
555                 setIppErrorStatus();                                        \
556                 CV_Error(cv::Error::StsAssert, #func);                      \
557             }                                                               \
558             return __VA_ARGS__;                                             \
559         }                                                                   \
560     }
561 #else
562 #define CV_IPP_RUN_(condition, func, ...)                                   \
563         if (cv::ipp::useIPP() && (condition))                               \
564         {                                                                   \
565             CV__TRACE_REGION_("IPP:" #func, CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP) \
566             if(func)                                                        \
567             {                                                               \
568                 CV_IMPL_ADD(CV_IMPL_IPP);                                   \
569                 return __VA_ARGS__;                                         \
570             }                                                               \
571         }
572 #endif
573 #else
574 #define CV_IPP_RUN_(condition, func, ...)
575 #endif
576
577 #define CV_IPP_RUN_FAST(func, ...) CV_IPP_RUN_(true, func, __VA_ARGS__)
578 #define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_((condition), (func), __VA_ARGS__)
579
580
581 #ifndef IPPI_CALL
582 #  define IPPI_CALL(func) CV_Assert((func) >= 0)
583 #endif
584
585 /* IPP-compatible return codes */
586 typedef enum CvStatus
587 {
588     CV_BADMEMBLOCK_ERR          = -113,
589     CV_INPLACE_NOT_SUPPORTED_ERR= -112,
590     CV_UNMATCHED_ROI_ERR        = -111,
591     CV_NOTFOUND_ERR             = -110,
592     CV_BADCONVERGENCE_ERR       = -109,
593
594     CV_BADDEPTH_ERR             = -107,
595     CV_BADROI_ERR               = -106,
596     CV_BADHEADER_ERR            = -105,
597     CV_UNMATCHED_FORMATS_ERR    = -104,
598     CV_UNSUPPORTED_COI_ERR      = -103,
599     CV_UNSUPPORTED_CHANNELS_ERR = -102,
600     CV_UNSUPPORTED_DEPTH_ERR    = -101,
601     CV_UNSUPPORTED_FORMAT_ERR   = -100,
602
603     CV_BADARG_ERR               = -49,  //ipp comp
604     CV_NOTDEFINED_ERR           = -48,  //ipp comp
605
606     CV_BADCHANNELS_ERR          = -47,  //ipp comp
607     CV_BADRANGE_ERR             = -44,  //ipp comp
608     CV_BADSTEP_ERR              = -29,  //ipp comp
609
610     CV_BADFLAG_ERR              =  -12,
611     CV_DIV_BY_ZERO_ERR          =  -11, //ipp comp
612     CV_BADCOEF_ERR              =  -10,
613
614     CV_BADFACTOR_ERR            =  -7,
615     CV_BADPOINT_ERR             =  -6,
616     CV_BADSCALE_ERR             =  -4,
617     CV_OUTOFMEM_ERR             =  -3,
618     CV_NULLPTR_ERR              =  -2,
619     CV_BADSIZE_ERR              =  -1,
620     CV_NO_ERR                   =   0,
621     CV_OK                       =   CV_NO_ERR
622 }
623 CvStatus;
624
625 #ifdef ENABLE_INSTRUMENTATION
626 namespace cv
627 {
628 namespace instr
629 {
630 struct InstrTLSStruct
631 {
632     InstrTLSStruct()
633     {
634         pCurrentNode = NULL;
635     }
636     InstrNode* pCurrentNode;
637 };
638
639 class InstrStruct
640 {
641 public:
642     InstrStruct()
643     {
644         useInstr    = false;
645         flags       = FLAGS_MAPPING;
646         maxDepth    = 0;
647
648         rootNode.m_payload = NodeData("ROOT", NULL, 0, NULL, false, TYPE_GENERAL, IMPL_PLAIN);
649         tlsStruct.get()->pCurrentNode = &rootNode;
650     }
651
652     Mutex mutexCreate;
653     Mutex mutexCount;
654
655     bool       useInstr;
656     int        flags;
657     int        maxDepth;
658     InstrNode  rootNode;
659     TLSData<InstrTLSStruct> tlsStruct;
660 };
661
662 class CV_EXPORTS IntrumentationRegion
663 {
664 public:
665     IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType = TYPE_GENERAL, IMPL implType = IMPL_PLAIN);
666     ~IntrumentationRegion();
667
668 private:
669     bool    m_disabled; // region status
670     uint64  m_regionTicks;
671 };
672
673 CV_EXPORTS InstrStruct& getInstrumentStruct();
674 InstrTLSStruct&         getInstrumentTLSStruct();
675 CV_EXPORTS InstrNode*   getCurrentNode();
676 }
677 }
678
679 #ifdef _WIN32
680 #define CV_INSTRUMENT_GET_RETURN_ADDRESS _ReturnAddress()
681 #else
682 #define CV_INSTRUMENT_GET_RETURN_ADDRESS __builtin_extract_return_addr(__builtin_return_address(0))
683 #endif
684
685 // Instrument region
686 #define CV_INSTRUMENT_REGION_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)        ::cv::instr::IntrumentationRegion __instr_region__(NAME, __FILE__, __LINE__, CV_INSTRUMENT_GET_RETURN_ADDRESS, ALWAYS_EXPAND, TYPE, IMPL);
687 #define CV_INSTRUMENT_REGION_CUSTOM_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)\
688     void *__curr_address__ = [&]() {return CV_INSTRUMENT_GET_RETURN_ADDRESS;}();\
689     ::cv::instr::IntrumentationRegion __instr_region__(NAME, __FILE__, __LINE__, __curr_address__, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
690 // Instrument functions with non-void return type
691 #define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]()\
692 {\
693     if(::cv::instr::useInstrumentation()){\
694         ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
695         try{\
696             auto status = ((FUN)(__VA_ARGS__));\
697             if(ERROR_COND){\
698                 ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
699                 CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
700             }\
701             return status;\
702         }catch(...){\
703             ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
704             CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
705             throw;\
706         }\
707     }else{\
708         return ((FUN)(__VA_ARGS__));\
709     }\
710 }())
711 // Instrument functions with void return type
712 #define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]()\
713 {\
714     if(::cv::instr::useInstrumentation()){\
715         ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
716         try{\
717             (FUN)(__VA_ARGS__);\
718         }catch(...){\
719             ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
720             CV_INSTRUMENT_MARK_META(IMPL, #FUN "- BadExit");\
721             throw;\
722         }\
723     }else{\
724         (FUN)(__VA_ARGS__);\
725     }\
726 }())
727 // Instrumentation information marker
728 #define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(NAME, __FILE__, __LINE__, NULL, false, ::cv::instr::TYPE_MARKER, IMPL);}
729
730 ///// General instrumentation
731 // General OpenCV region instrumentation macro
732 #define CV_INSTRUMENT_REGION_()             CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
733 // Custom OpenCV region instrumentation macro
734 #define CV_INSTRUMENT_REGION_NAME(NAME)     CV_INSTRUMENT_REGION_CUSTOM_META(NAME,  false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
735 // Instrumentation for parallel_for_ or other regions which forks and gathers threads
736 #define CV_INSTRUMENT_REGION_MT_FORK()      CV_INSTRUMENT_REGION_META(__FUNCTION__, true,  ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
737
738 ///// IPP instrumentation
739 // Wrapper region instrumentation macro
740 #define CV_INSTRUMENT_REGION_IPP()          CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
741 // Function instrumentation macro
742 #define CV_INSTRUMENT_FUN_IPP(FUN, ...)     CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, status < 0, FUN, __VA_ARGS__)
743 // Diagnostic markers
744 #define CV_INSTRUMENT_MARK_IPP(NAME)        CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)
745
746 ///// OpenCL instrumentation
747 // Wrapper region instrumentation macro
748 #define CV_INSTRUMENT_REGION_OPENCL()              CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
749 // OpenCL kernel compilation wrapper
750 #define CV_INSTRUMENT_REGION_OPENCL_COMPILE(NAME)  CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
751 // OpenCL kernel run wrapper
752 #define CV_INSTRUMENT_REGION_OPENCL_RUN(NAME)      CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_FUN, ::cv::instr::IMPL_OPENCL)
753 // Diagnostic markers
754 #define CV_INSTRUMENT_MARK_OPENCL(NAME)            CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_OPENCL, NAME)
755 #else
756 #define CV_INSTRUMENT_REGION_META(...)
757
758 #define CV_INSTRUMENT_REGION_()                            CV_TRACE_FUNCTION()
759 #define CV_INSTRUMENT_REGION_NAME(...)                     CV_TRACE_REGION(__VA_ARGS__)
760 #define CV_INSTRUMENT_REGION_MT_FORK()
761
762 #define CV_INSTRUMENT_REGION_IPP()                         CV__TRACE_REGION_("IPP", CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP)
763 #define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
764 #define CV_INSTRUMENT_MARK_IPP(...)
765
766 #define CV_INSTRUMENT_REGION_OPENCL()                      CV__TRACE_REGION_("OpenCL", CV_TRACE_NS::details::REGION_FLAG_IMPL_OPENCL)
767 #define CV_INSTRUMENT_REGION_OPENCL_COMPILE(...)
768 #define CV_INSTRUMENT_REGION_OPENCL_RUN(...)
769 #define CV_INSTRUMENT_MARK_OPENCL(...)
770 #endif
771
772 #ifdef __CV_AVX_GUARD
773 #define CV_INSTRUMENT_REGION() __CV_AVX_GUARD CV_INSTRUMENT_REGION_()
774 #else
775 #define CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION_()
776 #endif
777
778 //! @endcond
779
780 #endif // OPENCV_CORE_PRIVATE_HPP