]> rtime.felk.cvut.cz Git - opencv.git/blob - opencv/src/cxcore/cxsystem.cpp
f3123428a7e11c1b49d34ec9c998f486c5be82f2
[opencv.git] / opencv / src / cxcore / cxsystem.cpp
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 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
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.
26 //
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.
29 //
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.
40 //
41 //M*/
42
43 #include "_cxcore.h"
44
45 #if defined WIN32 || defined WIN64 || defined _WIN64 || defined WINCE
46 #include <tchar.h>
47 #ifdef _MSC_VER
48 #include <intrin.h>
49 #endif
50 #else
51 #include <pthread.h>
52 #include <sys/time.h>
53 #include <time.h>
54
55 #ifdef __MACH__
56 #include <mach/mach.h>
57 #include <mach/mach_time.h>
58 #endif
59
60 #endif
61
62 #ifdef _OPENMP
63 #include "omp.h"
64 #endif
65
66 #include <stdarg.h>
67
68 namespace cv
69 {
70
71 struct HWFeatures
72 {
73     enum { MAX_FEATURE = CV_HARDWARE_MAX_FEATURE };
74     
75     HWFeatures()
76     {
77         memset( have, 0, sizeof(have) );
78         x86_family = 0;
79     }
80     
81     static HWFeatures initialize()
82     {
83         HWFeatures f;
84         int cpuid_data[4]={0,0,0,0};
85         
86     #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
87         __cpuid(cpuid_data, 1);
88     #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
89         #ifdef __x86_64__
90         asm __volatile__
91         (
92          "movl $1, %%eax\n\t"
93          "cpuid\n\t"
94          :[eax]"=a"(cpuid_data[0]),[ebx]"=b"(cpuid_data[1]),[ecx]"=c"(cpuid_data[2]),[edx]"=d"(cpuid_data[3])
95          :
96          : "cc"
97         );
98         #else
99         asm volatile
100         (
101          "pushl %%ebx\n\t"
102          "movl $1,%%eax\n\t"
103          "cpuid\n\t"
104          "popl %%ebx\n\t"
105          : "=a"(cpuid_data[0]), "=c"(cpuid_data[2]), "=d"(cpuid_data[3])
106          :
107          : "cc"
108         );
109         #endif
110     #endif
111         
112         f.x86_family = (cpuid_data[0] >> 8) & 15;
113         if( f.x86_family >= 6 )
114         {
115             f.have[CV_CPU_MMX] = (cpuid_data[3] & (1 << 23)) != 0;
116             f.have[CV_CPU_SSE] = (cpuid_data[3] & (1<<25)) != 0;
117             f.have[CV_CPU_SSE2] = (cpuid_data[3] & (1<<26)) != 0;
118             f.have[CV_CPU_SSE3] = (cpuid_data[2] & (1<<0)) != 0;
119             f.have[CV_CPU_SSSE3] = (cpuid_data[2] & (1<<9)) != 0;
120             f.have[CV_CPU_SSE4_1] = (cpuid_data[2] & (1<<19)) != 0;
121             f.have[CV_CPU_SSE4_2] = (cpuid_data[2] & (1<<20)) != 0;
122             f.have[CV_CPU_AVX] = (cpuid_data[2] & (1<<28)) != 0;
123         }
124         
125         return f;
126     }
127     
128     int x86_family;
129     bool have[MAX_FEATURE+1];
130 };
131     
132 static HWFeatures featuresEnabled = HWFeatures::initialize(), featuresDisabled = HWFeatures();
133 static HWFeatures* currentFeatures = &featuresEnabled;
134
135 bool checkHardwareSupport(int feature)
136 {
137     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
138     return currentFeatures->have[feature];
139 }
140
141 #ifdef HAVE_IPP
142 volatile bool useOptimizedFlag = true;
143
144 struct IPPInitializer
145 {
146     IPPInitializer() { ippStaticInit(); }
147 };
148
149 IPPInitializer ippInitializer;
150 #else
151 volatile bool useOptimizedFlag = false;
152 #endif
153
154 void setUseOptimized( bool flag )
155 {
156     useOptimizedFlag = flag;
157     currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
158 }
159
160 bool useOptimized()
161 {
162     return useOptimizedFlag;
163 }
164     
165 int64 getTickCount()
166 {
167 #if defined WIN32 || defined WIN64 || defined _WIN64 || defined WINCE
168     LARGE_INTEGER counter;
169     QueryPerformanceCounter( &counter );
170     return (int64)counter.QuadPart;
171 #elif defined __linux || defined __linux__
172     struct timespec tp;
173     clock_gettime(CLOCK_MONOTONIC, &tp);
174     return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
175 #elif defined __MACH__
176     return (int64)mach_absolute_time();
177 #else    
178     struct timeval tv;
179     struct timezone tz;
180     gettimeofday( &tv, &tz );
181     return (int64)tv.tv_sec*1000000 + tv.tv_usec;
182 #endif
183 }
184
185 double getTickFrequency()
186 {
187 #if defined WIN32 || defined WIN64 || defined _WIN64 || defined WINCE
188     LARGE_INTEGER freq;
189     QueryPerformanceFrequency(&freq);
190     return (double)freq.QuadPart;
191 #elif defined __linux || defined __linux__
192     return 1e9;
193 #elif defined __MACH__
194     static double freq = 0;
195     if( freq == 0 )
196     {
197         mach_timebase_info_data_t sTimebaseInfo;
198         mach_timebase_info(&sTimebaseInfo);
199         freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
200     }
201     return freq; 
202 #else
203     return 1e6;
204 #endif
205 }
206
207 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__ || defined __ppc__) 
208 #if defined(__i386__)
209
210 int64 getCPUTickCount(void)
211 {
212     int64 x;
213     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
214     return x;
215 }
216 #elif defined(__x86_64__)
217
218 int64 getCPUTickCount(void)
219 {
220     unsigned hi, lo;
221     __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
222     return (int64)lo | ((int64)hi << 32);
223 }
224
225 #elif defined(__ppc__)
226
227 int64 getCPUTickCount(void)
228 {
229     int64 result=0;
230     unsigned upper, lower, tmp;
231     __asm__ volatile(
232                      "0:                  \n"
233                      "\tmftbu   %0           \n"
234                      "\tmftb    %1           \n"
235                      "\tmftbu   %2           \n"
236                      "\tcmpw    %2,%0        \n"
237                      "\tbne     0b         \n"
238                      : "=r"(upper),"=r"(lower),"=r"(tmp)
239                      );
240     return lower | ((int64)upper << 32);
241 }
242
243 #else
244
245 #error "RDTSC not defined"
246
247 #endif
248
249 #elif defined _MSC_VER && defined WIN32 && !defined _WIN64
250
251 int64 getCPUTickCount(void)
252 {
253     __asm _emit 0x0f;
254     __asm _emit 0x31;
255 }
256
257 #else
258
259 int64 getCPUTickCount()
260 {
261     return getTickCount();
262 }
263
264 #endif
265
266
267 static int numThreads = 0;
268 static int numProcs = 0;
269
270 int getNumThreads(void)
271 {
272     if( !numProcs )
273         setNumThreads(0);
274     return numThreads;
275 }
276
277 void setNumThreads( int
278 #ifdef _OPENMP
279                              threads
280 #endif
281                   )
282 {
283     if( !numProcs )
284     {
285 #ifdef _OPENMP
286         numProcs = omp_get_num_procs();
287 #else
288         numProcs = 1;
289 #endif
290     }
291
292 #ifdef _OPENMP
293     if( threads <= 0 )
294         threads = numProcs;
295     else
296         threads = MIN( threads, numProcs );
297
298     numThreads = threads;
299 #else
300     numThreads = 1;
301 #endif
302 }
303
304
305 int getThreadNum(void)
306 {
307 #ifdef _OPENMP
308     return omp_get_thread_num();
309 #else
310     return 0;
311 #endif
312 }
313     
314     
315 string format( const char* fmt, ... )
316 {
317     char buf[1 << 16];
318     va_list args;
319     va_start( args, fmt );
320     vsprintf( buf, fmt, args );
321     return string(buf);
322 }
323
324 static CvErrorCallback customErrorCallback = 0;
325 static void* customErrorCallbackData = 0;
326 static bool breakOnError = false;
327
328 bool setBreakOnError(bool value)
329 {
330     bool prevVal = breakOnError;
331     breakOnError = value;
332     return prevVal;
333 }        
334
335 void error( const Exception& exc )
336 {
337     if (customErrorCallback != 0) 
338         customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
339                             exc.file.c_str(), exc.line, customErrorCallbackData);
340     else
341     {
342         const char* errorStr = cvErrorStr(exc.code);
343         char buf[1 << 16];
344
345         sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
346             errorStr, exc.err.c_str(), exc.func.size() > 0 ?
347             exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
348         fprintf( stderr, "%s\n", buf );
349         fflush( stderr );
350     }
351     if(breakOnError)
352     {
353         static volatile int* p = 0;
354         *p = 0;
355     }
356     throw exc;
357 }
358     
359 CvErrorCallback
360 redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
361 {
362     if( prevUserdata )
363         *prevUserdata = customErrorCallbackData;
364     CvErrorCallback prevCallback = customErrorCallback;
365     customErrorCallback = errCallback;
366     customErrorCallbackData = userdata;
367     
368     return prevCallback;
369 }
370     
371 }
372
373 /*CV_IMPL int
374 cvGuiBoxReport( int code, const char *func_name, const char *err_msg,
375                 const char *file, int line, void* )
376 {
377 #if (!defined WIN32 && !defined WIN64) || defined WINCE
378     return cvStdErrReport( code, func_name, err_msg, file, line, 0 );
379 #else
380     if( code != CV_StsBackTrace && code != CV_StsAutoTrace )
381     {
382         size_t msg_len = strlen(err_msg ? err_msg : "") + 1024;
383         char* message = (char*)alloca(msg_len);
384         char title[100];
385
386         wsprintf( message, "%s (%s)\nin function %s, %s(%d)\n\n"
387                   "Press \"Abort\" to terminate application.\n"
388                   "Press \"Retry\" to debug (if the app is running under debugger).\n"
389                   "Press \"Ignore\" to continue (this is not safe).\n",
390                   cvErrorStr(code), err_msg ? err_msg : "no description",
391                   func_name, file, line );
392
393         wsprintf( title, "OpenCV GUI Error Handler" );
394
395         int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL );
396
397         if( answer == IDRETRY )
398         {
399             CV_DBG_BREAK();
400         }
401         return answer != IDIGNORE;
402     }
403     return 0;
404 #endif
405 }*/
406
407 CV_IMPL int cvCheckHardwareSupport(int feature)
408 {
409     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
410     return cv::currentFeatures->have[feature];
411 }
412
413 CV_IMPL int cvUseOptimized( int flag )
414 {
415     int prevMode = cv::useOptimizedFlag;
416     cv::setUseOptimized( flag != 0 );
417     return prevMode;
418 }
419
420 CV_IMPL int64  cvGetTickCount(void)
421 {
422     return cv::getTickCount();
423 }
424
425 CV_IMPL double cvGetTickFrequency(void)
426 {
427     return cv::getTickFrequency()*1e-6;
428 }
429
430 CV_IMPL void cvSetNumThreads(int nt)
431 {
432     cv::setNumThreads(nt);
433 }
434
435 CV_IMPL int cvGetNumThreads()
436 {
437     return cv::getNumThreads();
438 }
439
440 CV_IMPL int cvGetThreadNum()
441 {
442     return cv::getThreadNum();
443 }
444
445
446 CV_IMPL CvErrorCallback
447 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
448 {
449     return cv::redirectError(errCallback, userdata, prevUserdata);
450 }
451
452 CV_IMPL int cvNulDevReport( int, const char*, const char*,
453                             const char*, int, void* )
454 {
455     return 0;
456 }
457
458 CV_IMPL int cvStdErrReport( int, const char*, const char*,
459                             const char*, int, void* )
460 {
461     return 0;
462 }
463
464 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
465                             const char*, int, void* )
466 {
467     return 0;
468 }
469
470 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
471 {
472     return 0;
473 }
474
475
476 CV_IMPL const char* cvErrorStr( int status )
477 {
478     static char buf[256];
479
480     switch (status)
481     {
482     case CV_StsOk :        return "No Error";
483     case CV_StsBackTrace : return "Backtrace";
484     case CV_StsError :     return "Unspecified error";
485     case CV_StsInternal :  return "Internal error";
486     case CV_StsNoMem :     return "Insufficient memory";
487     case CV_StsBadArg :    return "Bad argument";
488     case CV_StsNoConv :    return "Iterations do not converge";
489     case CV_StsAutoTrace : return "Autotrace call";
490     case CV_StsBadSize :   return "Incorrect size of input array";
491     case CV_StsNullPtr :   return "Null pointer";
492     case CV_StsDivByZero : return "Division by zero occured";
493     case CV_BadStep :      return "Image step is wrong";
494     case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
495     case CV_StsObjectNotFound :      return "Requested object was not found";
496     case CV_BadDepth :     return "Input image depth is not supported by function";
497     case CV_StsUnmatchedFormats : return "Formats of input arguments do not match";
498     case CV_StsUnmatchedSizes :  return "Sizes of input arguments do not match";
499     case CV_StsOutOfRange : return "One of arguments\' values is out of range";
500     case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats";
501     case CV_BadCOI :      return "Input COI is not supported";
502     case CV_BadNumChannels : return "Bad number of channels";
503     case CV_StsBadFlag :   return "Bad flag (parameter or structure field)";
504     case CV_StsBadPoint :  return "Bad parameter of type CvPoint";
505     case CV_StsBadMask : return "Bad type of mask argument";
506     case CV_StsParseError : return "Parsing error";
507     case CV_StsNotImplemented : return "The function/feature is not implemented";
508     case CV_StsBadMemBlock :  return "Memory block has been corrupted";
509     case CV_StsAssert :  return "Assertion failed";
510     };
511
512     sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
513     return buf;
514 }
515
516 CV_IMPL int cvGetErrMode(void)
517 {
518     return 0;
519 }
520
521 CV_IMPL int cvSetErrMode(int)
522 {
523     return 0;
524 }
525
526 CV_IMPL int cvGetErrStatus()
527 {
528     return 0;
529 }
530
531 CV_IMPL void cvSetErrStatus(int)
532 {
533 }
534
535
536 CV_IMPL void cvError( int code, const char* func_name,
537                       const char* err_msg,
538                       const char* file_name, int line )
539 {
540     cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
541 }
542
543 /* function, which converts int to int */
544 CV_IMPL int
545 cvErrorFromIppStatus( int status )
546 {
547     switch (status)
548     {
549     case CV_BADSIZE_ERR: return CV_StsBadSize;
550     case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock;
551     case CV_NULLPTR_ERR: return CV_StsNullPtr;
552     case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero;
553     case CV_BADSTEP_ERR: return CV_BadStep ;
554     case CV_OUTOFMEM_ERR: return CV_StsNoMem;
555     case CV_BADARG_ERR: return CV_StsBadArg;
556     case CV_NOTDEFINED_ERR: return CV_StsError;
557     case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
558     case CV_NOTFOUND_ERR: return CV_StsObjectNotFound;
559     case CV_BADCONVERGENCE_ERR: return CV_StsNoConv;
560     case CV_BADDEPTH_ERR: return CV_BadDepth;
561     case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats;
562     case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI;
563     case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels;
564     case CV_BADFLAG_ERR: return CV_StsBadFlag;
565     case CV_BADRANGE_ERR: return CV_StsBadArg;
566     case CV_BADCOEF_ERR: return CV_StsBadArg;
567     case CV_BADFACTOR_ERR: return CV_StsBadArg;
568     case CV_BADPOINT_ERR: return CV_StsBadPoint;
569
570     default: return CV_StsError;
571     }
572 }
573
574 static CvModuleInfo cxcore_info = { 0, "cxcore", CV_VERSION, 0 };
575
576 CvModuleInfo *CvModule::first = 0, *CvModule::last = 0;
577
578 CvModule::CvModule( CvModuleInfo* _info )
579 {
580     cvRegisterModule( _info );
581     info = last;
582 }
583
584 CvModule::~CvModule()
585 {
586     if( info )
587     {
588         CvModuleInfo* p = first;
589         for( ; p != 0 && p->next != info; p = p->next )
590             ;
591         if( p )
592             p->next = info->next;
593         if( first == info )
594             first = info->next;
595         if( last == info )
596             last = p;
597         free( info );
598         info = 0;
599     }
600 }
601
602 CV_IMPL int
603 cvRegisterModule( const CvModuleInfo* module )
604 {
605     CV_Assert( module != 0 && module->name != 0 && module->version != 0 );
606
607     size_t name_len = strlen(module->name);
608     size_t version_len = strlen(module->version);
609
610     CvModuleInfo* module_copy = (CvModuleInfo*)malloc( sizeof(*module_copy) +
611                                 name_len + 1 + version_len + 1 );
612
613     *module_copy = *module;
614     module_copy->name = (char*)(module_copy + 1);
615     module_copy->version = (char*)(module_copy + 1) + name_len + 1;
616
617     memcpy( (void*)module_copy->name, module->name, name_len + 1 );
618     memcpy( (void*)module_copy->version, module->version, version_len + 1 );
619     module_copy->next = 0;
620
621     if( CvModule::first == 0 )
622         CvModule::first = module_copy;
623     else
624         CvModule::last->next = module_copy;
625     CvModule::last = module_copy;
626     return 0;
627 }
628
629 CvModule cxcore_module( &cxcore_info );
630
631 CV_IMPL void
632 cvGetModuleInfo( const char* name, const char **version, const char **plugin_list )
633 {
634     static char joint_verinfo[1024] = "";
635     static char plugin_list_buf[1024] = "";
636
637     if( version )
638         *version = 0;
639
640     if( plugin_list )
641         *plugin_list = 0;
642
643     CvModuleInfo* module;
644
645     if( version )
646     {
647         if( name )
648         {
649             size_t i, name_len = strlen(name);
650
651             for( module = CvModule::first; module != 0; module = module->next )
652             {
653                 if( strlen(module->name) == name_len )
654                 {
655                     for( i = 0; i < name_len; i++ )
656                     {
657                         int c0 = toupper(module->name[i]), c1 = toupper(name[i]);
658                         if( c0 != c1 )
659                             break;
660                     }
661                     if( i == name_len )
662                         break;
663                 }
664             }
665             if( !module )
666                 CV_Error( CV_StsObjectNotFound, "The module is not found" );
667
668             *version = module->version;
669         }
670         else
671         {
672             char* ptr = joint_verinfo;
673
674             for( module = CvModule::first; module != 0; module = module->next )
675             {
676                 sprintf( ptr, "%s: %s%s", module->name, module->version, module->next ? ", " : "" );
677                 ptr += strlen(ptr);
678             }
679
680             *version = joint_verinfo;
681         }
682     }
683
684     if( plugin_list )
685         *plugin_list = plugin_list_buf;
686 }
687
688 #if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
689 BOOL WINAPI DllMain( HINSTANCE, DWORD  fdwReason, LPVOID )
690 {
691     if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH )
692     {
693         cv::deleteThreadAllocData();
694         cv::deleteThreadRNGData();
695     }
696     return TRUE;
697 }
698 #endif
699
700 /* End of file. */