/* * $Id: spm_mapping.c 6549 2015-09-11 15:37:48Z guillaume $ * John Ashburner */ /* MATLAB dependent high level data access and map manipulation routines */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #ifdef SPM_WIN32 #include #include #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64 #define stat _stati64 #define fstat _fstati64 #define open _open #define close _close #endif #else #include #include #endif #include "spm_mapping.h" #include "spm_datatypes.h" /**************************************************************************/ void free_maps(MAPTYPE *maps, int n) { int j; for(j=0; j 3) { free_maps(maps,i); mexErrMsgTxt("Too many dimensions."); } dims = mxGetDimensions(tmp); for(j=0; j maps[i].len) { free_maps(maps,i+1); mexErrMsgTxt("File too small."); } for(j=0; j maps[i].len) { free_maps(maps,i+1); mexErrMsgTxt("File too small."); } } } } else { if (maps[i].dim[0]*maps[i].dim[1]*maps[i].dim[2]*(dsize/8) > maps[i].len) { free_maps(maps,i+1); mexErrMsgTxt("File too small."); } for(j=0; j 0) { if (mxGetField(ptr,0,"dat") == (mxArray *)0) for (i=0; i< *n; i++) get_map_file(i, ptr, maps); else for (i=0; i< *n; i++) get_map_dat(i, ptr, maps); } return(maps); } /**************************************************************************/ static MAPTYPE *get_maps_3dvol(const mxArray *ptr, int *n) { int num_dims, jj, t, dtype = 0; const mwSize *dims; MAPTYPE *maps; unsigned char *dptr; if (mxIsDouble(ptr)) dtype = SPM_DOUBLE; else if (mxIsSingle(ptr)) dtype = SPM_FLOAT; else if (mxIsInt32 (ptr)) dtype = SPM_SIGNED_INT; else if (mxIsUint32(ptr)) dtype = SPM_UNSIGNED_INT; else if (mxIsInt16 (ptr)) dtype = SPM_SIGNED_SHORT; else if (mxIsUint16(ptr)) dtype = SPM_UNSIGNED_SHORT; else if (mxIsInt8 (ptr)) dtype = SPM_SIGNED_CHAR; else if (mxIsUint8 (ptr)) dtype = SPM_UNSIGNED_CHAR; else mexErrMsgTxt("Unknown volume datatype."); maps = (MAPTYPE *)mxCalloc(1, sizeof(MAPTYPE)); num_dims = mxGetNumberOfDimensions(ptr); if (num_dims > 3) { mexErrMsgTxt("Too many dimensions."); } dims = mxGetDimensions(ptr); for(jj=0; jjdim[jj]=dims[jj]; for(jj=num_dims; jj<3; jj++) maps->dim[jj]=1; for(jj=0; jj<16; jj++) maps->mat[jj] = 0.0; for(jj=0; jj<4; jj++) maps->mat[jj + jj*4] = 1.0; maps->dtype = dtype; maps->data = (void **)mxCalloc(maps->dim[2],sizeof(void *)); maps->scale = (double *)mxCalloc(maps->dim[2],sizeof(double)); maps->offset = (double *)mxCalloc(maps->dim[2],sizeof(double)); t = maps->dim[0]*maps->dim[1]*get_datasize(maps->dtype)/8; dptr = (unsigned char *)mxGetPr(ptr); for(jj=0; jjdim[2]; jj++) { maps->scale[jj] = 1.0; maps->offset[jj] = 0.0; maps->data[jj] = &(dptr[jj*t]); } maps->addr = 0; maps->len = 0; *n = 1; return(maps); } /**************************************************************************/ MAPTYPE *get_maps(const mxArray *ptr, int *n) { if (mxIsStruct(ptr)) return(get_maps_struct(ptr, n)); else if (mxGetNumberOfDimensions(ptr) <= 3 && mxIsNumeric(ptr) && !mxIsComplex(ptr) && !mxIsSparse(ptr)) return(get_maps_3dvol(ptr, n)); else mexErrMsgTxt("What do I do with this?"); return((MAPTYPE *)0); } /**************************************************************************/ void voxdim(MAPTYPE *map, double vdim[3]) { int i, j; double t; for(j=0; j<3; j++) { t=0.0; for(i=0; i<3; i++) t += map->mat[i+j*4]*map->mat[i+j*4]; vdim[j] = sqrt(t); } } /**************************************************************************/ int get_dtype(const mxArray *ptr) { mxArray *tmp; double *pr; if (!mxIsStruct(ptr)) { mexErrMsgTxt("Not a structure."); return(0); } tmp=mxGetField(ptr,0,"dt"); if (tmp == (mxArray *)0) { mexErrMsgTxt("Cant find dt."); } if (mxGetM(tmp)*mxGetN(tmp) != 2) { mexErrMsgTxt("Wrong sized dt."); } pr = mxGetPr(tmp); return((int)fabs(pr[0])); } /**************************************************************************/