2010-05-12 01:44:00 +08:00
|
|
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
|
|
//
|
|
|
|
// By downloading, copying, installing or using the software you agree to this license.
|
|
|
|
// If you do not agree to this license, do not download, install,
|
|
|
|
// copy or use the software.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// License Agreement
|
|
|
|
// For Open Source Computer Vision Library
|
|
|
|
//
|
|
|
|
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
|
|
|
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
|
|
|
// Third party copyrights are property of their respective owners.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
// are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistribution's of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
//
|
|
|
|
// * The name of the copyright holders may not be used to endorse or promote products
|
|
|
|
// derived from this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// This software is provided by the copyright holders and contributors "as is" and
|
|
|
|
// any express or implied warranties, including, but not limited to, the implied
|
|
|
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
|
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
|
|
|
// indirect, incidental, special, exemplary, or consequential damages
|
|
|
|
// (including, but not limited to, procurement of substitute goods or services;
|
|
|
|
// loss of use, data, or profits; or business interruption) however caused
|
|
|
|
// and on any theory of liability, whether in contract, strict liability,
|
|
|
|
// or tort (including negligence or otherwise) arising in any way out of
|
|
|
|
// the use of this software, even if advised of the possibility of such damage.
|
|
|
|
//
|
|
|
|
//M*/
|
|
|
|
|
|
|
|
#include "precomp.hpp"
|
|
|
|
|
2010-07-17 06:38:57 +08:00
|
|
|
#if defined WIN32 || defined _WIN32 || defined WINCE
|
2012-11-01 16:44:10 +08:00
|
|
|
#ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
|
|
|
|
#define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
|
|
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
|
|
#undef small
|
|
|
|
#undef min
|
|
|
|
#undef max
|
|
|
|
#undef abs
|
2010-05-12 01:44:00 +08:00
|
|
|
#include <tchar.h>
|
|
|
|
#if defined _MSC_VER
|
|
|
|
#if _MSC_VER >= 1400
|
|
|
|
#include <intrin.h>
|
2010-12-24 07:00:04 +08:00
|
|
|
#elif defined _M_IX86
|
2010-05-12 01:44:00 +08:00
|
|
|
static void __cpuid(int* cpuid_data, int)
|
|
|
|
{
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
push edi
|
|
|
|
mov edi, cpuid_data
|
|
|
|
mov eax, 1
|
|
|
|
cpuid
|
|
|
|
mov [edi], eax
|
|
|
|
mov [edi + 4], ebx
|
|
|
|
mov [edi + 8], ecx
|
|
|
|
mov [edi + 12], edx
|
|
|
|
pop edi
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2011-06-13 04:29:50 +08:00
|
|
|
#if defined __MACH__ && defined __APPLE__
|
2010-05-12 01:44:00 +08:00
|
|
|
#include <mach/mach.h>
|
|
|
|
#include <mach/mach_time.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef _OPENMP
|
|
|
|
#include "omp.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
2011-08-02 20:42:58 +08:00
|
|
|
#if defined __linux__ || defined __APPLE__
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
2012-06-08 01:21:29 +08:00
|
|
|
#include <sys/types.h>
|
2011-08-02 22:56:51 +08:00
|
|
|
#if defined ANDROID
|
|
|
|
#include <sys/sysconf.h>
|
|
|
|
#else
|
2011-08-02 20:42:58 +08:00
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#endif
|
2011-08-02 22:56:51 +08:00
|
|
|
#endif
|
2011-08-02 20:42:58 +08:00
|
|
|
|
2012-08-08 20:39:24 +08:00
|
|
|
#ifdef ANDROID
|
|
|
|
# include <android/log.h>
|
|
|
|
#endif
|
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
namespace cv
|
|
|
|
{
|
|
|
|
|
2011-06-09 05:35:19 +08:00
|
|
|
Exception::Exception() { code = 0; line = 0; }
|
|
|
|
|
|
|
|
Exception::Exception(int _code, const string& _err, const string& _func, const string& _file, int _line)
|
|
|
|
: code(_code), err(_err), func(_func), file(_file), line(_line)
|
|
|
|
{
|
|
|
|
formatMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
Exception::~Exception() throw() {}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\return the error description and the context as a text string.
|
2012-06-08 01:21:29 +08:00
|
|
|
*/
|
2011-06-09 05:35:19 +08:00
|
|
|
const char* Exception::what() const throw() { return msg.c_str(); }
|
|
|
|
|
|
|
|
void Exception::formatMessage()
|
|
|
|
{
|
|
|
|
if( func.size() > 0 )
|
|
|
|
msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str());
|
|
|
|
else
|
|
|
|
msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
|
|
|
|
}
|
2012-06-08 01:21:29 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
struct HWFeatures
|
|
|
|
{
|
|
|
|
enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
|
2010-12-24 07:00:04 +08:00
|
|
|
|
|
|
|
HWFeatures(void)
|
|
|
|
{
|
2010-05-12 01:44:00 +08:00
|
|
|
memset( have, 0, sizeof(have) );
|
|
|
|
x86_family = 0;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
|
|
|
static HWFeatures initialize(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
|
|
|
HWFeatures f;
|
2010-12-24 07:00:04 +08:00
|
|
|
int cpuid_data[4] = { 0, 0, 0, 0 };
|
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
#if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
|
|
|
|
__cpuid(cpuid_data, 1);
|
|
|
|
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
|
|
|
|
#ifdef __x86_64__
|
|
|
|
asm __volatile__
|
|
|
|
(
|
|
|
|
"movl $1, %%eax\n\t"
|
|
|
|
"cpuid\n\t"
|
|
|
|
:[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
|
|
|
|
:
|
|
|
|
: "cc"
|
|
|
|
);
|
|
|
|
#else
|
|
|
|
asm volatile
|
|
|
|
(
|
|
|
|
"pushl %%ebx\n\t"
|
|
|
|
"movl $1,%%eax\n\t"
|
|
|
|
"cpuid\n\t"
|
|
|
|
"popl %%ebx\n\t"
|
|
|
|
: "=a"(cpuid_data[0]), "=c"(cpuid_data[2]), "=d"(cpuid_data[3])
|
|
|
|
:
|
|
|
|
: "cc"
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
#endif
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
f.x86_family = (cpuid_data[0] >> 8) & 15;
|
|
|
|
if( f.x86_family >= 6 )
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
f.have[CV_CPU_MMX] = (cpuid_data[3] & (1 << 23)) != 0;
|
|
|
|
f.have[CV_CPU_SSE] = (cpuid_data[3] & (1<<25)) != 0;
|
|
|
|
f.have[CV_CPU_SSE2] = (cpuid_data[3] & (1<<26)) != 0;
|
|
|
|
f.have[CV_CPU_SSE3] = (cpuid_data[2] & (1<<0)) != 0;
|
|
|
|
f.have[CV_CPU_SSSE3] = (cpuid_data[2] & (1<<9)) != 0;
|
2010-05-12 01:44:00 +08:00
|
|
|
f.have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
|
|
|
|
f.have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
|
2011-03-14 06:51:33 +08:00
|
|
|
f.have[CV_CPU_POPCNT] = (cpuid_data[2] & (1<<23)) != 0;
|
2012-09-04 18:59:38 +08:00
|
|
|
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
|
2010-05-12 01:44:00 +08:00
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
return f;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
int x86_family;
|
|
|
|
bool have[MAX_FEATURE+1];
|
|
|
|
};
|
2010-12-24 07:00:04 +08:00
|
|
|
|
|
|
|
static HWFeatures featuresEnabled = HWFeatures::initialize(), featuresDisabled = HWFeatures();
|
2010-05-12 01:44:00 +08:00
|
|
|
static HWFeatures* currentFeatures = &featuresEnabled;
|
|
|
|
|
|
|
|
bool checkHardwareSupport(int feature)
|
|
|
|
{
|
|
|
|
CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
|
|
|
|
return currentFeatures->have[feature];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-05 04:10:35 +08:00
|
|
|
volatile bool useOptimizedFlag = true;
|
|
|
|
#ifdef HAVE_IPP
|
2010-05-12 01:44:00 +08:00
|
|
|
struct IPPInitializer
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
IPPInitializer(void) { ippStaticInit(); }
|
2010-05-12 01:44:00 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
IPPInitializer ippInitializer;
|
|
|
|
#endif
|
|
|
|
|
2011-12-05 04:10:35 +08:00
|
|
|
volatile bool USE_SSE2 = featuresEnabled.have[CV_CPU_SSE2];
|
2012-07-24 21:24:31 +08:00
|
|
|
volatile bool USE_SSE4_2 = featuresEnabled.have[CV_CPU_SSE4_2];
|
|
|
|
volatile bool USE_AVX = featuresEnabled.have[CV_CPU_AVX];
|
2011-04-19 05:24:57 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
void setUseOptimized( bool flag )
|
|
|
|
{
|
|
|
|
useOptimizedFlag = flag;
|
|
|
|
currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
|
2011-04-17 21:14:45 +08:00
|
|
|
USE_SSE2 = currentFeatures->have[CV_CPU_SSE2];
|
2010-05-12 01:44:00 +08:00
|
|
|
}
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
bool useOptimized(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
|
|
|
return useOptimizedFlag;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
|
|
|
int64 getTickCount(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
2010-07-17 06:38:57 +08:00
|
|
|
#if defined WIN32 || defined _WIN32 || defined WINCE
|
2010-05-12 01:44:00 +08:00
|
|
|
LARGE_INTEGER counter;
|
|
|
|
QueryPerformanceCounter( &counter );
|
|
|
|
return (int64)counter.QuadPart;
|
|
|
|
#elif defined __linux || defined __linux__
|
|
|
|
struct timespec tp;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &tp);
|
|
|
|
return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
|
2011-05-31 23:22:22 +08:00
|
|
|
#elif defined __MACH__ && defined __APPLE__
|
2010-05-12 01:44:00 +08:00
|
|
|
return (int64)mach_absolute_time();
|
2010-12-24 07:00:04 +08:00
|
|
|
#else
|
2010-05-12 01:44:00 +08:00
|
|
|
struct timeval tv;
|
|
|
|
struct timezone tz;
|
|
|
|
gettimeofday( &tv, &tz );
|
|
|
|
return (int64)tv.tv_sec*1000000 + tv.tv_usec;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
double getTickFrequency(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
2010-07-17 06:38:57 +08:00
|
|
|
#if defined WIN32 || defined _WIN32 || defined WINCE
|
2010-05-12 01:44:00 +08:00
|
|
|
LARGE_INTEGER freq;
|
|
|
|
QueryPerformanceFrequency(&freq);
|
|
|
|
return (double)freq.QuadPart;
|
|
|
|
#elif defined __linux || defined __linux__
|
|
|
|
return 1e9;
|
2011-05-31 23:22:22 +08:00
|
|
|
#elif defined __MACH__ && defined __APPLE__
|
2010-05-12 01:44:00 +08:00
|
|
|
static double freq = 0;
|
|
|
|
if( freq == 0 )
|
|
|
|
{
|
|
|
|
mach_timebase_info_data_t sTimebaseInfo;
|
|
|
|
mach_timebase_info(&sTimebaseInfo);
|
|
|
|
freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
return freq;
|
2010-05-12 01:44:00 +08:00
|
|
|
#else
|
|
|
|
return 1e6;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
#if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__)
|
2010-05-12 01:44:00 +08:00
|
|
|
#if defined(__i386__)
|
|
|
|
|
|
|
|
int64 getCPUTickCount(void)
|
|
|
|
{
|
|
|
|
int64 x;
|
|
|
|
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
#elif defined(__x86_64__)
|
|
|
|
|
|
|
|
int64 getCPUTickCount(void)
|
|
|
|
{
|
|
|
|
unsigned hi, lo;
|
|
|
|
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
|
|
|
|
return (int64)lo | ((int64)hi << 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(__ppc__)
|
|
|
|
|
|
|
|
int64 getCPUTickCount(void)
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
int64 result = 0;
|
2010-05-12 01:44:00 +08:00
|
|
|
unsigned upper, lower, tmp;
|
|
|
|
__asm__ volatile(
|
|
|
|
"0: \n"
|
|
|
|
"\tmftbu %0 \n"
|
|
|
|
"\tmftb %1 \n"
|
|
|
|
"\tmftbu %2 \n"
|
|
|
|
"\tcmpw %2,%0 \n"
|
|
|
|
"\tbne 0b \n"
|
|
|
|
: "=r"(upper),"=r"(lower),"=r"(tmp)
|
|
|
|
);
|
|
|
|
return lower | ((int64)upper << 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#error "RDTSC not defined"
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-07-17 06:38:57 +08:00
|
|
|
#elif defined _MSC_VER && defined WIN32 && defined _M_IX86
|
2010-05-12 01:44:00 +08:00
|
|
|
|
|
|
|
int64 getCPUTickCount(void)
|
|
|
|
{
|
|
|
|
__asm _emit 0x0f;
|
|
|
|
__asm _emit 0x31;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
#ifdef HAVE_IPP
|
|
|
|
int64 getCPUTickCount(void)
|
|
|
|
{
|
|
|
|
return ippGetCpuClocks();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
int64 getCPUTickCount(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
|
|
|
return getTickCount();
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
#endif
|
2010-05-12 01:44:00 +08:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2012-04-14 05:50:59 +08:00
|
|
|
const std::string& getBuildInformation()
|
|
|
|
{
|
|
|
|
static std::string build_info =
|
|
|
|
#include "version_string.inc"
|
|
|
|
;
|
|
|
|
return build_info;
|
|
|
|
}
|
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
string format( const char* fmt, ... )
|
|
|
|
{
|
|
|
|
char buf[1 << 16];
|
|
|
|
va_list args;
|
|
|
|
va_start( args, fmt );
|
|
|
|
vsprintf( buf, fmt, args );
|
|
|
|
return string(buf);
|
|
|
|
}
|
|
|
|
|
2011-04-11 22:47:06 +08:00
|
|
|
string tempfile( const char* suffix )
|
|
|
|
{
|
2012-06-25 19:24:06 +08:00
|
|
|
#if defined WIN32 || defined _WIN32
|
|
|
|
char temp_dir[MAX_PATH + 1] = { 0 };
|
|
|
|
char temp_file[MAX_PATH + 1] = { 0 };
|
|
|
|
|
|
|
|
::GetTempPathA(sizeof(temp_dir), temp_dir);
|
2012-07-02 20:23:57 +08:00
|
|
|
if(0 == ::GetTempFileNameA(temp_dir, "ocv", 0, temp_file))
|
2012-06-25 19:24:06 +08:00
|
|
|
return string();
|
|
|
|
|
2012-10-04 13:44:29 +08:00
|
|
|
DeleteFileA(temp_file);
|
|
|
|
|
2012-06-25 19:24:06 +08:00
|
|
|
string name = temp_file;
|
|
|
|
if(suffix)
|
|
|
|
{
|
|
|
|
if (suffix[0] != '.')
|
|
|
|
return name + "." + suffix;
|
|
|
|
else
|
|
|
|
return name + suffix;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return name;
|
|
|
|
# else
|
|
|
|
# ifdef ANDROID
|
|
|
|
//char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
|
|
|
|
char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
|
|
|
|
# else
|
|
|
|
char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
|
|
|
|
# endif
|
|
|
|
|
|
|
|
string fname;
|
|
|
|
const char *temp_dir = getenv("OPENCV_TEMP_PATH");
|
|
|
|
if(temp_dir == 0 || temp_dir[0] == 0)
|
|
|
|
fname = defaultTemplate;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fname = temp_dir;
|
|
|
|
char ech = fname[fname.size() - 1];
|
|
|
|
if(ech != '/' && ech != '\\')
|
|
|
|
fname += "/";
|
|
|
|
fname += "__opencv_temp.XXXXXX";
|
|
|
|
}
|
|
|
|
|
|
|
|
const int fd = mkstemp((char*)fname.c_str());
|
|
|
|
if(fd == -1) return "";
|
|
|
|
close(fd);
|
|
|
|
remove(fname.c_str());
|
|
|
|
|
|
|
|
if(suffix)
|
|
|
|
{
|
|
|
|
if (suffix[0] != '.')
|
|
|
|
fname = fname + "." + suffix;
|
|
|
|
else
|
|
|
|
fname += suffix;
|
|
|
|
}
|
|
|
|
return fname;
|
|
|
|
# endif
|
2011-04-11 22:47:06 +08:00
|
|
|
}
|
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
static CvErrorCallback customErrorCallback = 0;
|
|
|
|
static void* customErrorCallbackData = 0;
|
|
|
|
static bool breakOnError = false;
|
|
|
|
|
|
|
|
bool setBreakOnError(bool value)
|
|
|
|
{
|
|
|
|
bool prevVal = breakOnError;
|
|
|
|
breakOnError = value;
|
|
|
|
return prevVal;
|
2010-12-24 07:00:04 +08:00
|
|
|
}
|
2010-05-12 01:44:00 +08:00
|
|
|
|
|
|
|
void error( const Exception& exc )
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
if (customErrorCallback != 0)
|
2010-05-12 01:44:00 +08:00
|
|
|
customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
|
|
|
|
exc.file.c_str(), exc.line, customErrorCallbackData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char* errorStr = cvErrorStr(exc.code);
|
|
|
|
char buf[1 << 16];
|
|
|
|
|
|
|
|
sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
|
|
|
|
errorStr, exc.err.c_str(), exc.func.size() > 0 ?
|
|
|
|
exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
|
|
|
|
fprintf( stderr, "%s\n", buf );
|
|
|
|
fflush( stderr );
|
2012-08-08 20:39:24 +08:00
|
|
|
# ifdef ANDROID
|
|
|
|
__android_log_print(ANDROID_LOG_ERROR, "cv::error()", "%s", buf);
|
|
|
|
# endif
|
2010-05-12 01:44:00 +08:00
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
if(breakOnError)
|
|
|
|
{
|
|
|
|
static volatile int* p = 0;
|
|
|
|
*p = 0;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
throw exc;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
CvErrorCallback
|
|
|
|
redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
|
|
|
|
{
|
|
|
|
if( prevUserdata )
|
|
|
|
*prevUserdata = customErrorCallbackData;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
CvErrorCallback prevCallback = customErrorCallback;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
|
|
|
customErrorCallback = errCallback;
|
2010-05-12 01:44:00 +08:00
|
|
|
customErrorCallbackData = userdata;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
return prevCallback;
|
|
|
|
}
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*CV_IMPL int
|
|
|
|
cvGuiBoxReport( int code, const char *func_name, const char *err_msg,
|
|
|
|
const char *file, int line, void* )
|
|
|
|
{
|
2010-07-17 06:38:57 +08:00
|
|
|
#if (!defined WIN32 && !defined _WIN32) || defined WINCE
|
2010-05-12 01:44:00 +08:00
|
|
|
return cvStdErrReport( code, func_name, err_msg, file, line, 0 );
|
|
|
|
#else
|
|
|
|
if( code != CV_StsBackTrace && code != CV_StsAutoTrace )
|
|
|
|
{
|
|
|
|
size_t msg_len = strlen(err_msg ? err_msg : "") + 1024;
|
|
|
|
char* message = (char*)alloca(msg_len);
|
|
|
|
char title[100];
|
|
|
|
|
|
|
|
wsprintf( message, "%s (%s)\nin function %s, %s(%d)\n\n"
|
|
|
|
"Press \"Abort\" to terminate application.\n"
|
|
|
|
"Press \"Retry\" to debug (if the app is running under debugger).\n"
|
|
|
|
"Press \"Ignore\" to continue (this is not safe).\n",
|
|
|
|
cvErrorStr(code), err_msg ? err_msg : "no description",
|
|
|
|
func_name, file, line );
|
|
|
|
|
|
|
|
wsprintf( title, "OpenCV GUI Error Handler" );
|
|
|
|
|
|
|
|
int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL );
|
|
|
|
|
|
|
|
if( answer == IDRETRY )
|
|
|
|
{
|
|
|
|
CV_DBG_BREAK();
|
|
|
|
}
|
|
|
|
return answer != IDIGNORE;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}*/
|
|
|
|
|
|
|
|
CV_IMPL int cvCheckHardwareSupport(int feature)
|
|
|
|
{
|
|
|
|
CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
|
|
|
|
return cv::currentFeatures->have[feature];
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvUseOptimized( int flag )
|
|
|
|
{
|
|
|
|
int prevMode = cv::useOptimizedFlag;
|
|
|
|
cv::setUseOptimized( flag != 0 );
|
|
|
|
return prevMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int64 cvGetTickCount(void)
|
|
|
|
{
|
|
|
|
return cv::getTickCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL double cvGetTickFrequency(void)
|
|
|
|
{
|
|
|
|
return cv::getTickFrequency()*1e-6;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL CvErrorCallback
|
|
|
|
cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
|
|
|
|
{
|
|
|
|
return cv::redirectError(errCallback, userdata, prevUserdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvNulDevReport( int, const char*, const char*,
|
|
|
|
const char*, int, void* )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvStdErrReport( int, const char*, const char*,
|
|
|
|
const char*, int, void* )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
|
|
|
|
const char*, int, void* )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CV_IMPL const char* cvErrorStr( int status )
|
|
|
|
{
|
|
|
|
static char buf[256];
|
|
|
|
|
|
|
|
switch (status)
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
case CV_StsOk : return "No Error";
|
|
|
|
case CV_StsBackTrace : return "Backtrace";
|
|
|
|
case CV_StsError : return "Unspecified error";
|
|
|
|
case CV_StsInternal : return "Internal error";
|
|
|
|
case CV_StsNoMem : return "Insufficient memory";
|
|
|
|
case CV_StsBadArg : return "Bad argument";
|
|
|
|
case CV_StsNoConv : return "Iterations do not converge";
|
|
|
|
case CV_StsAutoTrace : return "Autotrace call";
|
|
|
|
case CV_StsBadSize : return "Incorrect size of input array";
|
|
|
|
case CV_StsNullPtr : return "Null pointer";
|
|
|
|
case CV_StsDivByZero : return "Division by zero occured";
|
|
|
|
case CV_BadStep : return "Image step is wrong";
|
2010-05-12 01:44:00 +08:00
|
|
|
case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
|
|
|
|
case CV_StsObjectNotFound : return "Requested object was not found";
|
2010-12-24 07:00:04 +08:00
|
|
|
case CV_BadDepth : return "Input image depth is not supported by function";
|
|
|
|
case CV_StsUnmatchedFormats : return "Formats of input arguments do not match";
|
|
|
|
case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match";
|
|
|
|
case CV_StsOutOfRange : return "One of arguments\' values is out of range";
|
|
|
|
case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats";
|
|
|
|
case CV_BadCOI : return "Input COI is not supported";
|
|
|
|
case CV_BadNumChannels : return "Bad number of channels";
|
|
|
|
case CV_StsBadFlag : return "Bad flag (parameter or structure field)";
|
|
|
|
case CV_StsBadPoint : return "Bad parameter of type CvPoint";
|
|
|
|
case CV_StsBadMask : return "Bad type of mask argument";
|
|
|
|
case CV_StsParseError : return "Parsing error";
|
|
|
|
case CV_StsNotImplemented : return "The function/feature is not implemented";
|
|
|
|
case CV_StsBadMemBlock : return "Memory block has been corrupted";
|
|
|
|
case CV_StsAssert : return "Assertion failed";
|
2011-10-19 17:53:22 +08:00
|
|
|
case CV_GpuNotSupported : return "No GPU support";
|
2011-11-21 19:58:52 +08:00
|
|
|
case CV_GpuApiCallError : return "Gpu API call";
|
|
|
|
case CV_OpenGlNotSupported : return "No OpenGL support";
|
|
|
|
case CV_OpenGlApiCallError : return "OpenGL API call";
|
2010-05-12 01:44:00 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvGetErrMode(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int cvSetErrMode(int)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
CV_IMPL int cvGetErrStatus(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL void cvSetErrStatus(int)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CV_IMPL void cvError( int code, const char* func_name,
|
|
|
|
const char* err_msg,
|
|
|
|
const char* file_name, int line )
|
|
|
|
{
|
|
|
|
cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* function, which converts int to int */
|
|
|
|
CV_IMPL int
|
|
|
|
cvErrorFromIppStatus( int status )
|
|
|
|
{
|
|
|
|
switch (status)
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
case CV_BADSIZE_ERR: return CV_StsBadSize;
|
|
|
|
case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock;
|
|
|
|
case CV_NULLPTR_ERR: return CV_StsNullPtr;
|
|
|
|
case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero;
|
|
|
|
case CV_BADSTEP_ERR: return CV_BadStep;
|
|
|
|
case CV_OUTOFMEM_ERR: return CV_StsNoMem;
|
|
|
|
case CV_BADARG_ERR: return CV_StsBadArg;
|
|
|
|
case CV_NOTDEFINED_ERR: return CV_StsError;
|
2010-05-12 01:44:00 +08:00
|
|
|
case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
|
2010-12-24 07:00:04 +08:00
|
|
|
case CV_NOTFOUND_ERR: return CV_StsObjectNotFound;
|
|
|
|
case CV_BADCONVERGENCE_ERR: return CV_StsNoConv;
|
|
|
|
case CV_BADDEPTH_ERR: return CV_BadDepth;
|
|
|
|
case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats;
|
|
|
|
case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI;
|
|
|
|
case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels;
|
|
|
|
case CV_BADFLAG_ERR: return CV_StsBadFlag;
|
|
|
|
case CV_BADRANGE_ERR: return CV_StsBadArg;
|
|
|
|
case CV_BADCOEF_ERR: return CV_StsBadArg;
|
|
|
|
case CV_BADFACTOR_ERR: return CV_StsBadArg;
|
|
|
|
case CV_BADPOINT_ERR: return CV_StsBadPoint;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return CV_StsError;
|
2010-05-12 01:44:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static CvModuleInfo cxcore_info = { 0, "cxcore", CV_VERSION, 0 };
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
CvModuleInfo* CvModule::first = 0, *CvModule::last = 0;
|
2010-05-12 01:44:00 +08:00
|
|
|
|
|
|
|
CvModule::CvModule( CvModuleInfo* _info )
|
|
|
|
{
|
|
|
|
cvRegisterModule( _info );
|
|
|
|
info = last;
|
|
|
|
}
|
|
|
|
|
2010-12-24 07:00:04 +08:00
|
|
|
CvModule::~CvModule(void)
|
2010-05-12 01:44:00 +08:00
|
|
|
{
|
|
|
|
if( info )
|
|
|
|
{
|
|
|
|
CvModuleInfo* p = first;
|
|
|
|
for( ; p != 0 && p->next != info; p = p->next )
|
|
|
|
;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
if( p )
|
|
|
|
p->next = info->next;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
if( first == info )
|
|
|
|
first = info->next;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
if( last == info )
|
|
|
|
last = p;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
free( info );
|
|
|
|
info = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CV_IMPL int
|
|
|
|
cvRegisterModule( const CvModuleInfo* module )
|
|
|
|
{
|
|
|
|
CV_Assert( module != 0 && module->name != 0 && module->version != 0 );
|
|
|
|
|
|
|
|
size_t name_len = strlen(module->name);
|
|
|
|
size_t version_len = strlen(module->version);
|
|
|
|
|
|
|
|
CvModuleInfo* module_copy = (CvModuleInfo*)malloc( sizeof(*module_copy) +
|
|
|
|
name_len + 1 + version_len + 1 );
|
|
|
|
|
|
|
|
*module_copy = *module;
|
|
|
|
module_copy->name = (char*)(module_copy + 1);
|
|
|
|
module_copy->version = (char*)(module_copy + 1) + name_len + 1;
|
|
|
|
|
|
|
|
memcpy( (void*)module_copy->name, module->name, name_len + 1 );
|
|
|
|
memcpy( (void*)module_copy->version, module->version, version_len + 1 );
|
|
|
|
module_copy->next = 0;
|
|
|
|
|
|
|
|
if( CvModule::first == 0 )
|
|
|
|
CvModule::first = module_copy;
|
|
|
|
else
|
|
|
|
CvModule::last->next = module_copy;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
CvModule::last = module_copy;
|
2010-12-24 07:00:04 +08:00
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CvModule cxcore_module( &cxcore_info );
|
|
|
|
|
|
|
|
CV_IMPL void
|
|
|
|
cvGetModuleInfo( const char* name, const char **version, const char **plugin_list )
|
|
|
|
{
|
2010-12-24 07:00:04 +08:00
|
|
|
static char joint_verinfo[1024] = "";
|
2010-05-12 01:44:00 +08:00
|
|
|
static char plugin_list_buf[1024] = "";
|
|
|
|
|
|
|
|
if( version )
|
|
|
|
*version = 0;
|
|
|
|
|
|
|
|
if( plugin_list )
|
|
|
|
*plugin_list = 0;
|
|
|
|
|
|
|
|
CvModuleInfo* module;
|
|
|
|
|
|
|
|
if( version )
|
|
|
|
{
|
|
|
|
if( name )
|
|
|
|
{
|
|
|
|
size_t i, name_len = strlen(name);
|
|
|
|
|
|
|
|
for( module = CvModule::first; module != 0; module = module->next )
|
|
|
|
{
|
|
|
|
if( strlen(module->name) == name_len )
|
|
|
|
{
|
|
|
|
for( i = 0; i < name_len; i++ )
|
|
|
|
{
|
|
|
|
int c0 = toupper(module->name[i]), c1 = toupper(name[i]);
|
|
|
|
if( c0 != c1 )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( i == name_len )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( !module )
|
|
|
|
CV_Error( CV_StsObjectNotFound, "The module is not found" );
|
|
|
|
|
|
|
|
*version = module->version;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char* ptr = joint_verinfo;
|
|
|
|
|
|
|
|
for( module = CvModule::first; module != 0; module = module->next )
|
|
|
|
{
|
|
|
|
sprintf( ptr, "%s: %s%s", module->name, module->version, module->next ? ", " : "" );
|
|
|
|
ptr += strlen(ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
*version = joint_verinfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( plugin_list )
|
|
|
|
*plugin_list = plugin_list_buf;
|
|
|
|
}
|
|
|
|
|
2011-05-31 21:17:59 +08:00
|
|
|
#if defined BUILD_SHARED_LIBS && defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
|
2012-06-08 11:15:08 +08:00
|
|
|
BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID );
|
|
|
|
|
2010-05-12 01:44:00 +08:00
|
|
|
BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID )
|
|
|
|
{
|
|
|
|
if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH )
|
|
|
|
{
|
|
|
|
cv::deleteThreadAllocData();
|
|
|
|
cv::deleteThreadRNGData();
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
namespace cv
|
|
|
|
{
|
|
|
|
|
|
|
|
#if defined WIN32 || defined _WIN32 || defined WINCE
|
|
|
|
|
|
|
|
struct Mutex::Impl
|
|
|
|
{
|
|
|
|
Impl() { InitializeCriticalSection(&cs); refcount = 1; }
|
|
|
|
~Impl() { DeleteCriticalSection(&cs); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
void lock() { EnterCriticalSection(&cs); }
|
|
|
|
bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
|
|
|
|
void unlock() { LeaveCriticalSection(&cs); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
CRITICAL_SECTION cs;
|
|
|
|
int refcount;
|
|
|
|
};
|
2012-10-17 07:18:30 +08:00
|
|
|
|
2012-10-23 16:52:54 +08:00
|
|
|
#ifndef __GNUC__
|
2012-10-09 21:12:42 +08:00
|
|
|
int _interlockedExchangeAdd(int* addr, int delta)
|
|
|
|
{
|
|
|
|
#if defined _MSC_VER && _MSC_VER >= 1500
|
|
|
|
return (int)_InterlockedExchangeAdd((long volatile*)addr, delta);
|
|
|
|
#else
|
|
|
|
return (int)InterlockedExchangeAdd((long volatile*)addr, delta);
|
|
|
|
#endif
|
|
|
|
}
|
2012-10-23 16:52:54 +08:00
|
|
|
#endif // __GNUC__
|
2012-08-17 21:32:06 +08:00
|
|
|
|
|
|
|
#elif defined __APPLE__
|
|
|
|
|
|
|
|
#include <libkern/OSAtomic.h>
|
|
|
|
|
|
|
|
struct Mutex::Impl
|
|
|
|
{
|
|
|
|
Impl() { sl = OS_SPINLOCK_INIT; refcount = 1; }
|
|
|
|
~Impl() {}
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
void lock() { OSSpinLockLock(&sl); }
|
|
|
|
bool trylock() { return OSSpinLockTry(&sl); }
|
|
|
|
void unlock() { OSSpinLockUnlock(&sl); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
OSSpinLock sl;
|
|
|
|
int refcount;
|
|
|
|
};
|
|
|
|
|
2012-08-17 22:28:50 +08:00
|
|
|
#elif defined __linux__ && !defined ANDROID
|
2012-08-17 21:32:06 +08:00
|
|
|
|
|
|
|
struct Mutex::Impl
|
|
|
|
{
|
|
|
|
Impl() { pthread_spin_init(&sl, 0); refcount = 1; }
|
|
|
|
~Impl() { pthread_spin_destroy(&sl); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
void lock() { pthread_spin_lock(&sl); }
|
|
|
|
bool trylock() { return pthread_spin_trylock(&sl) == 0; }
|
|
|
|
void unlock() { pthread_spin_unlock(&sl); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
pthread_spinlock_t sl;
|
|
|
|
int refcount;
|
|
|
|
};
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
struct Mutex::Impl
|
|
|
|
{
|
|
|
|
Impl() { pthread_mutex_init(&sl, 0); refcount = 1; }
|
|
|
|
~Impl() { pthread_mutex_destroy(&sl); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
void lock() { pthread_mutex_lock(&sl); }
|
|
|
|
bool trylock() { return pthread_mutex_trylock(&sl) == 0; }
|
|
|
|
void unlock() { pthread_mutex_unlock(&sl); }
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
pthread_mutex_t sl;
|
|
|
|
int refcount;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Mutex::Mutex()
|
|
|
|
{
|
|
|
|
impl = new Mutex::Impl;
|
|
|
|
}
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
Mutex::~Mutex()
|
|
|
|
{
|
|
|
|
if( CV_XADD(&impl->refcount, -1) == 1 )
|
|
|
|
delete impl;
|
|
|
|
impl = 0;
|
|
|
|
}
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
Mutex::Mutex(const Mutex& m)
|
|
|
|
{
|
|
|
|
impl = m.impl;
|
|
|
|
CV_XADD(&impl->refcount, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Mutex& Mutex::operator = (const Mutex& m)
|
|
|
|
{
|
|
|
|
CV_XADD(&m.impl->refcount, 1);
|
|
|
|
if( CV_XADD(&impl->refcount, -1) == 1 )
|
|
|
|
delete impl;
|
|
|
|
impl = m.impl;
|
|
|
|
return *this;
|
|
|
|
}
|
2012-08-17 22:28:50 +08:00
|
|
|
|
2012-08-17 21:32:06 +08:00
|
|
|
void Mutex::lock() { impl->lock(); }
|
|
|
|
void Mutex::unlock() { impl->unlock(); }
|
2012-08-17 22:28:50 +08:00
|
|
|
bool Mutex::trylock() { return impl->trylock(); }
|
2012-08-17 21:32:06 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-24 21:24:31 +08:00
|
|
|
/* End of file. */
|