]> rtime.felk.cvut.cz Git - opencv.git/blob - opencv/src/cxcore/cxsystem.cpp
more accurate time measurements (getTickCount) on MacOSX; Use RDTSC() again (when...
[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 #else
48 #include <pthread.h>
49 #include <sys/time.h>
50 #include <time.h>
51
52 #ifdef __MACH__
53 #include <mach/mach.h>
54 #include <mach/mach_time.h>
55 #endif
56
57 #endif
58
59 #ifdef _OPENMP
60 #include "omp.h"
61 #endif
62
63 #include <stdarg.h>
64
65 namespace cv
66 {
67
68 #ifdef HAVE_IPP
69 volatile bool useOptimizedFlag = true;
70 #else
71 volatile bool useOptimizedFlag = false;
72 #endif
73
74 void setUseOptimized( bool flag )
75 {
76     useOptimizedFlag = flag;
77 }
78
79 bool useOptimized()
80 {
81     return useOptimizedFlag;
82 }
83
84 int64 getTickCount()
85 {
86 #if defined WIN32 || defined WIN64 || defined _WIN64 || defined WINCE
87     LARGE_INTEGER counter;
88     QueryPerformanceCounter( &counter );
89     return (int64)counter.QuadPart;
90 #elif defined __linux || defined __linux__
91     struct timespec tp;
92     clock_gettime(CLOCK_MONOTONIC, &tp);
93     return (int64)tp.tv_sec*1000000000 + tp.tv_nsec;
94 #elif defined __MACH__
95     return (int64)mach_absolute_time();
96 #else    
97     struct timeval tv;
98     struct timezone tz;
99     gettimeofday( &tv, &tz );
100     return (int64)tv.tv_sec*1000000 + tv.tv_usec;
101 #endif
102 }
103
104 double getTickFrequency()
105 {
106 #if defined WIN32 || defined WIN64 || defined _WIN64 || defined WINCE
107     LARGE_INTEGER freq;
108     QueryPerformanceFrequency(&freq);
109     return (double)freq.QuadPart;
110 #elif defined __linux || defined __linux__
111     return 1e9;
112 #elif defined __MACH__
113     static double freq = 0;
114     if( freq == 0 )
115     {
116         mach_timebase_info_data_t sTimebaseInfo;
117         mach_timebase_info(&sTimebaseInfo);
118         freq = sTimebaseInfo.denom*1e9/sTimebaseInfo.numer;
119     }
120     return freq; 
121 #else
122     return 1e6;
123 #endif
124 }
125
126 static int numThreads = 0;
127 static int numProcs = 0;
128
129 int getNumThreads(void)
130 {
131     if( !numProcs )
132         setNumThreads(0);
133     return numThreads;
134 }
135
136 void setNumThreads( int
137 #ifdef _OPENMP
138                              threads
139 #endif
140                   )
141 {
142     if( !numProcs )
143     {
144 #ifdef _OPENMP
145         numProcs = omp_get_num_procs();
146 #else
147         numProcs = 1;
148 #endif
149     }
150
151 #ifdef _OPENMP
152     if( threads <= 0 )
153         threads = numProcs;
154     else
155         threads = MIN( threads, numProcs );
156
157     numThreads = threads;
158 #else
159     numThreads = 1;
160 #endif
161 }
162
163
164 int getThreadNum(void)
165 {
166 #ifdef _OPENMP
167     return omp_get_thread_num();
168 #else
169     return 0;
170 #endif
171 }
172
173
174 string format( const char* fmt, ... )
175 {
176     char buf[1 << 16];
177     va_list args;
178     va_start( args, fmt );
179     vsprintf( buf, fmt, args );
180     return string(buf);
181 }
182
183 static CvErrorCallback customErrorCallback = 0;
184 static void* customErrorCallbackData = 0;
185 static bool breakOnError = false;
186
187 bool setBreakOnError(bool value)
188 {
189     bool prevVal = breakOnError;
190     breakOnError = value;
191     return prevVal;
192 }        
193
194 void error( const Exception& exc )
195 {
196     if (customErrorCallback != 0) 
197         customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
198                             exc.file.c_str(), exc.line, customErrorCallbackData);
199     else
200     {
201         const char* errorStr = cvErrorStr(exc.code);
202         char buf[1 << 16];
203
204         sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
205             errorStr, exc.err.c_str(), exc.func.size() > 0 ?
206             exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
207         fprintf( stderr, "%s\n", buf );
208         fflush( stderr );
209     }
210     if(breakOnError)
211     {
212         static volatile int* p = 0;
213         *p = 0;
214     }
215     throw exc;
216 }
217     
218 CvErrorCallback
219 redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
220 {
221     if( prevUserdata )
222         *prevUserdata = customErrorCallbackData;
223     CvErrorCallback prevCallback = customErrorCallback;
224     customErrorCallback = errCallback;
225     customErrorCallbackData = userdata;
226     
227     return prevCallback;
228 }
229     
230 }
231
232 /*CV_IMPL int
233 cvGuiBoxReport( int code, const char *func_name, const char *err_msg,
234                 const char *file, int line, void* )
235 {
236 #if (!defined WIN32 && !defined WIN64) || defined WINCE
237     return cvStdErrReport( code, func_name, err_msg, file, line, 0 );
238 #else
239     if( code != CV_StsBackTrace && code != CV_StsAutoTrace )
240     {
241         size_t msg_len = strlen(err_msg ? err_msg : "") + 1024;
242         char* message = (char*)alloca(msg_len);
243         char title[100];
244
245         wsprintf( message, "%s (%s)\nin function %s, %s(%d)\n\n"
246                   "Press \"Abort\" to terminate application.\n"
247                   "Press \"Retry\" to debug (if the app is running under debugger).\n"
248                   "Press \"Ignore\" to continue (this is not safe).\n",
249                   cvErrorStr(code), err_msg ? err_msg : "no description",
250                   func_name, file, line );
251
252         wsprintf( title, "OpenCV GUI Error Handler" );
253
254         int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL );
255
256         if( answer == IDRETRY )
257         {
258             CV_DBG_BREAK();
259         }
260         return answer != IDIGNORE;
261     }
262     return 0;
263 #endif
264 }*/
265
266 CV_IMPL int cvUseOptimized( int flag )
267 {
268     int prevMode = cv::useOptimizedFlag;
269     cv::setUseOptimized( flag != 0 );
270     return prevMode;
271 }
272
273 CV_IMPL int64  cvGetTickCount(void)
274 {
275     return cv::getTickCount();
276 }
277
278 CV_IMPL double cvGetTickFrequency(void)
279 {
280     return cv::getTickFrequency()*1e-6;
281 }
282
283 CV_IMPL void cvSetNumThreads(int nt)
284 {
285     cv::setNumThreads(nt);
286 }
287
288 CV_IMPL int cvGetNumThreads()
289 {
290     return cv::getNumThreads();
291 }
292
293 CV_IMPL int cvGetThreadNum()
294 {
295     return cv::getThreadNum();
296 }
297
298
299 CV_IMPL CvErrorCallback
300 cvRedirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
301 {
302     return cv::redirectError(errCallback, userdata, prevUserdata);
303 }
304
305 CV_IMPL int cvNulDevReport( int, const char*, const char*,
306                             const char*, int, void* )
307 {
308     return 0;
309 }
310
311 CV_IMPL int cvStdErrReport( int, const char*, const char*,
312                             const char*, int, void* )
313 {
314     return 0;
315 }
316
317 CV_IMPL int cvGuiBoxReport( int, const char*, const char*,
318                             const char*, int, void* )
319 {
320     return 0;
321 }
322
323 CV_IMPL int cvGetErrInfo( const char**, const char**, const char**, int* )
324 {
325     return 0;
326 }
327
328
329 CV_IMPL const char* cvErrorStr( int status )
330 {
331     static char buf[256];
332
333     switch (status)
334     {
335     case CV_StsOk :        return "No Error";
336     case CV_StsBackTrace : return "Backtrace";
337     case CV_StsError :     return "Unspecified error";
338     case CV_StsInternal :  return "Internal error";
339     case CV_StsNoMem :     return "Insufficient memory";
340     case CV_StsBadArg :    return "Bad argument";
341     case CV_StsNoConv :    return "Iterations do not converge";
342     case CV_StsAutoTrace : return "Autotrace call";
343     case CV_StsBadSize :   return "Incorrect size of input array";
344     case CV_StsNullPtr :   return "Null pointer";
345     case CV_StsDivByZero : return "Division by zero occured";
346     case CV_BadStep :      return "Image step is wrong";
347     case CV_StsInplaceNotSupported : return "Inplace operation is not supported";
348     case CV_StsObjectNotFound :      return "Requested object was not found";
349     case CV_BadDepth :     return "Input image depth is not supported by function";
350     case CV_StsUnmatchedFormats : return "Formats of input arguments do not match";
351     case CV_StsUnmatchedSizes :  return "Sizes of input arguments do not match";
352     case CV_StsOutOfRange : return "One of arguments\' values is out of range";
353     case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats";
354     case CV_BadCOI :      return "Input COI is not supported";
355     case CV_BadNumChannels : return "Bad number of channels";
356     case CV_StsBadFlag :   return "Bad flag (parameter or structure field)";
357     case CV_StsBadPoint :  return "Bad parameter of type CvPoint";
358     case CV_StsBadMask : return "Bad type of mask argument";
359     case CV_StsParseError : return "Parsing error";
360     case CV_StsNotImplemented : return "The function/feature is not implemented";
361     case CV_StsBadMemBlock :  return "Memory block has been corrupted";
362     case CV_StsAssert :  return "Assertion failed";
363     };
364
365     sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status);
366     return buf;
367 }
368
369 CV_IMPL int cvGetErrMode(void)
370 {
371     return 0;
372 }
373
374 CV_IMPL int cvSetErrMode(int)
375 {
376     return 0;
377 }
378
379 CV_IMPL int cvGetErrStatus()
380 {
381     return 0;
382 }
383
384 CV_IMPL void cvSetErrStatus(int)
385 {
386 }
387
388
389 CV_IMPL void cvError( int code, const char* func_name,
390                       const char* err_msg,
391                       const char* file_name, int line )
392 {
393     cv::error(cv::Exception(code, err_msg, func_name, file_name, line));
394 }
395
396 /* function, which converts int to int */
397 CV_IMPL int
398 cvErrorFromIppStatus( int status )
399 {
400     switch (status)
401     {
402     case CV_BADSIZE_ERR: return CV_StsBadSize;
403     case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock;
404     case CV_NULLPTR_ERR: return CV_StsNullPtr;
405     case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero;
406     case CV_BADSTEP_ERR: return CV_BadStep ;
407     case CV_OUTOFMEM_ERR: return CV_StsNoMem;
408     case CV_BADARG_ERR: return CV_StsBadArg;
409     case CV_NOTDEFINED_ERR: return CV_StsError;
410     case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported;
411     case CV_NOTFOUND_ERR: return CV_StsObjectNotFound;
412     case CV_BADCONVERGENCE_ERR: return CV_StsNoConv;
413     case CV_BADDEPTH_ERR: return CV_BadDepth;
414     case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats;
415     case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI;
416     case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels;
417     case CV_BADFLAG_ERR: return CV_StsBadFlag;
418     case CV_BADRANGE_ERR: return CV_StsBadArg;
419     case CV_BADCOEF_ERR: return CV_StsBadArg;
420     case CV_BADFACTOR_ERR: return CV_StsBadArg;
421     case CV_BADPOINT_ERR: return CV_StsBadPoint;
422
423     default: return CV_StsError;
424     }
425 }
426
427 static CvModuleInfo cxcore_info = { 0, "cxcore", CV_VERSION, 0 };
428
429 CvModuleInfo *CvModule::first = 0, *CvModule::last = 0;
430
431 CvModule::CvModule( CvModuleInfo* _info )
432 {
433     cvRegisterModule( _info );
434     info = last;
435 }
436
437 CvModule::~CvModule()
438 {
439     if( info )
440     {
441         CvModuleInfo* p = first;
442         for( ; p != 0 && p->next != info; p = p->next )
443             ;
444         if( p )
445             p->next = info->next;
446         if( first == info )
447             first = info->next;
448         if( last == info )
449             last = p;
450         free( info );
451         info = 0;
452     }
453 }
454
455 CV_IMPL int
456 cvRegisterModule( const CvModuleInfo* module )
457 {
458     CV_Assert( module != 0 && module->name != 0 && module->version != 0 );
459
460     size_t name_len = strlen(module->name);
461     size_t version_len = strlen(module->version);
462
463     CvModuleInfo* module_copy = (CvModuleInfo*)malloc( sizeof(*module_copy) +
464                                 name_len + 1 + version_len + 1 );
465
466     *module_copy = *module;
467     module_copy->name = (char*)(module_copy + 1);
468     module_copy->version = (char*)(module_copy + 1) + name_len + 1;
469
470     memcpy( (void*)module_copy->name, module->name, name_len + 1 );
471     memcpy( (void*)module_copy->version, module->version, version_len + 1 );
472     module_copy->next = 0;
473
474     if( CvModule::first == 0 )
475         CvModule::first = module_copy;
476     else
477         CvModule::last->next = module_copy;
478     CvModule::last = module_copy;
479     return 0;
480 }
481
482 CvModule cxcore_module( &cxcore_info );
483
484 CV_IMPL void
485 cvGetModuleInfo( const char* name, const char **version, const char **plugin_list )
486 {
487     static char joint_verinfo[1024] = "";
488     static char plugin_list_buf[1024] = "";
489
490     if( version )
491         *version = 0;
492
493     if( plugin_list )
494         *plugin_list = 0;
495
496     CvModuleInfo* module;
497
498     if( version )
499     {
500         if( name )
501         {
502             size_t i, name_len = strlen(name);
503
504             for( module = CvModule::first; module != 0; module = module->next )
505             {
506                 if( strlen(module->name) == name_len )
507                 {
508                     for( i = 0; i < name_len; i++ )
509                     {
510                         int c0 = toupper(module->name[i]), c1 = toupper(name[i]);
511                         if( c0 != c1 )
512                             break;
513                     }
514                     if( i == name_len )
515                         break;
516                 }
517             }
518             if( !module )
519                 CV_Error( CV_StsObjectNotFound, "The module is not found" );
520
521             *version = module->version;
522         }
523         else
524         {
525             char* ptr = joint_verinfo;
526
527             for( module = CvModule::first; module != 0; module = module->next )
528             {
529                 sprintf( ptr, "%s: %s%s", module->name, module->version, module->next ? ", " : "" );
530                 ptr += strlen(ptr);
531             }
532
533             *version = joint_verinfo;
534         }
535     }
536
537     if( plugin_list )
538         *plugin_list = plugin_list_buf;
539 }
540
541 #if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
542 BOOL WINAPI DllMain( HINSTANCE, DWORD  fdwReason, LPVOID )
543 {
544     if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH )
545     {
546         cv::deleteThreadAllocData();
547         cv::deleteThreadRNGData();
548     }
549     return TRUE;
550 }
551 #endif
552
553 /* End of file. */