/* * $Id: mat2file.c 7038 2017-03-15 12:43:51Z guillaume $ * John Ashburner */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include "mex.h" #ifdef SPM_WIN32 #include #include #include #if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64 #if defined _MSC_VER #define off_t __int64 #define fseeko _fseeki64 #else #define off_t off64_t #define fseeko fseeko64 #endif #endif #define snprintf _snprintf #endif #define MXDIMS 256 typedef struct dtype { int code; void (*swap)(); mxClassID clss; int bits; int channels; } Dtype; #define copy swap8 void swap8(int n, unsigned char id[], unsigned char od[]) { unsigned char *de; for(de=id+n; idbits/8; len = 0; poff = -999999; ocumprod[0] = nbytes*map.dtype->channels; icumprod[0] = nbytes*1; for(i=0; iswap; else swap = copy; put_bytes(map.ndim-1, map.fp, ptr, idim, (unsigned char *)idat, map.off, 0,swap); swap(len,dptr,wbuf); if (fwrite(wbuf,1,len,map.fp) != len) { /* Problem */ (void)fclose(map.fp); (void)mexErrMsgTxt("Problem writing last piece of data (could be a disk space or quota issue)."); } } const double *getpr(const mxArray *ptr, const char nam[], int len, int *n) { char s[256]; mxArray *arr; arr = mxGetField(ptr,0,nam); if (arr == (mxArray *)0) { (void)sprintf(s,"'%s' field is missing.", nam); mexErrMsgTxt(s); } if (!mxIsNumeric(arr)) { (void)sprintf(s,"'%s' field is non-numeric.", nam); mexErrMsgTxt(s); } if (!mxIsDouble(arr)) { (void)sprintf(s,"'%s' field is not double precision.", nam); mexErrMsgTxt(s); } if (len>=0) { *n = mxGetM(arr)*mxGetN(arr); if (*n != len) { (void)sprintf(s,"'%s' field should have %d elements (has %d).", nam, len, *n); mexErrMsgTxt(s); } } else { *n = mxGetNumberOfElements(arr); if (*n > -len) { (void)sprintf(s,"'%s' field should have a maximum of %d elements (has %d).", nam, -len, *n); mexErrMsgTxt(s); } } return (double *)mxGetData(arr); } void open_file(const mxArray *ptr, FTYPE *map) { int n; int i, dtype; const double *pr; mxArray *arr; if (!mxIsStruct(ptr)) mexErrMsgTxt("Not a structure."); dtype = (int)(getpr(ptr, "dtype", 1, &n)[0]); map->dtype = NULL; for(i=0; idtype = &table[i]; break; } } if (map->dtype == NULL) mexErrMsgTxt("Unrecognised 'dtype' value."); if (map->dtype->bits % 8) mexErrMsgTxt("Can not yet write logical data."); if (map->dtype->channels != 1) mexErrMsgTxt("Can not yet write complex data."); pr = getpr(ptr, "dim", -MXDIMS, &n); map->ndim = n; for(i=0; indim; i++) { map->dim[i] = (int)fabs(pr[i]); } pr = getpr(ptr, "be",1, &n); #ifdef SPM_BIGENDIAN map->swap = (int)pr[0]==0; #else map->swap = (int)pr[0]!=0; #endif pr = getpr(ptr, "offset",1, &n); map->off = (off_t)pr[0]; /* if (map->off < 0) map->off = 0; Unsigned, so not necessary */ arr = mxGetField(ptr,0,"fname"); if (arr == (mxArray *)0) mexErrMsgTxt("Cannot find 'fname' field."); if (mxIsChar(arr)) { char *buf = NULL; if ((buf = mxArrayToString(arr)) == NULL) { mxFree(buf); mexErrMsgTxt("Cannot get 'fname'."); } map->fp = fopen(buf,"rb+"); if (map->fp == (FILE *)0) { map->fp = fopen(buf,"wb"); if (map->fp == (FILE *)0) { char s[512]; (void)snprintf(s,sizeof(s),"Can't open file for writing:\n\t%s\nCheck for write permission or whether the directory exists.", buf); mxFree(buf); mexErrMsgTxt(s); } } mxFree(buf); } else mexErrMsgTxt("Wrong type of 'fname' field."); } void close_file(FTYPE map) { (void)fclose(map.fp); } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { FTYPE map; void *idat; int i; int *ptr[MXDIMS], *odim, ndim, idim[MXDIMS]; int one[1]; const mxArray *curr; one[0] = 1; if (nrhs < 3) mexErrMsgTxt("Not enough input arguments."); if (nlhs > 0) mexErrMsgTxt("Too many output arguments."); /* First input argument: file_array structure */ open_file(prhs[0], &map); ndim = map.ndim; odim = map.dim; if (ndim >= MXDIMS) { close_file(map); mexErrMsgTxt("Too many dimensions."); } /* Second input argument: data */ if (mxGetClassID(prhs[1]) != map.dtype->clss) { close_file(map); mexErrMsgTxt("Incompatible class types."); } idat = mxGetData(prhs[1]); /* Other input arguments: subscript vectors */ for(i=0;i ((i