1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
43 #include "precomp.hpp"
45 #if defined WIN32 || defined _WIN32 || defined WINCE
46 #ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
47 #define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
50 #if (_WIN32_WINNT >= 0x0602)
62 static void __cpuid(int* cpuid_data, int)
83 #include <wrl/client.h>
85 std::wstring GetTempPathWinRT()
87 return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
90 std::wstring GetTempFileNameWinRT(std::wstring prefix)
95 wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x";
96 swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask,
97 g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]),
98 UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]),
99 UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7]));
101 return prefix + std::wstring(guidStr);
107 #include <sys/time.h>
110 #if defined __MACH__ && defined __APPLE__
111 #include <mach/mach.h>
112 #include <mach/mach_time.h>
123 #if defined __linux__ || defined __APPLE__
126 #include <sys/types.h>
128 #include <sys/sysconf.h>
130 #include <sys/sysctl.h>
135 # include <android/log.h>
141 Exception::Exception() { code = 0; line = 0; }
143 Exception::Exception(int _code, const string& _err, const string& _func, const string& _file, int _line)
144 : code(_code), err(_err), func(_func), file(_file), line(_line)
149 Exception::~Exception() throw() {}
152 \return the error description and the context as a text string.
154 const char* Exception::what() const throw() { return msg.c_str(); }
156 void Exception::formatMessage()
158 if( func.size() > 0 )
159 msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str());
161 msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
166 enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
170 memset( have, 0, sizeof(have) );
174 static HWFeatures initialize(void)
177 int cpuid_data[4] = { 0, 0, 0, 0 };
179 #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
180 __cpuid(cpuid_data, 1);
181 #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
187 :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
198 : "=a"(cpuid_data[0]), "=c"(cpuid_data[2]), "=d"(cpuid_data[3])
205 f.x86_family = (cpuid_data[0] >> 8) & 15;
206 if( f.x86_family >= 6 )
208 f.have[CV_CPU_MMX] = (cpuid_data[3] & (1 << 23)) != 0;
209 f.have[CV_CPU_SSE] = (cpuid_data[3] & (1<<25)) != 0;
210 f.have[CV_CPU_SSE2] = (cpuid_data[3] & (1<<26)) != 0;
211 f.have[CV_CPU_SSE3] = (cpuid_data[2] & (1<<0)) != 0;
212 f.have[CV_CPU_SSSE3] = (cpuid_data[2] & (1<<9)) != 0;
213 f.have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
214 f.have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
215 f.have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0;
216 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
223 bool have[MAX_FEATURE+1];
226 static HWFeatures featuresEnabled = HWFeatures::initialize(), featuresDisabled = HWFeatures();
227 static HWFeatures* currentFeatures = &featuresEnabled;
229 bool checkHardwareSupport(int feature)
231 CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
232 return currentFeatures->have[feature];
236 volatile bool useOptimizedFlag = true;
238 struct IPPInitializer
240 IPPInitializer(void) { ippStaticInit(); }
243 IPPInitializer ippInitializer;
246 volatile bool USE_SSE2 = featuresEnabled.have[CV_CPU_SSE2];
247 volatile bool USE_SSE4_2 = featuresEnabled.have[CV_CPU_SSE4_2];
248 volatile bool USE_AVX = featuresEnabled.have[CV_CPU_AVX];
250 void setUseOptimized( bool flag )
252 useOptimizedFlag = flag;
253 currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
254 USE_SSE2 = currentFeatures->have[CV_CPU_SSE2];
257 bool useOptimized(void)
259 return useOptimizedFlag;
262 int64 getTickCount(void)
264 #if defined WIN32 || defined _WIN32 || defined WINCE
265 LARGE_INTEGER counter;
266 QueryPerformanceCounter( &counter );
267 return (int64)counter.QuadPart;
268 #elif defined __linux || defined __linux__
270 clock_gettime(CLOCK_MONOTONIC, &tp);
271 return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
272 #elif defined __MACH__ && defined __APPLE__
273 return (int64)mach_absolute_time();
277 gettimeofday( &tv, &tz );
278 return (int64)tv.tv_sec*1000000 + tv.tv_usec;
282 double getTickFrequency(void)
284 #if defined WIN32 || defined _WIN32 || defined WINCE
286 QueryPerformanceFrequency(&freq);
287 return (double)freq.QuadPart;
288 #elif defined __linux || defined __linux__
290 #elif defined __MACH__ && defined __APPLE__
291 static double freq = 0;
294 mach_timebase_info_data_t sTimebaseInfo;
295 mach_timebase_info(&sTimebaseInfo);
296 freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
304 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__)
305 #if defined(__i386__)
307 int64 getCPUTickCount(void)
310 __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
313 #elif defined(__x86_64__)
315 int64 getCPUTickCount(void)
318 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
319 return (int64)lo | ((int64)hi << 32);
322 #elif defined(__ppc__)
324 int64 getCPUTickCount(void)
327 unsigned upper, lower, tmp;
335 : "=r"(upper),"=r"(lower),"=r"(tmp)
337 return lower | ((int64)upper << 32);
342 #error "RDTSC not defined"
346 #elif defined _MSC_VER && defined WIN32 && defined _M_IX86
348 int64 getCPUTickCount(void)
357 int64 getCPUTickCount(void)
359 return ippGetCpuClocks();
362 int64 getCPUTickCount(void)
364 return getTickCount();
370 const std::string& getBuildInformation()
372 static std::string build_info =
373 #include "version_string.inc"
378 string format( const char* fmt, ... )
382 va_start( args, fmt );
383 vsprintf( buf, fmt, args );
387 string tempfile( const char* suffix )
390 std::wstring temp_dir = L"";
391 const wchar_t* opencv_temp_dir = _wgetenv(L"OPENCV_TEMP_PATH");
393 temp_dir = std::wstring(opencv_temp_dir);
395 const char *temp_dir = getenv("OPENCV_TEMP_PATH");
399 #if defined WIN32 || defined _WIN32
401 RoInitialize(RO_INIT_MULTITHREADED);
402 std::wstring temp_dir2;
403 if (temp_dir.empty())
404 temp_dir = GetTempPathWinRT();
406 std::wstring temp_file;
407 temp_file = GetTempFileNameWinRT(L"ocv");
408 if (temp_file.empty())
409 return std::string();
411 temp_file = temp_dir + std::wstring(L"\\") + temp_file;
412 DeleteFileW(temp_file.c_str());
414 size_t asize = wcstombs(NULL, temp_file.c_str(), 0);
415 Ptr<char> aname = new char[asize+1];
417 wcstombs(aname, temp_file.c_str(), asize);
418 fname = std::string(aname);
421 char temp_dir2[MAX_PATH + 1] = { 0 };
422 char temp_file[MAX_PATH + 1] = { 0 };
424 if (temp_dir == 0 || temp_dir[0] == 0)
426 ::GetTempPathA(sizeof(temp_dir2), temp_dir2);
427 temp_dir = temp_dir2;
429 if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file))
432 DeleteFileA(temp_file);
438 //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
439 char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
441 char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
444 if (temp_dir == 0 || temp_dir[0] == 0)
445 fname = defaultTemplate;
449 char ech = fname[fname.size() - 1];
450 if(ech != '/' && ech != '\\')
452 fname += "__opencv_temp.XXXXXX";
455 const int fd = mkstemp((char*)fname.c_str());
456 if (fd == -1) return string();
459 remove(fname.c_str());
464 if (suffix[0] != '.')
465 return fname + "." + suffix;
467 return fname + suffix;
472 static CvErrorCallback customErrorCallback = 0;
473 static void* customErrorCallbackData = 0;
474 static bool breakOnError = false;
476 bool setBreakOnError(bool value)
478 bool prevVal = breakOnError;
479 breakOnError = value;
483 void error( const Exception& exc )
485 if (customErrorCallback != 0)
486 customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
487 exc.file.c_str(), exc.line, customErrorCallbackData);
490 const char* errorStr = cvErrorStr(exc.code);
493 sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
494 errorStr, exc.err.c_str(), exc.func.size() > 0 ?
495 exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
496 fprintf( stderr, "%s\n", buf );
499 __android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf);
505 static volatile int* p = 0;
513 redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
516 *prevUserdata = customErrorCallbackData;
518 CvErrorCallback prevCallback = customErrorCallback;
520 customErrorCallback = errCallback;
521 customErrorCallbackData = userdata;
528 CV_IMPL int cvCheckHardwareSupport(int feature)
530 CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
531 return cv::currentFeatures->have[feature];
534 CV_IMPL int cvUseOptimized( int flag )
536 int prevMode = cv::useOptimizedFlag;
537 cv::setUseOptimized( flag != 0 );
541 CV_IMPL int64 cvGetTickCount(void)
543 return cv::getTickCount();
546 CV_IMPL double cvGetTickFrequency(void)
548 return cv::getTickFrequency()*1e-6;
551 CV_IMPL CvErrorCallback
552 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
554 return cv::redirectError(errCallback, userdata, prevUserdata);
557 CV_IMPL int cvNulDevReport( int, const char*, const char*,
558 const char*, int, void* )
563 CV_IMPL int cvStdErrReport( int, const char*, const char*,
564 const char*, int, void* )
569 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
570 const char*, int, void* )
575 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
581 CV_IMPL const char* cvErrorStr( int status )
583 static char buf[256];
587 case CV_StsOk : return "No Error";
588 case CV_StsBackTrace : return "Backtrace";
589 case CV_StsError : return "Unspecified error";
590 case CV_StsInternal : return "Internal error";
591 case CV_StsNoMem : return "Insufficient memory";
592 case CV_StsBadArg : return "Bad argument";
593 case CV_StsNoConv : return "Iterations do not converge";
594 case CV_StsAutoTrace : return "Autotrace call";
595 case CV_StsBadSize : return "Incorrect size of input array";
596 case CV_StsNullPtr : return "Null pointer";
597 case CV_StsDivByZero : return "Division by zero occured";
598 case CV_BadStep : return "Image step is wrong";
599 case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
600 case CV_StsObjectNotFound : return "Requested object was not found";
601 case CV_BadDepth : return "Input image depth is not supported by function";
602 case CV_StsUnmatchedFormats : return "Formats of input arguments do not match";
603 case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match";
604 case CV_StsOutOfRange : return "One of arguments\' values is out of range";
605 case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats";
606 case CV_BadCOI : return "Input COI is not supported";
607 case CV_BadNumChannels : return "Bad number of channels";
608 case CV_StsBadFlag : return "Bad flag (parameter or structure field)";
609 case CV_StsBadPoint : return "Bad parameter of type CvPoint";
610 case CV_StsBadMask : return "Bad type of mask argument";
611 case CV_StsParseError : return "Parsing error";
612 case CV_StsNotImplemented : return "The function/feature is not implemented";
613 case CV_StsBadMemBlock : return "Memory block has been corrupted";
614 case CV_StsAssert : return "Assertion failed";
615 case CV_GpuNotSupported : return "No GPU support";
616 case CV_GpuApiCallError : return "Gpu API call";
617 case CV_OpenGlNotSupported : return "No OpenGL support";
618 case CV_OpenGlApiCallError : return "OpenGL API call";
621 sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
625 CV_IMPL int cvGetErrMode(void)
630 CV_IMPL int cvSetErrMode(int)
635 CV_IMPL int cvGetErrStatus(void)
640 CV_IMPL void cvSetErrStatus(int)
645 CV_IMPL void cvError( int code, const char* func_name,
647 const char* file_name, int line )
649 cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
652 /* function, which converts int to int */
654 cvErrorFromIppStatus( int status )
658 case CV_BADSIZE_ERR: return CV_StsBadSize;
659 case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock;
660 case CV_NULLPTR_ERR: return CV_StsNullPtr;
661 case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero;
662 case CV_BADSTEP_ERR: return CV_BadStep;
663 case CV_OUTOFMEM_ERR: return CV_StsNoMem;
664 case CV_BADARG_ERR: return CV_StsBadArg;
665 case CV_NOTDEFINED_ERR: return CV_StsError;
666 case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
667 case CV_NOTFOUND_ERR: return CV_StsObjectNotFound;
668 case CV_BADCONVERGENCE_ERR: return CV_StsNoConv;
669 case CV_BADDEPTH_ERR: return CV_BadDepth;
670 case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats;
671 case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI;
672 case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels;
673 case CV_BADFLAG_ERR: return CV_StsBadFlag;
674 case CV_BADRANGE_ERR: return CV_StsBadArg;
675 case CV_BADCOEF_ERR: return CV_StsBadArg;
676 case CV_BADFACTOR_ERR: return CV_StsBadArg;
677 case CV_BADPOINT_ERR: return CV_StsBadPoint;
684 static CvModuleInfo cxcore_info = { 0, "cxcore", CV_VERSION, 0 };
686 CvModuleInfo* CvModule::first = 0, *CvModule::last = 0;
688 CvModule::CvModule( CvModuleInfo* _info )
690 cvRegisterModule( _info );
694 CvModule::~CvModule(void)
698 CvModuleInfo* p = first;
699 for( ; p != 0 && p->next != info; p = p->next )
703 p->next = info->next;
717 cvRegisterModule( const CvModuleInfo* module )
719 CV_Assert( module != 0 && module->name != 0 && module->version != 0 );
721 size_t name_len = strlen(module->name);
722 size_t version_len = strlen(module->version);
724 CvModuleInfo* module_copy = (CvModuleInfo*)malloc( sizeof(*module_copy) +
725 name_len + 1 + version_len + 1 );
727 *module_copy = *module;
728 module_copy->name = (char*)(module_copy + 1);
729 module_copy->version = (char*)(module_copy + 1) + name_len + 1;
731 memcpy( (void*)module_copy->name, module->name, name_len + 1 );
732 memcpy( (void*)module_copy->version, module->version, version_len + 1 );
733 module_copy->next = 0;
735 if( CvModule::first == 0 )
736 CvModule::first = module_copy;
738 CvModule::last->next = module_copy;
740 CvModule::last = module_copy;
745 CvModule cxcore_module( &cxcore_info );
748 cvGetModuleInfo( const char* name, const char **version, const char **plugin_list )
750 static char joint_verinfo[1024] = "";
751 static char plugin_list_buf[1024] = "";
759 CvModuleInfo* module;
765 size_t i, name_len = strlen(name);
767 for( module = CvModule::first; module != 0; module = module->next )
769 if( strlen(module->name) == name_len )
771 for( i = 0; i < name_len; i++ )
773 int c0 = toupper(module->name[i]), c1 = toupper(name[i]);
782 CV_Error( CV_StsObjectNotFound, "The module is not found" );
784 *version = module->version;
788 char* ptr = joint_verinfo;
790 for( module = CvModule::first; module != 0; module = module->next )
792 sprintf( ptr, "%s: %s%s", module->name, module->version, module->next ? ", " : "" );
796 *version = joint_verinfo;
801 *plugin_list = plugin_list_buf;
804 #if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
806 #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
809 BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID );
811 BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID )
813 if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH )
815 cv::deleteThreadAllocData();
816 cv::deleteThreadRNGData();
825 #if defined WIN32 || defined _WIN32 || defined WINCE
831 #if (_WIN32_WINNT >= 0x0600)
832 ::InitializeCriticalSectionEx(&cs, 1000, 0);
834 ::InitializeCriticalSection(&cs);
838 ~Impl() { DeleteCriticalSection(&cs); }
840 void lock() { EnterCriticalSection(&cs); }
841 bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
842 void unlock() { LeaveCriticalSection(&cs); }
849 int _interlockedExchangeAdd(int* addr, int delta)
851 #if defined _MSC_VER && _MSC_VER >= 1500
852 return (int)_InterlockedExchangeAdd((long volatile*)addr, delta);
854 return (int)InterlockedExchangeAdd((long volatile*)addr, delta);
859 #elif defined __APPLE__
861 #include <libkern/OSAtomic.h>
865 Impl() { sl = OS_SPINLOCK_INIT; refcount = 1; }
868 void lock() { OSSpinLockLock(&sl); }
869 bool trylock() { return OSSpinLockTry(&sl); }
870 void unlock() { OSSpinLockUnlock(&sl); }
876 #elif defined __linux__ && !defined ANDROID
880 Impl() { pthread_spin_init(&sl, 0); refcount = 1; }
881 ~Impl() { pthread_spin_destroy(&sl); }
883 void lock() { pthread_spin_lock(&sl); }
884 bool trylock() { return pthread_spin_trylock(&sl) == 0; }
885 void unlock() { pthread_spin_unlock(&sl); }
887 pthread_spinlock_t sl;
895 Impl() { pthread_mutex_init(&sl, 0); refcount = 1; }
896 ~Impl() { pthread_mutex_destroy(&sl); }
898 void lock() { pthread_mutex_lock(&sl); }
899 bool trylock() { return pthread_mutex_trylock(&sl) == 0; }
900 void unlock() { pthread_mutex_unlock(&sl); }
910 impl = new Mutex::Impl;
915 if( CV_XADD(&impl->refcount, -1) == 1 )
920 Mutex::Mutex(const Mutex& m)
923 CV_XADD(&impl->refcount, 1);
926 Mutex& Mutex::operator = (const Mutex& m)
928 CV_XADD(&m.impl->refcount, 1);
929 if( CV_XADD(&impl->refcount, -1) == 1 )
935 void Mutex::lock() { impl->lock(); }
936 void Mutex::unlock() { impl->unlock(); }
937 bool Mutex::trylock() { return impl->trylock(); }