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