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
__cpuid(int * cpuid_data,int)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     }
__cpuidex(int * cpuid_data,int,int)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 
GetTempPathWinRT()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 
GetTempFileNameWinRT(std::wstring prefix)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 
Exception()200 Exception::Exception() { code = 0; line = 0; }
201 
Exception(int _code,const String & _err,const String & _func,const String & _file,int _line)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 
~Exception()208 Exception::~Exception() throw() {}
209 
210 /*!
211  \return the error description and the context as a text string.
212  */
what() const213 const char* Exception::what() const throw() { return msg.c_str(); }
214 
formatMessage()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 
HWFeaturescv::HWFeatures227     HWFeatures(void)
228     {
229         memset( have, 0, sizeof(have) );
230         x86_family = 0;
231     }
232 
initializecv::HWFeatures233     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 
checkHardwareSupport(int feature)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 {
IPPInitializercv::IPPInitializer369     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 
setUseOptimized(bool flag)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 
useOptimized(void)400 bool useOptimized(void)
401 {
402     return useOptimizedFlag;
403 }
404 
getTickCount(void)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 
getTickFrequency(void)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 
getCPUTickCount(void)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 
getCPUTickCount(void)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 
getCPUTickCount(void)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 
getCPUTickCount(void)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
getCPUTickCount(void)505 int64 getCPUTickCount(void)
506 {
507     return getTickCount();
508 }
509 //#endif
510 
511 #endif
512 
getBuildInformation()513 const String& getBuildInformation()
514 {
515     static String build_info =
516 #include "version_string.inc"
517     ;
518     return build_info;
519 }
520 
format(const char * fmt,...)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 
tempfile(const char * suffix)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 
setBreakOnError(bool value)622 bool setBreakOnError(bool value)
623 {
624     bool prevVal = breakOnError;
625     breakOnError = value;
626     return prevVal;
627 }
628 
error(const Exception & exc)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 
error(int _code,const String & _err,const char * _func,const char * _file,int _line)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
redirectError(CvErrorCallback errCallback,void * userdata,void ** prevUserdata)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 
cvCheckHardwareSupport(int feature)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 
cvUseOptimized(int flag)685 CV_IMPL int cvUseOptimized( int flag )
686 {
687     int prevMode = cv::useOptimizedFlag;
688     cv::setUseOptimized( flag != 0 );
689     return prevMode;
690 }
691 
cvGetTickCount(void)692 CV_IMPL int64  cvGetTickCount(void)
693 {
694     return cv::getTickCount();
695 }
696 
cvGetTickFrequency(void)697 CV_IMPL double cvGetTickFrequency(void)
698 {
699     return cv::getTickFrequency()*1e-6;
700 }
701 
702 CV_IMPL CvErrorCallback
cvRedirectError(CvErrorCallback errCallback,void * userdata,void ** prevUserdata)703 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
704 {
705     return cv::redirectError(errCallback, userdata, prevUserdata);
706 }
707 
cvNulDevReport(int,const char *,const char *,const char *,int,void *)708 CV_IMPL int cvNulDevReport( int, const char*, const char*,
709                             const char*, int, void* )
710 {
711     return 0;
712 }
713 
cvStdErrReport(int,const char *,const char *,const char *,int,void *)714 CV_IMPL int cvStdErrReport( int, const char*, const char*,
715                             const char*, int, void* )
716 {
717     return 0;
718 }
719 
cvGuiBoxReport(int,const char *,const char *,const char *,int,void *)720 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
721                             const char*, int, void* )
722 {
723     return 0;
724 }
725 
cvGetErrInfo(const char **,const char **,const char **,int *)726 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
727 {
728     return 0;
729 }
730 
731 
cvErrorStr(int status)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 
cvGetErrMode(void)776 CV_IMPL int cvGetErrMode(void)
777 {
778     return 0;
779 }
780 
cvSetErrMode(int)781 CV_IMPL int cvSetErrMode(int)
782 {
783     return 0;
784 }
785 
cvGetErrStatus(void)786 CV_IMPL int cvGetErrStatus(void)
787 {
788     return 0;
789 }
790 
cvSetErrStatus(int)791 CV_IMPL void cvSetErrStatus(int)
792 {
793 }
794 
795 
cvError(int code,const char * func_name,const char * err_msg,const char * file_name,int line)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
cvErrorFromIppStatus(int status)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 {
Implcv::Mutex::Impl846     Impl()
847     {
848 #if (_WIN32_WINNT >= 0x0600)
849         ::InitializeCriticalSectionEx(&cs, 1000, 0);
850 #else
851         ::InitializeCriticalSection(&cs);
852 #endif
853         refcount = 1;
854     }
~Implcv::Mutex::Impl855     ~Impl() { DeleteCriticalSection(&cs); }
856 
lockcv::Mutex::Impl857     void lock() { EnterCriticalSection(&cs); }
trylockcv::Mutex::Impl858     bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
unlockcv::Mutex::Impl859     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 
Mutex()891 Mutex::Mutex()
892 {
893     impl = new Mutex::Impl;
894 }
895 
~Mutex()896 Mutex::~Mutex()
897 {
898     if( CV_XADD(&impl->refcount, -1) == 1 )
899         delete impl;
900     impl = 0;
901 }
902 
Mutex(const Mutex & m)903 Mutex::Mutex(const Mutex& m)
904 {
905     impl = m.impl;
906     CV_XADD(&impl->refcount, 1);
907 }
908 
operator =(const Mutex & m)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 
lock()918 void Mutex::lock() { impl->lock(); }
unlock()919 void Mutex::unlock() { impl->unlock(); }
trylock()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:
TLSStorage()929     TLSStorage() { tlsData_.reserve(16); }
930     ~TLSStorage();
getData(int key) const931     inline void* getData(int key) const
932     {
933         CV_DbgAssert(key >= 0);
934         return (key < (int)tlsData_.size()) ? tlsData_[key] : NULL;
935     }
setData(int key,void * data)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 
deleteThreadData()958     static void deleteThreadData()
959     {
960         if (g_tlsdata)
961         {
962             delete g_tlsdata;
963             g_tlsdata = NULL;
964         }
965     }
966 
get()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 
deleteThreadData()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 
get()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"
DllMain(HINSTANCE,DWORD fdwReason,LPVOID lpReserved)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 
deleteTLSStorage(void * data)1037     static void deleteTLSStorage(void* data)
1038     {
1039         delete (TLSStorage*)data;
1040     }
1041 
makeKey()1042     static void makeKey()
1043     {
1044         int errcode = pthread_key_create(&tlsKey, deleteTLSStorage);
1045         CV_Assert(errcode == 0);
1046     }
1047 
get()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:
TLSContainerStorage()1066     TLSContainerStorage() { }
~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 
allocateKey(TLSDataContainer * pContainer)1076     int allocateKey(TLSDataContainer* pContainer)
1077     {
1078         cv::AutoLock lock(mutex_);
1079         tlsContainers_.push_back(pContainer);
1080         return (int)tlsContainers_.size() - 1;
1081     }
releaseKey(int id,TLSDataContainer * pContainer)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 
destroyData(int key,void * data)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
getTLSContainerStorage()1109 static TLSContainerStorage& getTLSContainerStorage()
1110 {
1111     static TLSContainerStorage *tlsContainerStorage = new TLSContainerStorage();
1112     return *tlsContainerStorage;
1113 }
1114 
TLSDataContainer()1115 TLSDataContainer::TLSDataContainer()
1116     : key_(-1)
1117 {
1118     key_ = getTLSContainerStorage().allocateKey(this);
1119 }
1120 
~TLSDataContainer()1121 TLSDataContainer::~TLSDataContainer()
1122 {
1123     getTLSContainerStorage().releaseKey(key_, this);
1124     key_ = -1;
1125 }
1126 
getData() const1127 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 
~TLSStorage()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 
getCoreTlsData()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
getImplData()1166 ImplCollector& getImplData()
1167 {
1168     static ImplCollector *value = new ImplCollector();
1169     return *value;
1170 }
1171 
setImpl(int flags)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 
addImpl(int flag,const char * func)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 
getImpl(std::vector<int> & impl,std::vector<String> & funName)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 
useCollection()1206 bool useCollection()
1207 {
1208     return getImplData().useCollection;
1209 }
1210 
setUseCollection(bool flag)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 
setIppStatus(int status,const char * const _funcname,const char * const _filename,int _line)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 
getIppStatus()1234 int getIppStatus()
1235 {
1236     return ippStatus;
1237 }
1238 
getIppErrorLocation()1239 String getIppErrorLocation()
1240 {
1241     return format("%s:%d %s", filename ? filename : "", linen, funcname ? funcname : "");
1242 }
1243 
useIPP()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 
setUseIPP(bool flag)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 
useTegra()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 
setUseTegra(bool flag)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