/* * $Id: spm_add.c 4452 2011-09-02 10:45:26Z guillaume $ */ /* % add a series of images - a compiled routine % FORMAT s = spm_add(V,Q,flags) % V - Vector of mapped volumes (from spm_map or spm_vol). % Q - Filename for averaged image % flags - Flags can be: % 'f' - writes floating point output image. % 'm' - masks the mean to zero or NaN wherever % a zero occurs in the input images. % s - Scalefactor for output image. %_______________________________________________________________________ % % spm_add computes a sum of a set of image volumes to produce an % integral image that is written to a named file (Q). % % The image is written as signed short (16 bit) unless the `f' flag % is specified. % % A mean can be effected by scaling the output image via it's % scalefactor (see spm_mean for an example). A weighted sum can be % effected by weighting the image scalefactors appropriately. % %_______________________________________________________________________ */ #include #include "mex.h" #include "spm_mapping.h" #define RINT(A) floor((A)+0.5) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { MAPTYPE *maps = NULL, *get_maps(); double *sptr = NULL, *scales = NULL, *image = NULL, scale; short **dptr = NULL; int ni, nj, nk, i, j, k; static double mat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; int mask0flag = 0, floatflag = 0; double NaN = mxGetNaN(); mxArray *wplane_args[3]; int maxval = 0, minval = 0; int dtype; if ((nrhs != 2 && nrhs != 3) || nlhs > 1) mexErrMsgTxt("Incorrect usage."); if (nrhs == 3) { if (!mxIsChar(prhs[2])) mexErrMsgTxt("Incorrect usage."); else { char *buf; int buflen; buflen = mxGetN(prhs[2])*mxGetM(prhs[2])+1; buf = mxCalloc(buflen,sizeof(char)); if (mxGetString(prhs[2],buf,buflen)) { mxFree(buf); mexErrMsgTxt("Cant get flags."); } for (i=0; i 256) dtype>>=8; if (dtype == 2) { maxval = 255; minval = 0; floatflag = 0; } else if (dtype == 4) { maxval = 32767; minval = -32768; floatflag = 0; } else if (dtype == 8) { maxval = 2147483647; minval = -2147483647; floatflag = 0; } else { floatflag = 1; } nj = maps[0].dim[2]; nk = maps[0].dim[0]*maps[0].dim[1]; /* The compiler doesn't like this line - but I think it's OK */ wplane_args[0] = (struct mxArray_tag *)prhs[1]; wplane_args[1] = mxCreateDoubleMatrix(maps[0].dim[0],maps[0].dim[1],mxREAL); wplane_args[2] = mxCreateDoubleMatrix(1,1,mxREAL); sptr = mxGetPr(wplane_args[1]); image = (double *)mxCalloc(nk, sizeof(double)); if (!floatflag) { scales = (double *)mxCalloc(nj, sizeof(double)); dptr = (short **)mxCalloc(nj, sizeof(double)); } for(j=0; jmx) mx=sptr[k]; if (sptr[k] -mn) scales[j] = mx/32767.0; else scales[j] = -mn/32768.0; dptr[j] = (short *)mxCalloc(nk, sizeof(short)); for(k=0; k scale) scale = scales[j]; } scale = scale*32767/maxval; /* should really also use minval */ for(j=0; j