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