Home | History | Annotate | Download | only in src
      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