00001
00006
00007
00008
00009
00010
00011
00012
00013 #include"mex.h"
00014 #include<vl/generic.h>
00015 #include<ctype.h>
00016 #include<stdio.h>
00017 #include<stdarg.h>
00018
00019 #ifdef VL_COMPILER_MSC
00020 #define snprintf _snprintf
00021 #define vsnprintf _vsnprintf
00022 #endif
00023
00024 #if !defined(MX_API_VER) | (MX_API_VER < 0x07030000)
00025 typedef int mwSize ;
00026 typedef int mwIndex ;
00027 #endif
00028
00050 #define VL_USE_MATLAB_ENV \
00051 vl_set_alloc_func (mxMalloc, mxRealloc, mxCalloc, mxFree) ; \
00052 vl_set_printf_func (mexPrintf) ;
00053
00069 static mxArray *
00070 uCreateNumericArray (mwSize ndim, const mwSize * dims,
00071 mxClassID classid, void * data)
00072 {
00073 mxArray *A ;
00074
00075 if (data) {
00076 mwSize dims_ [2] = {0, 0} ;
00077 A = mxCreateNumericArray (2, dims_, classid, mxREAL) ;
00078 mxSetData (A, data) ;
00079 mxSetDimensions (A, dims, ndim) ;
00080 } else {
00081 A = mxCreateNumericArray (ndim, dims, classid, mxREAL) ;
00082 }
00083
00084 return A ;
00085 }
00086
00102 static mxArray *
00103 uCreateNumericMatrix (int M, int N, mxClassID classid, void * data)
00104 {
00105 mxArray *A ;
00106
00107 if (data) {
00108 A = mxCreateNumericMatrix (0, 0, classid, mxREAL) ;
00109 mxSetData (A, data) ;
00110 mxSetM(A, M) ;
00111 mxSetN(A, N) ;
00112 } else {
00113 A = mxCreateNumericMatrix (M, N, classid, mxREAL) ;
00114 }
00115
00116 return A ;
00117 }
00118
00127 static mxArray *
00128 uCreateScalar (double x)
00129 {
00130 mxArray *A = mxCreateDoubleMatrix(1,1,mxREAL) ;
00131 *mxGetPr(A) = x ;
00132 return A ;
00133 }
00134
00147 static int
00148 uIsScalar(const mxArray* A)
00149 {
00150 return
00151 mxIsNumeric (A) && mxGetNumberOfElements(A) == 1 ;
00152 }
00153
00170 static vl_bool
00171 uIsPlainArray (const mxArray* A)
00172 {
00173 return
00174 mxGetClassID(A) == mxDOUBLE_CLASS &&
00175 ! mxIsComplex(A) &&
00176 ! mxIsSparse(A) ;
00177 }
00178
00179 static vl_bool
00180 uIsPlainMatrix (const mxArray* A, int M, int N)
00181 {
00182 return
00183 uIsPlainArray(A) &&
00184 mxGetNumberOfDimensions(A) == 2 &&
00185 (M < 0 || mxGetM(A) == M) &&
00186 (N < 0 || mxGetN(A) == N) ;
00187 }
00188
00189 static vl_bool
00190 uIsPlainVector (const mxArray* A, int M)
00191 {
00192 return
00193 uIsPlainArray(A) &&
00194 mxGetNumberOfDimensions(A) == 2 &&
00195 (mxGetM(A) == 1 || mxGetN(A) == 1) &&
00196 (M < 0 || (mxGetM(A) == M || mxGetN(A) == M)) ;
00197 }
00198
00199 static vl_bool
00200 uIsPlainScalar (const mxArray* A)
00201 {
00202 return
00203 uIsPlainArray(A) &&
00204 mxGetNumberOfElements(A) == 1 ;
00205 }
00206
00207
00224 static int
00225 uIsMatrix (const mxArray* A, int M, int N)
00226 {
00227 return
00228 mxIsNumeric(A) &&
00229 mxGetNumberOfDimensions(A) == 2 &&
00230 (M < 0 || mxGetM(A) == M) &&
00231 (N < 0 || mxGetN(A) == N) ;
00232 }
00233
00248 static int
00249 uIsVector(const mxArray* A, int N)
00250 {
00251 return
00252 uIsMatrix(A, 1, N) || uIsMatrix(A, N, 1) ;
00253 }
00254
00267 static int
00268 uIsReal (const mxArray* A)
00269 {
00270 return
00271 mxIsDouble(A) &&
00272 ! mxIsComplex(A) ;
00273 }
00274
00287 static int
00288 uIsRealScalar(const mxArray* A)
00289 {
00290 return
00291 uIsReal (A) && mxGetNumberOfElements(A) == 1 ;
00292 }
00293
00310 static int
00311 uIsRealMatrix(const mxArray* A, int M, int N)
00312 {
00313 return
00314 mxIsDouble(A) &&
00315 !mxIsComplex(A) &&
00316 mxGetNumberOfDimensions(A) == 2 &&
00317 (M < 0 || mxGetM(A) == M) &&
00318 (N < 0 || mxGetN(A) == N) ;
00319 }
00320
00335 static int
00336 uIsRealVector(const mxArray* A, int N)
00337 {
00338 return
00339 uIsRealMatrix(A, 1, N) || uIsRealMatrix(A, N, 1) ;
00340 }
00341
00358 static int
00359 uIsRealArray(const mxArray* A, int D, int* dims)
00360 {
00361 if(!mxIsDouble(A) || mxIsComplex(A))
00362 return 0 ;
00363
00364 if(D >= 0) {
00365 int d ;
00366 mwSize const * actual_dims = mxGetDimensions(A) ;
00367
00368 if(mxGetNumberOfDimensions(A) != D)
00369 return 0 ;
00370
00371 return 1 ;
00372
00373 if(dims != NULL) {
00374 for(d = 0 ; d < D ; ++d) {
00375 if(dims[d] >= 0 && dims[d] != actual_dims[d])
00376 return 0 ;
00377 }
00378 }
00379 }
00380 return 1 ;
00381 }
00382
00398 static int
00399 uIsString(const mxArray* A, int L)
00400 {
00401 int M = mxGetM(A) ;
00402 int N = mxGetN(A) ;
00403
00404 return
00405 mxIsChar(A) &&
00406 mxGetNumberOfDimensions(A) == 2 &&
00407 M == 1 &&
00408 (L < 0 || N == L) ;
00409 }
00410
00418 void
00419 uErrMsgTxt(char const * format, ...)
00420 {
00421 enum { buffLen = 1024 } ;
00422 char buffer [buffLen] ;
00423 va_list args;
00424 va_start (args, format) ;
00425 #ifdef VL_COMPILER_LCC
00426 vsprintf(buffer, format, args) ;
00427 #else
00428 vsnprintf (buffer, buffLen, format, args) ;
00429 #endif
00430 va_end (args) ;
00431 mexErrMsgTxt (buffer) ;
00432 }
00433
00434
00439 struct _uMexOption
00440 {
00441 const char *name ;
00442 int has_arg ;
00443 int val ;
00444 } ;
00445
00449 typedef struct _uMexOption uMexOption ;
00450
00461 static int
00462 uStrICmp(const char *s1, const char *s2)
00463 {
00464 while (tolower((unsigned char)*s1) ==
00465 tolower((unsigned char)*s2))
00466 {
00467 if (*s1 == 0)
00468 return 0;
00469 s1++;
00470 s2++;
00471 }
00472 return
00473 (int)tolower((unsigned char)*s1) -
00474 (int)tolower((unsigned char)*s2) ;
00475 }
00476
00501 static int uNextOption(mxArray const *args[], int nargs,
00502 uMexOption const *options,
00503 int *next,
00504 mxArray const **optarg)
00505 {
00506 char err_msg [1024] ;
00507 char name [1024] ;
00508 int opt = -1, i, len ;
00509
00510 if (*next >= nargs) {
00511 return opt ;
00512 }
00513
00514
00515 if (! uIsString (args [*next], -1)) {
00516 snprintf(err_msg, sizeof(err_msg),
00517 "The option name is not a string (argument number %d).",
00518 *next + 1) ;
00519 mexErrMsgTxt(err_msg) ;
00520 }
00521
00522
00523 len = mxGetNumberOfElements (args [*next]) ;
00524
00525 if (mxGetString (args [*next], name, sizeof(name))) {
00526 snprintf(err_msg, sizeof(err_msg),
00527 "The option name is too long (argument number %d).",
00528 *next + 1) ;
00529 mexErrMsgTxt(err_msg) ;
00530 }
00531
00532
00533 ++ (*next) ;
00534
00535
00536 for (i = 0 ; options[i].name != 0 ; ++i) {
00537 if (uStrICmp(name, options[i].name) == 0) {
00538 opt = options[i].val ;
00539 break ;
00540 }
00541 }
00542
00543
00544 if (opt < 0) {
00545 snprintf(err_msg, sizeof(err_msg),
00546 "Unknown option '%s'.", name) ;
00547 mexErrMsgTxt(err_msg) ;
00548 }
00549
00550
00551 if (! options [i].has_arg) {
00552 if (optarg) *optarg = 0 ;
00553 return opt ;
00554 }
00555
00556
00557 if (*next >= nargs) {
00558 snprintf(err_msg, sizeof(err_msg),
00559 "Option '%s' requires an argument.", options[i].name) ;
00560 mexErrMsgTxt(err_msg) ;
00561 }
00562
00563 if (optarg) *optarg = args [*next] ;
00564 ++ (*next) ;
00565 return opt ;
00566 }