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