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