Home | History | Annotate | Download | only in src
      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) 2015, Itseez Inc., 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 #include "precomp.hpp"
     45 
     46 #ifdef _MSC_VER
     47 # if _MSC_VER >= 1700
     48 #  pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
     49 # endif
     50 #endif
     51 
     52 #if defined ANDROID || defined __linux__
     53 #  include <unistd.h>
     54 #  include <fcntl.h>
     55 #  include <elf.h>
     56 #  include <linux/auxvec.h>
     57 #endif
     58 
     59 #if defined WIN32 || defined _WIN32 || defined WINCE
     60 #ifndef _WIN32_WINNT           // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
     61   #define _WIN32_WINNT 0x0400  // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
     62 #endif
     63 #include <windows.h>
     64 #if (_WIN32_WINNT >= 0x0602)
     65   #include <synchapi.h>
     66 #endif
     67 #undef small
     68 #undef min
     69 #undef max
     70 #undef abs
     71 #include <tchar.h>
     72 #if defined _MSC_VER
     73   #if _MSC_VER >= 1400
     74     #include <intrin.h>
     75   #elif defined _M_IX86
     76     static void __cpuid(int* cpuid_data, int)
     77     {
     78         __asm
     79         {
     80             push ebx
     81             push edi
     82             mov edi, cpuid_data
     83             mov eax, 1
     84             cpuid
     85             mov [edi], eax
     86             mov [edi + 4], ebx
     87             mov [edi + 8], ecx
     88             mov [edi + 12], edx
     89             pop edi
     90             pop ebx
     91         }
     92     }
     93     static void __cpuidex(int* cpuid_data, int, int)
     94     {
     95         __asm
     96         {
     97             push edi
     98             mov edi, cpuid_data
     99             mov eax, 7
    100             mov ecx, 0
    101             cpuid
    102             mov [edi], eax
    103             mov [edi + 4], ebx
    104             mov [edi + 8], ecx
    105             mov [edi + 12], edx
    106             pop edi
    107         }
    108     }
    109   #endif
    110 #endif
    111 
    112 #ifdef WINRT
    113 #include <wrl/client.h>
    114 #ifndef __cplusplus_winrt
    115 #include <windows.storage.h>
    116 #pragma comment(lib, "runtimeobject.lib")
    117 #endif
    118 
    119 std::wstring GetTempPathWinRT()
    120 {
    121 #ifdef __cplusplus_winrt
    122     return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
    123 #else
    124     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> appdataFactory;
    125     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> appdataRef;
    126     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storagefolderRef;
    127     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageitemRef;
    128     HSTRING str;
    129     HSTRING_HEADER hstrHead;
    130     std::wstring wstr;
    131     if (FAILED(WindowsCreateStringReference(RuntimeClass_Windows_Storage_ApplicationData,
    132                                             (UINT32)wcslen(RuntimeClass_Windows_Storage_ApplicationData), &hstrHead, &str)))
    133         return wstr;
    134     if (FAILED(RoGetActivationFactory(str, IID_PPV_ARGS(appdataFactory.ReleaseAndGetAddressOf()))))
    135         return wstr;
    136     if (FAILED(appdataFactory->get_Current(appdataRef.ReleaseAndGetAddressOf())))
    137         return wstr;
    138     if (FAILED(appdataRef->get_TemporaryFolder(storagefolderRef.ReleaseAndGetAddressOf())))
    139         return wstr;
    140     if (FAILED(storagefolderRef.As(&storageitemRef)))
    141         return wstr;
    142     str = NULL;
    143     if (FAILED(storageitemRef->get_Path(&str)))
    144         return wstr;
    145     wstr = WindowsGetStringRawBuffer(str, NULL);
    146     WindowsDeleteString(str);
    147     return wstr;
    148 #endif
    149 }
    150 
    151 std::wstring GetTempFileNameWinRT(std::wstring prefix)
    152 {
    153     wchar_t guidStr[40];
    154     GUID g;
    155     CoCreateGuid(&g);
    156     wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x";
    157     swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask,
    158              g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]),
    159              UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]),
    160              UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7]));
    161 
    162     return prefix.append(std::wstring(guidStr));
    163 }
    164 
    165 #endif
    166 #else
    167 #include <pthread.h>
    168 #include <sys/time.h>
    169 #include <time.h>
    170 
    171 #if defined __MACH__ && defined __APPLE__
    172 #include <mach/mach.h>
    173 #include <mach/mach_time.h>
    174 #endif
    175 
    176 #endif
    177 
    178 #ifdef _OPENMP
    179 #include "omp.h"
    180 #endif
    181 
    182 #include <stdarg.h>
    183 
    184 #if defined __linux__ || defined __APPLE__ || defined __EMSCRIPTEN__
    185 #include <unistd.h>
    186 #include <stdio.h>
    187 #include <sys/types.h>
    188 #if defined ANDROID
    189 #include <sys/sysconf.h>
    190 #endif
    191 #endif
    192 
    193 #ifdef ANDROID
    194 # include <android/log.h>
    195 #endif
    196 
    197 namespace cv
    198 {
    199 
    200 Exception::Exception() { code = 0; line = 0; }
    201 
    202 Exception::Exception(int _code, const String& _err, const String& _func, const String& _file, int _line)
    203 : code(_code), err(_err), func(_func), file(_file), line(_line)
    204 {
    205     formatMessage();
    206 }
    207 
    208 Exception::~Exception() throw() {}
    209 
    210 /*!
    211  \return the error description and the context as a text string.
    212  */
    213 const char* Exception::what() const throw() { return msg.c_str(); }
    214 
    215 void Exception::formatMessage()
    216 {
    217     if( func.size() > 0 )
    218         msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str());
    219     else
    220         msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
    221 }
    222 
    223 struct HWFeatures
    224 {
    225     enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
    226 
    227     HWFeatures(void)
    228     {
    229         memset( have, 0, sizeof(have) );
    230         x86_family = 0;
    231     }
    232 
    233     static HWFeatures initialize(void)
    234     {
    235         HWFeatures f;
    236         int cpuid_data[4] = { 0, 0, 0, 0 };
    237 
    238     #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
    239         __cpuid(cpuid_data, 1);
    240     #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
    241         #ifdef __x86_64__
    242         asm __volatile__
    243         (
    244          "movl $1, %%eax\n\t"
    245          "cpuid\n\t"
    246          :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
    247          :
    248          : "cc"
    249         );
    250         #else
    251         asm volatile
    252         (
    253          "pushl %%ebx\n\t"
    254          "movl $1,%%eax\n\t"
    255          "cpuid\n\t"
    256          "popl %%ebx\n\t"
    257          : "=a"(cpuid_data[0]), "=c"(cpuid_data[2]), "=d"(cpuid_data[3])
    258          :
    259          : "cc"
    260         );
    261         #endif
    262     #endif
    263 
    264         f.x86_family = (cpuid_data[0] >> 8) & 15;
    265         if( f.x86_family >= 6 )
    266         {
    267             f.have[CV_CPU_MMX]    = (cpuid_data[3] & (1 << 23)) != 0;
    268             f.have[CV_CPU_SSE]    = (cpuid_data[3] & (1<<25)) != 0;
    269             f.have[CV_CPU_SSE2]   = (cpuid_data[3] & (1<<26)) != 0;
    270             f.have[CV_CPU_SSE3]   = (cpuid_data[2] & (1<<0)) != 0;
    271             f.have[CV_CPU_SSSE3]  = (cpuid_data[2] & (1<<9)) != 0;
    272             f.have[CV_CPU_FMA3]  = (cpuid_data[2] & (1<<12)) != 0;
    273             f.have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
    274             f.have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
    275             f.have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0;
    276             f.have[CV_CPU_AVX]    = (((cpuid_data[2] & (1<<28)) != 0)&&((cpuid_data[2] & (1<<27)) != 0));//OS uses XSAVE_XRSTORE and CPU support AVX
    277 
    278             // make the second call to the cpuid command in order to get
    279             // information about extended features like AVX2
    280         #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
    281             __cpuidex(cpuid_data, 7, 0);
    282         #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
    283             #ifdef __x86_64__
    284             asm __volatile__
    285             (
    286              "movl $7, %%eax\n\t"
    287              "movl $0, %%ecx\n\t"
    288              "cpuid\n\t"
    289              :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
    290              :
    291              : "cc"
    292             );
    293             #else
    294             asm volatile
    295             (
    296              "pushl %%ebx\n\t"
    297              "movl $7,%%eax\n\t"
    298              "movl $0,%%ecx\n\t"
    299              "cpuid\n\t"
    300              "movl %%ebx, %0\n\t"
    301              "popl %%ebx\n\t"
    302              : "=r"(cpuid_data[1]), "=c"(cpuid_data[2])
    303              :
    304              : "cc"
    305             );
    306             #endif
    307         #endif
    308             f.have[CV_CPU_AVX2]   = (cpuid_data[1] & (1<<5)) != 0;
    309 
    310             f.have[CV_CPU_AVX_512F]       = (cpuid_data[1] & (1<<16)) != 0;
    311             f.have[CV_CPU_AVX_512DQ]      = (cpuid_data[1] & (1<<17)) != 0;
    312             f.have[CV_CPU_AVX_512IFMA512] = (cpuid_data[1] & (1<<21)) != 0;
    313             f.have[CV_CPU_AVX_512PF]      = (cpuid_data[1] & (1<<26)) != 0;
    314             f.have[CV_CPU_AVX_512ER]      = (cpuid_data[1] & (1<<27)) != 0;
    315             f.have[CV_CPU_AVX_512CD]      = (cpuid_data[1] & (1<<28)) != 0;
    316             f.have[CV_CPU_AVX_512BW]      = (cpuid_data[1] & (1<<30)) != 0;
    317             f.have[CV_CPU_AVX_512VL]      = (cpuid_data[1] & (1<<31)) != 0;
    318             f.have[CV_CPU_AVX_512VBMI]    = (cpuid_data[2] &  (1<<1)) != 0;
    319         }
    320 
    321     #if defined ANDROID || defined __linux__
    322     #ifdef __aarch64__
    323         f.have[CV_CPU_NEON] = true;
    324     #else
    325         int cpufile = open("/proc/self/auxv", O_RDONLY);
    326 
    327         if (cpufile >= 0)
    328         {
    329             Elf32_auxv_t auxv;
    330             const size_t size_auxv_t = sizeof(auxv);
    331 
    332             while ((size_t)read(cpufile, &auxv, size_auxv_t) == size_auxv_t)
    333             {
    334                 if (auxv.a_type == AT_HWCAP)
    335                 {
    336                     f.have[CV_CPU_NEON] = (auxv.a_un.a_val & 4096) != 0;
    337                     break;
    338                 }
    339             }
    340 
    341             close(cpufile);
    342         }
    343     #endif
    344     #elif (defined __clang__ || defined __APPLE__) && (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
    345         f.have[CV_CPU_NEON] = true;
    346     #endif
    347 
    348         return f;
    349     }
    350 
    351     int x86_family;
    352     bool have[MAX_FEATURE+1];
    353 };
    354 
    355 static HWFeatures  featuresEnabled = HWFeatures::initialize(), featuresDisabled = HWFeatures();
    356 static HWFeatures* currentFeatures = &featuresEnabled;
    357 
    358 bool checkHardwareSupport(int feature)
    359 {
    360     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
    361     return currentFeatures->have[feature];
    362 }
    363 
    364 
    365 volatile bool useOptimizedFlag = true;
    366 #ifdef HAVE_IPP
    367 struct IPPInitializer
    368 {
    369     IPPInitializer(void)
    370     {
    371 #if IPP_VERSION_MAJOR >= 8
    372         ippInit();
    373 #else
    374         ippStaticInit();
    375 #endif
    376     }
    377 };
    378 
    379 IPPInitializer ippInitializer;
    380 #endif
    381 
    382 volatile bool USE_SSE2 = featuresEnabled.have[CV_CPU_SSE2];
    383 volatile bool USE_SSE4_2 = featuresEnabled.have[CV_CPU_SSE4_2];
    384 volatile bool USE_AVX = featuresEnabled.have[CV_CPU_AVX];
    385 volatile bool USE_AVX2 = featuresEnabled.have[CV_CPU_AVX2];
    386 
    387 void setUseOptimized( bool flag )
    388 {
    389     useOptimizedFlag = flag;
    390     currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
    391     USE_SSE2 = currentFeatures->have[CV_CPU_SSE2];
    392 
    393     ipp::setUseIPP(flag);
    394     ocl::setUseOpenCL(flag);
    395 #ifdef HAVE_TEGRA_OPTIMIZATION
    396     ::tegra::setUseTegra(flag);
    397 #endif
    398 }
    399 
    400 bool useOptimized(void)
    401 {
    402     return useOptimizedFlag;
    403 }
    404 
    405 int64 getTickCount(void)
    406 {
    407 #if defined WIN32 || defined _WIN32 || defined WINCE
    408     LARGE_INTEGER counter;
    409     QueryPerformanceCounter( &counter );
    410     return (int64)counter.QuadPart;
    411 #elif defined __linux || defined __linux__
    412     struct timespec tp;
    413     clock_gettime(CLOCK_MONOTONIC, &tp);
    414     return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
    415 #elif defined __MACH__ && defined __APPLE__
    416     return (int64)mach_absolute_time();
    417 #else
    418     struct timeval tv;
    419     struct timezone tz;
    420     gettimeofday( &tv, &tz );
    421     return (int64)tv.tv_sec*1000000 + tv.tv_usec;
    422 #endif
    423 }
    424 
    425 double getTickFrequency(void)
    426 {
    427 #if defined WIN32 || defined _WIN32 || defined WINCE
    428     LARGE_INTEGER freq;
    429     QueryPerformanceFrequency(&freq);
    430     return (double)freq.QuadPart;
    431 #elif defined __linux || defined __linux__
    432     return 1e9;
    433 #elif defined __MACH__ && defined __APPLE__
    434     static double freq = 0;
    435     if( freq == 0 )
    436     {
    437         mach_timebase_info_data_t sTimebaseInfo;
    438         mach_timebase_info(&sTimebaseInfo);
    439         freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
    440     }
    441     return freq;
    442 #else
    443     return 1e6;
    444 #endif
    445 }
    446 
    447 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__)
    448 #if defined(__i386__)
    449 
    450 int64 getCPUTickCount(void)
    451 {
    452     int64 x;
    453     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
    454     return x;
    455 }
    456 #elif defined(__x86_64__)
    457 
    458 int64 getCPUTickCount(void)
    459 {
    460     unsigned hi, lo;
    461     __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    462     return (int64)lo | ((int64)hi << 32);
    463 }
    464 
    465 #elif defined(__ppc__)
    466 
    467 int64 getCPUTickCount(void)
    468 {
    469     int64 result = 0;
    470     unsigned upper, lower, tmp;
    471     __asm__ volatile(
    472                      "0:                  \n"
    473                      "\tmftbu   %0           \n"
    474                      "\tmftb    %1           \n"
    475                      "\tmftbu   %2           \n"
    476                      "\tcmpw    %2,%0        \n"
    477                      "\tbne     0b         \n"
    478                      : "=r"(upper),"=r"(lower),"=r"(tmp)
    479                      );
    480     return lower | ((int64)upper << 32);
    481 }
    482 
    483 #else
    484 
    485 #error "RDTSC not defined"
    486 
    487 #endif
    488 
    489 #elif defined _MSC_VER && defined WIN32 && defined _M_IX86
    490 
    491 int64 getCPUTickCount(void)
    492 {
    493     __asm _emit 0x0f;
    494     __asm _emit 0x31;
    495 }
    496 
    497 #else
    498 
    499 //#ifdef HAVE_IPP
    500 //int64 getCPUTickCount(void)
    501 //{
    502 //    return ippGetCpuClocks();
    503 //}
    504 //#else
    505 int64 getCPUTickCount(void)
    506 {
    507     return getTickCount();
    508 }
    509 //#endif
    510 
    511 #endif
    512 
    513 const String& getBuildInformation()
    514 {
    515     static String build_info =
    516 #include "version_string.inc"
    517     ;
    518     return build_info;
    519 }
    520 
    521 String format( const char* fmt, ... )
    522 {
    523     AutoBuffer<char, 1024> buf;
    524 
    525     for ( ; ; )
    526     {
    527         va_list va;
    528         va_start(va, fmt);
    529         int bsize = static_cast<int>(buf.size()),
    530                 len = vsnprintf((char *)buf, bsize, fmt, va);
    531         va_end(va);
    532 
    533         if (len < 0 || len >= bsize)
    534         {
    535             buf.resize(std::max(bsize << 1, len + 1));
    536             continue;
    537         }
    538         return String((char *)buf, len);
    539     }
    540 }
    541 
    542 String tempfile( const char* suffix )
    543 {
    544     String fname;
    545 #ifndef WINRT
    546     const char *temp_dir = getenv("OPENCV_TEMP_PATH");
    547 #endif
    548 
    549 #if defined WIN32 || defined _WIN32
    550 #ifdef WINRT
    551     RoInitialize(RO_INIT_MULTITHREADED);
    552     std::wstring temp_dir = GetTempPathWinRT();
    553 
    554     std::wstring temp_file = GetTempFileNameWinRT(L"ocv");
    555     if (temp_file.empty())
    556         return String();
    557 
    558     temp_file = temp_dir.append(std::wstring(L"\\")).append(temp_file);
    559     DeleteFileW(temp_file.c_str());
    560 
    561     char aname[MAX_PATH];
    562     size_t copied = wcstombs(aname, temp_file.c_str(), MAX_PATH);
    563     CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
    564     fname = String(aname);
    565     RoUninitialize();
    566 #else
    567     char temp_dir2[MAX_PATH] = { 0 };
    568     char temp_file[MAX_PATH] = { 0 };
    569 
    570     if (temp_dir == 0 || temp_dir[0] == 0)
    571     {
    572         ::GetTempPathA(sizeof(temp_dir2), temp_dir2);
    573         temp_dir = temp_dir2;
    574     }
    575     if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file))
    576         return String();
    577 
    578     DeleteFileA(temp_file);
    579 
    580     fname = temp_file;
    581 #endif
    582 # else
    583 #  ifdef ANDROID
    584     //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
    585     char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
    586 #  else
    587     char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
    588 #  endif
    589 
    590     if (temp_dir == 0 || temp_dir[0] == 0)
    591         fname = defaultTemplate;
    592     else
    593     {
    594         fname = temp_dir;
    595         char ech = fname[fname.size() - 1];
    596         if(ech != '/' && ech != '\\')
    597             fname = fname + "/";
    598         fname = fname + "__opencv_temp.XXXXXX";
    599     }
    600 
    601     const int fd = mkstemp((char*)fname.c_str());
    602     if (fd == -1) return String();
    603 
    604     close(fd);
    605     remove(fname.c_str());
    606 # endif
    607 
    608     if (suffix)
    609     {
    610         if (suffix[0] != '.')
    611             return fname + "." + suffix;
    612         else
    613             return fname + suffix;
    614     }
    615     return fname;
    616 }
    617 
    618 static CvErrorCallback customErrorCallback = 0;
    619 static void* customErrorCallbackData = 0;
    620 static bool breakOnError = false;
    621 
    622 bool setBreakOnError(bool value)
    623 {
    624     bool prevVal = breakOnError;
    625     breakOnError = value;
    626     return prevVal;
    627 }
    628 
    629 void error( const Exception& exc )
    630 {
    631     if (customErrorCallback != 0)
    632         customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
    633                             exc.file.c_str(), exc.line, customErrorCallbackData);
    634     else
    635     {
    636         const char* errorStr = cvErrorStr(exc.code);
    637         char buf[1 << 16];
    638 
    639         sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
    640             errorStr, exc.err.c_str(), exc.func.size() > 0 ?
    641             exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
    642         fprintf( stderr, "%s\n", buf );
    643         fflush( stderr );
    644 #  ifdef __ANDROID__
    645         __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf);
    646 #  endif
    647     }
    648 
    649     if(breakOnError)
    650     {
    651         static volatile int* p = 0;
    652         *p = 0;
    653     }
    654 
    655     throw exc;
    656 }
    657 
    658 void error(int _code, const String& _err, const char* _func, const char* _file, int _line)
    659 {
    660     error(cv::Exception(_code, _err, _func, _file, _line));
    661 }
    662 
    663 CvErrorCallback
    664 redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
    665 {
    666     if( prevUserdata )
    667         *prevUserdata = customErrorCallbackData;
    668 
    669     CvErrorCallback prevCallback = customErrorCallback;
    670 
    671     customErrorCallback     = errCallback;
    672     customErrorCallbackData = userdata;
    673 
    674     return prevCallback;
    675 }
    676 
    677 }
    678 
    679 CV_IMPL int cvCheckHardwareSupport(int feature)
    680 {
    681     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
    682     return cv::currentFeatures->have[feature];
    683 }
    684 
    685 CV_IMPL int cvUseOptimized( int flag )
    686 {
    687     int prevMode = cv::useOptimizedFlag;
    688     cv::setUseOptimized( flag != 0 );
    689     return prevMode;
    690 }
    691 
    692 CV_IMPL int64  cvGetTickCount(void)
    693 {
    694     return cv::getTickCount();
    695 }
    696 
    697 CV_IMPL double cvGetTickFrequency(void)
    698 {
    699     return cv::getTickFrequency()*1e-6;
    700 }
    701 
    702 CV_IMPL CvErrorCallback
    703 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
    704 {
    705     return cv::redirectError(errCallback, userdata, prevUserdata);
    706 }
    707 
    708 CV_IMPL int cvNulDevReport( int, const char*, const char*,
    709                             const char*, int, void* )
    710 {
    711     return 0;
    712 }
    713 
    714 CV_IMPL int cvStdErrReport( int, const char*, const char*,
    715                             const char*, int, void* )
    716 {
    717     return 0;
    718 }
    719 
    720 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
    721                             const char*, int, void* )
    722 {
    723     return 0;
    724 }
    725 
    726 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
    727 {
    728     return 0;
    729 }
    730 
    731 
    732 CV_IMPL const char* cvErrorStr( int status )
    733 {
    734     static char buf[256];
    735 
    736     switch (status)
    737     {
    738     case CV_StsOk :                  return "No Error";
    739     case CV_StsBackTrace :           return "Backtrace";
    740     case CV_StsError :               return "Unspecified error";
    741     case CV_StsInternal :            return "Internal error";
    742     case CV_StsNoMem :               return "Insufficient memory";
    743     case CV_StsBadArg :              return "Bad argument";
    744     case CV_StsNoConv :              return "Iterations do not converge";
    745     case CV_StsAutoTrace :           return "Autotrace call";
    746     case CV_StsBadSize :             return "Incorrect size of input array";
    747     case CV_StsNullPtr :             return "Null pointer";
    748     case CV_StsDivByZero :           return "Division by zero occured";
    749     case CV_BadStep :                return "Image step is wrong";
    750     case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
    751     case CV_StsObjectNotFound :      return "Requested object was not found";
    752     case CV_BadDepth :               return "Input image depth is not supported by function";
    753     case CV_StsUnmatchedFormats :    return "Formats of input arguments do not match";
    754     case CV_StsUnmatchedSizes :      return "Sizes of input arguments do not match";
    755     case CV_StsOutOfRange :          return "One of arguments\' values is out of range";
    756     case CV_StsUnsupportedFormat :   return "Unsupported format or combination of formats";
    757     case CV_BadCOI :                 return "Input COI is not supported";
    758     case CV_BadNumChannels :         return "Bad number of channels";
    759     case CV_StsBadFlag :             return "Bad flag (parameter or structure field)";
    760     case CV_StsBadPoint :            return "Bad parameter of type CvPoint";
    761     case CV_StsBadMask :             return "Bad type of mask argument";
    762     case CV_StsParseError :          return "Parsing error";
    763     case CV_StsNotImplemented :      return "The function/feature is not implemented";
    764     case CV_StsBadMemBlock :         return "Memory block has been corrupted";
    765     case CV_StsAssert :              return "Assertion failed";
    766     case CV_GpuNotSupported :        return "No CUDA support";
    767     case CV_GpuApiCallError :        return "Gpu API call";
    768     case CV_OpenGlNotSupported :     return "No OpenGL support";
    769     case CV_OpenGlApiCallError :     return "OpenGL API call";
    770     };
    771 
    772     sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
    773     return buf;
    774 }
    775 
    776 CV_IMPL int cvGetErrMode(void)
    777 {
    778     return 0;
    779 }
    780 
    781 CV_IMPL int cvSetErrMode(int)
    782 {
    783     return 0;
    784 }
    785 
    786 CV_IMPL int cvGetErrStatus(void)
    787 {
    788     return 0;
    789 }
    790 
    791 CV_IMPL void cvSetErrStatus(int)
    792 {
    793 }
    794 
    795 
    796 CV_IMPL void cvError( int code, const char* func_name,
    797                       const char* err_msg,
    798                       const char* file_name, int line )
    799 {
    800     cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
    801 }
    802 
    803 /* function, which converts int to int */
    804 CV_IMPL int
    805 cvErrorFromIppStatus( int status )
    806 {
    807     switch (status)
    808     {
    809     case CV_BADSIZE_ERR:               return CV_StsBadSize;
    810     case CV_BADMEMBLOCK_ERR:           return CV_StsBadMemBlock;
    811     case CV_NULLPTR_ERR:               return CV_StsNullPtr;
    812     case CV_DIV_BY_ZERO_ERR:           return CV_StsDivByZero;
    813     case CV_BADSTEP_ERR:               return CV_BadStep;
    814     case CV_OUTOFMEM_ERR:              return CV_StsNoMem;
    815     case CV_BADARG_ERR:                return CV_StsBadArg;
    816     case CV_NOTDEFINED_ERR:            return CV_StsError;
    817     case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
    818     case CV_NOTFOUND_ERR:              return CV_StsObjectNotFound;
    819     case CV_BADCONVERGENCE_ERR:        return CV_StsNoConv;
    820     case CV_BADDEPTH_ERR:              return CV_BadDepth;
    821     case CV_UNMATCHED_FORMATS_ERR:     return CV_StsUnmatchedFormats;
    822     case CV_UNSUPPORTED_COI_ERR:       return CV_BadCOI;
    823     case CV_UNSUPPORTED_CHANNELS_ERR:  return CV_BadNumChannels;
    824     case CV_BADFLAG_ERR:               return CV_StsBadFlag;
    825     case CV_BADRANGE_ERR:              return CV_StsBadArg;
    826     case CV_BADCOEF_ERR:               return CV_StsBadArg;
    827     case CV_BADFACTOR_ERR:             return CV_StsBadArg;
    828     case CV_BADPOINT_ERR:              return CV_StsBadPoint;
    829 
    830     default:
    831       return CV_StsError;
    832     }
    833 }
    834 
    835 namespace cv {
    836 bool __termination = false;
    837 }
    838 
    839 namespace cv
    840 {
    841 
    842 #if defined WIN32 || defined _WIN32 || defined WINCE
    843 
    844 struct Mutex::Impl
    845 {
    846     Impl()
    847     {
    848 #if (_WIN32_WINNT >= 0x0600)
    849         ::InitializeCriticalSectionEx(&cs, 1000, 0);
    850 #else
    851         ::InitializeCriticalSection(&cs);
    852 #endif
    853         refcount = 1;
    854     }
    855     ~Impl() { DeleteCriticalSection(&cs); }
    856 
    857     void lock() { EnterCriticalSection(&cs); }
    858     bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
    859     void unlock() { LeaveCriticalSection(&cs); }
    860 
    861     CRITICAL_SECTION cs;
    862     int refcount;
    863 };
    864 
    865 #else
    866 
    867 struct Mutex::Impl
    868 {
    869     Impl()
    870     {
    871         pthread_mutexattr_t attr;
    872         pthread_mutexattr_init(&attr);
    873         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    874         pthread_mutex_init(&mt, &attr);
    875         pthread_mutexattr_destroy(&attr);
    876 
    877         refcount = 1;
    878     }
    879     ~Impl() { pthread_mutex_destroy(&mt); }
    880 
    881     void lock() { pthread_mutex_lock(&mt); }
    882     bool trylock() { return pthread_mutex_trylock(&mt) == 0; }
    883     void unlock() { pthread_mutex_unlock(&mt); }
    884 
    885     pthread_mutex_t mt;
    886     int refcount;
    887 };
    888 
    889 #endif
    890 
    891 Mutex::Mutex()
    892 {
    893     impl = new Mutex::Impl;
    894 }
    895 
    896 Mutex::~Mutex()
    897 {
    898     if( CV_XADD(&impl->refcount, -1) == 1 )
    899         delete impl;
    900     impl = 0;
    901 }
    902 
    903 Mutex::Mutex(const Mutex& m)
    904 {
    905     impl = m.impl;
    906     CV_XADD(&impl->refcount, 1);
    907 }
    908 
    909 Mutex& Mutex::operator = (const Mutex& m)
    910 {
    911     CV_XADD(&m.impl->refcount, 1);
    912     if( CV_XADD(&impl->refcount, -1) == 1 )
    913         delete impl;
    914     impl = m.impl;
    915     return *this;
    916 }
    917 
    918 void Mutex::lock() { impl->lock(); }
    919 void Mutex::unlock() { impl->unlock(); }
    920 bool Mutex::trylock() { return impl->trylock(); }
    921 
    922 
    923 //////////////////////////////// thread-local storage ////////////////////////////////
    924 
    925 class TLSStorage
    926 {
    927     std::vector<void*> tlsData_;
    928 public:
    929     TLSStorage() { tlsData_.reserve(16); }
    930     ~TLSStorage();
    931     inline void* getData(int key) const
    932     {
    933         CV_DbgAssert(key >= 0);
    934         return (key < (int)tlsData_.size()) ? tlsData_[key] : NULL;
    935     }
    936     inline void setData(int key, void* data)
    937     {
    938         CV_DbgAssert(key >= 0);
    939         if (key >= (int)tlsData_.size())
    940         {
    941             tlsData_.resize(key + 1, NULL);
    942         }
    943         tlsData_[key] = data;
    944     }
    945 
    946     inline static TLSStorage* get();
    947 };
    948 
    949 #ifdef WIN32
    950 #ifdef _MSC_VER
    951 #pragma warning(disable:4505) // unreferenced local function has been removed
    952 #endif
    953 
    954 #ifdef WINRT
    955     // using C++11 thread attribute for local thread data
    956     static __declspec( thread ) TLSStorage* g_tlsdata = NULL;
    957 
    958     static void deleteThreadData()
    959     {
    960         if (g_tlsdata)
    961         {
    962             delete g_tlsdata;
    963             g_tlsdata = NULL;
    964         }
    965     }
    966 
    967     inline TLSStorage* TLSStorage::get()
    968     {
    969         if (!g_tlsdata)
    970         {
    971             g_tlsdata = new TLSStorage;
    972         }
    973         return g_tlsdata;
    974     }
    975 #else
    976 #ifdef WINCE
    977 #   define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
    978 #endif
    979     static DWORD tlsKey = TLS_OUT_OF_INDEXES;
    980 
    981     static void deleteThreadData()
    982     {
    983         if(tlsKey != TLS_OUT_OF_INDEXES)
    984         {
    985             delete (TLSStorage*)TlsGetValue(tlsKey);
    986             TlsSetValue(tlsKey, NULL);
    987         }
    988     }
    989 
    990     inline TLSStorage* TLSStorage::get()
    991     {
    992         if (tlsKey == TLS_OUT_OF_INDEXES)
    993         {
    994             tlsKey = TlsAlloc();
    995             CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
    996         }
    997         TLSStorage* d = (TLSStorage*)TlsGetValue(tlsKey);
    998         if (!d)
    999         {
   1000             d = new TLSStorage;
   1001             TlsSetValue(tlsKey, d);
   1002         }
   1003         return d;
   1004     }
   1005 #endif //WINRT
   1006 
   1007 #if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
   1008 #ifdef WINRT
   1009     #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
   1010 #endif
   1011 
   1012 extern "C"
   1013 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
   1014 {
   1015     if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
   1016     {
   1017         if (lpReserved != NULL) // called after ExitProcess() call
   1018         {
   1019             cv::__termination = true;
   1020         }
   1021         else
   1022         {
   1023             // Not allowed to free resources if lpReserved is non-null
   1024             // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583.aspx
   1025             cv::deleteThreadAllocData();
   1026             cv::deleteThreadData();
   1027         }
   1028     }
   1029     return TRUE;
   1030 }
   1031 #endif
   1032 
   1033 #else
   1034     static pthread_key_t tlsKey = 0;
   1035     static pthread_once_t tlsKeyOnce = PTHREAD_ONCE_INIT;
   1036 
   1037     static void deleteTLSStorage(void* data)
   1038     {
   1039         delete (TLSStorage*)data;
   1040     }
   1041 
   1042     static void makeKey()
   1043     {
   1044         int errcode = pthread_key_create(&tlsKey, deleteTLSStorage);
   1045         CV_Assert(errcode == 0);
   1046     }
   1047 
   1048     inline TLSStorage* TLSStorage::get()
   1049     {
   1050         pthread_once(&tlsKeyOnce, makeKey);
   1051         TLSStorage* d = (TLSStorage*)pthread_getspecific(tlsKey);
   1052         if( !d )
   1053         {
   1054             d = new TLSStorage;
   1055             pthread_setspecific(tlsKey, d);
   1056         }
   1057         return d;
   1058     }
   1059 #endif
   1060 
   1061 class TLSContainerStorage
   1062 {
   1063     cv::Mutex mutex_;
   1064     std::vector<TLSDataContainer*> tlsContainers_;
   1065 public:
   1066     TLSContainerStorage() { }
   1067     ~TLSContainerStorage()
   1068     {
   1069         for (size_t i = 0; i < tlsContainers_.size(); i++)
   1070         {
   1071             CV_DbgAssert(tlsContainers_[i] == NULL); // not all keys released
   1072             tlsContainers_[i] = NULL;
   1073         }
   1074     }
   1075 
   1076     int allocateKey(TLSDataContainer* pContainer)
   1077     {
   1078         cv::AutoLock lock(mutex_);
   1079         tlsContainers_.push_back(pContainer);
   1080         return (int)tlsContainers_.size() - 1;
   1081     }
   1082     void releaseKey(int id, TLSDataContainer* pContainer)
   1083     {
   1084         cv::AutoLock lock(mutex_);
   1085         CV_Assert(tlsContainers_[id] == pContainer);
   1086         tlsContainers_[id] = NULL;
   1087         // currently, we don't go into thread's TLSData and release data for this key
   1088     }
   1089 
   1090     void destroyData(int key, void* data)
   1091     {
   1092         cv::AutoLock lock(mutex_);
   1093         TLSDataContainer* k = tlsContainers_[key];
   1094         if (!k)
   1095             return;
   1096         try
   1097         {
   1098             k->deleteDataInstance(data);
   1099         }
   1100         catch (...)
   1101         {
   1102             CV_DbgAssert(k == NULL); // Debug this!
   1103         }
   1104     }
   1105 };
   1106 
   1107 // This is a wrapper function that will ensure 'tlsContainerStorage' is constructed on first use.
   1108 // For more information: http://www.parashift.com/c++-faq/static-init-order-on-first-use.html
   1109 static TLSContainerStorage& getTLSContainerStorage()
   1110 {
   1111     static TLSContainerStorage *tlsContainerStorage = new TLSContainerStorage();
   1112     return *tlsContainerStorage;
   1113 }
   1114 
   1115 TLSDataContainer::TLSDataContainer()
   1116     : key_(-1)
   1117 {
   1118     key_ = getTLSContainerStorage().allocateKey(this);
   1119 }
   1120 
   1121 TLSDataContainer::~TLSDataContainer()
   1122 {
   1123     getTLSContainerStorage().releaseKey(key_, this);
   1124     key_ = -1;
   1125 }
   1126 
   1127 void* TLSDataContainer::getData() const
   1128 {
   1129     CV_Assert(key_ >= 0);
   1130     TLSStorage* tlsData = TLSStorage::get();
   1131     void* data = tlsData->getData(key_);
   1132     if (!data)
   1133     {
   1134         data = this->createDataInstance();
   1135         CV_DbgAssert(data != NULL);
   1136         tlsData->setData(key_, data);
   1137     }
   1138     return data;
   1139 }
   1140 
   1141 TLSStorage::~TLSStorage()
   1142 {
   1143     for (int i = 0; i < (int)tlsData_.size(); i++)
   1144     {
   1145         void*& data = tlsData_[i];
   1146         if (data)
   1147         {
   1148             getTLSContainerStorage().destroyData(i, data);
   1149             data = NULL;
   1150         }
   1151     }
   1152     tlsData_.clear();
   1153 }
   1154 
   1155 
   1156 
   1157 TLSData<CoreTLSData>& getCoreTlsData()
   1158 {
   1159     static TLSData<CoreTLSData> *value = new TLSData<CoreTLSData>();
   1160     return *value;
   1161 }
   1162 
   1163 
   1164 
   1165 #ifdef CV_COLLECT_IMPL_DATA
   1166 ImplCollector& getImplData()
   1167 {
   1168     static ImplCollector *value = new ImplCollector();
   1169     return *value;
   1170 }
   1171 
   1172 void setImpl(int flags)
   1173 {
   1174     cv::AutoLock lock(getImplData().mutex);
   1175 
   1176     getImplData().implFlags = flags;
   1177     getImplData().implCode.clear();
   1178     getImplData().implFun.clear();
   1179 }
   1180 
   1181 void addImpl(int flag, const char* func)
   1182 {
   1183     cv::AutoLock lock(getImplData().mutex);
   1184 
   1185     getImplData().implFlags |= flag;
   1186     if(func) // use lazy collection if name was not specified
   1187     {
   1188         size_t index = getImplData().implCode.size();
   1189         if(!index || (getImplData().implCode[index-1] != flag || getImplData().implFun[index-1].compare(func))) // avoid duplicates
   1190         {
   1191             getImplData().implCode.push_back(flag);
   1192             getImplData().implFun.push_back(func);
   1193         }
   1194     }
   1195 }
   1196 
   1197 int getImpl(std::vector<int> &impl, std::vector<String> &funName)
   1198 {
   1199     cv::AutoLock lock(getImplData().mutex);
   1200 
   1201     impl    = getImplData().implCode;
   1202     funName = getImplData().implFun;
   1203     return getImplData().implFlags; // return actual flags for lazy collection
   1204 }
   1205 
   1206 bool useCollection()
   1207 {
   1208     return getImplData().useCollection;
   1209 }
   1210 
   1211 void setUseCollection(bool flag)
   1212 {
   1213     cv::AutoLock lock(getImplData().mutex);
   1214 
   1215     getImplData().useCollection = flag;
   1216 }
   1217 #endif
   1218 
   1219 namespace ipp
   1220 {
   1221 
   1222 static int ippStatus = 0; // 0 - all is ok, -1 - IPP functions failed
   1223 static const char * funcname = NULL, * filename = NULL;
   1224 static int linen = 0;
   1225 
   1226 void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
   1227 {
   1228     ippStatus = status;
   1229     funcname = _funcname;
   1230     filename = _filename;
   1231     linen = _line;
   1232 }
   1233 
   1234 int getIppStatus()
   1235 {
   1236     return ippStatus;
   1237 }
   1238 
   1239 String getIppErrorLocation()
   1240 {
   1241     return format("%s:%d %s", filename ? filename : "", linen, funcname ? funcname : "");
   1242 }
   1243 
   1244 bool useIPP()
   1245 {
   1246 #ifdef HAVE_IPP
   1247     CoreTLSData* data = getCoreTlsData().get();
   1248     if(data->useIPP < 0)
   1249     {
   1250         const char* pIppEnv = getenv("OPENCV_IPP");
   1251         if(pIppEnv && (cv::String(pIppEnv) == "disabled"))
   1252             data->useIPP = false;
   1253         else
   1254             data->useIPP = true;
   1255     }
   1256     return (data->useIPP > 0);
   1257 #else
   1258     return false;
   1259 #endif
   1260 }
   1261 
   1262 void setUseIPP(bool flag)
   1263 {
   1264     CoreTLSData* data = getCoreTlsData().get();
   1265 #ifdef HAVE_IPP
   1266     data->useIPP = flag;
   1267 #else
   1268     (void)flag;
   1269     data->useIPP = false;
   1270 #endif
   1271 }
   1272 
   1273 } // namespace ipp
   1274 
   1275 } // namespace cv
   1276 
   1277 #ifdef HAVE_TEGRA_OPTIMIZATION
   1278 
   1279 namespace tegra {
   1280 
   1281 bool useTegra()
   1282 {
   1283     cv::CoreTLSData* data = cv::getCoreTlsData().get();
   1284 
   1285     if (data->useTegra < 0)
   1286     {
   1287         const char* pTegraEnv = getenv("OPENCV_TEGRA");
   1288         if (pTegraEnv && (cv::String(pTegraEnv) == "disabled"))
   1289             data->useTegra = false;
   1290         else
   1291             data->useTegra = true;
   1292     }
   1293 
   1294     return (data->useTegra > 0);
   1295 }
   1296 
   1297 void setUseTegra(bool flag)
   1298 {
   1299     cv::CoreTLSData* data = cv::getCoreTlsData().get();
   1300     data->useTegra = flag;
   1301 }
   1302 
   1303 } // namespace tegra
   1304 
   1305 #endif
   1306 
   1307 /* End of file. */
   1308