Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers system.cpp Source File

system.cpp

00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Copyright (C) 2015, Itseez Inc., all rights reserved.
00016 // Third party copyrights are property of their respective owners.
00017 //
00018 // Redistribution and use in source and binary forms, with or without modification,
00019 // are permitted provided that the following conditions are met:
00020 //
00021 //   * Redistribution's of source code must retain the above copyright notice,
00022 //     this list of conditions and the following disclaimer.
00023 //
00024 //   * Redistribution's in binary form must reproduce the above copyright notice,
00025 //     this list of conditions and the following disclaimer in the documentation
00026 //     and/or other materials provided with the distribution.
00027 //
00028 //   * The name of the copyright holders may not be used to endorse or promote products
00029 //     derived from this software without specific prior written permission.
00030 //
00031 // This software is provided by the copyright holders and contributors "as is" and
00032 // any express or implied warranties, including, but not limited to, the implied
00033 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00034 // In no event shall the Intel Corporation or contributors be liable for any direct,
00035 // indirect, incidental, special, exemplary, or consequential damages
00036 // (including, but not limited to, procurement of substitute goods or services;
00037 // loss of use, data, or profits; or business interruption) however caused
00038 // and on any theory of liability, whether in contract, strict liability,
00039 // or tort (including negligence or otherwise) arising in any way out of
00040 // the use of this software, even if advised of the possibility of such damage.
00041 //
00042 //M*/
00043 
00044 #include "precomp.hpp"
00045 #include <iostream>
00046 
00047 namespace cv {
00048 
00049 static Mutex* __initialization_mutex = NULL;
00050 Mutex& getInitializationMutex()
00051 {
00052     if (__initialization_mutex == NULL)
00053         __initialization_mutex = new Mutex();
00054     return *__initialization_mutex;
00055 }
00056 // force initialization (single-threaded environment)
00057 Mutex* __initialization_mutex_initializer = &getInitializationMutex();
00058 
00059 } // namespace cv
00060 
00061 #ifdef _MSC_VER
00062 # if _MSC_VER >= 1700
00063 #  pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
00064 # endif
00065 #endif
00066 
00067 #if defined ANDROID || defined __linux__ || defined __FreeBSD__
00068 #  include <unistd.h>
00069 #  include <fcntl.h>
00070 #  include <elf.h>
00071 #if defined ANDROID || defined __linux__
00072 #  include <linux/auxvec.h>
00073 #endif
00074 #endif
00075 
00076 #if defined WIN32 || defined _WIN32 || defined WINCE
00077 #ifndef _WIN32_WINNT           // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
00078   #define _WIN32_WINNT 0x0400  // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
00079 #endif
00080 #include <windows.h>
00081 #if (_WIN32_WINNT >= 0x0602)
00082   #include <synchapi.h>
00083 #endif
00084 #undef small
00085 #undef min
00086 #undef max
00087 #undef abs
00088 #include <tchar.h>
00089 #if defined _MSC_VER
00090   #if _MSC_VER >= 1400
00091     #include <intrin.h>
00092   #elif defined _M_IX86
00093     static void __cpuid(int* cpuid_data, int)
00094     {
00095         __asm
00096         {
00097             push ebx
00098             push edi
00099             mov edi, cpuid_data
00100             mov eax, 1
00101             cpuid
00102             mov [edi], eax
00103             mov [edi + 4], ebx
00104             mov [edi + 8], ecx
00105             mov [edi + 12], edx
00106             pop edi
00107             pop ebx
00108         }
00109     }
00110     static void __cpuidex(int* cpuid_data, int, int)
00111     {
00112         __asm
00113         {
00114             push edi
00115             mov edi, cpuid_data
00116             mov eax, 7
00117             mov ecx, 0
00118             cpuid
00119             mov [edi], eax
00120             mov [edi + 4], ebx
00121             mov [edi + 8], ecx
00122             mov [edi + 12], edx
00123             pop edi
00124         }
00125     }
00126   #endif
00127 #endif
00128 
00129 #ifdef WINRT
00130 #include <wrl/client.h>
00131 #ifndef __cplusplus_winrt
00132 #include <windows.storage.h>
00133 #pragma comment(lib, "runtimeobject.lib")
00134 #endif
00135 
00136 std::wstring GetTempPathWinRT()
00137 {
00138 #ifdef __cplusplus_winrt
00139     return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
00140 #else
00141     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> appdataFactory;
00142     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> appdataRef;
00143     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storagefolderRef;
00144     Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageitemRef;
00145     HSTRING str;
00146     HSTRING_HEADER hstrHead;
00147     std::wstring wstr;
00148     if (FAILED(WindowsCreateStringReference(RuntimeClass_Windows_Storage_ApplicationData,
00149                                             (UINT32)wcslen(RuntimeClass_Windows_Storage_ApplicationData), &hstrHead, &str)))
00150         return wstr;
00151     if (FAILED(RoGetActivationFactory(str, IID_PPV_ARGS(appdataFactory.ReleaseAndGetAddressOf()))))
00152         return wstr;
00153     if (FAILED(appdataFactory->get_Current(appdataRef.ReleaseAndGetAddressOf())))
00154         return wstr;
00155     if (FAILED(appdataRef->get_TemporaryFolder(storagefolderRef.ReleaseAndGetAddressOf())))
00156         return wstr;
00157     if (FAILED(storagefolderRef.As(&storageitemRef)))
00158         return wstr;
00159     str = NULL;
00160     if (FAILED(storageitemRef->get_Path(&str)))
00161         return wstr;
00162     wstr = WindowsGetStringRawBuffer(str, NULL);
00163     WindowsDeleteString(str);
00164     return wstr;
00165 #endif
00166 }
00167 
00168 std::wstring GetTempFileNameWinRT(std::wstring prefix)
00169 {
00170     wchar_t guidStr[40];
00171     GUID g;
00172     CoCreateGuid(&g);
00173     wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x";
00174     swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask,
00175              g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]),
00176              UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]),
00177              UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7]));
00178 
00179     return prefix.append(std::wstring(guidStr));
00180 }
00181 
00182 #endif
00183 #else
00184 //#include <pthread.h>
00185 //#include <sys/time.h>
00186 #include <time.h>
00187 
00188 #if defined __MACH__ && defined __APPLE__
00189 #include <mach/mach.h>
00190 #include <mach/mach_time.h>
00191 #endif
00192 
00193 #endif
00194 
00195 #ifdef _OPENMP
00196 #include "omp.h"
00197 #endif
00198 
00199 #include <stdarg.h>
00200 
00201 #if defined __linux__ || defined __APPLE__ || defined __EMSCRIPTEN__
00202 #include <unistd.h>
00203 #include <stdio.h>
00204 #include <sys/types.h>
00205 #if defined ANDROID
00206 #include <sys/sysconf.h>
00207 #endif
00208 #endif
00209 
00210 #ifdef ANDROID
00211 # include <android/log.h>
00212 #endif
00213 
00214 namespace cv
00215 {
00216 
00217 Exception::Exception () { code = 0; line = 0; }
00218 
00219 Exception::Exception (int _code, const String& _err, const String& _func, const String& _file, int _line)
00220 : code(_code), err(_err), func(_func), file(_file), line(_line)
00221 {
00222     formatMessage();
00223 }
00224 
00225 Exception::~Exception() throw() {}
00226 
00227 /*!
00228  \return the error description and the context as a text string.
00229  */
00230 const char* Exception::what () const throw() { return msg.c_str(); }
00231 
00232 void Exception::formatMessage()
00233 {
00234     if( func.size() > 0 )
00235         msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str());
00236     else
00237         msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
00238 }
00239 
00240 struct HWFeatures
00241 {
00242     enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
00243 
00244     HWFeatures(void)
00245     {
00246         memset( have, 0, sizeof(have) );
00247         x86_family = 0;
00248     }
00249 
00250     static HWFeatures initialize(void)
00251     {
00252         HWFeatures f;
00253         int cpuid_data[4] = { 0, 0, 0, 0 };
00254 
00255     #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
00256         __cpuid(cpuid_data, 1);
00257     #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
00258 
00259         #ifdef __x86_64__
00260         asm __volatile__
00261         (
00262          "movl $1, %%eax\n\t"
00263          "cpuid\n\t"
00264          :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
00265          :
00266          : "cc"
00267         );
00268         #else
00269         asm volatile
00270         (
00271          "pushl %%ebx\n\t"
00272          "movl $1,%%eax\n\t"
00273          "cpuid\n\t"
00274          "popl %%ebx\n\t"
00275          : "=a"(cpuid_data[0]), "=c"(cpuid_data[2]), "=d"(cpuid_data[3])
00276          :
00277          : "cc"
00278         );
00279         #endif
00280     #endif
00281 
00282         f.x86_family = (cpuid_data[0] >> 8) & 15;
00283         if( f.x86_family >= 6 )
00284         {
00285             f.have[CV_CPU_MMX]    = (cpuid_data[3] & (1 << 23)) != 0;
00286             f.have[CV_CPU_SSE]    = (cpuid_data[3] & (1<<25)) != 0;
00287             f.have[CV_CPU_SSE2]   = (cpuid_data[3] & (1<<26)) != 0;
00288             f.have[CV_CPU_SSE3]   = (cpuid_data[2] & (1<<0)) != 0;
00289             f.have[CV_CPU_SSSE3]  = (cpuid_data[2] & (1<<9)) != 0;
00290             f.have[CV_CPU_FMA3]  = (cpuid_data[2] & (1<<12)) != 0;
00291             f.have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
00292             f.have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
00293             f.have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0;
00294             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
00295 
00296             // make the second call to the cpuid command in order to get
00297             // information about extended features like AVX2
00298         #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
00299             __cpuidex(cpuid_data, 7, 0);
00300         #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
00301             #ifdef __x86_64__
00302             asm __volatile__
00303             (
00304              "movl $7, %%eax\n\t"
00305              "movl $0, %%ecx\n\t"
00306              "cpuid\n\t"
00307              :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
00308              :
00309              : "cc"
00310             );
00311             #else
00312             asm volatile
00313             (
00314              "pushl %%ebx\n\t"
00315              "movl $7,%%eax\n\t"
00316              "movl $0,%%ecx\n\t"
00317              "cpuid\n\t"
00318              "movl %%ebx, %0\n\t"
00319              "popl %%ebx\n\t"
00320              : "=r"(cpuid_data[1]), "=c"(cpuid_data[2])
00321              :
00322              : "cc"
00323             );
00324             #endif
00325         #endif
00326             f.have[CV_CPU_AVX2]   = (cpuid_data[1] & (1<<5)) != 0;
00327 
00328             f.have[CV_CPU_AVX_512F]       = (cpuid_data[1] & (1<<16)) != 0;
00329             f.have[CV_CPU_AVX_512DQ]      = (cpuid_data[1] & (1<<17)) != 0;
00330             f.have[CV_CPU_AVX_512IFMA512] = (cpuid_data[1] & (1<<21)) != 0;
00331             f.have[CV_CPU_AVX_512PF]      = (cpuid_data[1] & (1<<26)) != 0;
00332             f.have[CV_CPU_AVX_512ER]      = (cpuid_data[1] & (1<<27)) != 0;
00333             f.have[CV_CPU_AVX_512CD]      = (cpuid_data[1] & (1<<28)) != 0;
00334             f.have[CV_CPU_AVX_512BW]      = (cpuid_data[1] & (1<<30)) != 0;
00335             f.have[CV_CPU_AVX_512VL]      = (cpuid_data[1] & (1<<31)) != 0;
00336             f.have[CV_CPU_AVX_512VBMI]    = (cpuid_data[2] &  (1<<1)) != 0;
00337         }
00338 
00339     #if defined ANDROID || defined __linux__
00340     #ifdef __aarch64__
00341         f.have[CV_CPU_NEON] = true;
00342     #else
00343         int cpufile = open("/proc/self/auxv", O_RDONLY);
00344 
00345         if (cpufile >= 0)
00346         {
00347             Elf32_auxv_t auxv;
00348             const size_t size_auxv_t = sizeof(auxv);
00349 
00350             while ((size_t)read(cpufile, &auxv, size_auxv_t) == size_auxv_t)
00351             {
00352                 if (auxv.a_type == AT_HWCAP)
00353                 {
00354                     f.have[CV_CPU_NEON] = (auxv.a_un.a_val & 4096) != 0;
00355                     break;
00356                 }
00357             }
00358 
00359             close(cpufile);
00360         }
00361     #endif
00362     #elif (defined __clang__ || defined __APPLE__) && (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
00363         f.have[CV_CPU_NEON] = true;
00364     #endif
00365 
00366         return f;
00367     }
00368 
00369     int x86_family;
00370     bool have[MAX_FEATURE+1];
00371 };
00372 
00373 static HWFeatures  featuresEnabled = HWFeatures::initialize(), featuresDisabled = HWFeatures();
00374 static HWFeatures* currentFeatures = &featuresEnabled;
00375 
00376 bool checkHardwareSupport(int feature)
00377 {
00378     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
00379     return currentFeatures->have[feature];
00380 }
00381 
00382 
00383 volatile bool useOptimizedFlag = true;
00384 
00385 void setUseOptimized( bool flag )
00386 {
00387     useOptimizedFlag = flag;
00388     currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
00389 
00390     ipp::setUseIPP(flag);
00391 #ifdef HAVE_OPENCL
00392     ocl::setUseOpenCL(flag);
00393 #endif
00394 #ifdef HAVE_TEGRA_OPTIMIZATION
00395     ::tegra::setUseTegra(flag);
00396 #endif
00397 }
00398 
00399 struct timeval
00400 {
00401   unsigned long long int tv_sec;        /* Seconds. */
00402   unsigned long long int tv_usec;    /* Microseconds. */
00403 };
00404 
00405 
00406 bool useOptimized(void)
00407 {
00408     return useOptimizedFlag;
00409 }
00410 
00411 int64 getTickCount(void)
00412 {
00413 #if defined WIN32 || defined _WIN32 || defined WINCE
00414     LARGE_INTEGER counter;
00415     QueryPerformanceCounter( &counter );
00416     return (int64)counter.QuadPart;
00417 #elif defined __linux || defined __linux__
00418     struct timespec tp;
00419     clock_gettime(CLOCK_MONOTONIC, &tp);
00420     return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
00421 #elif defined __MACH__ && defined __APPLE__
00422     return (int64)mach_absolute_time();
00423 #else
00424     struct timeval tv;
00425     //struct timezone tz;
00426 //    gettimeofday( &tv, &tz );
00427     return (int64)tv.tv_sec*1000000 + tv.tv_usec;
00428 #endif
00429 }
00430 
00431 double getTickFrequency(void)
00432 {
00433 #if defined WIN32 || defined _WIN32 || defined WINCE
00434     LARGE_INTEGER freq;
00435     QueryPerformanceFrequency(&freq);
00436     return (double)freq.QuadPart;
00437 #elif defined __linux || defined __linux__
00438     return 1e9;
00439 #elif defined __MACH__ && defined __APPLE__
00440     static double freq = 0;
00441     if( freq == 0 )
00442     {
00443         mach_timebase_info_data_t sTimebaseInfo;
00444         mach_timebase_info(&sTimebaseInfo);
00445         freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
00446     }
00447     return freq;
00448 #else
00449     return 1e6;
00450 #endif
00451 }
00452 
00453 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__)
00454 #if defined(__i386__)
00455 
00456 int64 getCPUTickCount(void)
00457 {
00458     int64 x;
00459     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
00460     return x;
00461 }
00462 #elif defined(__x86_64__)
00463 
00464 int64 getCPUTickCount(void)
00465 {
00466     unsigned hi, lo;
00467     __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
00468     return (int64)lo | ((int64)hi << 32);
00469 }
00470 
00471 #elif defined(__ppc__)
00472 
00473 int64 getCPUTickCount(void)
00474 {
00475     int64 result = 0;
00476     unsigned upper, lower, tmp;
00477     __asm__ volatile(
00478                      "0:                  \n"
00479                      "\tmftbu   %0           \n"
00480                      "\tmftb    %1           \n"
00481                      "\tmftbu   %2           \n"
00482                      "\tcmpw    %2,%0        \n"
00483                      "\tbne     0b         \n"
00484                      : "=r"(upper),"=r"(lower),"=r"(tmp)
00485                      );
00486     return lower | ((int64)upper << 32);
00487 }
00488 
00489 #else
00490 
00491 #error "RDTSC not defined"
00492 
00493 #endif
00494 
00495 #elif defined _MSC_VER && defined WIN32 && defined _M_IX86
00496 
00497 int64 getCPUTickCount(void)
00498 {
00499     __asm _emit 0x0f;
00500     __asm _emit 0x31;
00501 }
00502 
00503 #else
00504 
00505 //#ifdef HAVE_IPP
00506 //int64 getCPUTickCount(void)
00507 //{
00508 //    return ippGetCpuClocks();
00509 //}
00510 //#else
00511 int64 getCPUTickCount(void)
00512 {
00513     return getTickCount();
00514 }
00515 //#endif
00516 
00517 #endif
00518 
00519 const String& getBuildInformation()
00520 {
00521     static String build_info =
00522 #include "version_string.inc"
00523     ;
00524     return build_info;
00525 }
00526 
00527 String format( const char* fmt, ... )
00528 {
00529     AutoBuffer<char, 1024> buf;
00530 
00531     for ( ; ; )
00532     {
00533         va_list va;
00534         va_start(va, fmt);
00535         int bsize = static_cast<int>(buf.size()),
00536                 len = vsnprintf((char *)buf, bsize, fmt, va);
00537         va_end(va);
00538 
00539         if (len < 0 || len >= bsize)
00540         {
00541             buf.resize(std::max(bsize << 1, len + 1));
00542             continue;
00543         }
00544         return String((char *)buf, len);
00545     }
00546 }
00547 
00548 String tempfile( const char* suffix )
00549 {
00550     String fname;
00551 #ifndef WINRT
00552     const char *temp_dir = getenv("OPENCV_TEMP_PATH");
00553 #endif
00554 
00555 #if defined WIN32 || defined _WIN32
00556 #ifdef WINRT
00557     RoInitialize(RO_INIT_MULTITHREADED);
00558     std::wstring temp_dir = GetTempPathWinRT();
00559 
00560     std::wstring temp_file = GetTempFileNameWinRT(L"ocv");
00561     if (temp_file.empty())
00562         return String();
00563 
00564     temp_file = temp_dir.append(std::wstring(L"\\")).append(temp_file);
00565     DeleteFileW(temp_file.c_str());
00566 
00567     char aname[MAX_PATH];
00568     size_t copied = wcstombs(aname, temp_file.c_str(), MAX_PATH);
00569     CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
00570     fname = String(aname);
00571     RoUninitialize();
00572 #else
00573     char temp_dir2[MAX_PATH] = { 0 };
00574     char temp_file[MAX_PATH] = { 0 };
00575 
00576     if (temp_dir == 0 || temp_dir[0] == 0)
00577     {
00578         ::GetTempPathA(sizeof(temp_dir2), temp_dir2);
00579         temp_dir = temp_dir2;
00580     }
00581     if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file))
00582         return String();
00583 
00584     DeleteFileA(temp_file);
00585 
00586     fname = temp_file;
00587 #endif
00588 # else
00589 #  ifdef ANDROID
00590     //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
00591     char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
00592 #  else
00593     char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
00594 #  endif
00595 
00596     if (temp_dir == 0 || temp_dir[0] == 0)
00597         fname = defaultTemplate;
00598     else
00599     {
00600         fname = temp_dir;
00601         char ech = fname[fname.size() - 1];
00602         if(ech != '/' && ech != '\\')
00603             fname = fname + "/";
00604         fname = fname + "__opencv_temp.XXXXXX";
00605     }
00606 
00607 //TDDB: Thedo comment here
00608 /*    const int fd = mkstemp((char*)fname.c_str());
00609     if (fd == -1) return String();
00610 
00611     close(fd);*/
00612     remove(fname.c_str());
00613 # endif
00614 
00615     if (suffix)
00616     {
00617         if (suffix[0] != '.')
00618             return fname + "." + suffix;
00619         else
00620             return fname + suffix;
00621     }
00622     return fname;
00623 }
00624 
00625 static CvErrorCallback customErrorCallback = 0;
00626 static void* customErrorCallbackData = 0;
00627 static bool breakOnError = false;
00628 
00629 bool setBreakOnError(bool value)
00630 {
00631     bool prevVal = breakOnError;
00632     breakOnError = value;
00633     return prevVal;
00634 }
00635 
00636 void error( const Exception& exc )
00637 {
00638     if (customErrorCallback != 0)
00639         customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
00640                             exc.file.c_str(), exc.line, customErrorCallbackData);
00641     else
00642     {
00643         const char* errorStr = cvErrorStr(exc.code);
00644         char buf[1 << 16];
00645 
00646         sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
00647             errorStr, exc.err.c_str(), exc.func.size() > 0 ?
00648             exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
00649         fprintf( stderr, "%s\n", buf );
00650         fflush( stderr );
00651 #  ifdef __ANDROID__
00652         __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf);
00653 #  endif
00654     }
00655 
00656     if(breakOnError)
00657     {
00658         static volatile int* p = 0;
00659         *p = 0;
00660     }
00661 
00662     return;//throw exc;
00663 }
00664 
00665 void error(int _code, const String& _err, const char* _func, const char* _file, int _line)
00666 {
00667     error(cv::Exception(_code, _err, _func, _file, _line));
00668 }
00669 
00670 CvErrorCallback
00671 redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
00672 {
00673     if( prevUserdata )
00674         *prevUserdata = customErrorCallbackData;
00675 
00676     CvErrorCallback prevCallback = customErrorCallback;
00677 
00678     customErrorCallback     = errCallback;
00679     customErrorCallbackData = userdata;
00680 
00681     return prevCallback;
00682 }
00683 
00684 }
00685 
00686 CV_IMPL int cvCheckHardwareSupport(int feature)
00687 {
00688     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
00689     return cv::currentFeatures->have[feature];
00690 }
00691 
00692 CV_IMPL int cvUseOptimized( int flag )
00693 {
00694     int prevMode = cv::useOptimizedFlag;
00695     cv::setUseOptimized( flag != 0 );
00696     return prevMode;
00697 }
00698 
00699 CV_IMPL int64  cvGetTickCount(void)
00700 {
00701     return cv::getTickCount();
00702 }
00703 
00704 CV_IMPL double cvGetTickFrequency(void)
00705 {
00706     return cv::getTickFrequency()*1e-6;
00707 }
00708 
00709 CV_IMPL CvErrorCallback
00710 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
00711 {
00712     return cv::redirectError(errCallback, userdata, prevUserdata);
00713 }
00714 
00715 CV_IMPL int cvNulDevReport( int, const char*, const char*,
00716                             const char*, int, void* )
00717 {
00718     return 0;
00719 }
00720 
00721 CV_IMPL int cvStdErrReport( int, const char*, const char*,
00722                             const char*, int, void* )
00723 {
00724     return 0;
00725 }
00726 
00727 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
00728                             const char*, int, void* )
00729 {
00730     return 0;
00731 }
00732 
00733 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
00734 {
00735     return 0;
00736 }
00737 
00738 
00739 CV_IMPL const char* cvErrorStr( int status )
00740 {
00741     static char buf[256];
00742 
00743     switch (status)
00744     {
00745     case CV_StsOk :                  return "No Error";
00746     case CV_StsBackTrace :           return "Backtrace";
00747     case CV_StsError :               return "Unspecified error";
00748     case CV_StsInternal :            return "Internal error";
00749     case CV_StsNoMem :               return "Insufficient memory";
00750     case CV_StsBadArg :              return "Bad argument";
00751     case CV_StsNoConv :              return "Iterations do not converge";
00752     case CV_StsAutoTrace :           return "Autotrace call";
00753     case CV_StsBadSize :             return "Incorrect size of input array";
00754     case CV_StsNullPtr :             return "Null pointer";
00755     case CV_StsDivByZero :           return "Division by zero occured";
00756     case CV_BadStep :                return "Image step is wrong";
00757     case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
00758     case CV_StsObjectNotFound :      return "Requested object was not found";
00759     case CV_BadDepth :               return "Input image depth is not supported by function";
00760     case CV_StsUnmatchedFormats :    return "Formats of input arguments do not match";
00761     case CV_StsUnmatchedSizes :      return "Sizes of input arguments do not match";
00762     case CV_StsOutOfRange :          return "One of arguments\' values is out of range";
00763     case CV_StsUnsupportedFormat :   return "Unsupported format or combination of formats";
00764     case CV_BadCOI :                 return "Input COI is not supported";
00765     case CV_BadNumChannels :         return "Bad number of channels";
00766     case CV_StsBadFlag :             return "Bad flag (parameter or structure field)";
00767     case CV_StsBadPoint :            return "Bad parameter of type CvPoint";
00768     case CV_StsBadMask :             return "Bad type of mask argument";
00769     case CV_StsParseError :          return "Parsing error";
00770     case CV_StsNotImplemented :      return "The function/feature is not implemented";
00771     case CV_StsBadMemBlock :         return "Memory block has been corrupted";
00772     case CV_StsAssert :              return "Assertion failed";
00773     case CV_GpuNotSupported :        return "No CUDA support";
00774     case CV_GpuApiCallError :        return "Gpu API call";
00775     case CV_OpenGlNotSupported :     return "No OpenGL support";
00776     case CV_OpenGlApiCallError :     return "OpenGL API call";
00777     };
00778 
00779     sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
00780     return buf;
00781 }
00782 
00783 CV_IMPL int cvGetErrMode(void)
00784 {
00785     return 0;
00786 }
00787 
00788 CV_IMPL int cvSetErrMode(int)
00789 {
00790     return 0;
00791 }
00792 
00793 CV_IMPL int cvGetErrStatus(void)
00794 {
00795     return 0;
00796 }
00797 
00798 CV_IMPL void cvSetErrStatus(int)
00799 {
00800 }
00801 
00802 
00803 CV_IMPL void cvError( int code, const char* func_name,
00804                       const char* err_msg,
00805                       const char* file_name, int line )
00806 {
00807     cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
00808 }
00809 
00810 /* function, which converts int to int */
00811 CV_IMPL int
00812 cvErrorFromIppStatus( int status )
00813 {
00814     switch (status)
00815     {
00816     case CV_BADSIZE_ERR:               return CV_StsBadSize;
00817     case CV_BADMEMBLOCK_ERR:           return CV_StsBadMemBlock;
00818     case CV_NULLPTR_ERR:               return CV_StsNullPtr;
00819     case CV_DIV_BY_ZERO_ERR:           return CV_StsDivByZero;
00820     case CV_BADSTEP_ERR:               return CV_BadStep;
00821     case CV_OUTOFMEM_ERR:              return CV_StsNoMem;
00822     case CV_BADARG_ERR:                return CV_StsBadArg;
00823     case CV_NOTDEFINED_ERR:            return CV_StsError;
00824     case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
00825     case CV_NOTFOUND_ERR:              return CV_StsObjectNotFound;
00826     case CV_BADCONVERGENCE_ERR:        return CV_StsNoConv;
00827     case CV_BADDEPTH_ERR:              return CV_BadDepth;
00828     case CV_UNMATCHED_FORMATS_ERR:     return CV_StsUnmatchedFormats;
00829     case CV_UNSUPPORTED_COI_ERR:       return CV_BadCOI;
00830     case CV_UNSUPPORTED_CHANNELS_ERR:  return CV_BadNumChannels;
00831     case CV_BADFLAG_ERR:               return CV_StsBadFlag;
00832     case CV_BADRANGE_ERR:              return CV_StsBadArg;
00833     case CV_BADCOEF_ERR:               return CV_StsBadArg;
00834     case CV_BADFACTOR_ERR:             return CV_StsBadArg;
00835     case CV_BADPOINT_ERR:              return CV_StsBadPoint;
00836 
00837     default:
00838       return CV_StsError;
00839     }
00840 }
00841 
00842 namespace cv {
00843 bool __termination = false;
00844 }
00845 
00846 namespace cv
00847 {
00848 
00849 #if defined WIN32 || defined _WIN32 || defined WINCE
00850 
00851 struct Mutex::Impl
00852 {
00853     Impl()
00854     {
00855 #if (_WIN32_WINNT >= 0x0600)
00856         ::InitializeCriticalSectionEx(&cs, 1000, 0);
00857 #else
00858         ::InitializeCriticalSection(&cs);
00859 #endif
00860         refcount = 1;
00861     }
00862     ~Impl() { DeleteCriticalSection(&cs); }
00863 
00864     void lock() { EnterCriticalSection(&cs); }
00865     bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
00866     void unlock() { LeaveCriticalSection(&cs); }
00867 
00868     CRITICAL_SECTION cs;
00869     int refcount;
00870 };
00871 
00872 #else
00873 
00874 struct Mutex::Impl
00875 {
00876 #ifdef USE_PTHREAD
00877     Impl()
00878     {
00879         pthread_mutexattr_t attr;
00880         pthread_mutexattr_init(&attr);
00881         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00882         pthread_mutex_init(&mt, &attr);
00883         pthread_mutexattr_destroy(&attr);
00884 
00885         refcount = 1;
00886     }
00887     ~Impl() { pthread_mutex_destroy(&mt); }
00888 
00889     void lock() { pthread_mutex_lock(&mt); }
00890     bool trylock() { return pthread_mutex_trylock(&mt) == 0; }
00891     void unlock() { pthread_mutex_unlock(&mt); }
00892 
00893     pthread_mutex_t mt;
00894 #else
00895     void lock() { }
00896     bool trylock() { }
00897     void unlock() { }
00898 #endif
00899     int refcount;
00900 };
00901 
00902 #endif
00903 
00904 Mutex::Mutex()
00905 {
00906     impl = new Mutex::Impl;
00907 }
00908 
00909 Mutex::~Mutex()
00910 {
00911     if( CV_XADD(&impl->refcount, -1) == 1 )
00912         delete impl;
00913     impl = 0;
00914 }
00915 
00916 Mutex::Mutex(const Mutex& m)
00917 {
00918     impl = m.impl;
00919     CV_XADD(&impl->refcount, 1);
00920 }
00921 
00922 Mutex& Mutex::operator = (const Mutex& m)
00923 {
00924     CV_XADD(&m.impl->refcount, 1);
00925     if( CV_XADD(&impl->refcount, -1) == 1 )
00926         delete impl;
00927     impl = m.impl;
00928     return *this;
00929 }
00930 
00931 void Mutex::lock() { impl->lock(); }
00932 void Mutex::unlock() { impl->unlock(); }
00933 bool Mutex::trylock() { return impl->trylock(); }
00934 
00935 
00936 //////////////////////////////// thread-local storage ////////////////////////////////
00937 
00938 #ifdef WIN32
00939 #ifdef _MSC_VER
00940 #pragma warning(disable:4505) // unreferenced local function has been removed
00941 #endif
00942 #ifndef TLS_OUT_OF_INDEXES
00943 #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
00944 #endif
00945 #endif
00946 
00947 // TLS platform abstraction layer
00948 class TlsAbstraction
00949 {
00950 public:
00951     TlsAbstraction();
00952     ~TlsAbstraction();
00953     void* GetData() const;
00954     void  SetData(void *pData);
00955 
00956 private:
00957 #ifdef WIN32
00958 #ifndef WINRT
00959     DWORD tlsKey;
00960 #endif
00961 #else // WIN32
00962 #ifdef USE_PTHREAD
00963     pthread_key_t  tlsKey;
00964 #endif
00965 #endif
00966 };
00967 
00968 #ifdef WIN32
00969 #ifdef WINRT
00970 static __declspec( thread ) void* tlsData = NULL; // using C++11 thread attribute for local thread data
00971 TlsAbstraction::TlsAbstraction() {}
00972 TlsAbstraction::~TlsAbstraction() {}
00973 void* TlsAbstraction::GetData() const
00974 {
00975     return tlsData;
00976 }
00977 void  TlsAbstraction::SetData(void *pData)
00978 {
00979     tlsData = pData;
00980 }
00981 #else //WINRT
00982 TlsAbstraction::TlsAbstraction()
00983 {
00984     tlsKey = TlsAlloc();
00985     CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
00986 }
00987 TlsAbstraction::~TlsAbstraction()
00988 {
00989     TlsFree(tlsKey);
00990 }
00991 void* TlsAbstraction::GetData() const
00992 {
00993     return TlsGetValue(tlsKey);
00994 }
00995 void  TlsAbstraction::SetData(void *pData)
00996 {
00997     CV_Assert(TlsSetValue(tlsKey, pData) == TRUE);
00998 }
00999 #endif
01000 #else // WIN32
01001 TlsAbstraction::TlsAbstraction()
01002 {
01003 #ifdef USE_PTHREAD
01004     CV_Assert(pthread_key_create(&tlsKey, NULL) == 0);
01005 #endif
01006 }
01007 TlsAbstraction::~TlsAbstraction()
01008 {
01009 #ifdef USE_PTHREAD
01010     CV_Assert(pthread_key_delete(tlsKey) == 0);
01011 #endif
01012 }
01013 void* TlsAbstraction::GetData() const
01014 {
01015 #ifdef USE_PTHREAD
01016     return pthread_getspecific(tlsKey);
01017 #endif
01018 }
01019 void  TlsAbstraction::SetData(void *pData)
01020 {
01021 #ifdef USE_PTHREAD
01022     CV_Assert(pthread_setspecific(tlsKey, pData) == 0);
01023 #endif
01024 }
01025 #endif
01026 
01027 // Per-thread data structure
01028 struct ThreadData
01029 {
01030     ThreadData()
01031     {
01032         idx = 0;
01033         slots.reserve(32);
01034     }
01035 
01036     std::vector<void*> slots; // Data array for a thread
01037     size_t idx;               // Thread index in TLS storage. This is not OS thread ID!
01038 };
01039 
01040 // Main TLS storage class
01041 class TlsStorage
01042 {
01043 public:
01044     TlsStorage()
01045     {
01046         tlsSlots.reserve(32);
01047         threads.reserve(32);
01048     }
01049     ~TlsStorage()
01050     {
01051         for(size_t i = 0; i < threads.size(); i++)
01052         {
01053             if(threads[i])
01054             {
01055                 /* Current architecture doesn't allow proper global objects relase, so this check can cause crashes
01056 
01057                 // Check if all slots were properly cleared
01058                 for(size_t j = 0; j < threads[i]->slots.size(); j++)
01059                 {
01060                     CV_Assert(threads[i]->slots[j] == 0);
01061                 }
01062                 */
01063                 delete threads[i];
01064             }
01065         }
01066         threads.clear();
01067     }
01068 
01069     void releaseThread()
01070     {
01071         AutoLock guard(mtxGlobalAccess);
01072         ThreadData *pTD = (ThreadData*)tls.GetData();
01073         for(size_t i = 0; i < threads.size(); i++)
01074         {
01075             if(pTD == threads[i])
01076             {
01077                 threads[i] = 0;
01078                 break;
01079             }
01080         }
01081         tls.SetData(0);
01082         delete pTD;
01083     }
01084 
01085     // Reserve TLS storage index
01086     size_t reserveSlot()
01087     {
01088         AutoLock guard(mtxGlobalAccess);
01089 
01090         // Find unused slots
01091         for(size_t slot = 0; slot < tlsSlots.size(); slot++)
01092         {
01093             if(!tlsSlots[slot])
01094             {
01095                 tlsSlots[slot] = 1;
01096                 return slot;
01097             }
01098         }
01099 
01100         // Create new slot
01101         tlsSlots.push_back(1);
01102         return (tlsSlots.size()-1);
01103     }
01104 
01105     // Release TLS storage index and pass assosiated data to caller
01106     void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec)
01107     {
01108         AutoLock guard(mtxGlobalAccess);
01109         CV_Assert(tlsSlots.size() > slotIdx);
01110 
01111         for(size_t i = 0; i < threads.size(); i++)
01112         {
01113             std::vector<void*>& thread_slots = threads[i]->slots;
01114             if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
01115             {
01116                 dataVec.push_back(thread_slots[slotIdx]);
01117                 threads[i]->slots[slotIdx] = 0;
01118             }
01119         }
01120 
01121         tlsSlots[slotIdx] = 0;
01122     }
01123 
01124     // Get data by TLS storage index
01125     void* getData(size_t slotIdx) const
01126     {
01127         CV_Assert(tlsSlots.size() > slotIdx);
01128 
01129         ThreadData* threadData = (ThreadData*)tls.GetData();
01130         if(threadData && threadData->slots.size() > slotIdx)
01131             return threadData->slots[slotIdx];
01132 
01133         return NULL;
01134     }
01135 
01136     // Gather data from threads by TLS storage index
01137     void gather(size_t slotIdx, std::vector<void*> &dataVec)
01138     {
01139         AutoLock guard(mtxGlobalAccess);
01140         CV_Assert(tlsSlots.size() > slotIdx);
01141 
01142         for(size_t i = 0; i < threads.size(); i++)
01143         {
01144             std::vector<void*>& thread_slots = threads[i]->slots;
01145             if (thread_slots.size() > slotIdx && thread_slots[slotIdx])
01146                 dataVec.push_back(thread_slots[slotIdx]);
01147         }
01148     }
01149 
01150     // Set data to storage index
01151     void setData(size_t slotIdx, void* pData)
01152     {
01153         CV_Assert(tlsSlots.size() > slotIdx && pData != NULL);
01154 
01155         ThreadData* threadData = (ThreadData*)tls.GetData();
01156         if(!threadData)
01157         {
01158             threadData = new ThreadData;
01159             tls.SetData((void*)threadData);
01160             {
01161                 AutoLock guard(mtxGlobalAccess);
01162                 threadData->idx = threads.size();
01163                 threads.push_back(threadData);
01164             }
01165         }
01166 
01167         if(slotIdx >= threadData->slots.size())
01168         {
01169             AutoLock guard(mtxGlobalAccess);
01170             while(slotIdx >= threadData->slots.size())
01171                 threadData->slots.push_back(NULL);
01172         }
01173         threadData->slots[slotIdx] = pData;
01174     }
01175 
01176 private:
01177     TlsAbstraction tls; // TLS abstraction layer instance
01178 
01179     Mutex  mtxGlobalAccess;           // Shared objects operation guard
01180     std::vector<int> tlsSlots;        // TLS keys state
01181     std::vector<ThreadData*> threads; // Array for all allocated data. Thread data pointers are placed here to allow data cleanup
01182 };
01183 
01184 // Create global TLS storage object
01185 static TlsStorage &getTlsStorage()
01186 {
01187     CV_SINGLETON_LAZY_INIT_REF(TlsStorage, new TlsStorage())
01188 }
01189 
01190 TLSDataContainer::TLSDataContainer()
01191 {
01192     key_ = (int)getTlsStorage().reserveSlot(); // Reserve key from TLS storage
01193 }
01194 
01195 TLSDataContainer::~TLSDataContainer()
01196 {
01197     CV_Assert(key_ == -1); // Key must be released in child object
01198 }
01199 
01200 void TLSDataContainer::gatherData(std::vector<void*> &data) const
01201 {
01202     getTlsStorage().gather(key_, data);
01203 }
01204 
01205 void TLSDataContainer::release()
01206 {
01207     std::vector<void*> data;
01208     data.reserve(32);
01209     getTlsStorage().releaseSlot(key_, data); // Release key and get stored data for proper destruction
01210     for(size_t i = 0; i < data.size(); i++)  // Delete all assosiated data
01211         deleteDataInstance(data[i]);
01212     key_ = -1;
01213 }
01214 
01215 void* TLSDataContainer::getData() const
01216 {
01217     void* pData = getTlsStorage().getData(key_); // Check if data was already allocated
01218     if(!pData)
01219     {
01220         // Create new data instance and save it to TLS storage
01221         pData = createDataInstance();
01222         getTlsStorage().setData(key_, pData);
01223     }
01224     return pData;
01225 }
01226 
01227 TLSData<CoreTLSData>& getCoreTlsData()
01228 {
01229     CV_SINGLETON_LAZY_INIT_REF(TLSData<CoreTLSData>, new TLSData<CoreTLSData>())
01230 }
01231 
01232 #if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
01233 #ifdef WINRT
01234     #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
01235 #endif
01236 
01237 extern "C"
01238 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved);
01239 
01240 extern "C"
01241 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
01242 {
01243     if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
01244     {
01245         if (lpReserved != NULL) // called after ExitProcess() call
01246         {
01247             cv::__termination = true;
01248         }
01249         else
01250         {
01251             // Not allowed to free resources if lpReserved is non-null
01252             // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583.aspx
01253             cv::deleteThreadAllocData();
01254             cv::getTlsStorage().releaseThread();
01255         }
01256     }
01257     return TRUE;
01258 }
01259 #endif
01260 
01261 #ifdef CV_COLLECT_IMPL_DATA
01262 ImplCollector& getImplData()
01263 {
01264     CV_SINGLETON_LAZY_INIT_REF(ImplCollector, new ImplCollector())
01265 }
01266 
01267 void setImpl(int flags)
01268 {
01269     cv::AutoLock lock(getImplData().mutex);
01270 
01271     getImplData().implFlags = flags;
01272     getImplData().implCode.clear();
01273     getImplData().implFun.clear();
01274 }
01275 
01276 void addImpl(int flag, const char* func)
01277 {
01278     cv::AutoLock lock(getImplData().mutex);
01279 
01280     getImplData().implFlags |= flag;
01281     if(func) // use lazy collection if name was not specified
01282     {
01283         size_t index = getImplData().implCode.size();
01284         if(!index || (getImplData().implCode[index-1] != flag || getImplData().implFun[index-1].compare(func))) // avoid duplicates
01285         {
01286             getImplData().implCode.push_back(flag);
01287             getImplData().implFun.push_back(func);
01288         }
01289     }
01290 }
01291 
01292 int getImpl(std::vector<int> &impl, std::vector<String> &funName)
01293 {
01294     cv::AutoLock lock(getImplData().mutex);
01295 
01296     impl    = getImplData().implCode;
01297     funName = getImplData().implFun;
01298     return getImplData().implFlags; // return actual flags for lazy collection
01299 }
01300 
01301 bool useCollection()
01302 {
01303     return getImplData().useCollection;
01304 }
01305 
01306 void setUseCollection(bool flag)
01307 {
01308     cv::AutoLock lock(getImplData().mutex);
01309 
01310     getImplData().useCollection = flag;
01311 }
01312 #endif
01313 
01314 namespace ipp
01315 {
01316 
01317 struct IPPInitSingelton
01318 {
01319 public:
01320     IPPInitSingelton()
01321     {
01322         useIPP      = true;
01323         ippStatus   = 0;
01324         funcname    = NULL;
01325         filename    = NULL;
01326         linen       = 0;
01327         ippFeatures = 0;
01328 
01329 #ifdef HAVE_IPP
01330         const char* pIppEnv = getenv("OPENCV_IPP");
01331         cv::String env = pIppEnv;
01332         if(env.size())
01333         {
01334             if(env == "disabled")
01335             {
01336                 std::cerr << "WARNING: IPP was disabled by OPENCV_IPP environment variable" << std::endl;
01337                 useIPP = false;
01338             }
01339 #if IPP_VERSION_X100 >= 900
01340             else if(env == "sse")
01341                 ippFeatures = ippCPUID_SSE;
01342             else if(env == "sse2")
01343                 ippFeatures = ippCPUID_SSE2;
01344             else if(env == "sse3")
01345                 ippFeatures = ippCPUID_SSE3;
01346             else if(env == "ssse3")
01347                 ippFeatures = ippCPUID_SSSE3;
01348             else if(env == "sse41")
01349                 ippFeatures = ippCPUID_SSE41;
01350             else if(env == "sse42")
01351                 ippFeatures = ippCPUID_SSE42;
01352             else if(env == "avx")
01353                 ippFeatures = ippCPUID_AVX;
01354             else if(env == "avx2")
01355                 ippFeatures = ippCPUID_AVX2;
01356 #endif
01357             else
01358                 std::cerr << "ERROR: Improper value of OPENCV_IPP: " << env.c_str() << std::endl;
01359         }
01360 
01361         IPP_INITIALIZER(ippFeatures)
01362 #endif
01363     }
01364 
01365     bool useIPP;
01366 
01367     int         ippStatus; // 0 - all is ok, -1 - IPP functions failed
01368     const char *funcname;
01369     const char *filename;
01370     int         linen;
01371     int         ippFeatures;
01372 };
01373 
01374 static IPPInitSingelton& getIPPSingelton()
01375 {
01376     CV_SINGLETON_LAZY_INIT_REF(IPPInitSingelton, new IPPInitSingelton())
01377 }
01378 
01379 int getIppFeatures()
01380 {
01381 #ifdef HAVE_IPP
01382     return getIPPSingelton().ippFeatures;
01383 #else
01384     return 0;
01385 #endif
01386 }
01387 
01388 void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
01389 {
01390     getIPPSingelton().ippStatus = status;
01391     getIPPSingelton().funcname = _funcname;
01392     getIPPSingelton().filename = _filename;
01393     getIPPSingelton().linen = _line;
01394 }
01395 
01396 int getIppStatus()
01397 {
01398     return getIPPSingelton().ippStatus;
01399 }
01400 
01401 String getIppErrorLocation()
01402 {
01403     return format("%s:%d %s", getIPPSingelton().filename ? getIPPSingelton().filename : "", getIPPSingelton().linen, getIPPSingelton().funcname ? getIPPSingelton().funcname : "");
01404 }
01405 
01406 bool useIPP()
01407 {
01408 #ifdef HAVE_IPP
01409     CoreTLSData* data = getCoreTlsData().get();
01410     if(data->useIPP < 0)
01411     {
01412         data->useIPP = getIPPSingelton().useIPP;
01413     }
01414     return (data->useIPP > 0);
01415 #else
01416     return false;
01417 #endif
01418 }
01419 
01420 void setUseIPP(bool flag)
01421 {
01422     CoreTLSData* data = getCoreTlsData().get();
01423 #ifdef HAVE_IPP
01424     data->useIPP = flag;
01425 #else
01426     (void)flag;
01427     data->useIPP = false;
01428 #endif
01429 }
01430 
01431 } // namespace ipp
01432 
01433 } // namespace cv
01434 
01435 #ifdef HAVE_TEGRA_OPTIMIZATION
01436 
01437 namespace tegra {
01438 
01439 bool useTegra()
01440 {
01441     cv::CoreTLSData* data = cv::getCoreTlsData().get();
01442 
01443     if (data->useTegra < 0)
01444     {
01445         const char* pTegraEnv = getenv("OPENCV_TEGRA");
01446         if (pTegraEnv && (cv::String(pTegraEnv) == "disabled"))
01447             data->useTegra = false;
01448         else
01449             data->useTegra = true;
01450     }
01451 
01452     return (data->useTegra > 0);
01453 }
01454 
01455 void setUseTegra(bool flag)
01456 {
01457     cv::CoreTLSData* data = cv::getCoreTlsData().get();
01458     data->useTegra = flag;
01459 }
01460 
01461 } // namespace tegra
01462 
01463 #endif
01464 
01465 /* End of file. */
01466