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 // Intel License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000, Intel Corporation, all rights reserved. 14 // Third party copyrights are property of their respective owners. 15 // 16 // Redistribution and use in source and binary forms, with or without modification, 17 // are permitted provided that the following conditions are met: 18 // 19 // * Redistribution's of source code must retain the above copyright notice, 20 // this list of conditions and the following disclaimer. 21 // 22 // * Redistribution's in binary form must reproduce the above copyright notice, 23 // this list of conditions and the following disclaimer in the documentation 24 // and/or other materials provided with the distribution. 25 // 26 // * The name of Intel Corporation may not be used to endorse or promote products 27 // derived from this software without specific prior written permission. 28 // 29 // This software is provided by the copyright holders and contributors "as is" and 30 // any express or implied warranties, including, but not limited to, the implied 31 // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 // In no event shall the Intel Corporation or contributors be liable for any direct, 33 // indirect, incidental, special, exemplary, or consequential damages 34 // (including, but not limited to, procurement of substitute goods or services; 35 // loss of use, data, or profits; or business interruption) however caused 36 // and on any theory of liability, whether in contract, strict liability, 37 // or tort (including negligence or otherwise) arising in any way out of 38 // the use of this software, even if advised of the possibility of such damage. 39 // 40 //M*/ 41 42 #include "_cxcore.h" 43 44 #if defined WIN32 || defined WIN64 45 #include <windows.h> 46 #else 47 #include <pthread.h> 48 #endif 49 50 typedef struct 51 { 52 const char* file; 53 int line; 54 } 55 CvStackRecord; 56 57 typedef struct CvContext 58 { 59 int err_code; 60 int err_mode; 61 CvErrorCallback error_callback; 62 void* userdata; 63 char err_msg[4096]; 64 CvStackRecord err_ctx; 65 } CvContext; 66 67 #if defined WIN32 || defined WIN64 68 #define CV_DEFAULT_ERROR_CALLBACK cvGuiBoxReport 69 #else 70 #define CV_DEFAULT_ERROR_CALLBACK cvStdErrReport 71 #endif 72 73 static CvContext* 74 icvCreateContext(void) 75 { 76 CvContext* context = (CvContext*)malloc( sizeof(*context) ); 77 78 context->err_mode = CV_ErrModeLeaf; 79 context->err_code = CV_StsOk; 80 81 context->error_callback = CV_DEFAULT_ERROR_CALLBACK; 82 context->userdata = 0; 83 84 return context; 85 } 86 87 static void 88 icvDestroyContext(CvContext* context) 89 { 90 free(context); 91 } 92 93 #if defined WIN32 || defined WIN64 94 static DWORD g_TlsIndex = TLS_OUT_OF_INDEXES; 95 #else 96 static pthread_key_t g_TlsIndex; 97 #endif 98 99 static CvContext* 100 icvGetContext(void) 101 { 102 #ifdef CV_DLL 103 #if defined WIN32 || defined WIN64 104 CvContext* context; 105 106 //assert(g_TlsIndex != TLS_OUT_OF_INDEXES); 107 if( g_TlsIndex == TLS_OUT_OF_INDEXES ) 108 { 109 g_TlsIndex = TlsAlloc(); 110 if( g_TlsIndex == TLS_OUT_OF_INDEXES ) 111 FatalAppExit( 0, "Only set CV_DLL for DLL usage" ); 112 } 113 114 context = (CvContext*)TlsGetValue( g_TlsIndex ); 115 if( !context ) 116 { 117 context = icvCreateContext(); 118 if( !context ) 119 FatalAppExit( 0, "OpenCV. Problem to allocate memory for TLS OpenCV context." ); 120 121 TlsSetValue( g_TlsIndex, context ); 122 } 123 return context; 124 #else 125 CvContext* context = (CvContext*)pthread_getspecific( g_TlsIndex ); 126 if( !context ) 127 { 128 context = icvCreateContext(); 129 if( !context ) 130 { 131 fprintf(stderr,"OpenCV. Problem to allocate memory for OpenCV context."); 132 exit(1); 133 } 134 pthread_setspecific( g_TlsIndex, context ); 135 } 136 return context; 137 #endif 138 #else /* static single-thread library case */ 139 static CvContext* context = 0; 140 141 if( !context ) 142 context = icvCreateContext(); 143 144 return context; 145 #endif 146 } 147 148 149 CV_IMPL int 150 cvStdErrReport( int code, const char *func_name, const char *err_msg, 151 const char *file, int line, void* ) 152 { 153 if( code == CV_StsBackTrace || code == CV_StsAutoTrace ) 154 fprintf( stderr, "\tcalled from " ); 155 else 156 fprintf( stderr, "OpenCV ERROR: %s (%s)\n\tin function ", 157 cvErrorStr(code), err_msg ? err_msg : "no description" ); 158 159 fprintf( stderr, "%s, %s(%d)\n", func_name ? func_name : "<unknown>", 160 file != NULL ? file : "", line ); 161 162 if( cvGetErrMode() == CV_ErrModeLeaf ) 163 { 164 fprintf( stderr, "Terminating the application...\n" ); 165 return 1; 166 } 167 else 168 return 0; 169 } 170 171 172 CV_IMPL int 173 cvGuiBoxReport( int code, const char *func_name, const char *err_msg, 174 const char *file, int line, void* ) 175 { 176 #if !defined WIN32 && !defined WIN64 177 return cvStdErrReport( code, func_name, err_msg, file, line, 0 ); 178 #else 179 if( code != CV_StsBackTrace && code != CV_StsAutoTrace ) 180 { 181 size_t msg_len = strlen(err_msg ? err_msg : "") + 1024; 182 char* message = (char*)alloca(msg_len); 183 char title[100]; 184 185 wsprintf( message, "%s (%s)\nin function %s, %s(%d)\n\n" 186 "Press \"Abort\" to terminate application.\n" 187 "Press \"Retry\" to debug (if the app is running under debugger).\n" 188 "Press \"Ignore\" to continue (this is not safe).\n", 189 cvErrorStr(code), err_msg ? err_msg : "no description", 190 func_name, file, line ); 191 192 wsprintf( title, "OpenCV GUI Error Handler" ); 193 194 int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL ); 195 196 if( answer == IDRETRY ) 197 { 198 CV_DBG_BREAK(); 199 } 200 return answer != IDIGNORE; 201 } 202 return 0; 203 #endif 204 } 205 206 207 CV_IMPL int cvNulDevReport( int /*code*/, const char* /*func_name*/, 208 const char* /*err_msg*/, const char* /*file*/, int /*line*/, void* ) 209 { 210 return cvGetErrMode() == CV_ErrModeLeaf; 211 } 212 213 214 CV_IMPL CvErrorCallback 215 cvRedirectError( CvErrorCallback func, void* userdata, void** prev_userdata ) 216 { 217 CvContext* context = icvGetContext(); 218 219 CvErrorCallback old = context->error_callback; 220 if( prev_userdata ) 221 *prev_userdata = context->userdata; 222 if( func ) 223 { 224 context->error_callback = func; 225 context->userdata = userdata; 226 } 227 else 228 { 229 context->error_callback = CV_DEFAULT_ERROR_CALLBACK; 230 context->userdata = 0; 231 } 232 233 return old; 234 } 235 236 237 CV_IMPL int cvGetErrInfo( const char** errorcode_desc, const char** description, 238 const char** filename, int* line ) 239 { 240 int code = cvGetErrStatus(); 241 242 if( errorcode_desc ) 243 *errorcode_desc = cvErrorStr( code ); 244 245 if( code >= 0 ) 246 { 247 if( description ) 248 *description = 0; 249 if( filename ) 250 *filename = 0; 251 if( line ) 252 *line = 0; 253 } 254 else 255 { 256 CvContext* ctx = icvGetContext(); 257 258 if( description ) 259 *description = ctx->err_msg; 260 if( filename ) 261 *filename = ctx->err_ctx.file; 262 if( line ) 263 *line = ctx->err_ctx.line; 264 } 265 266 return code; 267 } 268 269 270 CV_IMPL const char* cvErrorStr( int status ) 271 { 272 static char buf[256]; 273 274 switch (status) 275 { 276 case CV_StsOk : return "No Error"; 277 case CV_StsBackTrace : return "Backtrace"; 278 case CV_StsError : return "Unspecified error"; 279 case CV_StsInternal : return "Internal error"; 280 case CV_StsNoMem : return "Insufficient memory"; 281 case CV_StsBadArg : return "Bad argument"; 282 case CV_StsNoConv : return "Iterations do not converge"; 283 case CV_StsAutoTrace : return "Autotrace call"; 284 case CV_StsBadSize : return "Incorrect size of input array"; 285 case CV_StsNullPtr : return "Null pointer"; 286 case CV_StsDivByZero : return "Divizion by zero occured"; 287 case CV_BadStep : return "Image step is wrong"; 288 case CV_StsInplaceNotSupported : return "Inplace operation is not supported"; 289 case CV_StsObjectNotFound : return "Requested object was not found"; 290 case CV_BadDepth : return "Input image depth is not supported by function"; 291 case CV_StsUnmatchedFormats : return "Formats of input arguments do not match"; 292 case CV_StsUnmatchedSizes : return "Sizes of input arguments do not match"; 293 case CV_StsOutOfRange : return "One of arguments\' values is out of range"; 294 case CV_StsUnsupportedFormat : return "Unsupported format or combination of formats"; 295 case CV_BadCOI : return "Input COI is not supported"; 296 case CV_BadNumChannels : return "Bad number of channels"; 297 case CV_StsBadFlag : return "Bad flag (parameter or structure field)"; 298 case CV_StsBadPoint : return "Bad parameter of type CvPoint"; 299 case CV_StsBadMask : return "Bad type of mask argument"; 300 case CV_StsParseError : return "Parsing error"; 301 case CV_StsNotImplemented : return "The function/feature is not implemented"; 302 case CV_StsBadMemBlock : return "Memory block has been corrupted"; 303 }; 304 305 sprintf(buf, "Unknown %s code %d", status >= 0 ? "status":"error", status); 306 return buf; 307 } 308 309 CV_IMPL int cvGetErrMode(void) 310 { 311 return icvGetContext()->err_mode; 312 } 313 314 CV_IMPL int cvSetErrMode( int mode ) 315 { 316 CvContext* context = icvGetContext(); 317 int prev_mode = context->err_mode; 318 context->err_mode = mode; 319 return prev_mode; 320 } 321 322 CV_IMPL int cvGetErrStatus() 323 { 324 return icvGetContext()->err_code; 325 } 326 327 CV_IMPL void cvSetErrStatus( int code ) 328 { 329 icvGetContext()->err_code = code; 330 } 331 332 333 CV_IMPL void cvError( int code, const char* func_name, 334 const char* err_msg, 335 const char* file_name, int line ) 336 { 337 if( code == CV_StsOk ) 338 cvSetErrStatus( code ); 339 else 340 { 341 CvContext* context = icvGetContext(); 342 343 if( code != CV_StsBackTrace && code != CV_StsAutoTrace ) 344 { 345 char* message = context->err_msg; 346 context->err_code = code; 347 348 strcpy( message, err_msg ); 349 context->err_ctx.file = file_name; 350 context->err_ctx.line = line; 351 } 352 353 if( context->err_mode != CV_ErrModeSilent ) 354 { 355 int terminate = context->error_callback( code, func_name, err_msg, 356 file_name, line, context->userdata ); 357 if( terminate ) 358 { 359 CV_DBG_BREAK(); 360 //exit(-abs(terminate)); 361 } 362 } 363 } 364 } 365 366 367 /******************** End of implementation of profiling stuff *********************/ 368 369 370 /**********************DllMain********************************/ 371 372 #if defined WIN32 || defined WIN64 373 BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID ) 374 { 375 CvContext *pContext; 376 377 switch (fdwReason) 378 { 379 case DLL_PROCESS_ATTACH: 380 g_TlsIndex = TlsAlloc(); 381 if( g_TlsIndex == TLS_OUT_OF_INDEXES ) return FALSE; 382 //break; 383 384 case DLL_THREAD_ATTACH: 385 pContext = icvCreateContext(); 386 if( pContext == NULL) 387 return FALSE; 388 TlsSetValue( g_TlsIndex, (LPVOID)pContext ); 389 break; 390 391 case DLL_THREAD_DETACH: 392 if( g_TlsIndex != TLS_OUT_OF_INDEXES ) 393 { 394 pContext = (CvContext*)TlsGetValue( g_TlsIndex ); 395 if( pContext != NULL ) 396 icvDestroyContext( pContext ); 397 } 398 break; 399 400 case DLL_PROCESS_DETACH: 401 if( g_TlsIndex != TLS_OUT_OF_INDEXES ) 402 { 403 pContext = (CvContext*)TlsGetValue( g_TlsIndex ); 404 if( pContext != NULL ) 405 icvDestroyContext( pContext ); 406 } 407 TlsFree( g_TlsIndex ); 408 break; 409 default: 410 ; 411 } 412 return TRUE; 413 } 414 #else 415 /* POSIX pthread */ 416 417 /* function - destructor of thread */ 418 void icvPthreadDestructor(void* key_val) 419 { 420 CvContext* context = (CvContext*) key_val; 421 icvDestroyContext( context ); 422 } 423 424 int pthrerr = pthread_key_create( &g_TlsIndex, icvPthreadDestructor ); 425 426 #endif 427 428 /* function, which converts int to int */ 429 CV_IMPL int 430 cvErrorFromIppStatus( int status ) 431 { 432 switch (status) 433 { 434 case CV_BADSIZE_ERR: return CV_StsBadSize; 435 case CV_BADMEMBLOCK_ERR: return CV_StsBadMemBlock; 436 case CV_NULLPTR_ERR: return CV_StsNullPtr; 437 case CV_DIV_BY_ZERO_ERR: return CV_StsDivByZero; 438 case CV_BADSTEP_ERR: return CV_BadStep ; 439 case CV_OUTOFMEM_ERR: return CV_StsNoMem; 440 case CV_BADARG_ERR: return CV_StsBadArg; 441 case CV_NOTDEFINED_ERR: return CV_StsError; 442 case CV_INPLACE_NOT_SUPPORTED_ERR: return CV_StsInplaceNotSupported; 443 case CV_NOTFOUND_ERR: return CV_StsObjectNotFound; 444 case CV_BADCONVERGENCE_ERR: return CV_StsNoConv; 445 case CV_BADDEPTH_ERR: return CV_BadDepth; 446 case CV_UNMATCHED_FORMATS_ERR: return CV_StsUnmatchedFormats; 447 case CV_UNSUPPORTED_COI_ERR: return CV_BadCOI; 448 case CV_UNSUPPORTED_CHANNELS_ERR: return CV_BadNumChannels; 449 case CV_BADFLAG_ERR: return CV_StsBadFlag; 450 case CV_BADRANGE_ERR: return CV_StsBadArg; 451 case CV_BADCOEF_ERR: return CV_StsBadArg; 452 case CV_BADFACTOR_ERR: return CV_StsBadArg; 453 case CV_BADPOINT_ERR: return CV_StsBadPoint; 454 455 default: return CV_StsError; 456 } 457 } 458 /* End of file */ 459 460 461