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 ENABLE_INSTRUMENTATION
57 #include "opencv2/core/utils/instrumentation.hpp"
58 #endif
59 
60 #ifdef HAVE_EIGEN
61 #  if defined __GNUC__ && defined __APPLE__
62 #    pragma GCC diagnostic ignored "-Wshadow"
63 #  endif
64 #  if defined(_MSC_VER)
65 #    pragma warning(push)
66 #    pragma warning(disable:4701)  // potentially uninitialized local variable
67 #    pragma warning(disable:4702)  // unreachable code
68 #    pragma warning(disable:4714)  // const marked as __forceinline not inlined
69 #  endif
70 #  include <Eigen/Core>
71 #  if defined(_MSC_VER)
72 #    pragma warning(pop)
73 #  endif
74 #  include "opencv2/core/eigen.hpp"
75 #endif
76 
77 //! @cond IGNORED
78 
79 namespace cv
80 {
81     class BlockedRange
82     {
83     public:
BlockedRange()84         BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
BlockedRange(int b,int e,int g=1)85         BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
begin() const86         int begin() const { return _begin; }
end() const87         int end() const { return _end; }
grainsize() const88         int grainsize() const { return _grainsize; }
89 
90     protected:
91         int _begin, _end, _grainsize;
92     };
93 
94     template<typename Body> static inline
parallel_for(const BlockedRange & range,const Body & body)95     void parallel_for( const BlockedRange& range, const Body& body )
96     {
97         body(range);
98     }
99     typedef std::vector<Rect> ConcurrentRectVector;
100 
101     class Split {};
102 
103     template<typename Body> static inline
parallel_reduce(const BlockedRange & range,Body & body)104     void parallel_reduce( const BlockedRange& range, Body& body )
105     {
106         body(range);
107     }
108 
109     // Returns a static string if there is a parallel framework,
110     // NULL otherwise.
111     CV_EXPORTS const char* currentParallelFramework();
112 } //namespace cv
113 
114 /****************************************************************************************\
115 *                                  Common declarations                                   *
116 \****************************************************************************************/
117 
118 /* the alignment of all the allocated buffers */
119 #define  CV_MALLOC_ALIGN    64
120 
121 /* IEEE754 constants and macros */
122 #define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
123 #define  CV_TOGGLE_DBL(x) ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))
124 
cvAlignPtr(const void * ptr,int align=32)125 static inline void* cvAlignPtr( const void* ptr, int align = 32 )
126 {
127     CV_DbgAssert ( (align & (align-1)) == 0 );
128     return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
129 }
130 
cvAlign(int size,int align)131 static inline int cvAlign( int size, int align )
132 {
133     CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX );
134     return (size + align - 1) & -align;
135 }
136 
137 #ifdef IPL_DEPTH_8U
cvGetMatSize(const CvMat * mat)138 static inline cv::Size cvGetMatSize( const CvMat* mat )
139 {
140     return cv::Size(mat->cols, mat->rows);
141 }
142 #endif
143 
144 namespace cv
145 {
146 CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
147 
148 //! Allocate memory buffers which will not be freed, ease filtering memcheck issues. Uses fastMalloc() call.
149 CV_EXPORTS void* allocSingletonBuffer(size_t size);
150 
151 //! Allocate memory buffers which will not be freed, ease filtering memcheck issues. Uses fastMalloc() call
152 template <typename T> static inline
allocSingleton(size_t count=1)153 T* allocSingleton(size_t count = 1) { return static_cast<T*>(allocSingletonBuffer(sizeof(T) * count)); }
154 
155 //! Allocate memory buffers which will not be freed, ease filtering memcheck issues. Uses generic malloc() call.
156 CV_EXPORTS void* allocSingletonNewBuffer(size_t size);
157 
158 //! Allocate memory buffers which will not be freed, ease filtering memcheck issues.  Uses generic malloc() call.
159 template <typename T> static inline
allocSingletonNew()160 T* allocSingletonNew() { return new(allocSingletonNewBuffer(sizeof(T))) T(); }
161 
162 } // namespace
163 
164 #if 1 // TODO: Remove in OpenCV 4.x
165 
166 // property implementation macros
167 
168 #define CV_IMPL_PROPERTY_RO(type, name, member) \
169     inline type get##name() const { return member; }
170 
171 #define CV_HELP_IMPL_PROPERTY(r_type, w_type, name, member) \
172     CV_IMPL_PROPERTY_RO(r_type, name, member) \
173     inline void set##name(w_type val) { member = val; }
174 
175 #define CV_HELP_WRAP_PROPERTY(r_type, w_type, name, internal_name, internal_obj) \
176     r_type get##name() const { return internal_obj.get##internal_name(); } \
177     void set##name(w_type val) { internal_obj.set##internal_name(val); }
178 
179 #define CV_IMPL_PROPERTY(type, name, member) CV_HELP_IMPL_PROPERTY(type, type, name, member)
180 #define CV_IMPL_PROPERTY_S(type, name, member) CV_HELP_IMPL_PROPERTY(type, const type &, name, member)
181 
182 #define CV_WRAP_PROPERTY(type, name, internal_name, internal_obj)  CV_HELP_WRAP_PROPERTY(type, type, name, internal_name, internal_obj)
183 #define CV_WRAP_PROPERTY_S(type, name, internal_name, internal_obj) CV_HELP_WRAP_PROPERTY(type, const type &, name, internal_name, internal_obj)
184 
185 #define CV_WRAP_SAME_PROPERTY(type, name, internal_obj) CV_WRAP_PROPERTY(type, name, name, internal_obj)
186 #define CV_WRAP_SAME_PROPERTY_S(type, name, internal_obj) CV_WRAP_PROPERTY_S(type, name, name, internal_obj)
187 
188 #endif
189 
190 /****************************************************************************************\
191 *                     Structures and macros for integration with IPP                     *
192 \****************************************************************************************/
193 
194 #define OPENCV_IPP_REDUCE_SIZE 1
195 
196 // Temporary disabled named IPP region. Accuracy
197 #define IPP_DISABLE_PYRAMIDS_UP         1 // Different results
198 #define IPP_DISABLE_PYRAMIDS_DOWN       1 // Different results
199 #define IPP_DISABLE_PYRAMIDS_BUILD      1 // Different results
200 #define IPP_DISABLE_WARPAFFINE          1 // Different results
201 #define IPP_DISABLE_WARPPERSPECTIVE     1 // Different results
202 #define IPP_DISABLE_REMAP               1 // Different results
203 #define IPP_DISABLE_YUV_RGB             1 // accuracy difference
204 #define IPP_DISABLE_RGB_YUV             1 // breaks OCL accuracy tests
205 #define IPP_DISABLE_RGB_HSV             1 // breaks OCL accuracy tests
206 #define IPP_DISABLE_RGB_LAB             1 // breaks OCL accuracy tests
207 #define IPP_DISABLE_LAB_RGB             1 // breaks OCL accuracy tests
208 #define IPP_DISABLE_RGB_XYZ             1 // big accuracy difference
209 #define IPP_DISABLE_XYZ_RGB             1 // big accuracy difference
210 #define IPP_DISABLE_HOUGH               1 // improper integration/results
211 #define IPP_DISABLE_FILTER2D_BIG_MASK   1 // different results on masks > 7x7
212 
213 // Temporary disabled named IPP region. Performance
214 #define IPP_DISABLE_PERF_COPYMAKE       1 // performance variations
215 #define IPP_DISABLE_PERF_LUT            1 // there are no performance benefits (PR #2653)
216 #define IPP_DISABLE_PERF_TRUE_DIST_MT   1 // cv::distanceTransform OpenCV MT performance is better
217 #define IPP_DISABLE_PERF_CANNY_MT       1 // cv::Canny OpenCV MT performance is better
218 
219 #ifdef HAVE_IPP
220 #include "ippversion.h"
221 #ifndef IPP_VERSION_UPDATE // prior to 7.1
222 #define IPP_VERSION_UPDATE 0
223 #endif
224 
225 #define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)
226 
227 #ifdef HAVE_IPP_ICV
228 #define ICV_BASE
229 #if IPP_VERSION_X100 >= 201700
230 #include "ippicv.h"
231 #else
232 #include "ipp.h"
233 #endif
234 #else
235 #include "ipp.h"
236 #endif
237 #ifdef HAVE_IPP_IW
238 #  if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
239 #  pragma GCC diagnostic push
240 #  pragma GCC diagnostic ignored "-Wsuggest-override"
241 #  endif
242 #include "iw++/iw.hpp"
243 #  ifdef HAVE_IPP_IW_LL
244 #include "iw/iw_ll.h"
245 #  endif
246 #  if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
247 #  pragma GCC diagnostic pop
248 #  endif
249 #endif
250 
251 #if IPP_VERSION_X100 >= 201700
252 #define CV_IPP_MALLOC(SIZE) ippMalloc_L(SIZE)
253 #else
254 #define CV_IPP_MALLOC(SIZE) ippMalloc((int)SIZE)
255 #endif
256 
257 #define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
258 
259 #if IPP_VERSION_X100 >= 201700
260 #define ippCPUID_AVX512_SKX (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ)
261 #define ippCPUID_AVX512_KNL (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512PF|ippCPUID_AVX512ER)
262 #else
263 #define ippCPUID_AVX512_SKX 0xFFFFFFFF
264 #define ippCPUID_AVX512_KNL 0xFFFFFFFF
265 #endif
266 
267 namespace cv
268 {
269 namespace ipp
270 {
271 CV_EXPORTS   unsigned long long getIppTopFeatures(); // Returns top major enabled IPP feature flag
272 }
273 }
274 
ippiSize(size_t width,size_t height)275 static inline IppiSize ippiSize(size_t width, size_t height)
276 {
277     IppiSize size = { (int)width, (int)height };
278     return size;
279 }
280 
ippiSize(const cv::Size & _size)281 static inline IppiSize ippiSize(const cv::Size & _size)
282 {
283     IppiSize size = { _size.width, _size.height };
284     return size;
285 }
286 
287 #if IPP_VERSION_X100 >= 201700
ippiSizeL(size_t width,size_t height)288 static inline IppiSizeL ippiSizeL(size_t width, size_t height)
289 {
290     IppiSizeL size = { (IppSizeL)width, (IppSizeL)height };
291     return size;
292 }
293 
ippiSizeL(const cv::Size & _size)294 static inline IppiSizeL ippiSizeL(const cv::Size & _size)
295 {
296     IppiSizeL size = { _size.width, _size.height };
297     return size;
298 }
299 #endif
300 
ippiPoint(const cv::Point & _point)301 static inline IppiPoint ippiPoint(const cv::Point & _point)
302 {
303     IppiPoint point = { _point.x, _point.y };
304     return point;
305 }
306 
ippiPoint(int x,int y)307 static inline IppiPoint ippiPoint(int x, int y)
308 {
309     IppiPoint point = { x, y };
310     return point;
311 }
312 
ippiGetBorderType(int borderTypeNI)313 static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
314 {
315     return borderTypeNI == cv::BORDER_CONSTANT    ? ippBorderConst   :
316            borderTypeNI == cv::BORDER_TRANSPARENT ? ippBorderTransp  :
317            borderTypeNI == cv::BORDER_REPLICATE   ? ippBorderRepl    :
318            borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror  :
319            (IppiBorderType)-1;
320 }
321 
ippiGetMaskSize(int kx,int ky)322 static inline IppiMaskSize ippiGetMaskSize(int kx, int ky)
323 {
324     return (kx == 1 && ky == 3) ? ippMskSize1x3 :
325            (kx == 1 && ky == 5) ? ippMskSize1x5 :
326            (kx == 3 && ky == 1) ? ippMskSize3x1 :
327            (kx == 3 && ky == 3) ? ippMskSize3x3 :
328            (kx == 5 && ky == 1) ? ippMskSize5x1 :
329            (kx == 5 && ky == 5) ? ippMskSize5x5 :
330            (IppiMaskSize)-1;
331 }
332 
ippiGetDataType(int depth)333 static inline IppDataType ippiGetDataType(int depth)
334 {
335     depth = CV_MAT_DEPTH(depth);
336     return depth == CV_8U ? ipp8u :
337         depth == CV_8S ? ipp8s :
338         depth == CV_16U ? ipp16u :
339         depth == CV_16S ? ipp16s :
340         depth == CV_32S ? ipp32s :
341         depth == CV_32F ? ipp32f :
342         depth == CV_64F ? ipp64f :
343         (IppDataType)-1;
344 }
345 
ippiSuggestThreadsNum(size_t width,size_t height,size_t elemSize,double multiplier)346 static inline int ippiSuggestThreadsNum(size_t width, size_t height, size_t elemSize, double multiplier)
347 {
348     int threads = cv::getNumThreads();
349     if(threads > 1 && height >= 64)
350     {
351         size_t opMemory = (int)(width*height*elemSize*multiplier);
352         int l2cache = 0;
353 #if IPP_VERSION_X100 >= 201700
354         ippGetL2CacheSize(&l2cache);
355 #endif
356         if(!l2cache)
357             l2cache = 1 << 18;
358 
359         return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
360     }
361     return 1;
362 }
363 
ippiSuggestThreadsNum(const cv::Mat & image,double multiplier)364 static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier)
365 {
366     return ippiSuggestThreadsNum(image.cols, image.rows, image.elemSize(), multiplier);
367 }
368 
369 #ifdef HAVE_IPP_IW
ippiCheckAnchor(int x,int y,int kernelWidth,int kernelHeight)370 static inline bool ippiCheckAnchor(int x, int y, int kernelWidth, int kernelHeight)
371 {
372     if(x != ((kernelWidth-1)/2) || y != ((kernelHeight-1)/2))
373         return 0;
374     else
375         return 1;
376 }
377 
ippiGetSize(const cv::Size & size)378 static inline ::ipp::IwiSize ippiGetSize(const cv::Size & size)
379 {
380     return ::ipp::IwiSize((IwSize)size.width, (IwSize)size.height);
381 }
382 
ippiGetDerivType(int dx,int dy,bool nvert)383 static inline IwiDerivativeType ippiGetDerivType(int dx, int dy, bool nvert)
384 {
385     return (dx == 1 && dy == 0) ? ((nvert)?iwiDerivNVerFirst:iwiDerivVerFirst) :
386            (dx == 0 && dy == 1) ? iwiDerivHorFirst :
387            (dx == 2 && dy == 0) ? iwiDerivVerSecond :
388            (dx == 0 && dy == 2) ? iwiDerivHorSecond :
389            (IwiDerivativeType)-1;
390 }
391 
ippiGetImage(const cv::Mat & src,::ipp::IwiImage & dst)392 static inline void ippiGetImage(const cv::Mat &src, ::ipp::IwiImage &dst)
393 {
394     ::ipp::IwiBorderSize inMemBorder;
395     if(src.isSubmatrix()) // already have physical border
396     {
397         cv::Size  origSize;
398         cv::Point offset;
399         src.locateROI(origSize, offset);
400 
401         inMemBorder.left   = (IwSize)offset.x;
402         inMemBorder.top    = (IwSize)offset.y;
403         inMemBorder.right  = (IwSize)(origSize.width - src.cols - offset.x);
404         inMemBorder.bottom = (IwSize)(origSize.height - src.rows - offset.y);
405     }
406 
407     dst.Init(ippiSize(src.size()), ippiGetDataType(src.depth()), src.channels(), inMemBorder, (void*)src.ptr(), src.step);
408 }
409 
ippiGetImage(const cv::Mat & src)410 static inline ::ipp::IwiImage ippiGetImage(const cv::Mat &src)
411 {
412     ::ipp::IwiImage image;
413     ippiGetImage(src, image);
414     return image;
415 }
416 
ippiGetBorder(::ipp::IwiImage & image,int ocvBorderType,ipp::IwiBorderSize & borderSize)417 static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorderType, ipp::IwiBorderSize &borderSize)
418 {
419     int            inMemFlags = 0;
420     IppiBorderType border     = ippiGetBorderType(ocvBorderType & ~cv::BORDER_ISOLATED);
421     if((int)border == -1)
422         return (IppiBorderType)0;
423 
424     if(!(ocvBorderType & cv::BORDER_ISOLATED))
425     {
426         if(image.m_inMemSize.left)
427         {
428             if(image.m_inMemSize.left >= borderSize.left)
429                 inMemFlags |= ippBorderInMemLeft;
430             else
431                 return (IppiBorderType)0;
432         }
433         else
434             borderSize.left = 0;
435         if(image.m_inMemSize.top)
436         {
437             if(image.m_inMemSize.top >= borderSize.top)
438                 inMemFlags |= ippBorderInMemTop;
439             else
440                 return (IppiBorderType)0;
441         }
442         else
443             borderSize.top = 0;
444         if(image.m_inMemSize.right)
445         {
446             if(image.m_inMemSize.right >= borderSize.right)
447                 inMemFlags |= ippBorderInMemRight;
448             else
449                 return (IppiBorderType)0;
450         }
451         else
452             borderSize.right = 0;
453         if(image.m_inMemSize.bottom)
454         {
455             if(image.m_inMemSize.bottom >= borderSize.bottom)
456                 inMemFlags |= ippBorderInMemBottom;
457             else
458                 return (IppiBorderType)0;
459         }
460         else
461             borderSize.bottom = 0;
462     }
463     else
464         borderSize.left = borderSize.right = borderSize.top = borderSize.bottom = 0;
465 
466     return (IppiBorderType)(border|inMemFlags);
467 }
468 
ippiGetValue(const cv::Scalar & scalar)469 static inline ::ipp::IwValueFloat ippiGetValue(const cv::Scalar &scalar)
470 {
471     return ::ipp::IwValueFloat(scalar[0], scalar[1], scalar[2], scalar[3]);
472 }
473 
ippiSuggestThreadsNum(const::ipp::IwiImage & image,double multiplier)474 static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
475 {
476     return ippiSuggestThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, multiplier);
477 }
478 #endif
479 
480 // IPP temporary buffer helper
481 template<typename T>
482 class IppAutoBuffer
483 {
484 public:
IppAutoBuffer()485     IppAutoBuffer() { m_size = 0; m_pBuffer = NULL; }
IppAutoBuffer(size_t size)486     explicit IppAutoBuffer(size_t size) { m_size = 0; m_pBuffer = NULL; allocate(size); }
~IppAutoBuffer()487     ~IppAutoBuffer() { deallocate(); }
allocate(size_t size)488     T* allocate(size_t size)   { if(m_size < size) { deallocate(); m_pBuffer = (T*)CV_IPP_MALLOC(size); m_size = size; } return m_pBuffer; }
deallocate()489     void deallocate() { if(m_pBuffer) { ippFree(m_pBuffer); m_pBuffer = NULL; } m_size = 0; }
get()490     inline T* get() { return (T*)m_pBuffer;}
operator T*()491     inline operator T* () { return (T*)m_pBuffer;}
operator const T*() const492     inline operator const T* () const { return (const T*)m_pBuffer;}
493 private:
494     // Disable copy operations
IppAutoBuffer(IppAutoBuffer &)495     IppAutoBuffer(IppAutoBuffer &) {}
operator =(const IppAutoBuffer &)496     IppAutoBuffer& operator =(const IppAutoBuffer &) {return *this;}
497 
498     size_t m_size;
499     T*     m_pBuffer;
500 };
501 
502 // Extracts border interpolation type without flags
503 #if IPP_VERSION_X100 >= 201700
504 #define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF|((((BORDER)&ippBorderInMem) == ippBorderInMem)?ippBorderInMem:0));
505 #else
506 #define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF);
507 #endif
508 
509 #else
510 #define IPP_VERSION_X100 0
511 #endif
512 
513 #if defined HAVE_IPP
514 #if IPP_VERSION_X100 >= 900
515 #define IPP_INITIALIZER(FEAT)                           \
516 {                                                       \
517     if(FEAT)                                            \
518         ippSetCpuFeatures(FEAT);                        \
519     else                                                \
520         ippInit();                                      \
521 }
522 #elif IPP_VERSION_X100 >= 800
523 #define IPP_INITIALIZER(FEAT)                           \
524 {                                                       \
525     ippInit();                                          \
526 }
527 #else
528 #define IPP_INITIALIZER(FEAT)                           \
529 {                                                       \
530     ippStaticInit();                                    \
531 }
532 #endif
533 
534 #ifdef CVAPI_EXPORTS
535 #define IPP_INITIALIZER_AUTO                            \
536 struct __IppInitializer__                               \
537 {                                                       \
538     __IppInitializer__()                                \
539     {IPP_INITIALIZER(cv::ipp::getIppFeatures())}        \
540 };                                                      \
541 static struct __IppInitializer__ __ipp_initializer__;
542 #else
543 #define IPP_INITIALIZER_AUTO
544 #endif
545 #else
546 #define IPP_INITIALIZER
547 #define IPP_INITIALIZER_AUTO
548 #endif
549 
550 #define CV_IPP_CHECK_COND (cv::ipp::useIPP())
551 #define CV_IPP_CHECK() if(CV_IPP_CHECK_COND)
552 
553 #ifdef HAVE_IPP
554 
555 #ifdef CV_IPP_RUN_VERBOSE
556 #define CV_IPP_RUN_(condition, func, ...)                                   \
557     {                                                                       \
558         if (cv::ipp::useIPP() && (condition) && (func))                     \
559         {                                                                   \
560             printf("%s: IPP implementation is running\n", CV_Func);         \
561             fflush(stdout);                                                 \
562             CV_IMPL_ADD(CV_IMPL_IPP);                                       \
563             return __VA_ARGS__;                                             \
564         }                                                                   \
565         else                                                                \
566         {                                                                   \
567             printf("%s: Plain implementation is running\n", CV_Func);       \
568             fflush(stdout);                                                 \
569         }                                                                   \
570     }
571 #elif defined CV_IPP_RUN_ASSERT
572 #define CV_IPP_RUN_(condition, func, ...)                                   \
573     {                                                                       \
574         if (cv::ipp::useIPP() && (condition))                               \
575         {                                                                   \
576             CV__TRACE_REGION_("IPP:" #func, CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP) \
577             if(func)                                                        \
578             {                                                               \
579                 CV_IMPL_ADD(CV_IMPL_IPP);                                   \
580             }                                                               \
581             else                                                            \
582             {                                                               \
583                 setIppErrorStatus();                                        \
584                 CV_Error(cv::Error::StsAssert, #func);                      \
585             }                                                               \
586             return __VA_ARGS__;                                             \
587         }                                                                   \
588     }
589 #else
590 #define CV_IPP_RUN_(condition, func, ...)                                   \
591         if (cv::ipp::useIPP() && (condition))                               \
592         {                                                                   \
593             CV__TRACE_REGION_("IPP:" #func, CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP) \
594             if(func)                                                        \
595             {                                                               \
596                 CV_IMPL_ADD(CV_IMPL_IPP);                                   \
597                 return __VA_ARGS__;                                         \
598             }                                                               \
599         }
600 #endif
601 #else
602 #define CV_IPP_RUN_(condition, func, ...)
603 #endif
604 
605 #define CV_IPP_RUN_FAST(func, ...) CV_IPP_RUN_(true, func, __VA_ARGS__)
606 #define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_((condition), (func), __VA_ARGS__)
607 
608 
609 #ifndef IPPI_CALL
610 #  define IPPI_CALL(func) CV_Assert((func) >= 0)
611 #endif
612 
613 /* IPP-compatible return codes */
614 typedef enum CvStatus
615 {
616     CV_BADMEMBLOCK_ERR          = -113,
617     CV_INPLACE_NOT_SUPPORTED_ERR= -112,
618     CV_UNMATCHED_ROI_ERR        = -111,
619     CV_NOTFOUND_ERR             = -110,
620     CV_BADCONVERGENCE_ERR       = -109,
621 
622     CV_BADDEPTH_ERR             = -107,
623     CV_BADROI_ERR               = -106,
624     CV_BADHEADER_ERR            = -105,
625     CV_UNMATCHED_FORMATS_ERR    = -104,
626     CV_UNSUPPORTED_COI_ERR      = -103,
627     CV_UNSUPPORTED_CHANNELS_ERR = -102,
628     CV_UNSUPPORTED_DEPTH_ERR    = -101,
629     CV_UNSUPPORTED_FORMAT_ERR   = -100,
630 
631     CV_BADARG_ERR               = -49,  //ipp comp
632     CV_NOTDEFINED_ERR           = -48,  //ipp comp
633 
634     CV_BADCHANNELS_ERR          = -47,  //ipp comp
635     CV_BADRANGE_ERR             = -44,  //ipp comp
636     CV_BADSTEP_ERR              = -29,  //ipp comp
637 
638     CV_BADFLAG_ERR              =  -12,
639     CV_DIV_BY_ZERO_ERR          =  -11, //ipp comp
640     CV_BADCOEF_ERR              =  -10,
641 
642     CV_BADFACTOR_ERR            =  -7,
643     CV_BADPOINT_ERR             =  -6,
644     CV_BADSCALE_ERR             =  -4,
645     CV_OUTOFMEM_ERR             =  -3,
646     CV_NULLPTR_ERR              =  -2,
647     CV_BADSIZE_ERR              =  -1,
648     CV_NO_ERR                   =   0,
649     CV_OK                       =   CV_NO_ERR
650 }
651 CvStatus;
652 
653 #ifdef ENABLE_INSTRUMENTATION
654 namespace cv
655 {
656 namespace instr
657 {
658 struct InstrTLSStruct
659 {
InstrTLSStructcv::instr::InstrTLSStruct660     InstrTLSStruct()
661     {
662         pCurrentNode = NULL;
663     }
664     InstrNode* pCurrentNode;
665 };
666 
667 class InstrStruct
668 {
669 public:
InstrStruct()670     InstrStruct()
671     {
672         useInstr    = false;
673         flags       = FLAGS_MAPPING;
674         maxDepth    = 0;
675 
676         rootNode.m_payload = NodeData("ROOT", NULL, 0, NULL, false, TYPE_GENERAL, IMPL_PLAIN);
677         tlsStruct.get()->pCurrentNode = &rootNode;
678     }
679 
680     Mutex mutexCreate;
681     Mutex mutexCount;
682 
683     bool       useInstr;
684     int        flags;
685     int        maxDepth;
686     InstrNode  rootNode;
687     TLSData<InstrTLSStruct> tlsStruct;
688 };
689 
690 class CV_EXPORTS IntrumentationRegion
691 {
692 public:
693     IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType = TYPE_GENERAL, IMPL implType = IMPL_PLAIN);
694     ~IntrumentationRegion();
695 
696 private:
697     bool    m_disabled; // region status
698     uint64  m_regionTicks;
699 };
700 
701 CV_EXPORTS InstrStruct& getInstrumentStruct();
702 InstrTLSStruct&         getInstrumentTLSStruct();
703 CV_EXPORTS InstrNode*   getCurrentNode();
704 }
705 }
706 
707 #ifdef _WIN32
708 #define CV_INSTRUMENT_GET_RETURN_ADDRESS _ReturnAddress()
709 #else
710 #define CV_INSTRUMENT_GET_RETURN_ADDRESS __builtin_extract_return_addr(__builtin_return_address(0))
711 #endif
712 
713 // Instrument region
714 #define CV_INSTRUMENT_REGION_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)        ::cv::instr::IntrumentationRegion  CVAUX_CONCAT(__instr_region__, __LINE__) (NAME, __FILE__, __LINE__, CV_INSTRUMENT_GET_RETURN_ADDRESS, ALWAYS_EXPAND, TYPE, IMPL);
715 #define CV_INSTRUMENT_REGION_CUSTOM_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)\
716     void *CVAUX_CONCAT(__curr_address__, __LINE__) = [&]() {return CV_INSTRUMENT_GET_RETURN_ADDRESS;}();\
717     ::cv::instr::IntrumentationRegion CVAUX_CONCAT(__instr_region__, __LINE__) (NAME, __FILE__, __LINE__, CVAUX_CONCAT(__curr_address__, __LINE__), false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
718 // Instrument functions with non-void return type
719 #define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]()\
720 {\
721     if(::cv::instr::useInstrumentation()){\
722         ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
723         try{\
724             auto instrStatus = ((FUN)(__VA_ARGS__));\
725             if(ERROR_COND){\
726                 ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
727                 CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
728             }\
729             return instrStatus;\
730         }catch(...){\
731             ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
732             CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
733             throw;\
734         }\
735     }else{\
736         return ((FUN)(__VA_ARGS__));\
737     }\
738 }())
739 // Instrument functions with void return type
740 #define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]()\
741 {\
742     if(::cv::instr::useInstrumentation()){\
743         ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
744         try{\
745             (FUN)(__VA_ARGS__);\
746         }catch(...){\
747             ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
748             CV_INSTRUMENT_MARK_META(IMPL, #FUN "- BadExit");\
749             throw;\
750         }\
751     }else{\
752         (FUN)(__VA_ARGS__);\
753     }\
754 }())
755 // Instrumentation information marker
756 #define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(NAME, __FILE__, __LINE__, NULL, false, ::cv::instr::TYPE_MARKER, IMPL);}
757 
758 ///// General instrumentation
759 // General OpenCV region instrumentation macro
760 #define CV_INSTRUMENT_REGION_();             CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
761 // Custom OpenCV region instrumentation macro
762 #define CV_INSTRUMENT_REGION_NAME(NAME)     CV_INSTRUMENT_REGION_CUSTOM_META(NAME,  false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
763 // Instrumentation for parallel_for_ or other regions which forks and gathers threads
764 #define CV_INSTRUMENT_REGION_MT_FORK();      CV_INSTRUMENT_REGION_META(__FUNCTION__, true,  ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
765 
766 ///// IPP instrumentation
767 // Wrapper region instrumentation macro
768 #define CV_INSTRUMENT_REGION_IPP();          CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
769 // Function instrumentation macro
770 #define CV_INSTRUMENT_FUN_IPP(FUN, ...)     CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, instrStatus < 0, FUN, __VA_ARGS__)
771 // Diagnostic markers
772 #define CV_INSTRUMENT_MARK_IPP(NAME)        CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)
773 
774 ///// OpenCL instrumentation
775 // Wrapper region instrumentation macro
776 #define CV_INSTRUMENT_REGION_OPENCL();              CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
777 // OpenCL kernel compilation wrapper
778 #define CV_INSTRUMENT_REGION_OPENCL_COMPILE(NAME)  CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
779 // OpenCL kernel run wrapper
780 #define CV_INSTRUMENT_REGION_OPENCL_RUN(NAME)      CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_FUN, ::cv::instr::IMPL_OPENCL)
781 // Diagnostic markers
782 #define CV_INSTRUMENT_MARK_OPENCL(NAME)            CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_OPENCL, NAME)
783 #else
784 #define CV_INSTRUMENT_REGION_META(...)
785 
786 #define CV_INSTRUMENT_REGION_();                            CV_TRACE_FUNCTION()
787 #define CV_INSTRUMENT_REGION_NAME(...)                     CV_TRACE_REGION(__VA_ARGS__)
788 #define CV_INSTRUMENT_REGION_MT_FORK();
789 
790 #define CV_INSTRUMENT_REGION_IPP();                         CV__TRACE_REGION_("IPP", CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP)
791 #define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
792 #define CV_INSTRUMENT_MARK_IPP(...)
793 
794 #define CV_INSTRUMENT_REGION_OPENCL();                      CV__TRACE_REGION_("OpenCL", CV_TRACE_NS::details::REGION_FLAG_IMPL_OPENCL)
795 #define CV_INSTRUMENT_REGION_OPENCL_COMPILE(...)
796 #define CV_INSTRUMENT_REGION_OPENCL_RUN(...)
797 #define CV_INSTRUMENT_MARK_OPENCL(...)
798 #endif
799 
800 #ifdef __CV_AVX_GUARD
801 #define CV_INSTRUMENT_REGION() __CV_AVX_GUARD CV_INSTRUMENT_REGION_();
802 #else
803 #define CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION_();
804 #endif
805 
806 namespace cv {
807 
808 namespace utils {
809 
810 //! @addtogroup core_utils
811 //! @{
812 
813 /** @brief Try to find requested data file
814 
815 Search directories:
816 
817 1. Directories passed via `addDataSearchPath()`
818 2. Check path specified by configuration parameter with "_HINT" suffix (name of environment variable).
819 3. Check path specified by configuration parameter (name of environment variable).
820    If parameter value is not empty and nothing is found then stop searching.
821 4. Detects build/install path based on:
822    a. current working directory (CWD)
823    b. and/or binary module location (opencv_core/opencv_world, doesn't work with static linkage)
824 5. Scan `<source>/{,data}` directories if build directory is detected or the current directory is in source tree.
825 6. Scan `<install>/share/OpenCV` directory if install directory is detected.
826 
827 @param relative_path Relative path to data file
828 @param required Specify "file not found" handling.
829        If true, function prints information message and raises cv::Exception.
830        If false, function returns empty result
831 @param configuration_parameter specify configuration parameter name. Default NULL value means "OPENCV_DATA_PATH".
832 @return Returns path (absolute or relative to the current directory) or empty string if file is not found
833 
834 @note Implementation is not thread-safe.
835 */
836 CV_EXPORTS
837 cv::String findDataFile(const cv::String& relative_path, bool required = true,
838                         const char* configuration_parameter = NULL);
839 
840 /** @overload
841 @param relative_path Relative path to data file
842 @param configuration_parameter specify configuration parameter name. Default NULL value means "OPENCV_DATA_PATH".
843 @param search_paths override addDataSearchPath() settings.
844 @param subdir_paths override addDataSearchSubDirectory() settings.
845 @return Returns path (absolute or relative to the current directory) or empty string if file is not found
846 
847 @note Implementation is not thread-safe.
848 */
849 CV_EXPORTS
850 cv::String findDataFile(const cv::String& relative_path,
851                         const char* configuration_parameter,
852                         const std::vector<String>* search_paths,
853                         const std::vector<String>* subdir_paths);
854 
855 /** @brief Override default search data path by adding new search location
856 
857 Use this only to override default behavior
858 Passed paths are used in LIFO order.
859 
860 @param path Path to used samples data
861 
862 @note Implementation is not thread-safe.
863 */
864 CV_EXPORTS void addDataSearchPath(const cv::String& path);
865 
866 /** @brief Append default search data sub directory
867 
868 General usage is to add OpenCV modules name (`<opencv_contrib>/modules/<name>/data` -> `modules/<name>/data` + `<name>/data`).
869 Passed subdirectories are used in LIFO order.
870 
871 @param subdir samples data sub directory
872 
873 @note Implementation is not thread-safe.
874 */
875 CV_EXPORTS void addDataSearchSubDirectory(const cv::String& subdir);
876 
877 /** @brief Retrieve location of OpenCV libraries or current executable
878  */
879 CV_EXPORTS bool getBinLocation(std::string& dst);
880 
881 #if defined(_WIN32)
882 /** @brief Retrieve location of OpenCV libraries or current executable
883 
884 @note WIN32 only
885  */
886 CV_EXPORTS bool getBinLocation(std::wstring& dst);
887 #endif
888 
889 //! @}
890 
891 } // namespace utils
892 } // namespace cv
893 
894 //! @endcond
895 
896 #endif // OPENCV_CORE_PRIVATE_HPP
897