示例#1
0
void *GetCachedValue(NclFileVarNode *varnode,
                     long start, long finish, long stride, void *storage)
{
    long i,j;
    int tsize = varnode->the_nc_type < 1 ? 1 : nctypelen(varnode->the_nc_type);

    for (j = 0, i = start; i <= finish; i += stride,j++)
    {
        memcpy(((char*)storage) + j * tsize,((char *)varnode->value) + i * tsize,tsize);
    }
    return storage;
}
示例#2
0
/*
 * Return number of bytes per netCDF data type.
 */
static int
c_nctlen (
    nc_type datatype,	/* netCDF datatype */
    int* rcode		/* returned error code */
)
{
    int itype;

    *rcode = ((itype = (int) nctypelen (datatype)) == -1)
		?  ncerr
		: 0;

    return itype;
}
示例#3
0
文件: v2i.c 项目: stcorp/harp
/*
 * Computes record size (in bytes) of the record variable with a specified
 * variable id.  Returns size as 0 if not a record variable.
 */
static int
ncrecsize(int ncid, int varid, size_t *recsizep)
{
    int status;
    int recdimid;
    nc_type type;
    int ndims;
    int dimids[MAX_NC_DIMS];
    int id;
    size_t size;

    *recsizep = 0;
    status = nc_inq_unlimdim(ncid, &recdimid); 
    if(status != NC_NOERR)
	return status;
    status = nc_inq_vartype(ncid, varid, &type); 
    if(status != NC_NOERR)
	return status;
    status = nc_inq_varndims(ncid, varid, &ndims); 
    if(status != NC_NOERR)
	return status;
    status = nc_inq_vardimid(ncid, varid, dimids); 
    if(status != NC_NOERR)
	return status;
    if (ndims == 0 || dimids[0] != recdimid) {
	return NC_NOERR;
    }
    size = nctypelen(type);
    for (id = 1; id < ndims; id++) {
	size_t len;
	status = nc_inq_dimlen(ncid, dimids[id], &len);
	if(status != NC_NOERR)
		return status;
	size *= len;
    }
    *recsizep = size;
    return NC_NOERR;
}
示例#4
0
/*
 * Test nctypelen
 *    try with bad datatype, check error
 *    check returned values for each proper datatype
 */
int
test_nctypelen()
{
    int nerrs = 0;
    static char pname[] = "test_nctypelen";

    (void) fprintf(stderr, "*** Testing %s ...\t", &pname[5]);

    if (nctypelen(NC_BYTE) != sizeof(char)) {
	error("%s: nctypelen failed for NC_BYTE", pname);
	nerrs++;
    }
    if (nctypelen(NC_CHAR) != sizeof(char)) {
	error("%s: nctypelen failed for NC_CHAR", pname);
	nerrs++;
    }
    if (nctypelen(NC_SHORT) != sizeof(short)) {
	error("%s: nctypelen failed for NC_SHORT", pname);
	nerrs++;
    }
    if (nctypelen(NC_LONG) != sizeof(nclong)) {
	error("%s: nctypelen failed for NC_LONG", pname);
	nerrs++;
    }
    if (nctypelen(NC_FLOAT) != sizeof(float)) {
	error("%s: nctypelen failed for NC_FLOAT", pname);
	nerrs++;
    }
    if (nctypelen(NC_DOUBLE) != sizeof(double)) {
	error("%s: nctypelen failed for NC_DOUBLE", pname);
	nerrs++;
    }
    if (nerrs > 0)
      (void) fprintf(stderr,"FAILED! ***\n");
    else
      (void) fprintf(stderr,"ok ***\n");

    return nerrs;
}
示例#5
0
/* get some arb_path data, returns NULL on fail                */
int get_some_arb_path_data(double *data_buf, nc_type dtype, int is_signed,
                           int n_pts, int vector_size)
{
   int   nread;
   int   elem_size;
   int   n_elem;
   char    *ptr;
   int      c;

   /* buffer for data */
   void    *tmp;

   elem_size = nctypelen(dtype);
   n_elem = n_pts * vector_size;

   /* allocate space for data buffer */
   tmp = (void *)malloc((size_t)(elem_size * n_elem));

   /* get the data */
   nread = fread(tmp, (size_t)elem_size, (size_t)n_elem, data_fp);
   if(nread != n_elem){
      fprintf(stderr, "Premature end of data file: Number read %d != %d\n\n", nread,
              n_elem);
      exit(EXIT_FAILURE);
      }

   /* convert data to real */
   ptr = tmp;
   for(c = 0; c < n_elem; c++){
      switch (dtype){
      case NC_BYTE:
         if(is_signed)
            data_buf[c] = (double)*((signed char *)ptr);
         else
            data_buf[c] = (double)*((unsigned char *)ptr);
         break;
      case NC_SHORT:
         if(is_signed)
            data_buf[c] = (double)*((signed short *)ptr);
         else
            data_buf[c] = (double)*((unsigned short *)ptr);
         break;
      case NC_INT:
         if(is_signed)
            data_buf[c] = (double)*((signed int *)ptr);
         else
            data_buf[c] = (double)*((unsigned int *)ptr);
         break;
      case NC_FLOAT:
         data_buf[c] = (double)*((float *)ptr);
         break;
      case NC_DOUBLE:
         data_buf[c] = (double)*((double *)ptr);
         break;
      
      default:
         fprintf(stderr, "Erk: unknown data type (%d), this is bad\n\n", dtype);
         }

      ptr += elem_size;
      }

   free(tmp);

   return 1;
   }
示例#6
0
/** \internal
\ingroup variables
 */
int
NCDEFAULT_get_varm(int ncid, int varid, const size_t *start,
	    const size_t *edges, const ptrdiff_t *stride,
	    const ptrdiff_t *imapp, void *value0, nc_type memtype)
{
   int status = NC_NOERR;
   nc_type vartype = NC_NAT;
   int varndims,maxidim;
   NC* ncp;
   int memtypelen;
   char* value = (char*)value0;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

/*
  if(NC_indef(ncp)) return NC_EINDEFINE;
*/

   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;
   /* Check that this is an atomic type */
   if(vartype > NC_MAX_ATOMIC_TYPE)
	return NC_EMAPTYPE;

   status = nc_inq_varndims(ncid, varid, &varndims);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) {
      memtype = vartype;
   }

   if(memtype == NC_CHAR && vartype != NC_CHAR)
      return NC_ECHAR;
   else if(memtype != NC_CHAR && vartype == NC_CHAR)
      return NC_ECHAR;

   memtypelen = nctypelen(memtype);

   maxidim = (int) varndims - 1;

   if (maxidim < 0)
   {
      /*
       * The variable is a scalar; consequently,
       * there s only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_get_vara(ncid, varid, start, edge1, value, memtype);
   }

   /*
    * else
    * The variable is an array.
    */
   {
      int idim;
      size_t *mystart = NULL;
      size_t *myedges;
      size_t *iocount;    /* count vector */
      size_t *stop;   /* stop indexes */
      size_t *length; /* edge lengths in bytes */
      ptrdiff_t *mystride;
      ptrdiff_t *mymap;
      size_t varshape[NC_MAX_VAR_DIMS];
      int isrecvar;
      size_t numrecs;

      /* Compute some dimension related values */
      isrecvar = NC_is_recvar(ncid,varid,&numrecs);
      NC_getshape(ncid,varid,varndims,varshape);

      /*
       * Verify stride argument; also see if stride is all ones
       */
      if(stride != NULL) {
	 int stride1 = 1;
	 for (idim = 0; idim <= maxidim; ++idim)
	 {
            if (stride[idim] == 0
		/* cast needed for braindead systems with signed size_t */
                || ((unsigned long) stride[idim] >= X_INT_MAX))
            {
	       return NC_ESTRIDE;
            }
	    if(stride[idim] != 1) stride1 = 0;
	 }
         /* If stride1 is true, and there is no imap
            then call get_vara directly.
         */
         if(stride1 && imapp == NULL) {
	     return NC_get_vara(ncid, varid, start, edges, value, memtype);
	 }
      }

      /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
      /* Allocate space for mystart,mystride,mymap etc.all at once */
      mystart = (size_t *)calloc((size_t)(varndims * 7), sizeof(ptrdiff_t));
      if(mystart == NULL) return NC_ENOMEM;
      myedges = mystart + varndims;
      iocount = myedges + varndims;
      stop = iocount + varndims;
      length = stop + varndims;
      mystride = (ptrdiff_t *)(length + varndims);
      mymap = mystride + varndims;

      /*
       * Initialize I/O parameters.
       */
      for (idim = maxidim; idim >= 0; --idim)
      {
	 mystart[idim] = start != NULL
	    ? start[idim]
	    : 0;

	 if (edges != NULL && edges[idim] == 0)
	 {
	    status = NC_NOERR;    /* read/write no data */
	    goto done;
	 }

#ifdef COMPLEX
	 myedges[idim] = edges != NULL
	    ? edges[idim]
	    : idim == 0 && isrecvar
	    ? numrecs - mystart[idim]
	    : varshape[idim] - mystart[idim];
#else
	 if(edges != NULL)
	    myedges[idim] = edges[idim];
	 else if (idim == 0 && isrecvar)
	    myedges[idim] = numrecs - mystart[idim];
	 else
	    myedges[idim] = varshape[idim] - mystart[idim];
#endif

	 mystride[idim] = stride != NULL
	    ? stride[idim]
	    : 1;

	 /* Remember: in netCDF-2 imapp is byte oriented, not index oriented
	  *           Starting from netCDF-3, imapp is index oriented */
#ifdef COMPLEX
	 mymap[idim] = (imapp != NULL
			? imapp[idim]
			: (idim == maxidim ? 1
			   : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]));
#else
	 if(imapp != NULL)
	    mymap[idim] = imapp[idim];
	 else if (idim == maxidim)
	    mymap[idim] = 1;
	 else
	    mymap[idim] =
	       mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
#endif
	 iocount[idim] = 1;
	 length[idim] = ((size_t)mymap[idim]) * myedges[idim];
	 stop[idim] = (mystart[idim] + myedges[idim] * (size_t)mystride[idim]);
      }

      /*
       * Check start, edges
       */
      for (idim = maxidim; idim >= 0; --idim)
      {
	 size_t dimlen =
	    idim == 0 && isrecvar
	    ? numrecs
	    : varshape[idim];
	 if (mystart[idim] >= dimlen)
	 {
	    status = NC_EINVALCOORDS;
	    goto done;
	 }

	 if (mystart[idim] + myedges[idim] > dimlen)
	 {
	    status = NC_EEDGE;
	    goto done;
	 }

      }


      /* Lower body */
      /*
       * As an optimization, adjust I/O parameters when the fastest
       * dimension has unity stride both externally and internally.
       * In this case, the user could have called a simpler routine
       * (i.e. ncvar$1()
       */
      if (mystride[maxidim] == 1
	  && mymap[maxidim] == 1)
      {
	 iocount[maxidim] = myedges[maxidim];
	 mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
	 mymap[maxidim] = (ptrdiff_t) length[maxidim];
      }

      /*
       * Perform I/O.  Exit when done.
       */
      for (;;)
      {
	 /* TODO: */
	 int lstatus = NC_get_vara(ncid, varid, mystart, iocount,
				   value, memtype);
	 if (lstatus != NC_NOERR) {
	    if(status == NC_NOERR || lstatus != NC_ERANGE)
	       status = lstatus;
	 }
	 /*
	  * The following code permutes through the variable s
	  * external start-index space and it s internal address
	  * space.  At the UPC, this algorithm is commonly
	  * called "odometer code".
	  */
	 idim = maxidim;
        carry:
	 value += (((int)mymap[idim]) * memtypelen);
	 mystart[idim] += (size_t)mystride[idim];
	 if (mystart[idim] == stop[idim])
	 {
	    size_t l = (length[idim] * (size_t)memtypelen);
	    value -= l;
	    mystart[idim] = start[idim];
	    if (--idim < 0)
	       break; /* normal return */
	    goto carry;
	 }
      } /* I/O loop */
     done:
      free(mystart);
   } /* variable is array */
   return status;
}
示例#7
0
/** \internal
\ingroup variables
 Most dispatch tables will use the default procedures
*/
int
NCDEFAULT_get_vars(int ncid, int varid, const size_t * start,
	    const size_t * edges, const ptrdiff_t * stride,
	    void *value0, nc_type memtype)
{
#ifdef VARS_USES_VARM
   NC* ncp;
   int stat = NC_check_id(ncid, &ncp);

   if(stat != NC_NOERR) return stat;
   return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,NULL,value0,memtype);
#else
  /* Rebuilt get_vars code to simplify and avoid use of get_varm */

   int status = NC_NOERR;
   int i,simplestride,isrecvar;
   int rank;
   struct GETodometer odom;
   nc_type vartype = NC_NAT;
   NC* ncp;
   int memtypelen;
   size_t vartypelen;
   char* value = (char*)value0;
   size_t numrecs;
   size_t varshape[NC_MAX_VAR_DIMS];
   size_t mystart[NC_MAX_VAR_DIMS];
   size_t myedges[NC_MAX_VAR_DIMS];
   ptrdiff_t mystride[NC_MAX_VAR_DIMS];
   char *memptr = NULL;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) memtype = vartype;

   /* compute the variable type size */
   status = nc_inq_type(ncid,vartype,NULL,&vartypelen);
   if(status != NC_NOERR) return status;

   if(memtype > NC_MAX_ATOMIC_TYPE)
	memtypelen = (int)vartypelen;
    else
	memtypelen = nctypelen(memtype);

   /* Check gross internal/external type compatibility */
   if(vartype != memtype) {
      /* If !atomic, the two types must be the same */
      if(vartype > NC_MAX_ATOMIC_TYPE
         || memtype > NC_MAX_ATOMIC_TYPE)
	 return NC_EBADTYPE;
      /* ok, the types differ but both are atomic */
      if(memtype == NC_CHAR || vartype == NC_CHAR)
	 return NC_ECHAR;
   }

   /* Get the variable rank */
   status = nc_inq_varndims(ncid, varid, &rank);
   if(status != NC_NOERR) return status;

   /* Get variable dimension sizes */
   isrecvar = NC_is_recvar(ncid,varid,&numrecs);
   NC_getshape(ncid,varid,rank,varshape);

   /* Optimize out using various checks */
   if (rank == 0) {
      /*
       * The variable is a scalar; consequently,
       * there s only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_get_vara(ncid, varid, start, edge1, value, memtype);
   }

   /* Do various checks and fixups on start/edges/stride */
   simplestride = 1; /* assume so */
   for(i=0;i<rank;i++) {
	size_t dimlen;
	mystart[i] = (start == NULL ? 0 : start[i]);
	if(edges == NULL) {
	   if(i == 0 && isrecvar)
  	      myedges[i] = numrecs - start[i];
	   else
	      myedges[i] = varshape[i] - mystart[i];
	} else
	    myedges[i] = edges[i];
	if(myedges[i] == 0)
	    return NC_NOERR; /* cannot read anything */
	mystride[i] = (stride == NULL ? 1 : stride[i]);
	if(mystride[i] <= 0
	   /* cast needed for braindead systems with signed size_t */
           || ((unsigned long) mystride[i] >= X_INT_MAX))
           return NC_ESTRIDE;
  	if(mystride[i] != 1) simplestride = 0;
        /* illegal value checks */
	dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
        /* mystart is unsigned, never < 0 */
	if(mystart[i] >= dimlen)
	  return NC_EINVALCOORDS;
        /* myedges is unsigned, never < 0 */
	if(mystart[i] + myedges[i] > dimlen)
	  return NC_EEDGE;
   }
   if(simplestride) {
      return NC_get_vara(ncid, varid, mystart, myedges, value, memtype);
   }

   /* memptr indicates where to store the next value */
   memptr = value;

   odom_init(&odom,rank,mystart,myedges,mystride);

   /* walk the odometer to extract values */
   while(odom_more(&odom)) {
      int localstatus = NC_NOERR;
      /* Read a single value */
      localstatus = NC_get_vara(ncid,varid,odom.index,nc_sizevector1,memptr,memtype);
      /* So it turns out that when get_varm is used, all errors are
         delayed and ERANGE will be overwritten by more serious errors.
      */
      if(localstatus != NC_NOERR) {
	    if(status == NC_NOERR || localstatus != NC_ERANGE)
	       status = localstatus;
      }
      memptr += memtypelen;
      odom_next(&odom);
   }
   return status;
#endif
}
示例#8
0
/* Copy all the data values in an input netCDF file */
int copy_nc_data(struct fileinfo *ncinfile, int outncfid,
                 unsigned char appendnc, unsigned char verbose)
{
    int v, d, r;  /* Loop variables */
    int dimid;  /* ID of a dimension */
    void *values;  /* Data values to copy */
    long instart[MAX_NC_DIMS], outstart[MAX_NC_DIMS];  /* Copy array sizes */
    long count[MAX_NC_DIMS];                           /*        "         */
    long nrecs;  /* Number of records */
    long recsize;  /* Number of values in a record */
    int varrecdim;  /* Position of a variable's record dimension */

    /* Loop over all the records */
    nrecs=ncinfile->dimsize[ncinfile->recdim];
    for (r=0; r < nrecs; r++)
    {
#if DEBUG==0
        if (verbose) printf("\n  record=%d",r+1);
#endif

        /* Loop over all the variables */
        for (v=0; v < ncinfile->nvars; v++)
        {
#if DEBUG==0
            if (verbose) printf("\n    variable=%s",ncinfile->varname[v]);
#endif

            /* Avoid multiple reads/writes of non-decomposed dimensions */
            if ((dimid=ncdimid(ncinfile->ncfid,ncinfile->varname[v]))!=(-1))
                if (appendnc && ncinfile->dimend[dimid]==(-1)) continue;

            /* Get read/write dimension sizes for the variable */
            recsize=1;
            varrecdim=(-1);
            for (d=0; d < ncinfile->varndims[v]; d++)
            {
                if (ncinfile->vardim[v][d]==ncinfile->recdim)
                {
                    count[d]=1;
                    varrecdim=d;
                }
                else
                {
                    count[d]=ncinfile->dimsize[ncinfile->vardim[v][d]];
                    recsize*=count[d];
                    instart[d]=0;
                    outstart[d]=ncinfile->dimstart[ncinfile->vardim[v][d]]-1;
                }
#if DEBUG==1
                printf("%d:  instart=%ld  ouststart=%ld  count=%ld\n",d,
                       instart[d],outstart[d],count[d]);
#endif
            }

            /* Avoid multiple reads/writes of non-record variables */
            if (varrecdim==(-1) && r > 0) continue;

#if DEBUG==0
            if (verbose) printf("  (read/write)");
#endif

            /* Allocate a buffer for the variable's record */
            if ((values=malloc(nctypelen(ncinfile->datatype[v])*recsize))==NULL)
            {
                fprintf(stderr,"Error: cannot allocate memory for variable \"%s\"'s values!\n",
                        ncinfile->varname[v]);
                return(1);
            }

            /* Copy the record */
            if (varrecdim!=(-1)) instart[varrecdim]=outstart[varrecdim]=r;
            if (ncvarget(ncinfile->ncfid,v,instart,count,values)==(-1))
            {
                fprintf(stderr,"Error: cannot read variable \"%s\"'s values!\n",
                        ncinfile->varname[v]);
                return(1);
            }
            if (ncvarput(outncfid,v,outstart,count,values)==(-1))
            {
                fprintf(stderr,"Error: cannot write variable \"%s\"'s values!\n",
                        ncinfile->varname[v]);
                return(1);
            }

            /* Deallocate the record buffer */
            free(values);
        }
    }
    return(0);
}
示例#9
0
int main(int argc, char *argv[])
{
   char *filename;
   int mincid, imgid, icvid, ndims, dims[MAX_VAR_DIMS];
   nc_type datatype;
   int is_signed;
   long start[MAX_VAR_DIMS], count[MAX_VAR_DIMS], end[MAX_VAR_DIMS];
   long size;
   int idim;
   void *data;
   double temp;

   /* Check arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) {
      (void) fprintf(stderr, "\nUsage: %s [<options>] <mincfile>\n", argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];

   /* Check that a normalization option was specified */
   if (normalize_output == VIO_BOOL_DEFAULT) {
      (void) fprintf(stderr, 
                     "Please specify either -normalize or -nonormalize\n");
      (void) fprintf(stderr, "Usually -normalize is most appropriate\n");
      exit(EXIT_FAILURE);
   }

   /* Open the file */
   mincid = miopen(filename, NC_NOWRITE);

   /* Inquire about the image variable */
   imgid = ncvarid(mincid, MIimage);
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dims, NULL);
   (void)miget_datatype(mincid, imgid, &datatype, &is_signed);

   /* Check if arguments set */

   /* Get output data type */
   if (output_datatype == INT_MAX) output_datatype = datatype;

   /* Get output sign */ 
   if (output_signed == INT_MAX) {
      if (output_datatype == datatype)
         output_signed = is_signed;
      else 
         output_signed = (output_datatype != NC_BYTE);
   }

   /* Get output range */
   if (valid_range[0] == DBL_MAX) {
      if ((output_datatype == datatype) && (output_signed == is_signed)) {
         (void) miget_valid_range(mincid, imgid, valid_range);
      }
      else {
         (void) miget_default_range(output_datatype, output_signed, 
                                    valid_range);
      }
   }
   if (valid_range[0] > valid_range[1]) {
      temp = valid_range[0];
      valid_range[0] = valid_range[1];
      valid_range[1] = temp;
   }

   /* Set up image conversion */
   icvid = miicv_create();
   (void) miicv_setint(icvid, MI_ICV_TYPE, output_datatype);
   (void) miicv_setstr(icvid, MI_ICV_SIGN, (output_signed ? 
                                            MI_SIGNED : MI_UNSIGNED));
   (void) miicv_setdbl(icvid, MI_ICV_VALID_MIN, valid_range[0]);
   (void) miicv_setdbl(icvid, MI_ICV_VALID_MAX, valid_range[1]);
   if ((output_datatype == NC_FLOAT) || (output_datatype == NC_DOUBLE)) {
      (void) miicv_setint(icvid, MI_ICV_DO_NORM, TRUE);
      (void) miicv_setint(icvid, MI_ICV_USER_NORM, TRUE);
   }
   else if (normalize_output) {
      (void) miicv_setint(icvid, MI_ICV_DO_NORM, TRUE);
   }
   (void) miicv_attach(icvid, mincid, imgid);

   /* Set input file start, count and end vectors for reading a slice
      at a time */
   for (idim=0; idim < ndims; idim++) {
      (void) ncdiminq(mincid, dims[idim], NULL, &end[idim]);
   }
   (void) miset_coords(ndims, (long) 0, start);
   (void) miset_coords(ndims, (long) 1, count);
   size = nctypelen(output_datatype);
   for (idim=ndims-2; idim < ndims; idim++) {
      count[idim] = end[idim];
      size *= count[idim];
   }

   /* Allocate space */
   data = malloc(size);

   /* Loop over input slices */

   while (start[0] < end[0]) {

      /* Read in the slice */
      (void) miicv_get(icvid, start, count, data);

      /* Write out the slice */
      if (fwrite(data, sizeof(char), (size_t) size, stdout) != size) {
         (void) fprintf(stderr, "Error writing data.\n");
         exit(EXIT_FAILURE);
      }

      /* Increment start counter */
      idim = ndims-1;
      start[idim] += count[idim];
      while ( (idim>0) && (start[idim] >= end[idim])) {
         start[idim] = 0;
         idim--;
         start[idim] += count[idim];
      }

   }       /* End loop over slices */

   /* Clean up */
   (void) miclose(mincid);
   (void) miicv_free(icvid);
   free(data);

   exit(EXIT_SUCCESS);
}
示例#10
0
文件: copy_data.c 项目: BIC-MNI/minc
/* ----------------------------- MNI Header -----------------------------------
@NAME       : copy_data
@INPUT      : reshape_info - information for reshaping volume
@OUTPUT     : (none)
@RETURNS    : (none)
@DESCRIPTION: Copies data from one input volume to another, reorganizing
              it according to the reshaping info.
@METHOD     :
@GLOBALS    :
@CALLS      :
@CREATED    : October 25, 1994 (Peter Neelin)
@MODIFIED   :
---------------------------------------------------------------------------- */
void copy_data(Reshape_info *reshape_info)
{
   int idim, odim, out_ndims;
   long block_begin[MAX_VAR_DIMS], block_end[MAX_VAR_DIMS];
   long block_count[MAX_VAR_DIMS];
   long block_cur_start[MAX_VAR_DIMS], block_cur_count[MAX_VAR_DIMS];
   long chunk_begin[MAX_VAR_DIMS], chunk_end[MAX_VAR_DIMS];
   long chunk_count[MAX_VAR_DIMS];
   long chunk_cur_start[MAX_VAR_DIMS], chunk_cur_count[MAX_VAR_DIMS];
   long total_size;
   long num_min_values, num_max_values, num_values;
   double fillvalue, *minmax_buffer;
   void *chunk_data;

   /* Get number of dimensions */
   out_ndims = reshape_info->output_ndims;

   /* Set up variables for looping through blocks */
   for (odim=0; odim < out_ndims; odim++) {
      idim = reshape_info->map_out_to_in[odim];
      block_begin[odim] = 0;
      block_end[odim] = ABS(reshape_info->input_count[idim]);
      if (reshape_info->dim_used_in_block[odim])
         block_count[odim] = ABS(reshape_info->input_count[idim]);
      else
         block_count[odim] = 1;
   }

   /* Figure out size of chunks and allocate space */
   total_size = nctypelen(reshape_info->output_datatype);
   for (odim=0; odim < out_ndims; odim++) {
      total_size *= reshape_info->chunk_count[odim];
   }
   chunk_data = malloc(total_size);

   /* Get enough space for image-min and max values for a block */
   get_num_minmax_values(reshape_info, NULL, block_count, 
                         &num_min_values, &num_max_values);
   num_values = ((num_min_values > num_max_values) ?
                 num_min_values : num_max_values);
   if (num_values > 0)
      minmax_buffer = malloc(num_values * sizeof(double));
   else
      minmax_buffer = NULL;

   /* Print log message */
   if (reshape_info->verbose) {
      (void) fprintf(stderr, "Copying chunks:");
      (void) fflush(stderr);
   }

   /* Loop through blocks */

   nd_begin_looping(block_begin, block_cur_start, out_ndims);
   while (!nd_end_of_loop(block_cur_start, block_end, out_ndims)) {

      /* Set up count for current block */
      nd_update_current_count(block_cur_start, block_count, block_end,
                              block_cur_count, out_ndims);

      /* Set up chunk begin, end and count */
      for (odim=0; odim < out_ndims; odim++) {
         chunk_begin[odim] = block_cur_start[odim];
         chunk_end[odim] = chunk_begin[odim] + block_cur_count[odim];
         chunk_count[odim] = reshape_info->chunk_count[odim];
      }

      /* Set up icv for normalization, set output image-max/min and 
         calculate pixel fill value to use for current block */
      handle_normalization(reshape_info, block_cur_start, block_cur_count,
                           minmax_buffer, &fillvalue);

      /* Loop through chunks */

      nd_begin_looping(chunk_begin, chunk_cur_start, out_ndims);
      while (!nd_end_of_loop(chunk_cur_start, chunk_end, out_ndims)) {

         /* Set up count for current chunk */
         nd_update_current_count(chunk_cur_start, chunk_count, chunk_end,
                                 chunk_cur_count, out_ndims);

         /* Print log message for chunk */
         if (reshape_info->verbose) {
            (void) fprintf(stderr, ".");
            (void) fflush(stderr);
         }

         /* Copy the chunk */
         copy_the_chunk(reshape_info, 
                        chunk_cur_start, chunk_cur_count, chunk_data,
                        fillvalue);

         /* Increment chunk loop count */
         nd_increment_loop(chunk_cur_start, chunk_begin, chunk_count,
                           chunk_end, out_ndims);

      }

      /* Increment block loop count */
      nd_increment_loop(block_cur_start, block_begin, block_count,
                        block_end, out_ndims);

   }

   /* Free the chunk space */
   free(chunk_data);

   /* Free minmax buffer */
   if (minmax_buffer != NULL) {
      free(minmax_buffer);
   }

   /* Print ending log message */
   if (reshape_info->verbose) {
      (void) fprintf(stderr, "Done.\n");
      (void) fflush(stderr);
   }


}
示例#11
0
MNCAPI int
minc_load_data(char *path, void *dataptr, int datatype,
               long *ct, long *cz, long *cy, long *cx,
               double *dt, double *dz, double *dy, double *dx,
               void **infoptr)
{
    int fd;                     /* MINC file descriptor */
    nc_type nctype;             /* netCDF type */
    char *signstr;              /* MI_SIGNED or MI_UNSIGNED */
    int length;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i, j;                   /* Generic loop counters */
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    int icv;                    /* MINC image conversion variable */
    long start[MI_S_NDIMS];
    long count[MI_S_NDIMS];
    size_t ucount[MI_S_NDIMS];
    int dir[MI_S_NDIMS];        /* Dimension "directions" */
    int map[MI_S_NDIMS];        /* Dimension mapping */
    int old_ncopts;             /* For storing the old state of ncopts */
    double *p_dtmp;
    long *p_ltmp;
    struct file_info *p_file;
    struct att_info *p_att;
    int r;                      /* Generic return code */
    
    *infoptr = NULL;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }

    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
            var_id = ncvarid(fd, minc_dimnames[i]);
            ncattinq(fd, var_id, MIstep, &nctype, &length);

            switch (i) {
            case MI_S_T:
                p_ltmp = ct;
                p_dtmp = dt;
                break;
            case MI_S_X:
                p_ltmp = cx;
                p_dtmp = dx;
                break;
            case MI_S_Y:
                p_ltmp = cy;
                p_dtmp = dy;
                break;
            case MI_S_Z:
                p_ltmp = cz;
                p_dtmp = dz;
                break;
            default:
                return (MINC_STATUS_ERROR);
            }
                
            if (nctype == NC_DOUBLE && length == 1) {
                ncattget(fd, var_id, MIstep, p_dtmp);
            }
            else {
                *p_dtmp = 0;    /* Unknown/not set */
            }
            *p_ltmp = dim_len[i];
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    var_id = ncvarid(fd, MIimage);

    ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

    if (var_ndims != 3 && var_ndims != 4) {
        return (MINC_STATUS_ERROR);
    }

    /* We want the data to wind up in t, x, y, z order. */

    for (i = 0; i < MI_S_NDIMS; i++) {
        map[i] = -1;
    }

    for (i = 0; i < var_ndims; i++) {
        if (var_dims[i] == dim_id[MI_S_T]) {
            map[MI_S_T] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_X]) {
            map[MI_S_X] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Y]) {
            map[MI_S_Y] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Z]) {
            map[MI_S_Z] = i;
        }
    }

    icv = miicv_create();

    minc_simple_to_nc_type(datatype, &nctype, &signstr);
    miicv_setint(icv, MI_ICV_TYPE, nctype);
    miicv_setstr(icv, MI_ICV_SIGN, signstr);
    miicv_attach(icv, fd, var_id);

    for (i = 0; i < var_ndims; i++) {
        start[i] = 0;
    }

    for (i = 0; i < MI_S_NDIMS; i++) {
        if (map[i] >= 0) {
            count[map[i]] = dim_len[i];
        }
    }

    r = miicv_get(icv, start, count, dataptr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    if (map[MI_S_T] >= 0) {
        if (*dt < 0) {
            dir[MI_S_T] = -1;
            *dt = -*dt;
        }
        else {
            dir[MI_S_T] = 1;
        }
    }

    if (map[MI_S_X] >= 0) {
        if (*dx < 0) {
            dir[MI_S_X] = -1;
            *dx = -*dx;
        }
        else {
            dir[MI_S_X] = 1;
        }
    }

    if (map[MI_S_Y] >= 0) {
        if (*dy < 0) {
            dir[MI_S_Y] = -1;
            *dy = -*dy;
        }
        else {
            dir[MI_S_Y] = 1;
        }
    }

    if (map[MI_S_Z] >= 0) {
        if (*dz < 0) {
            dir[MI_S_Z] = -1;
            *dz = -*dz;
        }
        else {
            dir[MI_S_Z] = 1;
        }
    }

    if (var_ndims == 3) {
        for (i = 1; i < MI_S_NDIMS; i++) {
            map[i-1] = map[i];
            dir[i-1] = dir[i];
        }
    }

    j = 0;
    for (i = 0; i < MI_S_NDIMS; i++) {
        if (dim_len[i] > 0) {
            ucount[j++] = dim_len[i];
        }
    }

    restructure_array(var_ndims, dataptr, ucount, nctypelen(nctype),
                      map, dir);

    miicv_detach(icv);
    miicv_free(icv);

    old_ncopts =get_ncopts();
    set_ncopts(0);

    /* Generate the complete infoptr array.
     * This is essentially an in-memory copy of the variables and attributes
     * in the file.
     */

    p_file = (struct file_info *) malloc(sizeof (struct file_info));

    ncinquire(fd, &p_file->file_ndims, &p_file->file_nvars,
              &p_file->file_natts, NULL);

    p_file->file_atts = (struct att_info *) malloc(sizeof (struct att_info) * 
                                                   p_file->file_natts);

    p_file->file_vars = (struct var_info *) malloc(sizeof (struct var_info) *
                                                   p_file->file_nvars);

    for (i = 0; i < p_file->file_natts; i++) {
        p_att = &p_file->file_atts[i];

        ncattname(fd, NC_GLOBAL, i, p_att->att_name);
        ncattinq(fd, NC_GLOBAL, 
                 p_att->att_name, 
                 &p_att->att_type, 
                 &p_att->att_len);

        p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));

        ncattget(fd, NC_GLOBAL, p_att->att_name, p_att->att_val);
    }

    for (i = 0; i < p_file->file_nvars; i++) {
        struct var_info *p_var = &p_file->file_vars[i];

        ncvarinq(fd, i, 
                 p_var->var_name, 
                 &p_var->var_type, 
                 &p_var->var_ndims, 
                 p_var->var_dims,
                 &p_var->var_natts);

        p_var->var_atts = malloc(p_var->var_natts *
                                 sizeof (struct att_info));

        if (ncdimid(fd, p_var->var_name) >= 0) {
            /* It's a dimension variable, have to treat it specially... */
        }

        for (j = 0; j < p_var->var_natts; j++) {
            p_att = &p_var->var_atts[j];

            ncattname(fd, i, j, p_att->att_name);
            ncattinq(fd, i, 
                     p_att->att_name, 
                     &p_att->att_type, 
                     &p_att->att_len);

            p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));
            ncattget(fd, i, p_att->att_name, p_att->att_val);
        }
    }

    *infoptr = p_file;

    set_ncopts(old_ncopts);

    miclose(fd);

    return (MINC_STATUS_OK);
}
示例#12
0
MNCAPI int
minc_file_size(char *path,
               long *ct, long *cz, long *cy, long *cx,
               long *cvoxels, long *cbytes)
{
    int fd;
    nc_type nctype;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i;
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    long voxel_count;
    long byte_count;
    int old_ncopts;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }
    
    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    if (ct != NULL) {
        *ct = dim_len[MI_S_T];
    }
    if (cz != NULL) {
        *cz = dim_len[MI_S_Z];
    }
    if (cy != NULL) {
        *cy = dim_len[MI_S_Y];
    }
    if (cx != NULL) {
        *cx = dim_len[MI_S_X];
    }

    var_id = ncvarid(fd, MIimage);

    if (cvoxels != NULL || cbytes != NULL) {
        ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

        voxel_count = 1;

        for (i = 0; i < var_ndims; i++) {
            long length;
            ncdiminq(fd, var_dims[i], NULL, &length);
            voxel_count *= length;
        }

        byte_count = voxel_count * nctypelen(nctype);

        if (cvoxels != NULL) {
            *cvoxels = voxel_count;
        }
        if (cbytes != NULL) {
            *cbytes = byte_count;
        }
    }
    return (MINC_STATUS_OK);
}
int main(int argc, char *argv[])
{
   char *pname;
   char *filename, *tempfile, *newfile;
   char string[1024];
   char *variable_name, *attribute_name;
   int created_tempfile;
   int done_redef;
   int iatt;
   int mincid, varid;
   int variable_exists, attribute_exists;
   nc_type attribute_type, new_type;
   int attribute_length, new_length;
   void *new_value;
   int total_length, alloc_length, ival;
   char *zeros;
   int old_ncopts;

   /* Parse the command line */
   pname=argv[0];
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) {
      (void) fprintf(stderr, "\nUsage: %s [<options>] <file.mnc>\n", 
                     pname);
      (void) fprintf(stderr,   "       %s [-help]\n\n", pname);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];

   /* Create temp file name. First try looking for minc extension, then
      a compression extension. Chop off the unwanted extension. */
   (void) strncpy(string, filename, sizeof(string)-1);
   tempfile = strstr(string, MINC_EXTENSION);
   if (tempfile != NULL) {
      tempfile += strlen(MINC_EXTENSION);
      if (*tempfile == '\0')
         tempfile = NULL;
   }
   else {
      tempfile = strstr(string, GZIP_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, BZIP_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, BZIP2_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, COMPRESS_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, PACK_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, ZIP_EXTENSION);
   }
   if (tempfile != NULL) {
      *tempfile = '\0';
      tempfile = string;
   }

   /* If tempfile == NULL, then either we have a minc file or we don't know 
      how to edit the file in place. Check that it is a minc file. */
   if (tempfile == NULL) {
      newfile = miexpand_file(filename, tempfile, TRUE, &created_tempfile);
      if (created_tempfile) {
         if (newfile != NULL) {
            (void) remove(newfile);
            free(newfile);
         }
         (void) fprintf(stderr, "Cannot edit file \"%s\" in place.\n",
                        filename);
         exit(EXIT_FAILURE);
      }
   }

   /* Expand the file. */
   newfile = miexpand_file(filename, tempfile, FALSE, &created_tempfile);
   if (newfile == NULL) {
      (void) fprintf(stderr, "Error decompressing file \"%s\"\n",
                     filename);
      exit(EXIT_FAILURE);
   }

   /* If a new file was created, get rid of the old one */
   if (created_tempfile) {
      (void) remove(filename);
   }

   /* Open the file */
   mincid = miopen(newfile, NC_WRITE);

   /* Loop through attribute list, modifying values */
   done_redef = FALSE;
   ncopts = NC_VERBOSE;
   zeros = NULL;
   alloc_length = 0;
   for (iatt=0; iatt < attribute_list_size; iatt++) {

      /* Get variable and attribute name */
      variable_name = attribute_list[iatt].variable;
      attribute_name = attribute_list[iatt].attribute;

      /* Check for attribute existence */
      if (strlen(variable_name) == 0) {
         varid = NC_GLOBAL;
         variable_exists = TRUE;
      }
      else {
         old_ncopts = ncopts; ncopts = 0;
         varid = ncvarid(mincid, variable_name);
         ncopts = old_ncopts;
         variable_exists = (varid != MI_ERROR);
      }
      attribute_type = NC_CHAR;
      attribute_length = 0;
      if (variable_exists) {
         old_ncopts = ncopts; ncopts = 0;
         attribute_exists = 
            (ncattinq(mincid, varid, attribute_name,
                      &attribute_type, &attribute_length) != MI_ERROR);
         ncopts = old_ncopts;
      }
      else
         attribute_exists = FALSE;

      /* Are we inserting or deleting? */
      switch (attribute_list[iatt].action) {
      case Insert_attribute:
      case Append_attribute:
         if (attribute_list[iatt].value != NULL) {
            new_type = NC_CHAR;
            new_length = strlen(attribute_list[iatt].value)+1;
            new_value = (void *) attribute_list[iatt].value;
         }
         else {
            new_type = NC_DOUBLE;
            new_length = attribute_list[iatt].num_doubles;
            new_value = (void *) attribute_list[iatt].double_values;
         }

         /* For append we have to copy the entire attribute, if it 
          * already exists.
          */
         if (attribute_list[iatt].action == Append_attribute &&
             attribute_exists) {
             char *tmp_value;

             /* Verify that the existing type matches the newly
              * requested type.  Don't allow a -dappend on a 
              * string attribute, for example.
              */
             if (new_type != attribute_type) {
                 fprintf(stderr, 
                         "Can't append %s data to %s attribute %s:%s.\n",
                         (new_type == NC_DOUBLE) ? "double" : "string",
                         (attribute_type == NC_DOUBLE) ? "double" : "string",
                         variable_name, attribute_name);
                 exit(EXIT_FAILURE);
             }

             new_type = attribute_type;
             tmp_value = malloc((attribute_length + new_length) * nctypelen(new_type));
             ncattget(mincid, varid, attribute_name, tmp_value);

             /* For string attributes, remove any trailing null
              * character before appending.
              */
             if (new_type == NC_CHAR && tmp_value[attribute_length-1] == 0) {
                 attribute_length--;
             }

             memcpy(tmp_value + attribute_length * nctypelen(new_type),
                    new_value,
                    new_length * nctypelen(new_type));
             new_length += attribute_length;
             new_value = (void *) tmp_value;
         }

         total_length = attribute_length*nctypelen(attribute_type);
         if (!attribute_exists ||
             (total_length < new_length*nctypelen(new_type))) {
            if (! done_redef) {
               done_redef = TRUE;
               (void) ncredef(mincid);
            }
         }
         else if (!done_redef && attribute_exists && (total_length > 0)) {
            if (total_length > alloc_length) {
               if (zeros != NULL) free(zeros);
               zeros = malloc(total_length);
               alloc_length = total_length;
               for (ival=0; ival < alloc_length; ival++)
                  zeros[ival] = '\0';
            }
            (void) ncattput(mincid, varid, attribute_name, NC_CHAR,
                            total_length, zeros);
            (void) ncsync(mincid);
            
         }
         if (!variable_exists) {
            old_ncopts = ncopts; ncopts = 0;
            varid = micreate_group_variable(mincid, variable_name);
            ncopts = old_ncopts;
            if (varid == MI_ERROR) {
               varid = ncvardef(mincid, variable_name, NC_INT,
                                0, NULL);
            }
            variable_exists = (varid != MI_ERROR);
         }
         if (variable_exists) {
            (void) ncattput(mincid, varid, attribute_name,
                            new_type, new_length, new_value);
         }

         break;

      case Delete_attribute:

         if (attribute_exists) {
            if (! done_redef) {
               done_redef = TRUE;
               (void) ncredef(mincid);
            }
            (void) ncattdel(mincid, varid, attribute_name);
         }
              
         break;

      default:
          (void) fprintf(stderr, "Program error: unknown action %d\n",
                         (int) attribute_list[iatt].action);
          exit(EXIT_FAILURE);
      }

   }
   ncopts = NC_VERBOSE | NC_FATAL;

   /* Close the file */
   (void) miclose(mincid);

   /* Free stuff */
   free(newfile);
   if (zeros != NULL) free(zeros);

   exit(EXIT_SUCCESS);
}
示例#14
0
void
mexFunction	(
	INT			nlhs,
	Matrix	*	plhs[],
	INT			nrhs,
	const Matrix	*	prhs[]
	)

{
	char		*	opname;
	OPCODE			opcode;
	
	Matrix		*	mat;
	
	int				status;
	char		*	path;
	int				cmode;
	int				mode;
	int				cdfid;
	int				ndims;
	int				nvars;
	int				natts;
	int				recdim;
	char		*	name;
	long			length;
	int				dimid;
	nc_type			datatype;
	int			*	dim;
	int				varid;
	long		*	coords;
	VOIDP			value;
	long		*	start;
	long		*	count;
	int			*	intcount;
	long		*	stride;
	long		*	imap;
	long			recnum;
	int				nrecvars;
	int			*	recvarids;
	long		*	recsizes;
	VOIDPP			datap;		/*	pointers for record access.	*/
	int				len;
	int				incdf;
	int				invar;
	int				outcdf;
	int				outvar;
	int				attnum;
	char		*	attname;
	char		*	newname;
	int				fillmode;
	
	int				i;
	int				m;
	int				n;
	char		*	p;
	char			buffer[MAX_BUFFER];
	
	DOUBLE		*	pr;
	DOUBLE			addoffset;
	DOUBLE			scalefactor;
	int				autoscale;		/*	do auto-scaling if this flag is non-zero.	*/
	
	/*	Disable the NC_FATAL option from ncopts.	*/
	
	if (ncopts & NC_FATAL)	{
		ncopts -= NC_FATAL;
	}
	
	/*	Display usage if less than one input argument.	*/
	
	if (nrhs < 1)	{
	
		Usage();
		
		return;
	}
	
	/*	Convert the operation name to its opcode.	*/
	
	opname = Mat2Str(prhs[0]);
	for (i = 0; i < strlen(opname); i++)	{
		opname[i] = (char) tolower((int) opname[i]);
	}
	p = opname;
	if (strncmp(p, "nc", 2) == 0)	{	/*	Trim away "nc".	*/
		p += 2;
	}
	
	i = 0;
	opcode = NONE;
	while (ops[i].opcode != NONE)	{
		if (!strcmp(p, ops[i].opname))	{
			opcode = ops[i].opcode;
			if (ops[i].nrhs > nrhs)	{
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few input arguments.\n");
			}
			else if (0 && ops[i].nlhs > nlhs)	{	/*	Disabled.	*/
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few output arguments.\n");
			}
			break;
		}
		else	{
			i++;
		}
	}
	
	if (opcode == NONE)	{
		mexPrintf("MEXCDF: opname = %s\n", opname);
		mexErrMsgTxt("MEXCDF: No such operation.\n");
	}
	
	Free((VOIDPP) & opname);
	
	/*	Extract the cdfid by number.	*/
	
	switch (opcode)	{
	
	case USAGE:
	case CREATE:
	case OPEN:
	case TYPELEN:
	case SETOPTS:
	case ERR:
	case PARAMETER:
	
		break;
	
	default:

		cdfid = Scalar2Int(prhs[1]);
	
		break;
	}
	
	/*	Extract the dimid by number or name.	*/
	
	switch (opcode)	{

	case DIMINQ:
	case DIMRENAME:
	
		if (mxIsNumeric(prhs[2]))	{
			dimid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			dimid = ncdimid(cdfid, name);
			Free((VOIDPP) & name);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the varid by number or name.	*/
	
	switch (opcode)	{

	case VARINQ:
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:
	case VARRENAME:
	case VARCOPY:
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTNAME:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[2]))	{
			varid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			varid = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
			if (varid == -1)	{
				varid = Parameter(prhs[2]);
			}
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the attname by name or number.	*/
	
	switch (opcode)	{
	
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[3]))	{
			attnum = Scalar2Int(prhs[3]);
			attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
			status = ncattname(cdfid, varid, attnum, attname);
		}
		else	{
			attname = Mat2Str(prhs[3]);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the "add_offset" and "scale_factor" attributes.	*/
	
	switch (opcode)	{
	
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:

		addoffset = Add_Offset(cdfid, varid);
		scalefactor = Scale_Factor(cdfid, varid);
		if (scalefactor == 0.0)	{
			scalefactor = 1.0;
		}
		
		break;
	
	default:
	
		break;
	}
	
	/*	Perform the NetCDF operation.	*/
	
	switch (opcode)	{
		
	case USAGE:
	
		Usage();
		
		break;
	
	case CREATE:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			cmode = Parameter(prhs[2]);
		}
		else	{
			cmode = NC_NOCLOBBER;	/*	Default.	*/
		}
		
		cdfid = nccreate(path, cmode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case OPEN:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			mode = Parameter(prhs[2]);
		}
		else	{
			mode = NC_NOWRITE;	/*	Default.	*/
		}
		
		cdfid = ncopen(path, mode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case REDEF:
		
		status = ncredef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ENDEF:
		
		status = ncendef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case CLOSE:
		
		status = ncclose(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case INQUIRE:
	
		status = ncinquire(cdfid, & ndims, & nvars, & natts, & recdim);
		
		if (nlhs > 1)	{
			plhs[0] = Int2Scalar(ndims);
			plhs[1] = Int2Scalar(nvars);
			plhs[2] = Int2Scalar(natts);
			plhs[3] = Int2Scalar(recdim);
			plhs[4] = Int2Scalar(status);
		}
		else	{	/*	Default to 1 x 5 row vector.	*/
			plhs[0] = mxCreateFull(1, 5, REAL);
			pr = mxGetPr(plhs[0]);
			if (status == 0)	{
				pr[0] = (DOUBLE) ndims;
				pr[1] = (DOUBLE) nvars;
				pr[2] = (DOUBLE) natts;
				pr[3] = (DOUBLE) recdim;
			}
			pr[4] = (DOUBLE) status;
		}
		
		break;
		
	case SYNC:
	
		status = ncsync(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ABORT:
	
		status = ncabort(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case DIMDEF:
	
		name = Mat2Str(prhs[2]);
		length = Parameter(prhs[3]);
		
		dimid = ncdimdef(cdfid, name, length);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMID:
	
		name = Mat2Str(prhs[2]);
		
		dimid = ncdimid(cdfid, name);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMINQ:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncdiminq(cdfid, dimid, name, & length);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Long2Scalar(length);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncdimrename(cdfid, dimid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARDEF:
	
		name = Mat2Str(prhs[2]);
		datatype = (nc_type) Parameter(prhs[3]);
		ndims = Scalar2Int(prhs[4]);
		if (ndims == -1)	{
			ndims = Count(prhs[5]);
		}
		dim = Mat2Int(prhs[5]);
		
		varid = ncvardef(cdfid, name, datatype, ndims, dim);
		
		Free((VOIDPP) & name);
		
		plhs[0] = Int2Scalar(varid);
		plhs[1] = Int2Scalar((varid >= 0) ? 0 : varid);
		
		break;
		
	case VARID:
	
		name = Mat2Str(prhs[2]);
		
		varid = ncvarid(cdfid, name);
		
		Free((VOIDPP) & name);
		
		plhs[0] = Int2Scalar(varid);
		plhs[1] = Int2Scalar((varid >= 0) ? 0 : varid);
		
		break;
		
	case VARINQ:
	
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Int2Scalar(datatype);
		plhs[2] = Int2Scalar(ndims);
		plhs[3] = Int2Mat(dim, 1, ndims);
		plhs[4] = Int2Scalar(natts);
		plhs[5] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		break;
		
	case VARPUT1:
		
		coords = Mat2Long(prhs[3]);
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[4]);
		}
		else	{
			mat = prhs[4];
		}
		if (mat == NULL)	{
			mat = prhs[4];
		}
		
		pr = mxGetPr(mat);
		
		autoscale = (nrhs > 5 && Scalar2Int(prhs[5]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		status = Convert(opcode, datatype, 1, buffer, scalefactor, addoffset, pr);
		status = ncvarput1(cdfid, varid, coords, buffer);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & coords);
		
		break;
		
	case VARGET1:
		
		coords = Mat2Long(prhs[3]);
		
		autoscale = (nrhs > 4 && Scalar2Int(prhs[4]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		mat = Int2Scalar(0);
		
		pr = mxGetPr(mat);
		
		status = ncvarget1(cdfid, varid, coords, buffer);
		status = Convert(opcode, datatype, 1, buffer, scalefactor, addoffset, pr);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[0] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & coords);
		
		break;
		
	case VARPUT:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
		
		autoscale = (nrhs > 6 && Scalar2Int(prhs[6]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[5]);
		}
		else	{
			mat = prhs[5];
		}
		if (mat == NULL)	{
			mat = prhs[5];
		}
		
		pr = mxGetPr(mat);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		len = 0;
		if (ndims > 0)	{
			len = 1;
			for (i = 0; i < ndims; i++)	{
				len *= count[i];
			}
		}
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		status = ncvarput(cdfid, varid, start, count, value);
		Free((VOIDPP) & value);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & start);
		Free((VOIDPP) & count);
		
		break;
		
	case VARGET:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
        intcount = Mat2Int(prhs[4]);
		
		autoscale = (nrhs > 5 && Scalar2Int(prhs[5]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		m = 0;
		n = 0;
		if (ndims > 0)	{
			m = count[0];
			n = count[0];
			for (i = 1; i < ndims; i++)	{
				n *= count[i];
				if (count[i] > 1)	{
					m = count[i];
				}
			}
			n /= m;
		}
		len = m * n;
		if (ndims < 2)	{
			m = 1;
			n = len;
		}
		
		for (i = 0; i < ndims; i++)	{
			intcount[i] = count[ndims-i-1];   /*	Reverse order.	*/
		}
		
		if (MEXCDF_4 || ndims < 2)	{
			mat = mxCreateFull(m, n, mxREAL);	/*	mxCreateDoubleMatrix	*/
		}
# if MEXCDF_5
		else	{
			mat = mxCreateNumericArray(ndims, intcount, mxDOUBLE_CLASS, mxREAL);
		}
# endif
		
		pr = mxGetPr(mat);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncvarget(cdfid, varid, start, count, value);
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		Free((VOIDPP) & value);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
			plhs[0] = mat;
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & intcount);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;
		
	case VARPUTG:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		if (nrhs > 7)	{
			if (datatype == NC_CHAR)	{
				mat = SetStr(prhs[7]);
			}
			else	{
				mat = prhs[7];
			}
			if (mat == NULL)	{
				mat = prhs[7];
			}
		}
		else	{
			if (datatype == NC_CHAR)	{
				mat = SetStr(prhs[6]);
			}
			else	{
				mat = prhs[6];
			}
			if (mat == NULL)	{
				mat = prhs[6];
			}
		}
		pr = mxGetPr(mat);
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
		stride = Mat2Long(prhs[5]);
		imap = NULL;
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		len = 0;
		if (ndims > 0)	{
			len = 1;
			for (i = 0; i < ndims; i++)	{
				len *= count[i];
			}
		}
		
		autoscale = (nrhs > 8 && Scalar2Int(prhs[8]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		status = ncvarputg(cdfid, varid, start, count, stride, imap, value);
		Free((VOIDPP) & value);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & stride);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;
		
	case VARGETG:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
        intcount = Mat2Int(prhs[4]);
		stride = Mat2Long(prhs[5]);
		imap = NULL;
		
		autoscale = (nrhs > 7 && Scalar2Int(prhs[7]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		m = 0;
		n = 0;
		if (ndims > 0)	{
			m = count[0];
			n = count[0];
			for (i = 1; i < ndims; i++)	{
				n *= count[i];
				if (count[i] > 1)	{
					m = count[i];
				}
			}
			n /= m;
		}
		len = m * n;
		if (ndims < 2)	{
			m = 1;
			n = len;
		}
		
		for (i = 0; i < ndims; i++)	{
			intcount[i] = count[ndims-i-1];   /*	Reverse order.	*/
		}
		
		if (MEXCDF_4 || ndims < 2)	{
			mat = mxCreateFull(m, n, mxREAL);	/*	mxCreateDoubleMatrix	*/
		}
# if MEXCDF_5
		else	{
			mat = mxCreateNumericArray(ndims, intcount, mxDOUBLE_CLASS, mxREAL);
		}
# endif
		
		pr = mxGetPr(mat);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncvargetg(cdfid, varid, start, count, stride, imap, value);
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		Free((VOIDPP) & value);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[0] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & stride);
		Free((VOIDPP) & intcount);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;

	case VARRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncvarrename(cdfid, varid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARCOPY:
	
		incdf = cdfid;
		
		invar = varid;
		
		outcdf = Scalar2Int(prhs[3]);
	
		outvar = -1;
/*		outvar = ncvarcopy(incdf, invar, outcdf);	*/
		
		plhs[0] = Int2Scalar(outvar);
		plhs[1] = Int2Scalar((outvar >= 0) ? 0 : outvar);
		
		break;
		
	case ATTPUT:
		
		datatype = (nc_type) Parameter(prhs[4]);
		
		datatype = RepairBadDataType(datatype);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[6]);
		}
		else	{
			mat = prhs[6];
		}
		if (mat == NULL)	{
			mat = prhs[6];
		}
		
		len = Scalar2Int(prhs[5]);
		if (len == -1)	{
			len = Count(mat);
		}
		
		pr = mxGetPr(mat);
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, (DOUBLE) 1.0, (DOUBLE) 0.0, pr);
		
		status = ncattput(cdfid, varid, attname, datatype, len, value);
		
		if (value != NULL)	{
			Free((VOIDPP) & value);
		}
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTINQ:
		
		status = ncattinq(cdfid, varid, attname, & datatype, & len);
		
		datatype = RepairBadDataType(datatype);
		
		plhs[0] = Int2Scalar((int) datatype);
		plhs[1] = Int2Scalar(len);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTGET:
		
		status = ncattinq(cdfid, varid, attname, & datatype, & len);
		
		datatype = RepairBadDataType(datatype);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncattget(cdfid, varid, attname, value);
		
		mat = mxCreateDoubleMatrix(1, len, mxREAL);
		
		pr = mxGetPr(mat);
		
		status = Convert(opcode, datatype, len, value, (DOUBLE) 1.0, (DOUBLE) 0.0, pr);
		
		if (value != NULL)	{
			Free((VOIDPP) & value);
		}
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[4] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTCOPY:
	
		incdf = cdfid;
		
		invar = varid;
		
		outcdf = Scalar2Int(prhs[4]);
	
		if (mxIsNumeric(prhs[5]))	{
			outvar = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[5]);
			outvar = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
		}
	
		status = ncattcopy(incdf, invar, attname, outcdf, outvar);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTNAME:
		
		attnum = Scalar2Int(prhs[3]);
		attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncattname(cdfid, varid, attnum, attname);
		
		plhs[0] = Str2Mat(attname);
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTRENAME:
	
		newname = Mat2Str(prhs[4]);
		
		status = ncattrename(cdfid, varid, attname, newname);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		Free((VOIDPP) & newname);
		
		break;
		
	case ATTDEL:
		
		status = ncattdel(cdfid, varid, attname);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case RECPUT:
		
		recnum = Scalar2Long(prhs[2]);
		pr = mxGetPr(prhs[3]);
		
		autoscale = (nrhs > 4 && Scalar2Int(prhs[4]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		datap = (VOIDPP) mxCalloc(MAX_VAR_DIMS, sizeof(VOIDP));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status == -1)	{
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		n = 0;
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			length += recsizes[i];
			n += (recsizes[i] / nctypelen(datatype));
		}
		
		if (Count(prhs[3]) < n)	{
			status = -1;
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		if ((value = (VOIDP) mxCalloc((int) length, sizeof(char))) == NULL)	{
			status = -1;
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		p = value;
		for (i = 0; i < nrecvars; i++)	{
			datap[i] = p;
			p += recsizes[i];
		}
		
		p = (char *) value;
		pr = mxGetPr(prhs[3]);
		
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
		
			length = recsizes[i] / nctypelen(datatype);
			if (autoscale)	{
				addoffset = Add_Offset(cdfid, recvarids[i]);
				scalefactor = Scale_Factor(cdfid, recvarids[i]);
				if (scalefactor == 0.0)	{
					scalefactor = 1.0;
				}
			}
			Convert(opcode, datatype, length, (VOIDP) p,  scalefactor, addoffset, pr);
			pr += length;
			p += recsizes[i];
		}
		
		status = ncrecput(cdfid, recnum, datap);
		
		plhs[0] = Int2Scalar(status);
		
		Free ((VOIDPP) & value);
		Free ((VOIDPP) & datap);
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;
		
	case RECGET:
		
		recnum = Scalar2Long(prhs[2]);
		
		autoscale = (nrhs > 3 && Scalar2Int(prhs[3]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		datap = (VOIDPP) mxCalloc(MAX_VAR_DIMS, sizeof(VOIDP));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status == -1)	{
			Free ((VOIDPP) & recsizes);
			Free ((VOIDPP) & recvarids);
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		if (nrecvars == 0)	{
			Free ((VOIDPP) & recsizes);
			Free ((VOIDPP) & recvarids);
			plhs[0] = mxCreateFull(0, 0, REAL);
			break;
		}
		
		length = 0;
		n = 0;
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			length += recsizes[i];
			n += (recsizes[i] / nctypelen(datatype));
		}
		
		if ((value = (VOIDP) mxCalloc((int) length, sizeof(char))) == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		if (value == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		p = value;
		for (i = 0; i < nrecvars; i++)	{
			datap[i] = p;
			p += recsizes[i];
		}
		
		if ((status = ncrecget(cdfid, recnum, datap)) == -1)	{
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		m = 1;
		
		plhs[0] = mxCreateFull(m, n, REAL);
		
		if (plhs[0] == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		pr = mxGetPr(plhs[0]);
		p = (char *) value;
		
		for (i = 0; i < nrecvars; i++)	{
			status = ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			if (status == -1)	{
				plhs[1] = Int2Scalar(status);
				break;
			}
			length = recsizes[i] / nctypelen(datatype);
			if (autoscale)	{
				addoffset = Add_Offset(cdfid, recvarids[i]);
				scalefactor = Scale_Factor(cdfid, recvarids[i]);
				if (scalefactor == 0.0)	{
					scalefactor = 1.0;
				}
			}
			Convert(opcode, datatype, length, (VOIDP) p,  scalefactor, addoffset, pr);
			pr += length;
			p += recsizes[i];
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free ((VOIDPP) & value);
		Free ((VOIDPP) & datap);
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;

	case RECINQ:
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status != -1)	{
			for (i = 0; i < nrecvars; i++)	{
				ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
				datatype = RepairBadDataType(datatype);
			
				recsizes[i] /= nctypelen(datatype);
			}
			m = 1;
			n = nrecvars;
			plhs[0] = Int2Mat(recvarids, m, n);
			plhs[1] = Long2Mat(recsizes, m, n);
		}
		
		plhs[2] = Int2Scalar(status);
		
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;
		
	case TYPELEN:
	
		datatype = (nc_type) Parameter(prhs[1]);
		
		len = nctypelen(datatype);
		
		plhs[0] = Int2Scalar(len);
		plhs[1] = Int2Scalar((len >= 0) ? 0 : 1);
		
		break;
		
	case SETFILL:
	
		fillmode = Scalar2Int(prhs[1]);
		
		status = ncsetfill(cdfid, fillmode);
		
		plhs[0] = Int2Scalar(status);
		plhs[1] = Int2Scalar(0);
		
		break;

	case SETOPTS:
		
		plhs[0] = Int2Scalar(ncopts);
		plhs[1] = Int2Scalar(0);
		ncopts = Scalar2Int(prhs[1]);
		
		break;
		
	case ERR:
	
		plhs[0] = Int2Scalar(ncerr);
		ncerr = 0;
		plhs[1] = Int2Scalar(0);
		
		break;
		
	case PARAMETER:
	
		if (nrhs > 1)	{
			plhs[0] = Int2Scalar(Parameter(prhs[1]));
			plhs[1] = Int2Scalar(0);
		}
		else	{
			i = 0;
			while (strcmp(parms[i].name, "NONE") != 0)	{
				mexPrintf("%12d %s\n", parms[i].code, parms[i].name);
				i++;
			}
			plhs[0] = Int2Scalar(0);
			plhs[1] = Int2Scalar(-1);
		}
		
		break;
		
	default:
	
		break;
	}
	
	return;
}
示例#15
0
int
cpy_var_val(int in_id,int out_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the variable data from an input netCDF file
   * to an output netCDF file. 
   */

  int *dim_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;
  long *dim_cnt;
  long *dim_sz;
  long *dim_srt;
  long var_sz=1L;

  nc_type var_type_in, var_type_out;

  void *void_ptr;

  /* Get the var_id for the requested variable from both files. */
  var_in_id=ncvarid(in_id,var_nm);

  var_out_id=ncvarid(out_id,var_nm);
 
  /* Get the number of dimensions for the variable. */

  ncvarinq(out_id,var_out_id,(char *)NULL,&var_type_out,&nbr_dim,
                (int *)NULL,(int *)NULL);

  ncvarinq(in_id,var_in_id,(char *)NULL,&var_type_in,&nbr_dim,
                (int *)NULL,(int *)NULL);
 
  /* Allocate space to hold the dimension IDs */
  dim_cnt = malloc(nbr_dim*sizeof(long));

  dim_id=malloc(nbr_dim*sizeof(int));

  dim_sz=malloc(nbr_dim*sizeof(long));

  dim_srt=malloc(nbr_dim*sizeof(long));
 
  /* Get the dimension IDs from the input file */
  ncvarinq(in_id,var_in_id,(char *)NULL,(nc_type *)NULL,
                (int *)NULL,dim_id,(int *)NULL);
 
  /* Get the dimension sizes and names from the input file */
  for(idx=0;idx<nbr_dim;idx++){
  /* NB: For the unlimited dimension, ncdiminq() returns the maximum
     value used so far in writing data for that dimension.
     Thus if you read the dimension sizes from the output file, then
     the ncdiminq() returns dim_sz=0 for the unlimited dimension
     until a variable has been written with that dimension. This is
     the reason for always reading the input file for the dimension
     sizes. */

    ncdiminq(in_id,dim_id[idx],(char *)NULL,dim_cnt+idx);

    /* Initialize the indicial offset and stride arrays */
    dim_srt[idx]=0L;
    var_sz*=dim_cnt[idx];
  } /* end loop over dim */

  /* Allocate enough space to hold the variable */
  void_ptr=malloc(var_sz*nctypelen(var_type_in));

  /* Get the variable */

  /* if variable is float or double, convert if necessary */

  if(nbr_dim==0){  /* variable is a scalar */

    ncvarget1(in_id,var_in_id,0L,void_ptr);

    if ( ( (var_type_in == NC_FLOAT) && (var_type_out == NC_FLOAT) ) ||
         ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_DOUBLE) ) ) {
      /* no conversion necessary */

      ncvarput1(out_id,var_out_id,0L,void_ptr);

    } else if ( (var_type_in == NC_FLOAT) && (var_type_out == NC_DOUBLE) ) {
      /* convert up */

      ncvarput1(out_id,var_out_id,0L,
                ex_conv_array (out_id, WRITE_CONVERT_UP, void_ptr, 1));

    } else if ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_FLOAT) ) {
      /* convert down */

      ncvarput1(out_id,var_out_id,0L,
                ex_conv_array (out_id, WRITE_CONVERT_DOWN, void_ptr, 1));

    } else {  /* variable isn't float or double */

      /* no conversion necessary */

      ncvarput1(out_id,var_out_id,0L,void_ptr);

    }

  } else { /* variable is a vector */

    ncvarget(in_id,var_in_id,dim_srt,dim_cnt,void_ptr);

    if ( ( (var_type_in == NC_FLOAT) && (var_type_out == NC_FLOAT) ) ||
         ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_DOUBLE) ) ) {
      /* no conversion necessary */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,void_ptr);

    } else if ( (var_type_in == NC_FLOAT) && (var_type_out == NC_DOUBLE) ) {
      /* convert up */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,
               ex_conv_array (out_id,WRITE_CONVERT_UP,void_ptr,var_sz));

    } else if ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_FLOAT) ) {
      /* convert down */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,
               ex_conv_array (out_id,WRITE_CONVERT_DOWN,void_ptr,var_sz));

    } else {  /* variable isn't float or double */

      /* no conversion necessary */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,void_ptr);

    }

  } /* end if variable is an array */

  /* Free the space that held the dimension IDs */
  (void)free(dim_cnt);
  (void)free(dim_id);
  (void)free(dim_sz);
  (void)free(dim_srt);

  /* Free the space that held the variable */
  (void)free(void_ptr);

  return(EX_NOERR);

} /* end cpy_var_val() */
示例#16
0
int
cpy_coord_val(int in_id,int out_id,char *var_nm,
              int in_large, int out_large)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the coordinate data from an input netCDF file
   * to an output netCDF file. 
   */

  const char *routine = NULL;
  int i;
  long spatial_dim, num_nodes;
  long start[2], count[2];
  nc_type var_type_in, var_type_out;

  void *void_ptr;

  /* Handle easiest situation first: in_large matches out_large */
  if (in_large == out_large)
    return cpy_var_val(in_id, out_id, var_nm);
  
  /* At this point, know that in_large != out_large, so will need to
     either copy a vector to multiple scalars or vice-versa.  Also
     will a couple dimensions, so get them now.*/
  ex_get_dimension(in_id, DIM_NUM_DIM, "dimension", &spatial_dim, routine);
  ex_get_dimension(in_id, DIM_NUM_NODES, "nodes",   &num_nodes, routine);

  if (in_large == 0 && out_large == 1) {
    /* output file will have coordx, coordy, coordz (if 3d). */
    /* Get the var_id for the requested variable from both files. */
    int var_in_id, var_out_id[3];
    var_in_id = ncvarid(in_id, VAR_COORD);
    var_out_id[0] = ncvarid(out_id,VAR_COORD_X);
    var_out_id[1] = ncvarid(out_id,VAR_COORD_Y);
    var_out_id[2] = ncvarid(out_id,VAR_COORD_Z);

    ncvarinq(in_id,var_in_id,(char *)NULL,&var_type_in,(int*)NULL,
                (int *)NULL,(int *)NULL);
    ncvarinq(out_id,var_out_id[0],(char *)NULL,&var_type_out,(int *)NULL,
                (int *)NULL,(int *)NULL);

    void_ptr=malloc(num_nodes * nctypelen(var_type_in));

    /* Copy each component of the variable... */
    for (i=0; i < spatial_dim; i++) {
      start[0] = i; start[1] = 0;
      count[0] = 1; count[1] = num_nodes;
      ncvarget(in_id, var_in_id, start, count, void_ptr);
      
      if (var_type_in == var_type_out) {
        if (var_type_out == NC_FLOAT) {
          nc_put_var_float(out_id, var_out_id[i], void_ptr);
        } else {
          nc_put_var_double(out_id, var_out_id[i], void_ptr);
        }
      } else if (var_type_in == NC_FLOAT && var_type_out == NC_DOUBLE) {
        nc_put_var_double(out_id, var_out_id[i],
                          ex_conv_array(out_id, WRITE_CONVERT_UP, void_ptr, num_nodes));
      } else if (var_type_in == NC_DOUBLE && var_type_out == NC_FLOAT) {
        nc_put_var_float(out_id, var_out_id[i],
                          ex_conv_array(out_id, WRITE_CONVERT_DOWN, void_ptr, num_nodes));
      }
    }
  }

  if (in_large == 1 && out_large == 0) {
    /* input file will have coordx, coordy, coordz (if 3d); output has
       only "coord" */
    int var_in_id[3], var_out_id;
    var_in_id[0] = ncvarid(in_id,  VAR_COORD_X);
    var_in_id[1] = ncvarid(in_id,  VAR_COORD_Y);
    var_in_id[2] = ncvarid(in_id,  VAR_COORD_Z);
    var_out_id   = ncvarid(out_id, VAR_COORD);
    
    ncvarinq(in_id,var_in_id[0],(char *)NULL,&var_type_in,(int *)NULL,
                (int *)NULL,(int *)NULL);

    ncvarinq(out_id,var_out_id,(char *)NULL,&var_type_out,(int*)NULL,
                (int *)NULL,(int *)NULL);

    void_ptr=malloc(num_nodes * nctypelen(var_type_in));

    /* Copy each component of the variable... */
    for (i=0; i < spatial_dim; i++) {
      if (var_type_in == NC_FLOAT) {
        nc_get_var_float(in_id, var_in_id[i], void_ptr);
      } else {
        nc_get_var_double(in_id, var_in_id[i], void_ptr);
      }

      start[0] = i; start[1] = 0;
      count[0] = 1; count[1] = num_nodes;
      if (var_type_in == var_type_out) {
        ncvarput(out_id, var_out_id, start, count, void_ptr);
      } else if (var_type_in == NC_FLOAT && var_type_out == NC_DOUBLE) {
        ncvarput(out_id, var_out_id, start, count,
                 ex_conv_array(out_id, WRITE_CONVERT_UP, void_ptr, num_nodes));
      } else if (var_type_in == NC_DOUBLE && var_type_out == NC_FLOAT) {
        ncvarput(out_id, var_out_id, start, count,
                 ex_conv_array(out_id, WRITE_CONVERT_DOWN, void_ptr, num_nodes));
      }
    }
  }

  /* Free the space that held the variable */
  (void)free(void_ptr);

  return(EX_NOERR);

} /* end cpy_coord_val() */
示例#17
0
MNCAPI int
minc_save_data(int fd, void *dataptr, int datatype,
               long st, long sz, long sy, long sx,
               long ct, long cz, long cy, long cx)
{
    nc_type nctype;
    char *signstr;
    int i;
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    int icv;
    long start[MI_S_NDIMS];
    long count[MI_S_NDIMS];
    int old_ncopts;
    int r;
    double min, max;
    long slice_size;
    long index;
    int dtbytes;                /* Length of datatype in bytes */

    old_ncopts =get_ncopts();
    set_ncopts(0);

    var_id = ncvarid(fd, MIimage);

    ncvarinq(fd, var_id, NULL, NULL, &var_ndims, var_dims, NULL);

    set_ncopts(old_ncopts);
    
    if (var_ndims < 2 || var_ndims > 4) {
        return (MINC_STATUS_ERROR);
    }
    
    r = minc_simple_to_nc_type(datatype, &nctype, &signstr);
    if (r == MINC_STATUS_ERROR) {
        return (MINC_STATUS_ERROR);
    }

    dtbytes = nctypelen(nctype);

    /* Update the image-min and image-max values */
    if (ct > 0) {
        slice_size = cz * cy * cx;
        index = st;

        for (i = 0; i < ct; i++) {
            find_minmax((char *) dataptr + (dtbytes * slice_size * i), 
                        slice_size, datatype, &min, &max);
        
            mivarput1(fd, ncvarid(fd, MIimagemin), &index, 
                      NC_DOUBLE, MI_SIGNED, &min);
            mivarput1(fd, ncvarid(fd, MIimagemax), &index, 
                      NC_DOUBLE, MI_SIGNED, &max);
            index++;
        }
    }
    else {
        slice_size = cy * cx;
        index = sz;

        for (i = 0; i < cz; i++) {
            find_minmax((char *) dataptr + (dtbytes * slice_size * i), 
                        slice_size, datatype, &min, &max);
            mivarput1(fd, ncvarid(fd, MIimagemin), &index, 
                      NC_DOUBLE, MI_SIGNED, &min);
            mivarput1(fd, ncvarid(fd, MIimagemax), &index, 
                      NC_DOUBLE, MI_SIGNED, &max);
            index++;
        }
    }

    /* We want the data to wind up in t, x, y, z order. */

    icv = miicv_create();
    if (icv < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setint(icv, MI_ICV_TYPE, nctype);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setstr(icv, MI_ICV_SIGN, signstr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setint(icv, MI_ICV_DO_NORM, 1);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setint(icv, MI_ICV_DO_FILLVALUE, 1);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_attach(icv, fd, var_id);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    i = 0;
    switch (var_ndims) {
    case 4:
        count[i] = ct;
        start[i] = st;
        i++;
        /* fall through */
    case 3:
        count[i] = cz;
        start[i] = sz;
        i++;
        /* fall through */
    case 2:
        count[i] = cy;
        start[i] = sy;
        i++;
        
        count[i] = cx;
        start[i] = sx;
        i++;
        break;
    }

    r = miicv_put(icv, start, count, dataptr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    miicv_detach(icv);
    miicv_free(icv);
    return (MINC_STATUS_OK);
}
示例#18
0
文件: copy_data.c 项目: BIC-MNI/minc
/* ----------------------------- MNI Header -----------------------------------
@NAME       : copy_the_chunk
@INPUT      : reshape_info - information for reshaping volume
              chunk_start - start of current block
              chunk_count - count for current block
              chunk_data - pointer to enough space for chunk
              fillvalue - pixel value to zero volume, if necessary.
@OUTPUT     : (none)
@RETURNS    : (nothing)
@DESCRIPTION: Copies the chunk from the input file to the output file.
@METHOD     :
@GLOBALS    :
@CALLS      :
@CREATED    : October 25, 1994 (Peter Neelin)
@MODIFIED   :
---------------------------------------------------------------------------- */
static void copy_the_chunk(Reshape_info *reshape_info,
                           long chunk_start[],
                           long chunk_count[],
                           void *chunk_data,
                           double fillvalue)
{
   int idim, odim, in_ndims, out_ndims;
   long input_start[MAX_VAR_DIMS], input_count[MAX_VAR_DIMS];
   long output_start[MAX_VAR_DIMS], output_count[MAX_VAR_DIMS];
   long input_imap[MAX_VAR_DIMS], output_imap[MAX_VAR_DIMS];
   void *output_origin;
   int datatype_size;
   long total_size, ipix, first, last;
   int zero_data, really_copy_the_data;
   union {
      char c; short s; long l; float f; double d;
   } value_buffer;

   /* Get number of dimensions */
   out_ndims = reshape_info->output_ndims;
   in_ndims = reshape_info->input_ndims;

   /* Get size of output datatype */
   datatype_size = nctypelen(reshape_info->output_datatype);

   /* Create input start and count */
   translate_output_to_input(reshape_info, chunk_start, chunk_count,
                             input_start, input_count);

   /* Find out if we need to zero the volume and if we need to copy any
      data */
   zero_data = FALSE;
   really_copy_the_data = TRUE;
   total_size = 1;
   for (idim=0; idim < in_ndims; idim++) {
      first = input_start[idim];
      last = input_start[idim] + input_count[idim] - 1;
      if ((first < 0) || (last >= reshape_info->input_size[idim]))
         zero_data = TRUE;
      if ((last < 0) || (first >= reshape_info->input_size[idim]))
         really_copy_the_data = FALSE;
      total_size *= input_count[idim];
   }

   /* Make sure that input vectors are legal and translate them back 
      to output */
   truncate_input_vectors(reshape_info, input_start, input_count);
   translate_input_to_output(reshape_info, input_start, input_count,
                             output_start, output_count);

   /* Write out zero data if needed */
   if (zero_data) {
      convert_value_from_double(fillvalue, 
                                reshape_info->output_datatype,
                                reshape_info->output_is_signed,
                                &value_buffer);
      for (ipix=0; ipix < total_size; ipix++) {
         (void) memcpy((char *)chunk_data + ipix*datatype_size,
                       &value_buffer, datatype_size);
      }
      (void) ncvarput(reshape_info->outmincid, reshape_info->outimgid,
                      chunk_start, chunk_count, chunk_data);
   }

   /* Set up hypothetical imap variable for input */
   for (idim=in_ndims-1; idim >= 0; idim--) {
      input_imap[idim] = ((idim == in_ndims-1) ? 
                          datatype_size :
                          input_imap[idim+1] * input_count[idim+1]);
   }

   /* Create output imap variable from input one (re-ordering dimensions and
      flipping). Also work out the chunk origin (point to byte for output
      [0,0,0...]). */
   output_origin = chunk_data;
   for (odim=0; odim < out_ndims; odim++) {
      idim = reshape_info->map_out_to_in[odim];
      if (reshape_info->input_count[idim] > 0) {
         output_imap[odim] = input_imap[idim];
      }
      else {
         output_imap[odim] = -input_imap[idim];
         output_origin = 
            (void *) ((char *)output_origin - 
                      (output_count[odim] - 1) * output_imap[odim]);
      }
   }

   /* Should we really copy the data? */
   if (really_copy_the_data) {

      /* Read in the data */
      (void) miicv_get(reshape_info->icvid, input_start, input_count, 
                       chunk_data);
   
      /* Write it out */
      (void) ncvarputg(reshape_info->outmincid, reshape_info->outimgid,
                       output_start, output_count, NULL, output_imap, 
                       output_origin);

   }

}
示例#19
0
文件: test_speed.c 项目: BIC-MNI/minc
int
test_icv_read(char *filename, int xsize, int ysize, double image_min,
              double image_max, nc_type datatype, char *signtype)
{
   int icv, cdfid, img, ndims;
   static long coord[MAX_VAR_DIMS];
   static long count[MAX_VAR_DIMS];
   int dim[MAX_VAR_DIMS];
   long dim_size;
   unsigned char *image;
   int i;
   double min, max;
   int n;

   min = DBL_MAX;
   max = -DBL_MAX;

   image = malloc(xsize * ysize * nctypelen(datatype));
   if (image == NULL) {
       return (ERROR_STATUS);
   }

   /* Create the icv */
   icv=miicv_create();
   (void) miicv_setint(icv, MI_ICV_XDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_YDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_ZDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_ADIM_SIZE, xsize);
   (void) miicv_setint(icv, MI_ICV_BDIM_SIZE, ysize);
   (void) miicv_setint(icv, MI_ICV_KEEP_ASPECT, FALSE);
   (void) miicv_setint(icv, MI_ICV_DO_DIM_CONV, TRUE);
   (void) miicv_setint(icv, MI_ICV_TYPE, datatype);
   (void) miicv_setstr(icv, MI_ICV_SIGN, signtype);
   (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, image_max);
   (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, image_min);

   /* Open the file, attach the image variable */
   cdfid=miopen(filename, NC_NOWRITE);

   /* Attach image variable */
   img=ncvarid(cdfid, MIimage);
   (void) miicv_attach(icv, cdfid, img);

   /* Get the number of dimensions and modify count and coord */
   (void) ncvarinq(cdfid, img, NULL, NULL, &ndims, dim, NULL);
   if (ndims!=3) {
      (void) fprintf(stderr, "File must have 3 dimensions\n");
      return ERROR_STATUS;
   }
   (void) ncdiminq(cdfid, dim[0], NULL, &dim_size);
   count[0]=1;
   count[1]=ysize;
   count[2]=xsize;
   coord[1]=0;
   coord[2]=0;

   /* Get the data */
   for (i=0; i<dim_size; i++) {
      coord[0]=i;
      (void) miicv_get(icv, coord, count, image);

      switch (datatype) {
      case NC_BYTE:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned char uc = *(((unsigned char *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed char sc = *(((signed char *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_SHORT:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned short uc = *(((unsigned short *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed short sc = *(((signed short *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_INT:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned int uc = *(((unsigned int *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed int sc = *(((signed int *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_FLOAT:
          for (n = 0; n < xsize*ysize; n++) {
              float sc = *(((float *)image) + n);
              if (sc > max) {
                  max = sc;
              }
              if (sc < min) {
                  min = sc;
              }
          }
          break;
      case NC_DOUBLE:
          for (n = 0; n < xsize*ysize; n++) {
              double sc = *(((double *)image) + n);
              if (sc > max) {
                  max = sc;
              }
              if (sc < min) {
                  min = sc;
              }
          }
          break;
      }
      printf("%d %s %s %f %f\n", i, signtype, nctypename(datatype), min, max);
   }

   /* Close the file and free the icv */
   (void) miclose(cdfid);
   (void) miicv_free(icv);

   free(image);
   return (NORMAL_STATUS);
}