private.hpp 33.0 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
10
//                          License Agreement
11 12 13 14
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

S
sourin 已提交
44 45
#ifndef OPENCV_CORE_PRIVATE_HPP
#define OPENCV_CORE_PRIVATE_HPP
46

47 48
#ifndef __OPENCV_BUILD
#  error this is a private header which should not be used from outside of the OpenCV library
49 50
#endif

51 52 53
#include "opencv2/core.hpp"
#include "cvconfig.h"

54 55
#include <opencv2/core/utils/trace.hpp>

56 57 58 59
#ifdef ENABLE_INSTRUMENTATION
#include "opencv2/core/utils/instrumentation.hpp"
#endif

60 61 62 63
#ifdef HAVE_EIGEN
#  if defined __GNUC__ && defined __APPLE__
#    pragma GCC diagnostic ignored "-Wshadow"
#  endif
64 65 66 67 68 69
#  if defined(_MSC_VER)
#    pragma warning(push)
#    pragma warning(disable:4701)  // potentially uninitialized local variable
#    pragma warning(disable:4702)  // unreachable code
#    pragma warning(disable:4714)  // const marked as __forceinline not inlined
#  endif
70
#  include <Eigen/Core>
71 72 73
#  if defined(_MSC_VER)
#    pragma warning(pop)
#  endif
74
#  include "opencv2/core/eigen.hpp"
75 76
#endif

77 78
//! @cond IGNORED

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
namespace cv
{
    class BlockedRange
    {
    public:
        BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
        BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
        int begin() const { return _begin; }
        int end() const { return _end; }
        int grainsize() const { return _grainsize; }

    protected:
        int _begin, _end, _grainsize;
    };

    template<typename Body> static inline
    void parallel_for( const BlockedRange& range, const Body& body )
96
    {
97 98 99 100 101 102 103 104 105 106
        body(range);
    }
    typedef std::vector<Rect> ConcurrentRectVector;

    class Split {};

    template<typename Body> static inline
    void parallel_reduce( const BlockedRange& range, Body& body )
    {
        body(range);
107
    }
108 109 110 111

    // Returns a static string if there is a parallel framework,
    // NULL otherwise.
    CV_EXPORTS const char* currentParallelFramework();
112
} //namespace cv
113

114 115 116 117
/****************************************************************************************\
*                                  Common declarations                                   *
\****************************************************************************************/

118
/* the alignment of all the allocated buffers */
119
#define  CV_MALLOC_ALIGN    64
120

121 122
/* IEEE754 constants and macros */
#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

125
static inline void* cvAlignPtr( const void* ptr, int align = 32 )
126
{
127
    CV_DbgAssert ( (align & (align-1)) == 0 );
128 129 130
    return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
}

131
static inline int cvAlign( int size, int align )
132
{
133
    CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX );
134 135 136
    return (size + align - 1) & -align;
}

137
#ifdef IPL_DEPTH_8U
138
static inline cv::Size cvGetMatSize( const CvMat* mat )
139
{
140
    return cv::Size(mat->cols, mat->rows);
141
}
142
#endif
143

144 145 146
namespace cv
{
CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
M
Maksim Shabunin 已提交
147

148
//! Allocate memory buffers which will not be freed, ease filtering memcheck issues. Uses fastMalloc() call.
149 150
CV_EXPORTS void* allocSingletonBuffer(size_t size);

151
//! Allocate memory buffers which will not be freed, ease filtering memcheck issues. Uses fastMalloc() call
152 153 154
template <typename T> static inline
T* allocSingleton(size_t count = 1) { return static_cast<T*>(allocSingletonBuffer(sizeof(T) * count)); }

155 156 157 158 159 160 161
//! Allocate memory buffers which will not be freed, ease filtering memcheck issues. Uses generic malloc() call.
CV_EXPORTS void* allocSingletonNewBuffer(size_t size);

//! Allocate memory buffers which will not be freed, ease filtering memcheck issues.  Uses generic malloc() call.
template <typename T> static inline
T* allocSingletonNew() { return new(allocSingletonNewBuffer(sizeof(T))) T(); }

162
} // namespace
163

164 165
#if 1 // TODO: Remove in OpenCV 4.x

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
// property implementation macros

#define CV_IMPL_PROPERTY_RO(type, name, member) \
    inline type get##name() const { return member; }

#define CV_HELP_IMPL_PROPERTY(r_type, w_type, name, member) \
    CV_IMPL_PROPERTY_RO(r_type, name, member) \
    inline void set##name(w_type val) { member = val; }

#define CV_HELP_WRAP_PROPERTY(r_type, w_type, name, internal_name, internal_obj) \
    r_type get##name() const { return internal_obj.get##internal_name(); } \
    void set##name(w_type val) { internal_obj.set##internal_name(val); }

#define CV_IMPL_PROPERTY(type, name, member) CV_HELP_IMPL_PROPERTY(type, type, name, member)
#define CV_IMPL_PROPERTY_S(type, name, member) CV_HELP_IMPL_PROPERTY(type, const type &, name, member)

#define CV_WRAP_PROPERTY(type, name, internal_name, internal_obj)  CV_HELP_WRAP_PROPERTY(type, type, name, internal_name, internal_obj)
#define CV_WRAP_PROPERTY_S(type, name, internal_name, internal_obj) CV_HELP_WRAP_PROPERTY(type, const type &, name, internal_name, internal_obj)

#define CV_WRAP_SAME_PROPERTY(type, name, internal_obj) CV_WRAP_PROPERTY(type, name, name, internal_obj)
#define CV_WRAP_SAME_PROPERTY_S(type, name, internal_obj) CV_WRAP_PROPERTY_S(type, name, name, internal_obj)
187

188 189
#endif

190 191 192 193
/****************************************************************************************\
*                     Structures and macros for integration with IPP                     *
\****************************************************************************************/

194 195
#define OPENCV_IPP_REDUCE_SIZE 1

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
// Temporary disabled named IPP region. Accuracy
#define IPP_DISABLE_PYRAMIDS_UP         1 // Different results
#define IPP_DISABLE_PYRAMIDS_DOWN       1 // Different results
#define IPP_DISABLE_PYRAMIDS_BUILD      1 // Different results
#define IPP_DISABLE_WARPAFFINE          1 // Different results
#define IPP_DISABLE_WARPPERSPECTIVE     1 // Different results
#define IPP_DISABLE_REMAP               1 // Different results
#define IPP_DISABLE_YUV_RGB             1 // accuracy difference
#define IPP_DISABLE_RGB_YUV             1 // breaks OCL accuracy tests
#define IPP_DISABLE_RGB_HSV             1 // breaks OCL accuracy tests
#define IPP_DISABLE_RGB_LAB             1 // breaks OCL accuracy tests
#define IPP_DISABLE_LAB_RGB             1 // breaks OCL accuracy tests
#define IPP_DISABLE_RGB_XYZ             1 // big accuracy difference
#define IPP_DISABLE_XYZ_RGB             1 // big accuracy difference
#define IPP_DISABLE_HOUGH               1 // improper integration/results
M
maver1 已提交
211
#define IPP_DISABLE_FILTER2D_BIG_MASK   1 // different results on masks > 7x7
212

213 214 215 216 217 218 219 220
// Temporary disabled named IPP region. Performance
#define IPP_DISABLE_PERF_COPYMAKE       1 // performance variations
#define IPP_DISABLE_PERF_LUT            1 // there are no performance benefits (PR #2653)
#define IPP_DISABLE_PERF_TRUE_DIST_MT   1 // cv::distanceTransform OpenCV MT performance is better
#define IPP_DISABLE_PERF_CANNY_MT       1 // cv::Canny OpenCV MT performance is better

#ifdef HAVE_IPP
#include "ippversion.h"
P
Pavel Vlasov 已提交
221 222 223 224 225 226
#ifndef IPP_VERSION_UPDATE // prior to 7.1
#define IPP_VERSION_UPDATE 0
#endif

#define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)

P
Pavel Vlasov 已提交
227
#ifdef HAVE_IPP_ICV
228 229 230 231 232 233 234 235 236 237
#define ICV_BASE
#if IPP_VERSION_X100 >= 201700
#include "ippicv.h"
#else
#include "ipp.h"
#endif
#else
#include "ipp.h"
#endif
#ifdef HAVE_IPP_IW
M
Maksim Shabunin 已提交
238 239 240 241
#  if defined(__OPENCV_BUILD) && defined(__clang__)
#  pragma clang diagnostic push
#  pragma clang diagnostic ignored "-Wstrict-prototypes"
#  endif
242 243 244 245
#  if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wsuggest-override"
#  endif
246
#include "iw++/iw.hpp"
M
maver1 已提交
247
#  ifdef HAVE_IPP_IW_LL
P
Pavel Vlasov 已提交
248
#include "iw/iw_ll.h"
M
maver1 已提交
249
#  endif
250 251 252
#  if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
#  pragma GCC diagnostic pop
#  endif
M
Maksim Shabunin 已提交
253 254 255
#  if defined(__OPENCV_BUILD) && defined(__clang__)
#  pragma clang diagnostic pop
#  endif
256
#endif
257

258 259 260 261 262 263
#if IPP_VERSION_X100 >= 201700
#define CV_IPP_MALLOC(SIZE) ippMalloc_L(SIZE)
#else
#define CV_IPP_MALLOC(SIZE) ippMalloc((int)SIZE)
#endif

I
Ilya Lavrenov 已提交
264 265
#define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)

266
#if IPP_VERSION_X100 >= 201700
P
Pavel Vlasov 已提交
267 268
#define ippCPUID_AVX512_SKX (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ)
#define ippCPUID_AVX512_KNL (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512PF|ippCPUID_AVX512ER)
269 270 271 272
#else
#define ippCPUID_AVX512_SKX 0xFFFFFFFF
#define ippCPUID_AVX512_KNL 0xFFFFFFFF
#endif
P
Pavel Vlasov 已提交
273 274 275 276 277 278 279 280 281

namespace cv
{
namespace ipp
{
CV_EXPORTS   unsigned long long getIppTopFeatures(); // Returns top major enabled IPP feature flag
}
}

282
static inline IppiSize ippiSize(size_t width, size_t height)
283
{
284
    IppiSize size = { (int)width, (int)height };
285 286
    return size;
}
I
Ilya Lavrenov 已提交
287 288 289 290 291 292 293

static inline IppiSize ippiSize(const cv::Size & _size)
{
    IppiSize size = { _size.width, _size.height };
    return size;
}

294 295 296 297 298 299 300 301 302 303 304 305 306 307
#if IPP_VERSION_X100 >= 201700
static inline IppiSizeL ippiSizeL(size_t width, size_t height)
{
    IppiSizeL size = { (IppSizeL)width, (IppSizeL)height };
    return size;
}

static inline IppiSizeL ippiSizeL(const cv::Size & _size)
{
    IppiSizeL size = { _size.width, _size.height };
    return size;
}
#endif

308 309 310 311 312 313 314 315 316 317 318 319
static inline IppiPoint ippiPoint(const cv::Point & _point)
{
    IppiPoint point = { _point.x, _point.y };
    return point;
}

static inline IppiPoint ippiPoint(int x, int y)
{
    IppiPoint point = { x, y };
    return point;
}

I
Ilya Lavrenov 已提交
320 321
static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
{
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
    return borderTypeNI == cv::BORDER_CONSTANT    ? ippBorderConst   :
           borderTypeNI == cv::BORDER_TRANSPARENT ? ippBorderTransp  :
           borderTypeNI == cv::BORDER_REPLICATE   ? ippBorderRepl    :
           borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror  :
           (IppiBorderType)-1;
}

static inline IppiMaskSize ippiGetMaskSize(int kx, int ky)
{
    return (kx == 1 && ky == 3) ? ippMskSize1x3 :
           (kx == 1 && ky == 5) ? ippMskSize1x5 :
           (kx == 3 && ky == 1) ? ippMskSize3x1 :
           (kx == 3 && ky == 3) ? ippMskSize3x3 :
           (kx == 5 && ky == 1) ? ippMskSize5x1 :
           (kx == 5 && ky == 5) ? ippMskSize5x5 :
           (IppiMaskSize)-1;
I
Ilya Lavrenov 已提交
338 339
}

340 341
static inline IppDataType ippiGetDataType(int depth)
{
342
    depth = CV_MAT_DEPTH(depth);
343 344 345 346 347 348
    return depth == CV_8U ? ipp8u :
        depth == CV_8S ? ipp8s :
        depth == CV_16U ? ipp16u :
        depth == CV_16S ? ipp16s :
        depth == CV_32S ? ipp32s :
        depth == CV_32F ? ipp32f :
349 350
        depth == CV_64F ? ipp64f :
        (IppDataType)-1;
351 352
}

P
Pavel Vlasov 已提交
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
static inline int ippiSuggestThreadsNum(size_t width, size_t height, size_t elemSize, double multiplier)
{
    int threads = cv::getNumThreads();
    if(threads > 1 && height >= 64)
    {
        size_t opMemory = (int)(width*height*elemSize*multiplier);
        int l2cache = 0;
#if IPP_VERSION_X100 >= 201700
        ippGetL2CacheSize(&l2cache);
#endif
        if(!l2cache)
            l2cache = 1 << 18;

        return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
    }
    return 1;
}

static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier)
{
    return ippiSuggestThreadsNum(image.cols, image.rows, image.elemSize(), multiplier);
}

376
#ifdef HAVE_IPP_IW
P
Pavel Vlasov 已提交
377 378 379 380 381 382 383 384 385 386 387 388 389
static inline bool ippiCheckAnchor(int x, int y, int kernelWidth, int kernelHeight)
{
    if(x != ((kernelWidth-1)/2) || y != ((kernelHeight-1)/2))
        return 0;
    else
        return 1;
}

static inline ::ipp::IwiSize ippiGetSize(const cv::Size & size)
{
    return ::ipp::IwiSize((IwSize)size.width, (IwSize)size.height);
}

390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
static inline IwiDerivativeType ippiGetDerivType(int dx, int dy, bool nvert)
{
    return (dx == 1 && dy == 0) ? ((nvert)?iwiDerivNVerFirst:iwiDerivVerFirst) :
           (dx == 0 && dy == 1) ? iwiDerivHorFirst :
           (dx == 2 && dy == 0) ? iwiDerivVerSecond :
           (dx == 0 && dy == 2) ? iwiDerivHorSecond :
           (IwiDerivativeType)-1;
}

static inline void ippiGetImage(const cv::Mat &src, ::ipp::IwiImage &dst)
{
    ::ipp::IwiBorderSize inMemBorder;
    if(src.isSubmatrix()) // already have physical border
    {
        cv::Size  origSize;
        cv::Point offset;
        src.locateROI(origSize, offset);

P
Pavel Vlasov 已提交
408 409 410 411
        inMemBorder.left   = (IwSize)offset.x;
        inMemBorder.top    = (IwSize)offset.y;
        inMemBorder.right  = (IwSize)(origSize.width - src.cols - offset.x);
        inMemBorder.bottom = (IwSize)(origSize.height - src.rows - offset.y);
412 413 414 415 416 417 418 419 420 421 422 423
    }

    dst.Init(ippiSize(src.size()), ippiGetDataType(src.depth()), src.channels(), inMemBorder, (void*)src.ptr(), src.step);
}

static inline ::ipp::IwiImage ippiGetImage(const cv::Mat &src)
{
    ::ipp::IwiImage image;
    ippiGetImage(src, image);
    return image;
}

P
Pavel Vlasov 已提交
424
static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorderType, ipp::IwiBorderSize &borderSize)
425 426 427 428 429 430 431 432
{
    int            inMemFlags = 0;
    IppiBorderType border     = ippiGetBorderType(ocvBorderType & ~cv::BORDER_ISOLATED);
    if((int)border == -1)
        return (IppiBorderType)0;

    if(!(ocvBorderType & cv::BORDER_ISOLATED))
    {
P
Pavel Vlasov 已提交
433
        if(image.m_inMemSize.left)
434
        {
P
Pavel Vlasov 已提交
435
            if(image.m_inMemSize.left >= borderSize.left)
436 437 438 439 440
                inMemFlags |= ippBorderInMemLeft;
            else
                return (IppiBorderType)0;
        }
        else
P
Pavel Vlasov 已提交
441 442
            borderSize.left = 0;
        if(image.m_inMemSize.top)
443
        {
P
Pavel Vlasov 已提交
444
            if(image.m_inMemSize.top >= borderSize.top)
445 446 447 448 449
                inMemFlags |= ippBorderInMemTop;
            else
                return (IppiBorderType)0;
        }
        else
P
Pavel Vlasov 已提交
450 451
            borderSize.top = 0;
        if(image.m_inMemSize.right)
452
        {
P
Pavel Vlasov 已提交
453
            if(image.m_inMemSize.right >= borderSize.right)
454 455 456 457 458
                inMemFlags |= ippBorderInMemRight;
            else
                return (IppiBorderType)0;
        }
        else
P
Pavel Vlasov 已提交
459 460
            borderSize.right = 0;
        if(image.m_inMemSize.bottom)
461
        {
P
Pavel Vlasov 已提交
462
            if(image.m_inMemSize.bottom >= borderSize.bottom)
463 464 465 466 467
                inMemFlags |= ippBorderInMemBottom;
            else
                return (IppiBorderType)0;
        }
        else
P
Pavel Vlasov 已提交
468
            borderSize.bottom = 0;
469 470
    }
    else
P
Pavel Vlasov 已提交
471
        borderSize.left = borderSize.right = borderSize.top = borderSize.bottom = 0;
472 473 474 475

    return (IppiBorderType)(border|inMemFlags);
}

P
Pavel Vlasov 已提交
476
static inline ::ipp::IwValueFloat ippiGetValue(const cv::Scalar &scalar)
477
{
P
Pavel Vlasov 已提交
478
    return ::ipp::IwValueFloat(scalar[0], scalar[1], scalar[2], scalar[3]);
479 480 481 482
}

static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
{
P
Pavel Vlasov 已提交
483
    return ippiSuggestThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, multiplier);
484 485 486 487
}
#endif

// IPP temporary buffer helper
P
Pavel Vlasov 已提交
488 489 490 491
template<typename T>
class IppAutoBuffer
{
public:
492
    IppAutoBuffer() { m_size = 0; m_pBuffer = NULL; }
493
    explicit IppAutoBuffer(size_t size) { m_size = 0; m_pBuffer = NULL; allocate(size); }
494 495 496 497
    ~IppAutoBuffer() { deallocate(); }
    T* allocate(size_t size)   { if(m_size < size) { deallocate(); m_pBuffer = (T*)CV_IPP_MALLOC(size); m_size = size; } return m_pBuffer; }
    void deallocate() { if(m_pBuffer) { ippFree(m_pBuffer); m_pBuffer = NULL; } m_size = 0; }
    inline T* get() { return (T*)m_pBuffer;}
P
Pavel Vlasov 已提交
498 499 500 501
    inline operator T* () { return (T*)m_pBuffer;}
    inline operator const T* () const { return (const T*)m_pBuffer;}
private:
    // Disable copy operations
I
Ilya Lavrenov 已提交
502 503
    IppAutoBuffer(IppAutoBuffer &) {}
    IppAutoBuffer& operator =(const IppAutoBuffer &) {return *this;}
P
Pavel Vlasov 已提交
504

505 506
    size_t m_size;
    T*     m_pBuffer;
P
Pavel Vlasov 已提交
507 508
};

509
// Extracts border interpolation type without flags
510
#if IPP_VERSION_X100 >= 201700
511 512 513 514 515
#define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF|((((BORDER)&ippBorderInMem) == ippBorderInMem)?ippBorderInMem:0));
#else
#define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF);
#endif

V
vbystricky 已提交
516
#else
P
Pavel Vlasov 已提交
517
#define IPP_VERSION_X100 0
518 519
#endif

520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
#if defined HAVE_IPP
#if IPP_VERSION_X100 >= 900
#define IPP_INITIALIZER(FEAT)                           \
{                                                       \
    if(FEAT)                                            \
        ippSetCpuFeatures(FEAT);                        \
    else                                                \
        ippInit();                                      \
}
#elif IPP_VERSION_X100 >= 800
#define IPP_INITIALIZER(FEAT)                           \
{                                                       \
    ippInit();                                          \
}
#else
#define IPP_INITIALIZER(FEAT)                           \
{                                                       \
    ippStaticInit();                                    \
}
#endif

#ifdef CVAPI_EXPORTS
#define IPP_INITIALIZER_AUTO                            \
struct __IppInitializer__                               \
{                                                       \
    __IppInitializer__()                                \
    {IPP_INITIALIZER(cv::ipp::getIppFeatures())}        \
};                                                      \
static struct __IppInitializer__ __ipp_initializer__;
#else
#define IPP_INITIALIZER_AUTO
#endif
#else
#define IPP_INITIALIZER
#define IPP_INITIALIZER_AUTO
#endif
D
Dmitry Budnikov 已提交
556

557 558 559
#define CV_IPP_CHECK_COND (cv::ipp::useIPP())
#define CV_IPP_CHECK() if(CV_IPP_CHECK_COND)

D
Dmitry Budnikov 已提交
560 561 562 563 564
#ifdef HAVE_IPP

#ifdef CV_IPP_RUN_VERBOSE
#define CV_IPP_RUN_(condition, func, ...)                                   \
    {                                                                       \
565
        if (cv::ipp::useIPP() && (condition) && (func))                     \
D
Dmitry Budnikov 已提交
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
        {                                                                   \
            printf("%s: IPP implementation is running\n", CV_Func);         \
            fflush(stdout);                                                 \
            CV_IMPL_ADD(CV_IMPL_IPP);                                       \
            return __VA_ARGS__;                                             \
        }                                                                   \
        else                                                                \
        {                                                                   \
            printf("%s: Plain implementation is running\n", CV_Func);       \
            fflush(stdout);                                                 \
        }                                                                   \
    }
#elif defined CV_IPP_RUN_ASSERT
#define CV_IPP_RUN_(condition, func, ...)                                   \
    {                                                                       \
        if (cv::ipp::useIPP() && (condition))                               \
        {                                                                   \
583
            CV__TRACE_REGION_("IPP:" #func, CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP) \
D
Dmitry Budnikov 已提交
584 585 586 587 588 589 590 591 592 593 594 595 596 597
            if(func)                                                        \
            {                                                               \
                CV_IMPL_ADD(CV_IMPL_IPP);                                   \
            }                                                               \
            else                                                            \
            {                                                               \
                setIppErrorStatus();                                        \
                CV_Error(cv::Error::StsAssert, #func);                      \
            }                                                               \
            return __VA_ARGS__;                                             \
        }                                                                   \
    }
#else
#define CV_IPP_RUN_(condition, func, ...)                                   \
598 599 600 601 602 603 604 605 606
        if (cv::ipp::useIPP() && (condition))                               \
        {                                                                   \
            CV__TRACE_REGION_("IPP:" #func, CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP) \
            if(func)                                                        \
            {                                                               \
                CV_IMPL_ADD(CV_IMPL_IPP);                                   \
                return __VA_ARGS__;                                         \
            }                                                               \
        }
D
Dmitry Budnikov 已提交
607 608 609 610 611
#endif
#else
#define CV_IPP_RUN_(condition, func, ...)
#endif

612
#define CV_IPP_RUN_FAST(func, ...) CV_IPP_RUN_(true, func, __VA_ARGS__)
613
#define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_((condition), (func), __VA_ARGS__)
D
Dmitry Budnikov 已提交
614 615


616 617 618 619
#ifndef IPPI_CALL
#  define IPPI_CALL(func) CV_Assert((func) >= 0)
#endif

620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
/* IPP-compatible return codes */
typedef enum CvStatus
{
    CV_BADMEMBLOCK_ERR          = -113,
    CV_INPLACE_NOT_SUPPORTED_ERR= -112,
    CV_UNMATCHED_ROI_ERR        = -111,
    CV_NOTFOUND_ERR             = -110,
    CV_BADCONVERGENCE_ERR       = -109,

    CV_BADDEPTH_ERR             = -107,
    CV_BADROI_ERR               = -106,
    CV_BADHEADER_ERR            = -105,
    CV_UNMATCHED_FORMATS_ERR    = -104,
    CV_UNSUPPORTED_COI_ERR      = -103,
    CV_UNSUPPORTED_CHANNELS_ERR = -102,
    CV_UNSUPPORTED_DEPTH_ERR    = -101,
    CV_UNSUPPORTED_FORMAT_ERR   = -100,

638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
    CV_BADARG_ERR               = -49,  //ipp comp
    CV_NOTDEFINED_ERR           = -48,  //ipp comp

    CV_BADCHANNELS_ERR          = -47,  //ipp comp
    CV_BADRANGE_ERR             = -44,  //ipp comp
    CV_BADSTEP_ERR              = -29,  //ipp comp

    CV_BADFLAG_ERR              =  -12,
    CV_DIV_BY_ZERO_ERR          =  -11, //ipp comp
    CV_BADCOEF_ERR              =  -10,

    CV_BADFACTOR_ERR            =  -7,
    CV_BADPOINT_ERR             =  -6,
    CV_BADSCALE_ERR             =  -4,
    CV_OUTOFMEM_ERR             =  -3,
    CV_NULLPTR_ERR              =  -2,
    CV_BADSIZE_ERR              =  -1,
    CV_NO_ERR                   =   0,
    CV_OK                       =   CV_NO_ERR
657 658 659
}
CvStatus;

660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
#ifdef ENABLE_INSTRUMENTATION
namespace cv
{
namespace instr
{
struct InstrTLSStruct
{
    InstrTLSStruct()
    {
        pCurrentNode = NULL;
    }
    InstrNode* pCurrentNode;
};

class InstrStruct
{
public:
    InstrStruct()
    {
679 680 681
        useInstr    = false;
        flags       = FLAGS_MAPPING;
        maxDepth    = 0;
682

683
        rootNode.m_payload = NodeData("ROOT", NULL, 0, NULL, false, TYPE_GENERAL, IMPL_PLAIN);
684 685 686 687 688 689 690
        tlsStruct.get()->pCurrentNode = &rootNode;
    }

    Mutex mutexCreate;
    Mutex mutexCount;

    bool       useInstr;
691 692
    int        flags;
    int        maxDepth;
693 694 695 696 697 698 699
    InstrNode  rootNode;
    TLSData<InstrTLSStruct> tlsStruct;
};

class CV_EXPORTS IntrumentationRegion
{
public:
700
    IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType = TYPE_GENERAL, IMPL implType = IMPL_PLAIN);
701 702 703 704 705 706 707
    ~IntrumentationRegion();

private:
    bool    m_disabled; // region status
    uint64  m_regionTicks;
};

708 709 710
CV_EXPORTS InstrStruct& getInstrumentStruct();
InstrTLSStruct&         getInstrumentTLSStruct();
CV_EXPORTS InstrNode*   getCurrentNode();
711 712 713
}
}

714 715 716 717 718 719
#ifdef _WIN32
#define CV_INSTRUMENT_GET_RETURN_ADDRESS _ReturnAddress()
#else
#define CV_INSTRUMENT_GET_RETURN_ADDRESS __builtin_extract_return_addr(__builtin_return_address(0))
#endif

720
// Instrument region
721
#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);
722
#define CV_INSTRUMENT_REGION_CUSTOM_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)\
723 724
    void *CVAUX_CONCAT(__curr_address__, __LINE__) = [&]() {return CV_INSTRUMENT_GET_RETURN_ADDRESS;}();\
    ::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);
725 726 727 728
// Instrument functions with non-void return type
#define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]()\
{\
    if(::cv::instr::useInstrumentation()){\
729
        ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
730
        try{\
731
            auto instrStatus = ((FUN)(__VA_ARGS__));\
732 733
            if(ERROR_COND){\
                ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
734
                CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
735
            }\
736
            return instrStatus;\
737 738
        }catch(...){\
            ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
739
            CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
740 741 742 743 744 745 746 747 748 749
            throw;\
        }\
    }else{\
        return ((FUN)(__VA_ARGS__));\
    }\
}())
// Instrument functions with void return type
#define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]()\
{\
    if(::cv::instr::useInstrumentation()){\
750
        ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
751 752 753 754
        try{\
            (FUN)(__VA_ARGS__);\
        }catch(...){\
            ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
755
            CV_INSTRUMENT_MARK_META(IMPL, #FUN "- BadExit");\
756 757 758 759 760 761 762
            throw;\
        }\
    }else{\
        (FUN)(__VA_ARGS__);\
    }\
}())
// Instrumentation information marker
763
#define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(NAME, __FILE__, __LINE__, NULL, false, ::cv::instr::TYPE_MARKER, IMPL);}
764 765 766

///// General instrumentation
// General OpenCV region instrumentation macro
767
#define CV_INSTRUMENT_REGION_();             CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
768 769 770
// Custom OpenCV region instrumentation macro
#define CV_INSTRUMENT_REGION_NAME(NAME)     CV_INSTRUMENT_REGION_CUSTOM_META(NAME,  false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
// Instrumentation for parallel_for_ or other regions which forks and gathers threads
771
#define CV_INSTRUMENT_REGION_MT_FORK();      CV_INSTRUMENT_REGION_META(__FUNCTION__, true,  ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
772 773 774

///// IPP instrumentation
// Wrapper region instrumentation macro
775
#define CV_INSTRUMENT_REGION_IPP();          CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
776
// Function instrumentation macro
777
#define CV_INSTRUMENT_FUN_IPP(FUN, ...)     CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, instrStatus < 0, FUN, __VA_ARGS__)
778 779 780 781 782
// Diagnostic markers
#define CV_INSTRUMENT_MARK_IPP(NAME)        CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)

///// OpenCL instrumentation
// Wrapper region instrumentation macro
783
#define CV_INSTRUMENT_REGION_OPENCL();              CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
784 785 786 787
// OpenCL kernel compilation wrapper
#define CV_INSTRUMENT_REGION_OPENCL_COMPILE(NAME)  CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
// OpenCL kernel run wrapper
#define CV_INSTRUMENT_REGION_OPENCL_RUN(NAME)      CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_FUN, ::cv::instr::IMPL_OPENCL)
788 789 790
// Diagnostic markers
#define CV_INSTRUMENT_MARK_OPENCL(NAME)            CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_OPENCL, NAME)
#else
791 792
#define CV_INSTRUMENT_REGION_META(...)

793
#define CV_INSTRUMENT_REGION_();                            CV_TRACE_FUNCTION()
794
#define CV_INSTRUMENT_REGION_NAME(...)                     CV_TRACE_REGION(__VA_ARGS__)
795
#define CV_INSTRUMENT_REGION_MT_FORK();
796

797
#define CV_INSTRUMENT_REGION_IPP();                         CV__TRACE_REGION_("IPP", CV_TRACE_NS::details::REGION_FLAG_IMPL_IPP)
798
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
799
#define CV_INSTRUMENT_MARK_IPP(...)
800

801
#define CV_INSTRUMENT_REGION_OPENCL();                      CV__TRACE_REGION_("OpenCL", CV_TRACE_NS::details::REGION_FLAG_IMPL_OPENCL)
802 803 804
#define CV_INSTRUMENT_REGION_OPENCL_COMPILE(...)
#define CV_INSTRUMENT_REGION_OPENCL_RUN(...)
#define CV_INSTRUMENT_MARK_OPENCL(...)
805 806
#endif

807
#ifdef __CV_AVX_GUARD
A
Alexander Alekhin 已提交
808
#define CV_INSTRUMENT_REGION() __CV_AVX_GUARD CV_INSTRUMENT_REGION_();
809
#else
A
Alexander Alekhin 已提交
810
#define CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION_();
811 812
#endif

813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
namespace cv {

namespace utils {

//! @addtogroup core_utils
//! @{

/** @brief Try to find requested data file

Search directories:

1. Directories passed via `addDataSearchPath()`
2. Check path specified by configuration parameter with "_HINT" suffix (name of environment variable).
3. Check path specified by configuration parameter (name of environment variable).
   If parameter value is not empty and nothing is found then stop searching.
4. Detects build/install path based on:
   a. current working directory (CWD)
   b. and/or binary module location (opencv_core/opencv_world, doesn't work with static linkage)
5. Scan `<source>/{,data}` directories if build directory is detected or the current directory is in source tree.
6. Scan `<install>/share/OpenCV` directory if install directory is detected.

@param relative_path Relative path to data file
@param required Specify "file not found" handling.
       If true, function prints information message and raises cv::Exception.
       If false, function returns empty result
@param configuration_parameter specify configuration parameter name. Default NULL value means "OPENCV_DATA_PATH".
@return Returns path (absolute or relative to the current directory) or empty string if file is not found

@note Implementation is not thread-safe.
*/
CV_EXPORTS
cv::String findDataFile(const cv::String& relative_path, bool required = true,
                        const char* configuration_parameter = NULL);

/** @overload
@param relative_path Relative path to data file
@param configuration_parameter specify configuration parameter name. Default NULL value means "OPENCV_DATA_PATH".
@param search_paths override addDataSearchPath() settings.
@param subdir_paths override addDataSearchSubDirectory() settings.
@return Returns path (absolute or relative to the current directory) or empty string if file is not found

@note Implementation is not thread-safe.
*/
CV_EXPORTS
cv::String findDataFile(const cv::String& relative_path,
                        const char* configuration_parameter,
                        const std::vector<String>* search_paths,
                        const std::vector<String>* subdir_paths);

/** @brief Override default search data path by adding new search location

Use this only to override default behavior
Passed paths are used in LIFO order.

@param path Path to used samples data

@note Implementation is not thread-safe.
*/
CV_EXPORTS void addDataSearchPath(const cv::String& path);

/** @brief Append default search data sub directory

General usage is to add OpenCV modules name (`<opencv_contrib>/modules/<name>/data` -> `modules/<name>/data` + `<name>/data`).
Passed subdirectories are used in LIFO order.

@param subdir samples data sub directory

@note Implementation is not thread-safe.
*/
CV_EXPORTS void addDataSearchSubDirectory(const cv::String& subdir);

884
/** @brief Retrieve location of OpenCV libraries or current executable
885
 */
886 887 888 889 890 891 892 893 894
CV_EXPORTS bool getBinLocation(std::string& dst);

#if defined(_WIN32)
/** @brief Retrieve location of OpenCV libraries or current executable

@note WIN32 only
 */
CV_EXPORTS bool getBinLocation(std::wstring& dst);
#endif
895

896 897 898 899 900
//! @}

} // namespace utils
} // namespace cv

901 902
//! @endcond

S
sourin 已提交
903
#endif // OPENCV_CORE_PRIVATE_HPP