/** @internal ** @file imintegral.c ** @author Brian Fulkerson ** @brief Create an integral image - MEX definition **/ /* Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson. All rights reserved. This file is part of the VLFeat library and is made available under the terms of the BSD license (see the COPYING file). */ #include #include #include #include #include #include void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { vl_size numDimensions, numChannels ; mwSize const *dimensions ; mxClassID classId ; void * integral ; void const * image ; vl_uindex k ; enum {IN_I=0} ; enum {OUT_J=0} ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin > 1) { vlmxError(vlmxErrTooManyInputArguments, NULL) ; } if (nin < 1) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } if (nout > 1) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } if (! mxIsNumeric(IN(I))) { vlmxError(vlmxErrInvalidArgument, "I is not numeric.") ; } dimensions = mxGetDimensions(IN(I)) ; numDimensions = mxGetNumberOfDimensions(IN(I)) ; if (numDimensions > 3) { vlmxError(vlmxErrInvalidArgument, "I has more than 3 dimensions (%d).", numDimensions) ; } if (numDimensions > 2) { numChannels = dimensions [2] ; } else { numChannels = 1 ; } classId = mxGetClassID(IN(I)) ; if (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS && classId != mxUINT32_CLASS && classId != mxINT32_CLASS) { vlmxError(vlmxErrInvalidArgument, "I is not of a supported storage class.") ; } OUT(J) = mxCreateNumericArray(numDimensions, dimensions, classId, mxREAL) ; image = mxGetData(IN(I)) ; integral = mxGetData(OUT(J)) ; /* ----------------------------------------------------------------- * Do the job * -------------------------------------------------------------- */ #define DO(CLASS, T, SFX) \ case mx ## CLASS ## _CLASS : \ vl_imintegral_ ## SFX (integral, dimensions[0], \ image, dimensions[0], dimensions[1], dimensions[0]) ; \ integral = ((T *) integral) + dimensions[0]*dimensions[1] ; \ image = ((T const *) image) + dimensions[0]*dimensions[1] ; \ break for (k = 0 ; k < numChannels ; ++k) { switch (classId) { DO(SINGLE, float, f) ; DO(DOUBLE, double, d) ; DO(UINT32, vl_uint32, ui32) ; DO(INT32, vl_int32, i32) ; default: abort() ; } } }