Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
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
Generated on Tue Jul 12 2022 14:47:39 by
