changeset 55:a23deb019f17

Initial revision
author neelin <neelin>
date Fri, 08 Jan 1993 09:45:04 +0000
parents 22d0cb5dac63
children 1d6d893eadcd
files conversion/mnitominc/Makefile conversion/mnitominc/mnitominc.c conversion/mnitominc/mnitominc.h conversion/scxtominc/define_scx_header.perl conversion/scxtominc/pc5r1.drs progs/Proglib/Makefile progs/Proglib/ParseArgv.c progs/Proglib/ParseArgv.h progs/Proglib/vax_conversions.c progs/rawtominc/Makefile progs/rawtominc/rawtominc.c
diffstat 11 files changed, 2668 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/conversion/mnitominc/Makefile
@@ -0,0 +1,70 @@
+# --------------------------------------------------------------------
+#
+# MINC Makefile
+#
+
+# Executable names
+PROGS    = mnitominc
+HEADERS  = $(PROGS:=.h)
+PROG_LIB_DIR = ../proglib
+PROG_LIB  = mincprog
+LIB_DIR  = ../../src#                         directory for library
+LIBRARY  = minc#                           library
+CDEFINES = -DDEBUG#                        cpp defines
+OPT      = -g#                             compiler options
+LDOPT    = -L/usr/local/lib -lnetcdf -lsun -lm -lgl_s -lm -lc_s# ld options
+INCLUDES = -I. -I../proglib -I../../src -I/usr/local/include
+
+# For cleaning up
+RM       = rm
+RM_FLAGS = -f
+
+# --------------------------------------------------------------------
+
+CFLAGS    = $(CDEFINES) $(INCLUDES) $(OPT)# CFLAGS and LINTFLAGS should
+LINTFLAGS = $(CDEFINES) $(INCLUDES)#        be same, except for -g/-O
+
+PROG_OBJ  = $(PROGS:=.o)#                 list of objects
+CC_LIB    = lib$(LIBRARY).a#              C library file
+CC_PROG_LIB= $(PROG_LIB_DIR)/lib$(PROG_LIB).a# library for prog objs
+LINT_LIST = $(PROG_OBJ:.o=.ln)
+LINT_LIST_EXE = $(LINT_LIST:.ln=.)#       list of executable names to lint
+LINT_LIB  = llib-l$(LIBRARY).ln#          lint library file
+LINT_PROG_LIB = $(PROG_LIB_DIR)/llib-l$(PROG_LIB).ln#
+
+# --------------------------------------------------------------------
+
+.SUFFIXES: .ln#                           tell make to watch for .ln's
+
+default: $(PROGS)
+
+#Dependency on Makefile
+$(PROG_OBJ) $(LINT_OBJS) : Makefile
+
+all: $(PROGS) lint
+
+.c.ln:#                                   defines the rule for creating .ln
+	lint $(LINTFLAGS) -c $< -o $@
+
+.c.o:#                                    defines the rule for creating .o
+	$(CC) $(CFLAGS) -c $< -o $@
+
+#Dependency of .o and .ln on .h
+$(PROG_OBJ) : $(HEADERS)
+
+$(LINT_LIST) : $(HEADERS)
+
+# How to make executables
+$(PROGS) : $$@.o $(CC_PROG_LIB) $(LIB_DIR)/$(CC_LIB)
+	$(CC) $@.o -o $@ $(CC_PROG_LIB) -L$(LIB_DIR) -l$(LIBRARY) $(LDOPT)
+
+#  how to lint the executable source
+lint: $(LINT_LIST_EXE)
+
+$(LINT_LIST_EXE) : $$@ln $(LINT_PROG_LIB) $(LIB_DIR)/$(LINT_LIB)
+	lint -u $(LINTFLAGS) $@ln $(LINT_PROG_LIB) $(LIB_DIR)/$(LINT_LIB)
+
+# Remove all derived files in this directory
+clean:
+	$(RM) $(RM_FLAGS) $(LINT_LIST) $(PROGS) $(PROG_OBJ)
+
new file mode 100644
--- /dev/null
+++ b/conversion/mnitominc/mnitominc.c
@@ -0,0 +1,788 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : mnitominc
+@INPUT      : argc, argv - command line arguments
+@OUTPUT     : (none)
+@RETURNS    : error status
+@DESCRIPTION: Converts an mni format file to a minc format file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : December 7, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+
+#ifndef lint
+static char rcsid[]="$Header: /private-cvsroot/minc/conversion/mnitominc/mnitominc.c,v 1.1 1993-01-08 09:46:55 neelin Exp $";
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <minc.h>
+#include <float.h>
+#include <string.h>
+#include <math.h>
+#include <ParseArgv.h>
+#include "mnitominc.h"
+
+
+/* Main program */
+
+main(int argc, char *argv[])
+{
+   int cdfid, imgid, maxid, minid, patid, study, acqid;
+   int dimvar[MAX_VAR_DIMS], twidth;
+   long start[MAX_VAR_DIMS];
+   long count[MAX_VAR_DIMS];
+   long end[MAX_VAR_DIMS];
+   long temp_coord[MAX_VAR_DIMS];
+   int dim[MAX_VAR_DIMS];
+   int fastdim;
+   int iframe, islice, image_num, i;
+   mni_header_type mni_header;
+   mni_image_type mni_image;
+   int zdim, tdim;
+   double last_z, diff_z, curr_diff_z, first_z;
+   double last_t, diff_t, curr_diff_t, first_t;
+   int z_regular, t_regular;
+
+   /* Parse arguments and get header info from mni file */
+   parse_args(argc, argv, &mni_header);
+
+   /* Create the file */
+   cdfid=nccreate(outfilename, (clobber ? NC_CLOBBER : NC_NOCLOBBER));
+
+   /* Create the dimensions */
+   zdim = tdim = -1;
+   for (i=0; i<ndims; i++) {
+      dim[i] = ncdimdef(cdfid, dimname[i], dimlength[i]);
+
+      /* Create dimension variable if mni file or for image dimensions */
+      if ((mni_header.file_type==MNI_FILE_TYPE) ||
+          (i>=ndims-IMAGE_DIMS)) {
+         if (dimfixed[i])
+            dimvar[i] = micreate_std_variable(cdfid, dimname[i], 
+                                           NC_LONG, 0, NULL);
+         else 
+            dimvar[i] = micreate_std_variable(cdfid, dimname[i], 
+                                           NC_DOUBLE, 1, &dim[i]);
+
+         /* Add MIstep attribute */
+         if (i==ndims-1) {
+            (void) miattputdbl(cdfid, dimvar[i], MIstep, xstep);
+            if ((mni_header.file_type == MNI_FILE_TYPE) &&
+                (mni_header.scanner_id == MNI_STX_SCAN) &&
+                (orientation == TRANSVERSE) &&
+                (mni_header.npixels == 128)) {
+               (void) miattputdbl(cdfid, dimvar[i], MIstart, 
+                                  mni_header.xstart);
+            }
+         }
+         else if (i==ndims-2) {
+            (void) miattputdbl(cdfid, dimvar[i], MIstep, ystep);
+            if ((mni_header.file_type == MNI_FILE_TYPE) &&
+                (mni_header.scanner_id == MNI_STX_SCAN) &&
+                (orientation == TRANSVERSE) &&
+                (mni_header.npixels == 128)) {
+               (void) miattputdbl(cdfid, dimvar[i], MIstart, 
+                                  mni_header.ystart);
+            }
+         }
+         else {
+            (void) miattputdbl(cdfid, dimvar[i], MIstep, 0.0);
+            (void) miattputdbl(cdfid, dimvar[i], MIstart, 0.0);
+         }
+
+         /* If MItime, then create dimwidth variable */
+         if (STR_EQ(dimname[i], MItime)) {
+            tdim=i;
+            if (dimfixed[i])
+               twidth = micreate_std_variable(cdfid, MItime_width, 
+                                                NC_LONG, 0, NULL);
+            else 
+               twidth = micreate_std_variable(cdfid, MItime_width, 
+                                              NC_DOUBLE, 1, &dim[i]);
+            (void) miattputstr(cdfid, dimvar[i], MIunits, "seconds");
+            (void) miattputstr(cdfid, twidth, MIunits, "seconds");
+         }
+
+         /* If not MItime, add attribute to describe spacetype */
+         else {
+            (void) miattputstr(cdfid, dimvar[i], MIunits, "mm");
+            if (i<ndims-IMAGE_DIMS) zdim=i;
+            if (mni_header.scanner_id==MNI_STX_SCAN)
+               (void) miattputstr(cdfid, dimvar[i], MIspacetype, MI_TALAIRACH);
+            else
+               (void) miattputstr(cdfid, dimvar[i], MIspacetype, MI_NATIVE);
+         }
+
+      }     /* Dimension variable */
+
+      /* Initialize coordinate vectors */
+      start[i] = 0;
+      count[i] = ((i<ndims-IMAGE_DIMS) ? 1 : dimlength[i]);
+      end[i]   = dimlength[i];
+   }
+
+   /* Create the image */
+   imgid=micreate_std_variable(cdfid, MIimage, 
+                               (mni_header.pix_size==1 ? NC_BYTE : NC_SHORT),
+                               ndims, dim);
+   (void) miattputstr(cdfid, imgid, MIsigntype, 
+                      (mni_header.pix_size==1 ? MI_UNSIGNED : MI_SIGNED));
+   (void) ncattput(cdfid, imgid, MIvalid_range, NC_DOUBLE, 2, 
+                   mni_header.valid_range);
+   if (mni_header.file_type==MNI_FILE_TYPE) {
+      maxid = micreate_std_variable(cdfid, MIimagemax, 
+                                    NC_DOUBLE, ndims-IMAGE_DIMS, dim);
+      minid = micreate_std_variable(cdfid, MIimagemin, 
+                                    NC_DOUBLE, ndims-IMAGE_DIMS, dim);
+   }
+
+   /* Add patient information */
+   patid=micreate_group_variable(cdfid, MIpatient);
+   (void) miattputstr(cdfid, patid, MIfull_name, mni_header.patient_name);
+   (void) miattputstr(cdfid, patid, MIidentification, 
+                      mni_header.patient_num);
+
+   /* Add study information */
+   study=micreate_group_variable(cdfid, MIstudy);
+   (void) miattputstr(cdfid, study, MIstart_time, mni_header.start_time);
+   if ((mni_header.file_type==MNI_FILE_TYPE) &&
+       (mni_header.scanner_id!=MNI_MRI_SCAN) &&
+       (mni_header.scanner_id!=MNI_STX_SCAN) &&
+       (mni_header.npixels<=128))
+      (void) miattputstr(cdfid, study, MImodality, MI_PET);
+   else if (mni_header.scanner_id!=MNI_STX_SCAN)
+      (void) miattputstr(cdfid, study, MImodality, MI_MRI);
+
+   /* Add acquisition information */
+   if ((mni_header.file_type==MNI_FILE_TYPE) &&
+       (mni_header.scanner_id!=MNI_MRI_SCAN) &&
+       (mni_header.scanner_id!=MNI_STX_SCAN) &&
+       (mni_header.npixels<=128)) {
+      acqid=micreate_group_variable(cdfid, MIacquisition);
+      (void) miattputstr(cdfid, acqid, MIinjection_time, 
+                         mni_header.injection_time);
+      (void) miattputstr(cdfid, acqid, MIradionuclide, mni_header.isotope);
+      (void) miattputdbl(cdfid, acqid, MIinjection_dose, mni_header.dose);
+      (void) miattputstr(cdfid, acqid, MIdose_units, mni_header.dose_units);
+   }
+
+   /* End definition mode */
+   (void) ncsetfill(cdfid, NC_NOFILL);
+   (void) ncendef(cdfid);
+
+   /* Get a buffer for reading images */
+   mni_image.npixels=mni_header.npixels;
+   mni_image.image_pix=mni_image.npixels*mni_image.npixels;
+   mni_image.pix_size=mni_header.pix_size;
+   mni_image.image_size=mni_image.image_pix*mni_image.pix_size;
+   mni_image.image=malloc(mni_image.image_size);
+
+   /* Loop through the images */
+   fastdim=ndims-IMAGE_DIMS-1;
+   if (fastdim<0) fastdim=0;
+   z_regular = t_regular = TRUE;
+   for (iframe=0; iframe<nframes; iframe++) {
+      for (islice=0; islice<nslices; islice++) {
+
+         /* Read in image */
+         image_num = islice*nframes + iframe;
+         if (get_mni_image(&mni_header, &mni_image, image_num)) {
+            (void) fprintf(stderr, "%s: Error reading mni image.\n", pname);
+            exit(ERROR_STATUS);
+         }
+ 
+         /* Write the image */
+         (void) ncvarput(cdfid, imgid, start, count, mni_image.image);
+
+         /* Write the image max and min, z position and time */
+         if (mni_header.file_type==MNI_FILE_TYPE) {
+            (void) ncvarput1(cdfid, minid, start, &mni_image.minimum);
+            (void) ncvarput1(cdfid, maxid, start, &mni_image.maximum);
+            if ((zdim>=0) && (iframe==0)) {
+               (void) ncvarput1(cdfid, dimvar[zdim], 
+                         mitranslate_coords(cdfid, 
+                                            imgid, start,
+                                            dimvar[zdim], 
+                            miset_coords(MAX_DIMS, 0L, temp_coord)),
+                                &mni_image.zposition);
+               if (islice>0) {
+                  curr_diff_z = mni_image.zposition - last_z;
+                  if ((islice>1) && !dblcmp(curr_diff_z, diff_z, EPSILON))
+                     z_regular = FALSE;
+                  diff_z = curr_diff_z;
+               }
+               else
+                  first_z = mni_image.zposition;
+               last_z=mni_image.zposition;
+            }
+            if ((tdim>=0) && (islice==0)) {
+               (void) ncvarput1(cdfid, dimvar[tdim], 
+                         mitranslate_coords(cdfid, 
+                                            imgid, start,
+                                            dimvar[tdim],
+                            miset_coords(MAX_DIMS, 0L, temp_coord)),
+                                &mni_image.time);
+               (void) ncvarput1(cdfid, twidth, 
+                         mitranslate_coords(cdfid, 
+                                            imgid, start,
+                                            twidth,
+                            miset_coords(MAX_DIMS, 0L, temp_coord)),
+                                &mni_image.time_length);
+               if (iframe>0) {
+                  curr_diff_t = mni_image.time - last_t;
+                  if ((iframe>1) && !dblcmp(curr_diff_t, diff_t, EPSILON))
+                     t_regular = FALSE;
+                  diff_t = curr_diff_t;
+               }
+               else
+                  first_t = mni_image.time;
+               last_t=mni_image.time;
+            }
+         }
+
+         /* Increment the counters */
+         start[fastdim] += count[fastdim];
+         i=fastdim;
+         while ((i>0) && (start[i]>=end[i])) {
+            start[i] = 0;
+            i--;
+            start[i] += count[i];
+         }
+      }
+   }
+
+   /* Write dimension attributes for z and t */
+   if (zdim>=0) {
+      if (nslices>1)
+         diff_z = (last_z - first_z) / (double) (nslices - 1);
+      else
+         diff_z = 0.0;
+      (void) miattputdbl(cdfid, dimvar[zdim], MIstep, diff_z);
+      (void) miattputdbl(cdfid, dimvar[zdim], MIstart, first_z);
+      if (z_regular)
+         (void) miattputstr(cdfid, dimvar[zdim], MIspacing, MI_REGULAR);
+      else
+         (void) miattputstr(cdfid, dimvar[zdim], MIspacing, MI_IRREGULAR);
+   }
+
+   if (tdim>=0) {
+      if (nframes>1)
+         diff_t = (last_t - first_t) / (double) (nframes - 1);
+      else
+         diff_t = 0.0;
+      (void) miattputdbl(cdfid, dimvar[tdim], MIstep, diff_t);
+      (void) miattputdbl(cdfid, dimvar[tdim], MIstart, first_t);
+      if (t_regular)
+         (void) miattputstr(cdfid, dimvar[tdim], MIspacing, MI_REGULAR);
+      else
+         (void) miattputstr(cdfid, dimvar[tdim], MIspacing, MI_IRREGULAR);
+   }
+
+   /* Free the memory */
+   free(mni_image.image);
+
+   /* Close the file */
+   (void) ncclose(cdfid);
+   
+   return NORMAL_STATUS;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : parse_args
+@INPUT      : argc        - number of command line arguments
+              argv        - array of arguments
+@OUTPUT     : 
+@RETURNS    : (nothing).
+@DESCRIPTION: Parses command line arguments.
+@METHOD     : 
+@GLOBALS    : pname        - program name
+              infilename   - mni file to read
+              outfilename  - minc file to write
+              clobber      - overwrite?
+              dimname      - names of dimensions
+              dimlength    - lengths of dimensions
+              ndims        - number of dimensions
+              orientation  - orientation of dimensions
+              type         - type of output data
+              signtype     - sign of output data
+              sign         - string sign of output
+              valid_range  - valid range of output data
+              vrange_set   - valid range used?
+@CALLS      : 
+@CREATED    : December 7, 1992
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void parse_args(int argc, char *argv[], mni_header_type *mni_header)
+{
+   int i, j, npix;
+
+   /* Parse the command line */
+   pname=argv[0];
+   if (ParseArgv(&argc, argv, argTable, 0)) {
+      usage_error(pname);
+   }
+
+   /* Check number of arguments */
+   if (argc!=3)
+      usage_error(pname);
+
+   /* Get filenames */
+   infilename = argv[1];
+   outfilename = argv[2];
+
+   /* Get mni file header info */
+   if (get_mni_header(infilename, mni_header)) {
+      (void) fprintf(stderr, "%s: Error reading mni file header.\n", pname);
+      usage_error(pname);
+   }
+
+   /* Get dimensions */
+
+   /* Get fastest two dim sizes */
+   for (i=0; i<IMAGE_DIMS; i++)
+
+   dimlength[MAX_DIMS-i-1] = mni_header->npixels;
+
+   /* Try to guess slowest two dim sizes if user doesn't give info */
+   if ((dimlength[0]<=0) && (dimlength[1]<=0)) {
+
+      /* If fewer than MAX_VOL_IMGS images, assume volume */
+      if (mni_header->nimages<=MAX_VOL_IMGS) {
+         dimlength[0]=1;
+         dimlength[1]=mni_header->nimages;
+      }
+
+      /* Otherwise, divide by DEFAULT_NSLICES to get nframes */
+      else {
+         dimlength[1]=DEFAULT_NSLICES;
+         dimlength[0]=mni_header->nimages / dimlength[1];
+      }
+   }
+   /* User gave nframes */
+   else if ((dimlength[0]>0) && (dimlength[1]<=0)) {
+      dimlength[1]=mni_header->nimages / dimlength[0];
+   }
+   /* User gave nslices */
+   else if ((dimlength[0]<=0) && (dimlength[1]>0)) {
+      dimlength[0]=mni_header->nimages / dimlength[1];
+   }
+   /* User gave both */
+   else {
+      if (dimlength[0]*dimlength[1]!=mni_header->nimages) {
+         (void) fprintf(stderr, 
+      "%s: <nframes>*<nslices> is not equal to # of images in file.\n",
+                 pname);
+         exit(ERROR_STATUS);
+      }
+   }
+
+   /* Check that nframes*nslices = nimages */
+   if ((dimlength[0]*dimlength[1])!=mni_header->nimages) {
+      (void) fprintf(stderr, 
+              "%s: Cannot work out number of slices and frames.\n",
+              pname);
+      exit(ERROR_STATUS);
+   }
+   else if ((dimlength[0]<1) || (dimlength[1]<1)) {
+      (void) fprintf(stderr, 
+              "%s: Number of frames and slices must be greater than zero.\n",
+              pname);
+      exit(ERROR_STATUS);
+   }
+
+   /* Get orientation */
+   if (orientation == DEF_ORIENT) {
+      if (mni_header->orientation==MNI_CORONAL)
+         orientation = CORONAL;
+      else if (mni_header->orientation==MNI_SAGITTAL)
+         orientation = SAGITTAL;
+      else
+         orientation = TRANSVERSE;
+   }
+   for (i=1; i<MAX_DIMS; i++) {
+      dimname[i]=orientation_names[orientation][i-1];
+   }
+
+   /* Get number of dimensions and check for dimensions of length 1 */
+   nframes = dimlength[0];
+   nslices = dimlength[1];
+   for (i=0, j=0; i<MAX_DIMS; i++) {
+      if ((i>=MAX_DIMS-IMAGE_DIMS) || (dimlength[i]>1)) {
+         dimlength[j] = dimlength[i];
+         dimname[j]   = dimname[i];
+         dimfixed[j]  = dimfixed[i];
+         j++;
+      }
+   }
+   ndims=j;
+
+   /* Set x,y step for stereotaxic files */
+   if ((mni_header->file_type == MNI_FILE_TYPE) && 
+       (mni_header->scanner_id == MNI_STX_SCAN)) {
+      npix = mni_header->npixels;
+      switch (orientation) {
+      case TRANSVERSE:
+         mni_header->xstep = 
+            MNI_DIR * MNI_STX_XFOV / ((double) npix);
+         mni_header->ystep = 
+            MNI_DIR * MNI_STX_YFOV / ((double) npix);
+         mni_header->zstep_scale = MNI_STX_ZSCALE;
+         mni_header->xstart = -((int) npix/2) * mni_header->xstep;
+         mni_header->ystart = -((int) npix/2) * mni_header->ystep;
+         break;
+      case SAGITTAL:
+         mni_header->xstep = 
+            MNI_DIR * MNI_STX_YFOV / ((double) npix);
+         mni_header->ystep = 
+            MNI_DIR * MNI_STX_ZFOV / ((double) npix);
+         mni_header->zstep_scale = MNI_STX_XSCALE;
+         break;
+      case CORONAL:
+         mni_header->xstep = 
+            MNI_DIR * MNI_STX_XFOV / ((double) npix);
+         mni_header->ystep = 
+            MNI_DIR * MNI_STX_ZFOV / ((double) npix);
+         mni_header->zstep_scale = MNI_STX_YSCALE;
+         break;
+      }
+   }
+
+   /* Field of view */
+   if (xstep==0.0) xstep = field_of_view;
+   if (ystep==0.0) ystep = field_of_view;
+   if (xstep==0.0) xstep = mni_header->xstep;
+   if (ystep==0.0) ystep = mni_header->ystep;
+
+   return;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : usage_error
+@INPUT      : progname - program name
+@OUTPUT     : (none)
+@RETURNS    : (nothing)
+@DESCRIPTION: Prints a usage error message and exits.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : December 7, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void usage_error(char *progname)
+{
+   (void) fprintf(stderr, 
+                "\nUsage: %s [<options>] <infile> <outfile>\n", progname);
+   (void) fprintf(stderr,   
+                  "       %s [-help]\n\n", progname);
+
+   exit(ERROR_STATUS);
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_mni_header
+@INPUT      : file - name of mni format file
+@OUTPUT     : mni_header - pointer to structure containing mni header info
+@RETURNS    : TRUE if an error occurs
+@DESCRIPTION: Opens an mni format file and reads the header information
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : December 8, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int get_mni_header(char *file, mni_header_type *mni_header)
+{
+   char buffer[MNI_HEADER_SIZE];
+   int matrix_type;
+   short stemp;
+   int i, j;
+
+   if ((mni_header->fp=fopen(file, "r"))==NULL) {
+      (void) fprintf(stderr, "Cannot open file %s\n", file);
+      return(TRUE);
+   }
+
+   /* Read in the header block */
+   if (fseek(mni_header->fp, 0, SEEK_SET) ||
+       (fread(buffer, sizeof(char), MNI_HEADER_SIZE, mni_header->fp)
+                          !=MNI_HEADER_SIZE)) {
+      (void) fprintf(stderr, "Cannot read from file.\n");
+      return(TRUE);
+   }
+
+   /* Get interesting information */
+
+   /* Get offset to data */
+   get_vax_short(1, &buffer[MNI_LOC_OFFSET], &(mni_header->offset));
+
+   /* Get number of images */
+   get_vax_short(1, &buffer[MNI_LOC_NIMAGES], &(mni_header->nimages));
+
+   /* Get image size and file type info */
+   matrix_type=buffer[MNI_LOC_MATYPE];
+   switch (matrix_type) {
+   case '3':
+      mni_header->npixels=64;
+      mni_header->file_type=MNI_FILE_TYPE;
+      break;
+   case '4':
+      mni_header->npixels=64;
+      mni_header->file_type=NIL_FILE_TYPE;
+      break;
+   case '5':
+      mni_header->npixels=128;
+      mni_header->file_type=MNI_FILE_TYPE;
+      break;
+   case '6':
+      mni_header->npixels=128;
+      mni_header->file_type=NIL_FILE_TYPE;
+      break;
+   case '7':
+      mni_header->npixels=256;
+      mni_header->file_type=MNI_FILE_TYPE;
+      break;
+   case '8':
+      mni_header->npixels=256;
+      mni_header->file_type=NIL_FILE_TYPE;
+      break;
+   default:
+      (void) fprintf(stderr, "Unknown matrix format.\n");
+      return(TRUE);
+   }
+
+   /* Get pixel size and valid range info from file type. */
+   if (mni_header->file_type==MNI_FILE_TYPE) {
+      mni_header->pix_size=1;
+      mni_header->valid_range[0]=MNI_VMIN;
+      mni_header->valid_range[1]=MNI_VMAX;
+   }
+   else {
+      mni_header->pix_size=2;
+      mni_header->valid_range[0]=NIL_VMIN;
+      mni_header->valid_range[1]=NIL_VMAX;
+   }
+
+   /* Get image type */
+   get_vax_short(1, &buffer[MNI_LOC_SCANNER_ID], &(mni_header->scanner_id));
+   get_vax_short(1, &buffer[MNI_LOC_CORR_MASK], &stemp);
+   if (stemp==MNI_POSITOME_MASK) mni_header->scanner_id=MNI_POS_SCAN;
+
+   /* Get step sizes */
+   if (mni_header->file_type==MNI_FILE_TYPE) {
+      /* We have to deal with step for stereotaxic files after knowing
+         orientation (i.e. after parsing args) */
+      if (mni_header->scanner_id != MNI_STX_SCAN) {
+         mni_header->xstep = mni_header->ystep = 
+            MNI_DIR * MNI_FOV / ((double) mni_header->npixels);
+      }
+   }
+   else
+      mni_header->xstep = mni_header->ystep = 
+         NIL_DIR * NIL_FOV / ((double) mni_header->npixels);
+
+   /* Get image orientation */
+   get_vax_short(1, &buffer[MNI_LOC_ORIENTATION], &(mni_header->orientation));
+
+   /* Get Patient name */
+   for (i=0; i<MNI_PATNAM_LENGTH; i++) {
+      mni_header->patient_name[i]=buffer[MNI_LOC_PATNAM+i];
+      if ((mni_header->patient_name[i] < MIN_VALID_CHAR) ||
+          (mni_header->patient_name[i] > MAX_VALID_CHAR))
+         mni_header->patient_name[i] = PADDING_CHAR;
+   }
+   mni_header->patient_name[i]='\0';
+
+   /* Get Patient number */
+   for (i=0; i<MNI_PATNUM_LENGTH; i++) {
+      mni_header->patient_num[i]=buffer[MNI_LOC_PATNUM+i];
+      if ((mni_header->patient_num[i] < MIN_VALID_CHAR) ||
+          (mni_header->patient_num[i] > MAX_VALID_CHAR))
+         mni_header->patient_num[i] = PADDING_CHAR;
+   }
+   mni_header->patient_num[i]='\0';
+
+   /* Get acquisition time and date */
+   for (i=0, j=0; i<MNI_ACQDAT_LENGTH; i++, j++) {
+      mni_header->start_time[j]=buffer[MNI_LOC_ACQDAT+i];
+      if ((mni_header->start_time[j] < MIN_VALID_CHAR) ||
+          (mni_header->start_time[j] > MAX_VALID_CHAR))
+         mni_header->start_time[j] = PADDING_CHAR;
+   }
+   mni_header->start_time[j++]=' ';
+   for (i=0; i<MNI_ACQTIM_LENGTH; i++, j++) {
+      mni_header->start_time[j]=buffer[MNI_LOC_ACQTIM+i];
+      if ((mni_header->start_time[j] < MIN_VALID_CHAR) ||
+          (mni_header->start_time[j] > MAX_VALID_CHAR))
+         mni_header->start_time[j] = PADDING_CHAR;
+   }
+   mni_header->start_time[j]='\0';
+
+   /* Get isotope name */
+   for (i=0; i<MNI_ISOTOPE_LENGTH; i++) {
+      mni_header->isotope[i]=buffer[MNI_LOC_ISOTOPE+i];
+      if ((mni_header->isotope[i] < MIN_VALID_CHAR) ||
+          (mni_header->isotope[i] > MAX_VALID_CHAR))
+         mni_header->isotope[i] = PADDING_CHAR;
+   }
+   mni_header->isotope[i]='\0';
+
+   /* Get dose */
+   for (i=0; i<MNI_DOSE_LENGTH; i++) {
+      mni_header->dose_string[i]=buffer[MNI_LOC_DOSE+i];
+      if ((mni_header->dose_string[i] < MIN_VALID_CHAR) ||
+          (mni_header->dose_string[i] > MAX_VALID_CHAR))
+         mni_header->dose_string[i] = PADDING_CHAR;
+   }
+   mni_header->dose_string[i]='\0';
+   mni_header->dose = atof(mni_header->dose_string);
+   (void) strcpy(mni_header->dose_units, "mCurie");
+
+   /* Get injection time */
+   for (i=0; i<MNI_INJTIM_LENGTH; i++) {
+      mni_header->injection_time[i]=buffer[MNI_LOC_INJTIM+i];
+      if ((mni_header->injection_time[i] < MIN_VALID_CHAR) ||
+          (mni_header->injection_time[i] > MAX_VALID_CHAR))
+         mni_header->injection_time[i] = PADDING_CHAR;
+   }
+   mni_header->injection_time[i]='\0';
+
+   return(FALSE);
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_mni_image
+@INPUT      : mni_header - pointer to structure containing file header info
+                 and file pointer.
+              image_num - number of image to read (counting from zero).
+@OUTPUT     : mni_image - pointer to structure containing image information
+                 (space for the image must already be allocated).
+@RETURNS    : TRUE if an error occurs.
+@DESCRIPTION: Read an image from an mni format file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : December 8, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int get_mni_image(mni_header_type *mni_header, mni_image_type *mni_image,
+                  int image_num)
+{
+   float qsc, zpos, time;
+   short isea, tlen;
+   int i, j, nrow, nread;
+   unsigned char *image;
+   double zero, denom, *valid_range;
+
+   /* Check the image number */
+   if (image_num >= mni_header->nimages) {
+      (void) fprintf(stderr, "Tried to read past last image.\n");
+      return(TRUE);
+   }
+
+   /* Read the image */
+   if (fseek(mni_header->fp, mni_header->offset*BLOCK_SIZE + 
+             image_num*mni_image->image_size, SEEK_SET)) {
+      (void) fprintf(stderr, "Cannot seek to image.\n");
+      return(TRUE);
+   }
+   nread=fread(mni_image->image, mni_header->pix_size, mni_image->image_pix,
+             mni_header->fp);
+   if (nread<=0) {
+      (void) fprintf(stderr, "Cannot read image from file.\n");
+      return(TRUE);
+   }
+   /* Check for read of only part of image (happens to last image of files
+      created by cnvmri) */
+   if (nread<mni_image->image_pix) {
+      for (i=nread; i<mni_image->image_pix; i++)
+         mni_image->image[i]=0;
+   }
+   image = mni_image->image;
+   nrow=mni_image->npixels*mni_image->pix_size;
+
+   /* Get interesting stuff from the image */
+   if (mni_header->file_type==MNI_FILE_TYPE) {
+      get_vax_float(1, &image[MNI_XLOC_QSC+MNI_YLOC_QSC*nrow], &qsc);
+      get_vax_short(1, &image[MNI_XLOC_ISEA+MNI_YLOC_ISEA*nrow], &isea);
+      get_vax_float(1, &image[MNI_XLOC_ZPOS+MNI_YLOC_ZPOS*nrow], &zpos);
+      get_vax_float(1, &image[MNI_XLOC_TIME+MNI_YLOC_TIME*nrow], &time);
+      get_vax_short(1, &image[MNI_XLOC_TLEN+MNI_YLOC_TLEN*nrow], &tlen);
+      mni_image->minimum = (MNI_VMIN-isea) * qsc;
+      mni_image->maximum = (MNI_VMAX-isea) * qsc;
+      mni_image->zposition = ((mni_header->scanner_id != MNI_STX_SCAN) ?
+                              zpos :
+                              zpos * mni_header->zstep_scale);
+      mni_image->time = time*SEC_PER_MIN;
+      mni_image->time_length = tlen;
+   }
+   else {
+      mni_image->minimum = NIL_VMIN;
+      mni_image->maximum = NIL_VMAX;
+      mni_image->zposition = 0.0;
+      mni_image->time = 0.0;
+      mni_image->time_length = 0.0;
+   }
+
+   /* Do byte swap if needed */
+   if (mni_image->pix_size==2) {
+      get_vax_short(mni_image->image_pix, image, (short *) image);
+   }
+
+   /* Zero the fruit salad */
+   valid_range = mni_header->valid_range;
+   denom = mni_image->maximum - mni_image->minimum;
+   if (denom == 0.0) {
+      zero = valid_range[0];
+   }
+   else {
+      zero = valid_range[0] - mni_image->minimum *
+         (valid_range[1] - valid_range[0]) / denom;
+   }
+   if (zero < valid_range[0]) zero = valid_range[0];
+   if (zero > valid_range[1]) zero = valid_range[1];
+   zero = rint(zero);
+   for (j=0; j < MNI_CORNER_YSIZE; j++)
+      for (i=0; i < MNI_CORNER_XSIZE; i += mni_image->pix_size)
+         if (mni_image->pix_size == 1) {
+            *((unsigned char *) &image[j*nrow+i]) = zero;
+         }
+         else if (mni_image->pix_size == 2) {
+            *((short *) &image[j*nrow+i]) = zero;
+         }
+
+   return(FALSE);
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : dblcmp
+@INPUT      : dbl1 - first value
+              dbl2 - second value
+              epsilon - maximum difference
+@OUTPUT     : (none)
+@RETURNS    : TRUE if values are the same within epsilon, FALSE otherwise.
+@DESCRIPTION: Compares two double precision values. If their normalized
+              difference is less than epsilon, then return TRUE, 
+              otherwise FALSE.
+              Returns the following :
+                 abs((dbl1-dbl2)/(dbl1+dbl2)) < epsilon
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : December 14, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int dblcmp(double dbl1, double dbl2, double epsilon)
+{
+   double diff, sum;
+
+   diff = dbl1 - dbl2;
+   sum = dbl1 + dbl2;
+   diff = (diff < 0.0) ? -diff : diff;
+   sum = (sum < 0.0) ? -sum : sum;
+   if (sum==0.0) sum = 1.0;
+   return((diff/sum) <= epsilon);
+
+}
new file mode 100644
--- /dev/null
+++ b/conversion/mnitominc/mnitominc.h
@@ -0,0 +1,211 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : mnitominc.h
+@DESCRIPTION: Header file for mnitominc
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : December 9, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+/* Some constants */
+
+#define NORMAL_STATUS 0
+#define ERROR_STATUS 1
+#define TRUE 1
+#define FALSE 0
+#define MIN_VALID_CHAR ' '
+#define MAX_VALID_CHAR '\177'
+#define PADDING_CHAR ' '
+#define SEC_PER_MIN 60.0
+#define EPSILON 100.0*FLT_EPSILON
+
+/* Constants for argument parsing */
+#define MAX_VOL_IMGS 128
+#define DEFAULT_NSLICES 15
+#define IMAGE_DIMS 2
+#define MAX_DIMS 4
+#define DEF_ORIENT -1
+#define TRANSVERSE 0
+#define SAGITTAL 1
+#define CORONAL 2
+
+/* Constants for mni files */
+#define BLOCK_SIZE 512
+#define MNI_HEADER_SIZE BLOCK_SIZE
+#define MNI_FILE_TYPE 1
+#define NIL_FILE_TYPE 2
+#define MNI_STX_XBRAIN 67.0
+#define MNI_STX_YBRAIN 86.0
+#define MNI_STX_ZBRAIN 75.0
+#define MNI_STX_PBRAIN 50.0
+#define MNI_STX_NPIXEL 128
+#define MNI_STX_FACTOR 100.0
+#define MNI_STX_XFOV MNI_STX_NPIXEL*MNI_STX_XBRAIN/MNI_STX_PBRAIN
+#define MNI_STX_YFOV MNI_STX_NPIXEL*MNI_STX_YBRAIN/MNI_STX_PBRAIN
+#define MNI_STX_ZFOV MNI_STX_NPIXEL*MNI_STX_ZBRAIN/MNI_STX_PBRAIN
+#define MNI_STX_XSCALE MNI_STX_XBRAIN/MNI_STX_FACTOR
+#define MNI_STX_YSCALE MNI_STX_YBRAIN/MNI_STX_FACTOR
+#define MNI_STX_ZSCALE MNI_STX_ZBRAIN/MNI_STX_FACTOR
+#define MNI_FOV 256.0
+#define NIL_FOV 250.0
+#define MNI_DIR (1.0)
+#define NIL_DIR (-1.0)
+#define MNI_VMIN 0.0
+#define MNI_VMAX 255.0
+#define NIL_VMIN 0.0
+#define NIL_VMAX 4095.0
+#define MNI_MRI_SCAN 1
+#define MNI_SCX_SCAN 2
+#define MNI_STX_SCAN 3
+#define MNI_POS_SCAN 4
+#define MNI_TRANSVERSE 100
+#define MNI_CORONAL 200
+#define MNI_SAGITTAL 300
+#define MNI_POSITOME_MASK 0
+#define MNI_CORNER_XSIZE 12
+#define MNI_CORNER_YSIZE 7
+#define MNI_LOC_OFFSET 212
+#define MNI_LOC_NIMAGES 230
+#define MNI_LOC_MATYPE 238
+#define MNI_LOC_SCANNER_ID 200
+#define MNI_LOC_ORIENTATION 204
+#define MNI_LOC_PATNAM 0
+#define MNI_PATNAM_LENGTH 23
+#define MNI_LOC_PATNUM 23
+#define MNI_PATNUM_LENGTH 14
+#define MNI_LOC_ACQDAT 42
+#define MNI_ACQDAT_LENGTH 10
+#define MNI_LOC_ACQTIM 52
+#define MNI_ACQTIM_LENGTH 10
+#define MNI_LOC_ISOTOPE 129
+#define MNI_ISOTOPE_LENGTH 14
+#define MNI_LOC_DOSE 143
+#define MNI_DOSE_LENGTH 14
+#define MNI_LOC_INJTIM 157
+#define MNI_INJTIM_LENGTH 10
+#define MNI_LOC_CORR_MASK 196
+#define MNI_XLOC_QSC 0
+#define MNI_YLOC_QSC 0
+#define MNI_XLOC_ISEA 4
+#define MNI_YLOC_ISEA 2
+#define MNI_XLOC_ZPOS 8
+#define MNI_YLOC_ZPOS 0
+#define MNI_XLOC_TIME 0
+#define MNI_YLOC_TIME 2
+#define MNI_XLOC_TLEN 4
+#define MNI_YLOC_TLEN 3
+
+/* Macros */
+#define STR_EQ(s1,s2) (strcmp(s1,s2)==0)
+
+/* Structure containing information about orientation */
+char *orientation_names[][IMAGE_DIMS+1] = {
+   {MIzspace, MIyspace, MIxspace},
+   {MIxspace, MIzspace, MIyspace},
+   {MIyspace, MIzspace, MIxspace},
+};
+
+/* Structure containing information about signs */
+char *sign_names[][6] = {
+   {MI_SIGNED, MI_UNSIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED},
+   {MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED},
+   {MI_SIGNED, MI_UNSIGNED, MI_UNSIGNED, MI_UNSIGNED, MI_UNSIGNED, MI_UNSIGNED}
+};
+
+/* Argument variables */
+char *pname;
+char *infilename;
+char *outfilename;
+int clobber = TRUE;
+char *dimname[MAX_VAR_DIMS] = {MItime, NULL, NULL, NULL};
+long dimlength[MAX_VAR_DIMS] = {0};
+int dimfixed[MAX_VAR_DIMS] = {FALSE, FALSE, TRUE, TRUE};
+long nframes;
+long nslices;
+int ndims;
+int orientation = DEF_ORIENT;
+double field_of_view = 0.0;
+double xstep = 0.0;
+double ystep = 0.0;
+
+/* Argument table */
+ArgvInfo argTable[] = {
+   {NULL, ARGV_HELP, (char *) NULL, (char *) NULL, 
+       "Options to specify image orientation. Default = -transverse."},
+   {"-transverse", ARGV_CONSTANT, (char *) TRANSVERSE, (char *) &orientation,
+       "Transverse images"},
+   {"-sagittal", ARGV_CONSTANT, (char *) SAGITTAL, (char *) &orientation,
+       "Sagittal images"},
+   {"-coronal", ARGV_CONSTANT, (char *) CORONAL, (char *) &orientation,
+       "Coronal images"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options to help specify number of slices and time frames."},
+   {"-nslices", ARGV_INT, (char *) 1, (char *) &dimlength[1],
+       "Number of slices in volume."},
+   {"-nframes", ARGV_INT, (char *) 1, (char *) &dimlength[0],
+       "Number of time frames."},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options for writing output file. Default = -clobber."},
+   {"-clobber", ARGV_CONSTANT, (char *) TRUE, (char *) &clobber,
+       "Overwrite existing file"},
+   {"-noclobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber,
+       "Don't overwrite existing file"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Other options."},
+   {"-field_of_view", ARGV_FLOAT, (char *) 1, (char *) &field_of_view,
+       "Field of view of images (in mm)."},
+   {"-xstep", ARGV_FLOAT, (char *) 1, (char *) &xstep,
+       "Distance between pixels in x dimension (in mm)."},
+   {"-ystep", ARGV_FLOAT, (char *) 1, (char *) &ystep,
+       "Distance between pixels in y dimension (in mm)."},
+   {NULL, ARGV_END, NULL, NULL, NULL}
+};
+
+/* Mni format file information */
+typedef struct {
+   FILE *fp;
+   int file_type;
+   short offset;
+   short nimages;
+   int npixels;
+   int pix_size;
+   double valid_range[2];
+   short scanner_id;
+   double xstep;
+   double ystep;
+   double zstep_scale;
+   double xstart;
+   double ystart;
+   short orientation;
+   char patient_name[MNI_PATNAM_LENGTH + 1];
+   char patient_num[MNI_PATNUM_LENGTH + 1];
+   char start_time[MNI_ACQDAT_LENGTH + MNI_ACQTIM_LENGTH + 2];
+   char isotope[MNI_ISOTOPE_LENGTH + 1];
+   char dose_string[MNI_DOSE_LENGTH + 1];
+   double dose;
+   char dose_units[10];
+   char injection_time[MNI_INJTIM_LENGTH + 1];
+} mni_header_type;
+
+typedef struct {
+   unsigned char *image;
+   long npixels;
+   long image_pix;
+   int pix_size;
+   long image_size;
+   double minimum;
+   double maximum;
+   double zposition;
+   double time;
+   double time_length;
+} mni_image_type;
+
+/* Function declarations */
+void parse_args(int argc, char *argv[], mni_header_type *mni_header);
+void usage_error(char *progname);
+int get_mni_header(char *file, mni_header_type *mni_header);
+int get_mni_image(mni_header_type *mni_header, mni_image_type *mni_image,
+                  int image_num);
+int dblcmp(double dbl1, double dbl2, double epsilon);
+void get_vax_short(int nvals, void *vax_value, short *mach_value);
+void get_vax_float(int nvals, void *vax_value, float *mach_value);
+
new file mode 100755
--- /dev/null
+++ b/conversion/scxtominc/define_scx_header.perl
@@ -0,0 +1,313 @@
+#! /usr/local/bin/perl
+# Script to read in Scanditronix .DRS files (defining scx files)
+# and convert them to a .h file containing mnemonics and offsets.
+#
+# Usage:
+#    define_scx_header.perl <header_file> <drs file> [<drs file> ...]
+#
+
+# Constants
+%types = (
+            "B",  "byte",
+            "W",  "word",
+            "L",  "long",
+            "F",  "float",
+            "FS", "short_float",
+            "S",  "string",
+            "B-",  "date",
+            "B:",  "time"
+);
+%lengths = (
+            "byte", 1,
+            "word", 2,
+            "long", 4,
+            "float", 4,
+            "short_float", 2,
+            "string", 1,
+            "date", 1,
+            "time", 1
+);
+@mnem_fields = 
+   ("name", "type", "length", "in_file", "default", "start", "block");
+@block_fields = 
+   ("length", "multiplicity", "parent", "start");
+
+# Check arguments
+if ($#ARGV<1) {
+   die "Usage : define_scx_header.perl <header_file> <drs file> ".
+       "[<drs file> ...]\n";
+}
+$header_file = shift;
+
+# Open the header file and write initial stuff
+@drs_list = ();
+open(hfile, ">$header_file") || die "$0 : Cannot open file $header_file\n";
+@types = values(%types);
+@lengths = ();
+foreach $types (@types) {push(@lengths, $lengths{$types});}
+print hfile '
+/* Header file for scanditronix file definition */
+
+/* Mnemonic types */
+enum scx_mnem_types 
+   {' . join(', ', @types) . '};
+static int scx_mnem_type_size[] =
+   {' . join(', ', @lengths) . '};
+
+/* Block type */
+typedef struct scx_block_struct scx_block_type;
+struct scx_block_struct {
+   int length;
+   int multiplicity;
+   scx_block_type *parent;
+};
+
+/* Mnemonic type */
+typedef struct scx_mnemonic_struct scx_mnemonic_type;
+struct scx_mnemonic_struct {
+   char *name;
+   scx_mnem_types type;
+   int length;
+   int in_file;
+   long default;
+   long start;
+   scx_block_type *block;
+};
+
+';
+
+# Loop through drs files
+while ($drs_file = shift) {
+
+# Initialize the variables needed
+undef(%mnemonics);
+undef(%blocks);
+$nmnems  = 0;
+$nblocks = 0;
+$blk= -1;
+@block_list = ($blk);
+$position = $next_position = 0;
+undef $file_type;
+undef $rev;
+undef $ext;
+
+#  Open the drs file
+   if (!open(dfile, $drs_file)) {
+      print STDERR "Unable to open drs file $drs_file\n";
+      next;
+   }
+
+#  Loop through the lines of the drs file
+   while (<dfile>) {
+
+#     Look for leading lines
+      if (! (defined($file_type) && defined($rev) && defined($ext))) {
+         if (/^\s*TYPE\S*\s+\D*(\d+)/) {
+            $file_type = $1;
+            if ($file_type == 0) {die "Illegal file type : $file_type\n";}
+         }
+         elsif (/^\s*REV\.\S*\s+\D*(\d+)/) {
+            $rev = $1;
+         }
+         elsif (/^\s*EXT\.\S*\s+(.*)/) {
+            $ext = $1;
+         }
+      }
+
+#     Look for mnemonic lines
+      elsif (/^\s*[EDM]\s/) {
+
+#        Parse the line
+         ($code, $mnem, $ftype, $default, $prio, @rest) = split(' ');
+         next if ($prio eq "");
+         $nmnems++;
+
+#        Get the mnemonic name
+         $mnemonics{$nmnems-1, "name"} = $mnem;
+
+#        Is the mnemonic stored in the file
+         $mnemonics{$nmnems-1, "in_file"} = ($code ne "E");
+
+#        Get data type and length (if there is a - or : on the end, and
+#          the type is B, then we have a date or time)
+         if ( $ftype !~ /^(\d*)(B|W|L|F|FS|S|B-|B:)$/ ) {next;}
+         if ($1 ne "") {$mnemonics{$nmnems-1, "length"} = $1;}
+         else {$mnemonics{$nmnems-1, "length"} = 1;}
+         $mnemonics{$nmnems-1, "type"} = $types{$2};
+
+#        Get pre-defined values
+         if ($default !~ /^=(.*)$/) {next;}
+         $mnemonics{$nmnems-1, "default"} = $1;
+
+#        Get block
+         $mnemonics{$nmnems-1, "block"} = $blk;
+
+#        Increment position counters
+         if ($code ne "M")
+            {$position = $next_position;}
+         if ($code ne "E") {
+            $next_position = $position +
+                     $mnemonics{$nmnems-1, "length"} * 
+                     $lengths{$mnemonics{$nmnems-1, "type"}};
+         }
+
+#        Get position of first value
+         if ($mnemonics{$nmnems-1, "in_file"}) 
+            {$mnemonics{$nmnems-1, "start"} = $position;}
+         else
+            {$mnemonics{$nmnems-1, "start"} = -1;}
+
+#        Check for file type matching first word of file
+         if (($position == 0) && ($code eq 'D') && 
+             ($file_type != $mnemonics{$nmnems-1, "default"})) {
+            die "Type $file_type does not match first word of file (",
+                  $mnemonics{$nmnems-1, "default"},")\n";
+         }
+
+      }
+
+#     Look for reserved space lines
+      elsif (/^\s*R\s/) {
+         if (! /^\s*R\s+(\d+)\s+.*$/) {next;}
+         $next_position += $1;
+      }
+
+#     Look for block definitions
+      elsif (/^\s*([\(\)])-/) {
+
+#        Look for block open or close
+         $open = ($1 eq "(");
+         if ($open) {
+
+#           Parse block open line
+            if (!/^\s*\(-+LEN=([^-]+)-+MULT=([^-]+)-+/) 
+               {die "Error parsing block open\n";}
+            $length = $1;
+            $mult = $2;
+            if (($mult !~ /^\d+$/) || ($mult < 1))
+               {die "Error in block multiplicity\n";}
+            if ($length !~ /^\d+$/) {$length = -1;}
+            if (($length < 0) && ($mult>1))
+               {die "Error in block length\n";}
+
+#           Add new block
+            $nblocks++;
+            $blk = $nblocks-1;
+            $blocks{$blk, "length"} = $length;
+            $blocks{$blk, "multiplicity"} = $mult;
+            $blocks{$blk, "parent"} = $block_list[$#block_list];
+            $blocks{$blk, "start"} = $next_position;
+            push(@block_list, $blk);
+
+         }
+
+#        Otherwise, we have a close block
+         else {
+
+#           Check for an open block
+            if (($nblocks<=0) || ($#block_list<=0))
+               {die "Unbalanced block bounds\n";}
+
+#           Check the block length
+            $block_length = $next_position - $blocks{$blk, "start"};
+            if ($blocks{$blk,"length"} >= 0) {
+               if ($blocks{$blk,"length"} != $block_length) {
+                  die "Actual block length not equal to given block length\n";
+               }
+            }
+            else {
+               $blocks{$blk,"length"} = $block_length;
+            }
+
+#           Move up the pointer (only changes if multiplicity is > 1)
+            $next_position += $blocks{$blk, "length"} *
+                             ($blocks{$blk, "multiplicity"} - 1);
+
+#           Pop the block
+            pop(@block_list);
+            $blk = $block_list[$#block_list];
+         
+         }
+
+      }  # End of block
+
+   }  #  End of read loop
+
+#  Add drs file to list of files
+   ($drs_id = "pc_".$file_type."_r_".$rev) =~ tr/\W/_/;
+   if (grep(/$drs_id/, @drs_list)) {
+         die "Two files with the same type and revision : $drs_id\n";
+   }
+   push(@drs_list, $drs_id);
+
+   $block_array = 'drs_block_'.$drs_id;
+   $mnem_array = 'drs_mnems_'.$drs_id;
+
+   $drs_file_types{$drs_id} = $file_type;
+   $drs_blocks{$drs_id} = $block_array;
+   $drs_mnemonics{$drs_id} = $mnem_array;
+
+#  Write out block table for file
+   print hfile '
+/* Blocks for drs file with id '.$drs_id.' */
+static scx_block_type '.$block_array.'[] = {
+';
+
+   foreach $blk (0..$nblocks-1) {
+      $the_block = $blocks{$blk, "parent"};
+      if ($the_block < 0) {$the_block = 'NULL';}
+      else {$the_block = '&('.$block_array.'['.$the_block.'])';}
+      print hfile "   " . 
+         $blocks{$blk, "length"} . ', ' .
+         $blocks{$blk, "multiplicity"} . ', ' . $the_block . ",\n";
+   }
+   print hfile "   0, 0, NULL\n};\n\n";
+
+#  Write out mnemonic table for file
+   print hfile '
+/* Mnemonics for drs file with id '.$drs_id.' */
+static scx_mnemonic_type '.$mnem_array.'[] = {
+';
+
+   foreach $mnem (0..$nmnems-1) {
+
+      $the_block = $mnemonics{$mnem, "block"};
+      if ($the_block < 0) {$the_block = 'NULL';}
+      else {$the_block = '&('.$block_array.'['.$the_block.'])';}
+
+      $the_default = $mnemonics{$mnem, "default"};
+      if ($the_default eq "") {$the_default = "0";}
+      elsif ($mnemonics{$mnem, "type"} eq "string")
+         {$the_default = '(long) "'.$the_default.'"';}
+
+      print hfile '   "' . 
+         $mnemonics{$mnem, "name"} . '", ' .
+         $mnemonics{$mnem, "type"} . ', ' .
+         $mnemonics{$mnem, "length"} . ', ' .
+         $mnemonics{$mnem, "in_file"} . ', ' .
+         $the_default . ', ' .
+         $mnemonics{$mnem, "start"} . ', ' .
+         $the_block . ",\n";
+   }
+   print hfile "   NULL, byte, 0, 0, 0, NULL\n};\n\n";
+   
+}  # End of loop over files
+
+# Write out list of file types
+print hfile '
+/* List of drs files and types */
+
+static struct {
+   int file_type;
+   scx_block_type *block_list;
+   scx_mnemonic_type *mnemonic_list;
+} scx_file_types[] = {
+';
+
+foreach $drs_id (@drs_list) {
+   print hfile "   $drs_file_types{$drs_id}, " .
+               "$drs_blocks{$drs_id}, " .
+               "$drs_mnemonics{$drs_id},\n";
+}
+
+   print hfile "   0, NULL, NULL\n};\n";
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/pc5r1.drs
@@ -0,0 +1,148 @@
+      
+                  TYPE:     PC-5
+                  REV.:     1
+                  EXT.:     .DAT
+
+      Definition of the file header structure for
+      the PC4096-15WB positron camera data file.
+
+(---LEN=FHS--MULT=1-----------------------------------------------------
+E       FHS     B       =4      P0F     ; File header size (Records)
+E       REC     W       =512    P0F     ; Record size
+
+D       TYP     W       =5      P0F     ; Type of equipment
+D       NCS     B       =15     P0F     ; Number of slices
+D       SITE    4S      =KS     P0A     ; Installation site
+D       REV     W       =1      P0F     ; Revision number          
+
+D       NDET    W       =256    P0F     ; Number of detectors per ring
+D       NPRO    W       =256    P0F     ; Number of projections per slice
+D       NMEM    W       =48     P0F     ; Number of members in stat. proj.
+D       NWOB    B       =5      P0F     ; Number of wobble bins per member
+D       CDI     FS      =6.5    P0A     ; Cross-section distance (mm)
+D       CSZ     FS      =6.0    P0A     ; Cross-section thickness (p) (mm)
+D       CSX     FS      =6.0    P0A     ; Cross-section thickness (x) (mm)
+
+D       RID     10S     =       P0A     ; Run id (user def)
+D       RIN     L       =       P02     ; Identification number   
+D       ETN     W       =       P02     ; ET-number (user def)
+D       PNM   24S       =       P02     ; Patient name            
+D       BRN     L       =       P02     ; Birth number            
+D       ASS     22S     =       P02     ; Responsible technician  
+D       DOC     22S     =       P02     ; Responsible doctor      
+D       DAT     3B-     =       P0A     ; Measurement date        
+M       DATY    B       =       P0A     ;   Year  (B)             
+D       DATM    B       =       P0A     ;   Month (B)             
+D       DATD    B       =       P0A     ;   Day   (B)             
+D       TIM     4B:     =       P0A     ; Measurement time        
+M       TIMH    B       =       P0A     ;   Hour                  
+D       TIMM    B       =       P0A     ;   Minutes               
+D       TIMS    B       =       P0A     ;   Seconds               
+D       TIHU    B       =       P0A     ;   Hundredths of seconds
+D       QES   12S       =       P02     ; Question                
+D       POR     4S      =       P02     ; Patient orientation     
+D       PAN     W       =       P02     ; Patient angle           
+D       CLV     FS      =       P0A     ; Cross-section level (mm+OM)
+D       ZDI     FS      =       P0A     ; Z displacement (mm)
+D       NRV     W       =       P02     ; Number of revolutions/min
+D       NME     W       =       P02     ; Number of measurements  
+D       MTM     F       =       P02     ; Measuring time    
+D       RPRT    FS      =       P02	; Time in s. between rates-file reports
+D       ISO     6S      =       P02     ; Isotope (eg GA-68)
+D       HALF    F       =       P02     ; Halftime of isotope (user supplied)
+D       CAR     8S      =       P02     ; Carrier (eg EDTA)
+D       ACT     F       =       P02     ; Injected activity
+D       INP     4S      =       P02     ; Injection place
+D       INT     4S      =       P02     ; Injection type
+D       ITM     3B:     =       P02     ; Injection time
+M       ITMH    B       =       P02     ;   Hour   (B)
+D       ITMM    B       =       P02     ;   Minute (B)
+D       ITMS    B       =       P02     ;   Second (B)
+D       COL     1S      =       P0A     ; Collimator type (' '=standard)
+D       SAMP    B       =       P0A     ; Sampling mode (0=stat, X=bins)
+D       DTYP    B       =       P0A     ; Data type (0=word, 1=byte)
+D       FOV     B       =       P02     ; Field-of-view type
+D       PRJL    W       =       P0A     ; Projection length in members
+D       TILT    FS      =       P0A     ; Gantry tilt angle
+D       SLEW    FS      =       P0A     ; Gantry slew angle
+D       ELV     W       =       P0A     ; Energy level (keV)
+D       TIW     FS      =       P0A     ; Time window (ns)    
+D       COM     20S     =       P02     ; Comments                
+D       STYP    B       =       P0A     ; Scan type (0=em, 1=tr, 2=bl, 3=norm)
+D       BLAN    L       =       P02     ; Blank scan number
+D       TRAN    L       =       P02     ; Transmission scan number
+
+D       PAR     B       =       P0A     ; Parameter file number
+D       NORM    W       =       P02     ; Norm file number
+
+D       DPR     B       =       P0A     ; Data present in file (1=present)
+D       TNM     8S      =       P02     ; Tape name (user def)
+
+D       FERR    L       =       P0A     ; FIFO errors
+D       FLOS    F       =       P0A     ; FIFO loss rate
+D       INVA    F       =       P0A     ; Invalid count rate
+D       TRAT    F       =       P0A     ; Total count rate
+
+D       TAC     W       =       P0A     ; Type of attenuation corr.
+D       IMFM    W       =       P0A     ; Image format (eg 128)
+D       IMTP    10S     =       P02     ; Image type (' '=activity)
+D       IMUN    10S     =       P02     ; Image scale unit (eg nCi/cc)
+D       PXS     FS      =       P0A     ; Pixel size (mm/pixel)
+D       FFN     4S      =       P0A     ; Filter function (eg 'BOHM')
+D       FWD     FS      =       P0A     ; Filter width (mm)
+
+D       SLOT    W       =       P0F     ; Slot on DAP disk
+D       CNTX    10S     =       P0A     ; Context of study (user def)
+D       AGE     B       =       P0A     ; Patient's age
+D       SEX     1S      =       P0A     ; Patient's sex
+D       MAX     W       =       P02     ; Repr. of highest pixel in image
+
+R 34
+
+(---LEN=4--MULT=8-------------------------------------------------------
+D       SING    F       =       P0A     ; Singles count rate per detector
+)-----------------------------------------------------------------------
+
+(---LEN=4--MULT=8-------------------------------------------------------
+D       XRAT    F       =       P0A     ; Physiological input count rate
+)-----------------------------------------------------------------------
+
+
+(---LEN=18--MULT=5-----------------------------------------------------
+D       USR     F       =       P02     ; User definable reals
+D       USI     L       =       P02     ; User definable longwords
+D       USC     10S     =       P02     ; User definable character strings
+)-----------------------------------------------------------------------
+
+(---LEN=18--MULT=1-----------------------------------------------------
+D       CYCL    F       =       P0F     ; Gate cycle time low limit
+D       CYCH    F       =       P0F     ; Gate cycle time high limit
+D       GTLL    FS      =       P0F     ; Gate low limit ( in % of cycle )
+D       GTLH    FS      =       P0F     ; Gate high limit ( in % of cycle )
+D       GTNR    B       =       P0F     ; Gate number
+D       FRNR    W       =       P0F     ; Time frame number
+D       DCY     FS      =       P0F     ; MTM duty cycle ( in % )
+D       NGAT    B       =       P0F     ; Number of gating bins
+)-----------------------------------------------------------------------
+
+ (---LEN=87--MULT=15----------------------------------------------------
+D       STOT    F       =       P0A     ; Total number of counts per slice
+D       CAL     F       =       P02     ; Slice calibration factors
+
+D       MAG     F       =       P02     ; Image magnification
+D       SPOS    B       =       P02     ; Slice image position in file
+D       SCA     F       =       P02     ; Scatter per slice
+D       RAN     F       =       P02     ; Randoms per slice
+D       DTC     FS      =       P02     ; Dead time correction factor
+
+ (---LEN=2--MULT=32-----------------------------------------------------
+D       PERX    B       =       P02     ; Perimeter point x-coordinate
+D       PERY    B       =       P02     ; Perimeter point y-coordinate
+  )--------------------------------------------------------------------
+ )---------------------------------------------------------------------
+
+(---LEN=4--MULT=15----------------------------------------------------
+D       OFFS    F       =       P02     ;Offset in image
+)-----------------------------------------------------------------------
+ 
+)-----------------------------------------------------------------------
new file mode 100644
--- /dev/null
+++ b/progs/Proglib/Makefile
@@ -0,0 +1,62 @@
+# --------------------------------------------------------------------
+#
+# MINC Makefile
+#
+
+# Object names
+OBJS     = ParseArgv.o vax_conversions.o
+PROG_LIB  = mincprog
+CDEFINES = #                        cpp defines
+OPT      = -g#                             compiler options
+INCLUDES = -I. # include directories
+
+# Options for creating library
+RM       = rm
+RM_FLAGS = -f
+AR       = ar
+AR_FLAGS = -r
+RANLIB   = true
+
+# --------------------------------------------------------------------
+
+CFLAGS    = $(CDEFINES) $(INCLUDES) $(OPT)# CFLAGS and LINTFLAGS should
+LINTFLAGS = $(CDEFINES) $(INCLUDES)#        be same, except for -g/-O
+
+CC_PROG_LIB= lib$(PROG_LIB).a#            library for objs
+LINT_OBJS = $(OBJS:.o=.ln)
+LINT_PROG_LIB = llib-l$(PROG_LIB).ln#
+
+# --------------------------------------------------------------------
+
+.SUFFIXES: .ln#                           tell make to watch for .ln's
+
+default: $(CC_PROG_LIB)
+
+#Dependency on Makefile
+$(OBJS) $(LINT_OBJS) : Makefile
+
+all: $(CC_PROG_LIB) lint
+
+.c.ln:#                                   defines the rule for creating .ln
+	lint $(LINTFLAGS) -c $< -o $@
+
+.c.o:#                                    defines the rule for creating .o
+	$(CC) $(CFLAGS) -c $< -o $@
+
+# How to create library
+$(CC_PROG_LIB): $(OBJS)
+	$(RM) $(RM_FLAGS) $(CC_PROG_LIB)
+	$(AR) $(AR_FLAGS) $(CC_PROG_LIB) $(OBJS)
+	$(RANLIB) $(CC_PROG_LIB)
+
+# Lint
+lint : $(LINT_PROG_LIB)
+
+# How to create lint library
+$(LINT_PROG_LIB) : $(LINT_OBJS)
+	lint -o $(PROG_LIB) -x -u $(LINTFLAGS) $(LINT_OBJS)
+
+# Remove all derived files in this directory
+clean:
+	\rm -f   $(OBJS) $(LINT_OBJS)
+
new file mode 100644
--- /dev/null
+++ b/progs/Proglib/ParseArgv.c
@@ -0,0 +1,418 @@
+/*
+ * ParseArgv.c --
+ *
+ *	This file contains a procedure that handles table-based
+ *	argv-argc parsing.
+ *
+ * Copyright 1990 Regents of the University of California
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ *
+ * This file has been modified to not rely on tcl, tk or X11.
+ * Based on tkArgv.c from tk2.3 : 
+static char rcsid[] = "$Header: /private-cvsroot/minc/progs/Proglib/Attic/ParseArgv.c,v 1.1 1993-01-08 09:47:37 neelin Exp $ SPRITE (Berkeley)";
+ *
+ * Modifications by Peter Neelin (November 27, 1992)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ParseArgv.h>
+
+#define TRUE  1
+#define FALSE 0
+
+/*
+ * Default table of argument descriptors.  These are normally available
+ * in every application.
+ */
+
+static ArgvInfo defaultTable[] = {
+    {"-help",	ARGV_HELP,	(char *) NULL,	(char *) NULL,
+	"Print summary of command-line options and abort"},
+    {NULL,	ARGV_END,	(char *) NULL,	(char *) NULL,
+	(char *) NULL}
+};
+
+/*
+ * Forward declarations for procedures defined in this file:
+ */
+
+static void	PrintUsage _ANSI_ARGS_((ArgvInfo *argTable, int flags));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseArgv --
+ *
+ *	Process an argv array according to a table of expected
+ *	command-line options.  See the manual page for more details.
+ *
+ * Results:
+ *	The return value is a Boolean value with TRUE indicating an error.  
+ *	If an error occurs then an error message is printed on stderr.
+ *	Under normal conditions, both *argcPtr and *argv are modified
+ *	to return the arguments that couldn't be processed here (they
+ *	didn't match the option table, or followed an ARGV_REST
+ *	argument).
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ParseArgv(argcPtr, argv, argTable, flags)
+    int *argcPtr;		/* Number of arguments in argv.  Modified
+				 * to hold # args left in argv at end. */
+    char **argv;		/* Array of arguments.  Modified to hold
+				 * those that couldn't be processed here. */
+    ArgvInfo *argTable;	/* Array of option descriptions */
+    int flags;			/* Or'ed combination of various flag bits,
+				 * such as ARGV_NO_DEFAULTS. */
+{
+   register ArgvInfo *infoPtr;
+				/* Pointer to the current entry in the
+				 * table of argument descriptions. */
+   ArgvInfo *matchPtr;	/* Descriptor that matches current argument. */
+   char *curArg;		/* Current argument */
+   register char c;		/* Second character of current arg (used for
+				 * quick check for matching;  use 2nd char.
+				 * because first char. will almost always
+				 * be '-'). */
+   int srcIndex;		/* Location from which to read next argument
+				 * from argv. */
+   int dstIndex;		/* Index into argv to which next unused
+				 * argument should be copied (never greater
+				 * than srcIndex). */
+   int argc;			/* # arguments in argv still to process. */
+   int length;			/* Number of characters in current argument. */
+   int nargs;        /* Number of following arguments to get. */
+   int i;
+
+/* Macro to optionally print errors */
+#define FPRINTF if (!(flags&ARGV_NO_PRINT)) (void) fprintf
+
+   if (flags & ARGV_DONT_SKIP_FIRST_ARG) {
+      srcIndex = dstIndex = 0;
+      argc = *argcPtr;
+   } else {
+      srcIndex = dstIndex = 1;
+      argc = *argcPtr-1;
+   }
+
+   while (argc > 0) {
+      curArg = argv[srcIndex];
+      srcIndex++;
+      argc--;
+      c = curArg[1];
+      length = strlen(curArg);
+      
+      /*
+       * Loop throught the argument descriptors searching for one with
+       * the matching key string.  If found, leave a pointer to it in
+       * matchPtr.
+       */
+
+      matchPtr = NULL;
+      for (i = 0; i < 2; i++) {
+         if (i == 0) {
+            infoPtr = argTable;
+         } else {
+            infoPtr = defaultTable;
+         }
+         for (; infoPtr->type != ARGV_END; infoPtr++) {
+            if (infoPtr->key == NULL) {
+               continue;
+            }
+            if ((infoPtr->key[1] != c)
+                || (strncmp(infoPtr->key, curArg, length) != 0)) {
+               continue;
+            }
+            if (infoPtr->key[length] == 0) {
+               matchPtr = infoPtr;
+               goto gotMatch;
+            }
+            if (flags & ARGV_NO_ABBREV) {
+               continue;
+            }
+            if (matchPtr != NULL) {
+               FPRINTF(stderr, "ambiguous option \"%s\"\n", curArg);
+               return TRUE;
+            }
+            matchPtr = infoPtr;
+         }
+      }
+      if (matchPtr == NULL) {
+
+         /*
+          * Unrecognized argument.  Just copy it down, unless the caller
+          * prefers an error to be registered.
+          */
+
+         if (flags & ARGV_NO_LEFTOVERS) {
+            FPRINTF(stderr, "unrecognized argument \"%s\"\n", curArg);
+         }
+         argv[dstIndex] = curArg;
+         dstIndex++;
+         continue;
+      }
+
+      /*
+       * Take the appropriate action based on the option type
+       */
+	gotMatch:
+      infoPtr = matchPtr;
+      switch (infoPtr->type) {
+      case ARGV_CONSTANT:
+         *((int *) infoPtr->dst) = (int) infoPtr->src;
+         break;
+      case ARGV_INT:
+         nargs = (int) infoPtr->src;
+         if (nargs<1) nargs=1;
+         for (i=0; i<nargs; i++) {
+            if (argc == 0) {
+               goto missingArg;
+            } else {
+               char *endPtr;
+
+               *(((int *) infoPtr->dst)+i) =
+                  strtol(argv[srcIndex], &endPtr, 0);
+               if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
+                  FPRINTF(stderr, 
+                  "expected integer argument for \"%s\" but got \"%s\"",
+                          infoPtr->key, argv[srcIndex]);
+                  return TRUE;
+               }
+               srcIndex++;
+               argc--;
+            }
+         }
+         break;
+      case ARGV_STRING:
+         nargs = (int) infoPtr->src;
+         if (nargs<1) nargs=1;
+         for (i=0; i<nargs; i++) {
+            if (argc == 0) {
+               goto missingArg;
+            } else {
+               *(((char **)infoPtr->dst)+i) = argv[srcIndex];
+               srcIndex++;
+               argc--;
+            }
+         }
+         break;
+      case ARGV_REST:
+         *((int *) infoPtr->dst) = dstIndex;
+         goto argsDone;
+      case ARGV_FLOAT:
+         nargs = (int) infoPtr->src;
+         if (nargs<1) nargs=1;
+         for (i=0; i<nargs; i++) {
+            if (argc == 0) {
+               goto missingArg;
+            } else {
+               char *endPtr;
+
+               *(((double *) infoPtr->dst)+i) =
+                  strtod(argv[srcIndex], &endPtr);
+               if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
+                  FPRINTF(stderr, 
+       "expected floating-point argument for \"%s\" but got\"%s\"\n",
+                          infoPtr->key, argv[srcIndex]);
+                  return TRUE;
+               }
+               srcIndex++;
+               argc--;
+            }
+         }
+         break;
+      case ARGV_FUNC: {
+         int (*handlerProc)();
+
+         handlerProc = (int (*)())infoPtr->src;
+		
+         if ((*handlerProc)(infoPtr->dst, infoPtr->key,
+                            argv[srcIndex])) {
+            srcIndex += 1;
+            argc -= 1;
+         }
+         break;
+      }
+      case ARGV_GENFUNC: {
+         int	    (*handlerProc)();
+
+         handlerProc = (int (*)())infoPtr->src;
+
+         argc = (*handlerProc)(infoPtr->dst, infoPtr->key,
+                               argc, argv+srcIndex);
+         if (argc < 0) {
+            return TRUE;
+         }
+         break;
+      }
+      case ARGV_HELP:
+         PrintUsage (argTable, flags);
+         return TRUE;
+      default:
+         FPRINTF(stderr, "bad argument type %d in ArgvInfo",
+                 infoPtr->type);
+         return TRUE;
+      }
+   }
+   
+   /*
+    * If we broke out of the loop because of an OPT_REST argument,
+    * copy the remaining arguments down.
+    */
+
+ argsDone:
+   while (argc) {
+      argv[dstIndex] = argv[srcIndex];
+      srcIndex++;
+      dstIndex++;
+      argc--;
+   }
+   argv[dstIndex] = (char *) NULL;
+   *argcPtr = dstIndex;
+   return FALSE;
+
+ missingArg:
+   FPRINTF(stderr, "\"%s\" option requires an additional argument\n", curArg);
+   return TRUE;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintUsage --
+ *
+ *	Generate a help string describing command-line options.
+ *
+ * Results:
+ *	Prints on stderr (unless ARGV_NO_PRINT is specified in flags) 
+ *	a help string describing all the options in argTable, plus all those
+ *	in the default table unless ARGV_NO_DEFAULTS is
+ *	specified in flags.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintUsage(argTable, flags)
+     ArgvInfo *argTable;	/* Array of command-specific argument
+				 * descriptions. */
+     int flags;			/* If the ARGV_NO_DEFAULTS bit is set
+				 * in this word, then don't generate
+				 * information for default options. */
+{
+   register ArgvInfo *infoPtr;
+   int width, i, j, numSpaces;
+#define NUM_SPACES 20
+   static char spaces[] = "                    ";
+/*   char tmp[30]; */
+   int nargs;
+
+/* Macro to optionally print errors */
+#define FPRINTF if (!(flags&ARGV_NO_PRINT)) (void) fprintf
+
+   /*
+    * First, compute the width of the widest option key, so that we
+    * can make everything line up.
+    */
+
+   width = 4;
+   for (i = 0; i < 2; i++) {
+      for (infoPtr = i ? defaultTable : argTable;
+           infoPtr->type != ARGV_END; infoPtr++) {
+         int length;
+         if (infoPtr->key == NULL) {
+            continue;
+         }
+         length = strlen(infoPtr->key);
+         if (length > width) {
+            width = length;
+         }
+      }
+   }
+
+   FPRINTF(stderr, "Command-specific options:");
+   for (i = 0; ; i++) {
+      for (infoPtr = i ? defaultTable : argTable;
+           infoPtr->type != ARGV_END; infoPtr++) {
+         if ((infoPtr->type == ARGV_HELP) && (infoPtr->key == NULL)) {
+            FPRINTF(stderr, "\n%s", infoPtr->help);
+            continue;
+         }
+         FPRINTF(stderr, "\n %s:", infoPtr->key);
+         numSpaces = width + 1 - strlen(infoPtr->key);
+         while (numSpaces > 0) {
+            if (numSpaces >= NUM_SPACES) {
+               FPRINTF(stderr, "%s",spaces);
+            } else {
+               FPRINTF(stderr, "%s",spaces+NUM_SPACES-numSpaces);
+            }
+            numSpaces -= NUM_SPACES;
+         }
+         FPRINTF(stderr, "%s",infoPtr->help);
+         switch (infoPtr->type) {
+         case ARGV_INT: {
+            FPRINTF(stderr, "\n\t\tDefault value:");
+            nargs = (int) infoPtr->src;
+            if (nargs<1) nargs=1;
+            for (j=0; j<nargs; j++) {
+               FPRINTF(stderr, " %d", *(((int *) infoPtr->dst)+j));
+            }
+            break;
+         }
+         case ARGV_FLOAT: {
+            FPRINTF(stderr, "\n\t\tDefault value:");
+            nargs = (int) infoPtr->src;
+            if (nargs<1) nargs=1;
+            for (j=0; j<nargs; j++) {
+               FPRINTF(stderr, " %lg", *(((double *) infoPtr->dst)+j));
+            }
+            break;
+         }
+         case ARGV_STRING: {
+            char *string;
+
+            nargs = (int) infoPtr->src;
+            if (nargs<1) nargs=1;
+            string = *((char **) infoPtr->dst);
+            if ((nargs==1) && (string == NULL)) break;
+            for (j=0; j<nargs; j++) {
+               string = *(((char **) infoPtr->dst)+j);
+               if (string != NULL) {
+                  FPRINTF(stderr, " \"%s\"", string);
+               }
+               else {
+                  FPRINTF(stderr, " \"%s\"", string);
+               }
+            }
+
+            break;
+         }
+         default: {
+            break;
+         }
+         }
+      }
+
+      if ((flags & ARGV_NO_DEFAULTS) || (i > 0)) {
+         break;
+      }
+      FPRINTF(stderr, "\nGeneric options for all commands:");
+   }
+
+   FPRINTF(stderr, "\n");
+}
new file mode 100644
--- /dev/null
+++ b/progs/Proglib/ParseArgv.h
@@ -0,0 +1,83 @@
+/*
+ * ParseArgv.h --
+ *
+ *	Declarations for Tk-related things that are visible
+ *	outside of the Tk module itself.
+ *
+ * Copyright 1989-1992 Regents of the University of California.
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ * This file has been modified to be used only for argv parsing without
+ * reference to tk, tcl or X11. Base on tk.h from tk2.3
+ * $Header: /private-cvsroot/minc/progs/Proglib/Attic/ParseArgv.h,v 1.1 1993-01-08 09:48:00 neelin Exp $ SPRITE (Berkeley)
+ */
+
+/*
+ * Definitions that allow this header file to be used either with or
+ * without ANSI C features like function prototypes.
+ */
+
+#undef _ANSI_ARGS_
+#if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus)
+#   define _ANSI_ARGS_(x)	x
+#else
+#   define _ANSI_ARGS_(x)	()
+#endif
+
+/*
+ * Structure used to specify how to handle argv options.
+ */
+
+typedef struct {
+    char *key;		/* The key string that flags the option in the
+			 * argv array. */
+    int type;		/* Indicates option type;  see below. */
+    char *src;		/* Value to be used in setting dst;  usage
+			 * depends on type. */
+    char *dst;		/* Address of value to be modified;  usage
+			 * depends on type. */
+    char *help;		/* Documentation message describing this option. */
+} ArgvInfo;
+
+/*
+ * Legal values for the type field of a ArgvInfo: see the user
+ * documentation for details.
+ */
+
+#define ARGV_CONSTANT		15
+#define ARGV_INT			16
+#define ARGV_STRING			17
+#define ARGV_REST			19
+#define ARGV_FLOAT			20
+#define ARGV_FUNC			21
+#define ARGV_GENFUNC			22
+#define ARGV_HELP			23
+#define ARGV_END			27
+
+/*
+ * Flag bits for passing to ParseArgv:
+ */
+
+#define ARGV_NO_DEFAULTS		0x1
+#define ARGV_NO_LEFTOVERS		0x2
+#define ARGV_NO_ABBREV		0x4
+#define ARGV_DONT_SKIP_FIRST_ARG	0x8
+#define ARGV_NO_PRINT 0x16
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Exported procedures and variables.
+ *
+ *--------------------------------------------------------------
+ */
+extern int ParseArgv _ANSI_ARGS_((int *argcPtr, char **argv,
+                                  ArgvInfo *argTable, int flags));
+
new file mode 100644
--- /dev/null
+++ b/progs/Proglib/vax_conversions.c
@@ -0,0 +1,92 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : vax_conversions.c
+@DESCRIPTION: File containing routines to convert machine values to vax format
+              values.
+@METHOD     : 
+@CREATED    : December 10, 1992 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+
+#ifndef lint
+static char rcsid[]="$Header: /private-cvsroot/minc/progs/Proglib/vax_conversions.c,v 1.1 1993-01-08 09:47:46 neelin Exp $";
+#endif
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_vax_short
+@INPUT      : nvals - number of values to convert
+              vax_value - pointer to array of shorts in vax format
+@OUTPUT     : mach_value - pointer to array of shorts in current machine format
+@RETURNS    : (nothing)
+@DESCRIPTION: Converts vax short integers to short integers in the format of
+              the current machine.
+@METHOD     : 
+@GLOBALS    : (none)
+@CALLS      : memcpy
+@CREATED    : December 10, 1992.
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void get_vax_short(int nvals, void *vax_value, short *mach_value)
+{
+   int i;
+   char *ptr1, *ptr2, v0, v1;
+
+#ifdef vax
+   memcpy((void *) mach_value, vax_value, nvals*sizeof(short));
+#else
+   ptr1 = (char *) vax_value;
+   ptr2 = (char *) mach_value;
+   for (i=0; i<nvals; i++) {
+      v0 = ptr1[1];
+      v1 = ptr1[0];
+      ptr2[0] = v0;
+      ptr2[1] = v1;
+      ptr1 += sizeof(mach_value[0]);
+      ptr2 += sizeof(mach_value[0]);
+   }
+#endif
+
+   return;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_vax_float
+@INPUT      : nvals - number of values to convert
+              vax_value - pointer to array of floats in vax format
+@OUTPUT     : mach_value - pointer to array of floats in current machine format
+@RETURNS    : (nothing)
+@DESCRIPTION: Converts vax floats to floats in the format of
+              the current machine.
+@METHOD     : 
+@GLOBALS    : (none)
+@CALLS      : memcpy
+@CREATED    : December 10, 1992.
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void get_vax_float(int nvals, void *vax_value, float *mach_value)
+{
+   int i;
+   char *ptr1, *ptr2, v0, v1;
+
+#ifdef vax
+   memcpy((void *) mach_value, vax_value, nvals*sizeof(short));
+#else
+   ptr1 = (char *) vax_value;
+   ptr2 = (char *) mach_value;
+   for (i=0; i<nvals; i++) {
+      v0 = ptr1[1];
+      v1 = ptr1[0];
+      ptr2[0] = v0;
+      ptr2[1] = v1;
+      v0 = ptr1[3];
+      v1 = ptr1[2];
+      ptr2[2] = v0;
+      ptr2[3] = v1;
+      mach_value[i] /= 4.0;
+      ptr1 += sizeof(mach_value[0]);
+      ptr2 += sizeof(mach_value[0]);
+   }
+#endif
+
+   return;
+}
+
new file mode 100644
--- /dev/null
+++ b/progs/rawtominc/Makefile
@@ -0,0 +1,70 @@
+# --------------------------------------------------------------------
+#
+# MINC Makefile
+#
+
+# Executable names
+PROGS    = rawtominc
+HEADERS  = 
+PROG_LIB_DIR = ../proglib
+PROG_LIB  = mincprog
+LIB_DIR  = ../../src#                         directory for library
+LIBRARY  = minc#                           library
+CDEFINES = -DDEBUG#                        cpp defines
+OPT      = -g#                             compiler options
+LDOPT    = -L/usr/local/lib -lnetcdf -lsun -lm -lgl_s -lm -lc_s# ld options
+INCLUDES = -I. -I../proglib -I../../src -I/usr/local/include
+
+# For cleaning up
+RM       = rm
+RM_FLAGS = -f
+
+# --------------------------------------------------------------------
+
+CFLAGS    = $(CDEFINES) $(INCLUDES) $(OPT)# CFLAGS and LINTFLAGS should
+LINTFLAGS = $(CDEFINES) $(INCLUDES)#        be same, except for -g/-O
+
+PROG_OBJ  = $(PROGS:=.o)#                 list of objects
+CC_LIB    = lib$(LIBRARY).a#              C library file
+CC_PROG_LIB= $(PROG_LIB_DIR)/lib$(PROG_LIB).a# library for prog objs
+LINT_LIST = $(PROG_OBJ:.o=.ln)
+LINT_LIST_EXE = $(LINT_LIST:.ln=.)#       list of executable names to lint
+LINT_LIB  = llib-l$(LIBRARY).ln#          lint library file
+LINT_PROG_LIB = $(PROG_LIB_DIR)/llib-l$(PROG_LIB).ln#
+
+# --------------------------------------------------------------------
+
+.SUFFIXES: .ln#                           tell make to watch for .ln's
+
+default: $(PROGS)
+
+#Dependency on Makefile
+$(PROG_OBJ) $(LINT_OBJS) : Makefile
+
+all: $(PROGS) lint
+
+.c.ln:#                                   defines the rule for creating .ln
+	lint $(LINTFLAGS) -c $< -o $@
+
+.c.o:#                                    defines the rule for creating .o
+	$(CC) $(CFLAGS) -c $< -o $@
+
+#Dependency of .o and .ln on .h
+$(PROG_OBJ) : $(HEADERS)
+
+$(LINT_LIST) : $(HEADERS)
+
+# How to make executables
+$(PROGS) : $$@.o $(CC_PROG_LIB) $(LIB_DIR)/$(CC_LIB)
+	$(CC) $@.o -o $@ $(CC_PROG_LIB) -L$(LIB_DIR) -l$(LIBRARY) $(LDOPT)
+
+#  how to lint the executable source
+lint: $(LINT_LIST_EXE)
+
+$(LINT_LIST_EXE) : $$@ln $(LINT_PROG_LIB) $(LIB_DIR)/$(LINT_LIB)
+	lint -u $(LINTFLAGS) $@ln $(LINT_PROG_LIB) $(LIB_DIR)/$(LINT_LIB)
+
+# Remove all derived files in this directory
+clean:
+	$(RM) $(RM_FLAGS) $(LINT_LIST) $(PROGS) $(PROG_OBJ)
+
new file mode 100644
--- /dev/null
+++ b/progs/rawtominc/rawtominc.c
@@ -0,0 +1,413 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : rawtominc
+@INPUT      : argc, argv - command line arguments
+@OUTPUT     : (none)
+@RETURNS    : error status
+@DESCRIPTION: Converts a raw volume of data values (read from standard input)
+              to a minc format file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : September 25, 1992 (Peter Neelin)
+@MODIFIED   : December 2, 1992 (P.N.)
+                 - changed to parse argv with ParseArgv
+---------------------------------------------------------------------------- */
+
+#ifndef lint
+static char rcsid[]="$Header: /private-cvsroot/minc/progs/rawtominc/rawtominc.c,v 1.1 1993-01-08 09:45:04 neelin Exp $";
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <minc.h>
+#include <float.h>
+#include <ParseArgv.h>
+
+/* Some constants */
+
+#define NORMAL_STATUS 0
+#define ERROR_STATUS 1
+#define MIN_DIMS 2
+#define MAX_DIMS 4
+#define TRANSVERSE 0
+#define SAGITTAL 1
+#define CORONAL 2
+#define TIME_FAST 3
+#define DEF_TYPE 0
+#define DEF_SIGN 0
+#define SIGNED 1
+#define UNSIGNED 2
+#define TRUE 1
+#define FALSE 0
+
+/* Macros */
+#define STR_EQ(s1,s2) (strcmp(s1,s2)==0)
+
+/* Function declarations */
+void parse_args(int argc, char *argv[]);
+void usage_error(char *pname);
+
+/* Structure containing information about orientation */
+char *orientation_names[][MAX_DIMS] = {
+   {MItime, MIzspace, MIyspace, MIxspace},
+   {MItime, MIxspace, MIzspace, MIyspace},
+   {MItime, MIyspace, MIzspace, MIxspace},
+   {MIzspace, MItime, MIyspace, MIxspace}
+};
+
+/* Structure containing information about signs */
+char *sign_names[][6] = {
+   {MI_SIGNED, MI_UNSIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED},
+   {MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED, MI_SIGNED},
+   {MI_SIGNED, MI_UNSIGNED, MI_UNSIGNED, MI_UNSIGNED, MI_UNSIGNED, MI_UNSIGNED}
+};
+
+/* Argument variables */
+char *pname;
+char *filename;
+int clobber=TRUE;
+char *dimname[MAX_VAR_DIMS];
+long dimlength[MAX_VAR_DIMS];
+int ndims;
+int orientation = TRANSVERSE;
+nc_type type = NC_BYTE;
+int signtype = DEF_SIGN;
+char *sign;
+double valid_range[2] = {0.0, -1.0};
+int vrange_set;
+nc_type otype = DEF_TYPE;
+int osigntype = DEF_SIGN;
+char *osign;
+double ovalid_range[2] = {0.0, -1.0};
+int ovrange_set;
+
+/* Argument table */
+ArgvInfo argTable[] = {
+   {NULL, ARGV_HELP, (char *) NULL, (char *) NULL, 
+       "Options to specify input dimension order (from slowest to fastest)."},
+   {NULL, ARGV_HELP, (char *) NULL, (char *) NULL, 
+       "   Default = -transverse."},
+   {"-transverse", ARGV_CONSTANT, (char *) TRANSVERSE, (char *) &orientation,
+       "Transverse images   : [[time] z] y x"},
+   {"-sagittal", ARGV_CONSTANT, (char *) SAGITTAL, (char *) &orientation,
+       "Sagittal images     : [[time] x] z y"},
+   {"-coronal", ARGV_CONSTANT, (char *) CORONAL, (char *) &orientation,
+       "Coronal images      : [[time] y] z x"},
+   {"-time", ARGV_CONSTANT, (char *) TIME_FAST, (char *) &orientation,
+       "Time ordered images : [[z] time] y x"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options to specify input data type. Default = -byte."},
+   {"-byte", ARGV_CONSTANT, (char *) NC_BYTE, (char *) &type,
+       "Byte values"},
+   {"-short", ARGV_CONSTANT, (char *) NC_SHORT, (char *) &type,
+       "Short integer values"},
+   {"-long", ARGV_CONSTANT, (char *) NC_LONG, (char *) &type,
+       "Long integer values"},
+   {"-float", ARGV_CONSTANT, (char *) NC_FLOAT, (char *) &type,
+       "Single-precision floating point values"},
+   {"-double", ARGV_CONSTANT, (char *) NC_DOUBLE, (char *) &type,
+       "Double-precision floating point values"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options for sign of input data. Default = -signed (-unsigned for byte)."},
+   {"-signed", ARGV_CONSTANT, (char *) SIGNED, (char *) &signtype,
+       "Signed values"},
+   {"-unsigned", ARGV_CONSTANT, (char *) UNSIGNED, (char *) &signtype,
+       "Unsigned values"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Other input value options."},
+   {"-range", ARGV_FLOAT, (char *) 2, (char *) valid_range, 
+       "Valid range of input values (default = full range)."},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options for type of output minc data. Default = input data type"},
+   {"-obyte", ARGV_CONSTANT, (char *) NC_BYTE, (char *) &otype,
+       "Byte values"},
+   {"-oshort", ARGV_CONSTANT, (char *) NC_SHORT, (char *) &otype,
+       "Short integer values"},
+   {"-olong", ARGV_CONSTANT, (char *) NC_LONG, (char *) &otype,
+       "Long integer values"},
+   {"-ofloat", ARGV_CONSTANT, (char *) NC_FLOAT, (char *) &otype,
+       "Single-precision floating point values"},
+   {"-odouble", ARGV_CONSTANT, (char *) NC_DOUBLE, (char *) &otype,
+       "Double precision floating point values"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options for sign of output minc data."},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "   Default = -signed (-unsigned for byte data)"},
+   {"-osigned", ARGV_CONSTANT, (char *) SIGNED, (char *) &osigntype,
+       "Signed values"},
+   {"-ounsigned", ARGV_CONSTANT, (char *) UNSIGNED, (char *) &osigntype,
+       "Unsigned values"},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Other output value options."},
+   {"-orange", ARGV_FLOAT, (char *) 2, (char *) ovalid_range, 
+       "Valid range of output minc values."},
+   {NULL, ARGV_HELP, NULL, NULL,
+       "Options for writing output file. Default = -clobber."},
+   {"-clobber", ARGV_CONSTANT, (char *) TRUE, (char *) &clobber,
+       "Overwrite existing file"},
+   {"-noclobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber,
+       "Don't overwrite existing file"},
+   {NULL, ARGV_END, NULL, NULL, NULL}
+};
+
+/* Main program */
+
+main(int argc, char *argv[])
+{
+   int do_norm, do_vrange;
+   int cdfid, imgid, maxid, minid;
+   int icv;
+   long start[MAX_VAR_DIMS];
+   long count[MAX_VAR_DIMS];
+   long end[MAX_VAR_DIMS];
+   int dim[MAX_VAR_DIMS];
+   void *image;
+   double *dimage;
+   float *fimage;
+   double imgmax, imgmin, value;
+   long image_size, image_pix, nread, fastdim;
+   int pix_size;
+   int i, j;
+   FILE *instream;
+
+   /* Parse arguments */
+   parse_args(argc, argv);
+
+   /* Do normalization if input type is float */
+   do_norm = (( type==NC_FLOAT) || ( type==NC_DOUBLE));
+
+   /* Find max and min for vrange if output type is float */
+   do_vrange = do_norm && (( otype==NC_FLOAT) || ( otype==NC_DOUBLE));
+   
+   /* Create an icv */
+   icv=miicv_create();
+   (void) miicv_setint(icv, MI_ICV_TYPE, type);
+   (void) miicv_set(icv, MI_ICV_SIGN, sign);
+   if (vrange_set) {
+      (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, valid_range[0]);
+      (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, valid_range[1]);
+   }
+   if (do_norm) {
+      (void) miicv_setint(icv, MI_ICV_DO_NORM, TRUE);
+      (void) miicv_setint(icv, MI_ICV_USER_NORM, TRUE);
+   }
+
+   /* Create the file */
+   cdfid=nccreate(filename, (clobber ? NC_CLOBBER : NC_NOCLOBBER));
+
+   /* Create the dimensions */
+   for (i=0; i<ndims; i++) {
+      dim[i] = ncdimdef(cdfid, dimname[i], dimlength[i]);
+      (void) micreate_std_variable(cdfid, dimname[i], 
+                                   NC_LONG, 0, NULL);
+      start[i]=0;
+      count[i]= ((i<ndims-2) ? 1 : dimlength[i]);
+      end[i]=dimlength[i];
+   }
+
+   /* Create the image */
+   imgid=micreate_std_variable(cdfid, MIimage, otype, ndims, dim);
+   (void) miattputstr(cdfid, imgid, MIsigntype, osign);
+   if (ovrange_set) 
+      (void) ncattput(cdfid, imgid, MIvalid_range, NC_DOUBLE, 2, ovalid_range);
+   if (do_norm) {
+      maxid = micreate_std_variable(cdfid, MIimagemax, 
+                                    NC_DOUBLE, ndims-2, dim);
+      minid = micreate_std_variable(cdfid, MIimagemin, 
+                                    NC_DOUBLE, ndims-2, dim);
+   }
+
+   /* End definition mode */
+   (void) ncendef(cdfid);
+
+   /* Attach the icv */
+   (void) miicv_attach(icv, cdfid, imgid);
+
+   /* Get a buffer for reading images */
+   image_pix=dimlength[ndims-1]*dimlength[ndims-2];
+   pix_size=nctypelen(type);
+   image_size=image_pix*pix_size;
+   image=malloc(image_size);
+
+   /* Loop through the images */
+   instream=stdin;
+   fastdim=ndims-2-1;
+   if (fastdim<0) fastdim=0;
+   if (do_vrange) {
+      ovalid_range[0]=DBL_MAX;
+      ovalid_range[1]=(-DBL_MAX);
+   }
+   fimage = image; dimage = image;
+
+   while (start[0] < end[0]) {
+
+      /* Read in image */
+      nread=fread(image, pix_size, image_pix, instream);
+      if (nread!=image_pix) {
+         (void) fprintf(stderr, "%s: Premature end of file.\n", pname);
+         exit(ERROR_STATUS);
+      }
+ 
+      /* Search for max and min for float and double */
+      if (do_norm) {
+         imgmax=(-DBL_MAX);
+         imgmin=DBL_MAX;
+         for (j=0; j<image_pix; j++) {
+            switch (type) {
+            case NC_DOUBLE:
+               value=dimage[j]; break;
+            case NC_FLOAT:
+               value=fimage[j]; break;
+            }
+            if (value<imgmin) imgmin=value;
+            if (value>imgmax) imgmax=value;
+         }
+         if (do_vrange) {
+            if (imgmin<ovalid_range[0]) ovalid_range[0]=imgmin;
+            if (imgmax>ovalid_range[1]) ovalid_range[1]=imgmax;
+         }
+
+         /* Write the image max and min */
+         (void) mivarput1(cdfid, minid, start, NC_DOUBLE, NULL, &imgmin);
+         (void) mivarput1(cdfid, maxid, start, NC_DOUBLE, NULL, &imgmax);
+      }
+
+      /* Write the image */
+      (void) miicv_put(icv, start, count, image);
+
+     /* Increment the counters */
+      start[fastdim] += count[fastdim];
+      i=fastdim;
+      while ((i>0) && (start[i]>=end[i])) {
+         start[i] = 0;
+         i--;
+         start[i] += count[i];
+      }
+   }
+
+   /* Free the memory */
+   free(image);
+
+   /* Write the valid max and min */
+   if (do_vrange) {
+      (void) ncattput(cdfid, imgid, MIvalid_range, NC_DOUBLE, 2, ovalid_range);
+   }
+
+   /* Close the file */
+   (void) ncclose(cdfid);
+   
+   return NORMAL_STATUS;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : parse_args
+@INPUT      : argc        - number of command line arguments
+              argv        - array of arguments
+@OUTPUT     : 
+@RETURNS    : (nothing).
+@DESCRIPTION: Parses command line arguments.
+@METHOD     : 
+@GLOBALS    : pname        - program name
+              filename     - file to write
+              clobber      - overwrite?
+              dimname      - names of dimensions
+              dimlength    - lengths of dimensions
+              ndims        - number of dimensions
+              orientation  - orientation of dimensions
+              type         - type of input data
+              signtype     - sign of input data
+              sign         - string sign of input
+              valid_range  - valid range of input data
+              vrange_set   - valid range used?
+              otype        - type of output data
+              osigntype    - sign of output data
+              osign        - string sign of output
+              ovalid_range - valid range of output data
+              ovrange_set  - valid range used?
+@CALLS      : 
+@CREATED    : December 3, 1992
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void parse_args(int argc, char *argv[])
+{
+   char *ptr;
+   int i;
+
+   /* Parse the command line */
+   pname=argv[0];
+   if (ParseArgv(&argc, argv, argTable, 0)) {
+      usage_error(pname);
+   }
+
+   /* Check dimensions */
+   ndims = argc - 2;
+   if ((ndims<MIN_DIMS)||(ndims>MAX_DIMS)) {
+      usage_error(pname);
+   }
+
+   /* Get filename */
+   filename = argv[1];
+
+   /* Get dimensions */
+   for (i=0; i<ndims; i++) {
+      dimlength[i] = strtol(argv[2+i], &ptr, 0);
+      if ((ptr==argv[2+i]) || (*ptr!=0)) {
+         usage_error(pname);
+      }
+      dimname[i]=orientation_names[orientation][i+MAX_DIMS-ndims];
+   }
+
+   /* Set types and signs */
+   if ((otype==DEF_TYPE) && (osigntype==DEF_TYPE))
+      osigntype=signtype;
+   if (otype==DEF_TYPE) otype=type;
+   sign  = sign_names[signtype][type];
+   osign = sign_names[osigntype][otype];
+
+   /* Check valid ranges */
+   vrange_set=(valid_range[0]<valid_range[1]);
+   ovrange_set=(ovalid_range[0]<ovalid_range[1]);
+   if ((otype==type) && (STR_EQ(osign,sign))) {
+      if (!ovrange_set && vrange_set) {
+         ovalid_range[0]=valid_range[0];
+         ovalid_range[1]=valid_range[1];
+         ovrange_set = TRUE;
+      }
+      if (ovrange_set && !vrange_set) {
+         valid_range[0]=ovalid_range[0];
+         valid_range[1]=ovalid_range[1];
+         vrange_set = TRUE;
+      }
+   }
+
+   /* Always write valid range for floating point values */
+   if ((otype==NC_FLOAT) || (otype==NC_DOUBLE)) {
+      ovalid_range[0]=0.0;
+      ovalid_range[1]=1.0;
+      ovrange_set=TRUE;
+   }
+
+   return;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : usage_error
+@INPUT      : progname - program name
+@OUTPUT     : (none)
+@RETURNS    : (nothing)
+@DESCRIPTION: Prints a usage error message and exits.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : September 25, 1992 (Peter Neelin)
+@MODIFIED   : December 2, 1992 (P.N.)
+---------------------------------------------------------------------------- */
+void usage_error(char *progname)
+{
+   (void) fprintf(stderr, "\nUsage: %s [<options>] <filename> ", progname);
+   (void) fprintf(stderr, "[[<size4>] <size3>] <size2> <size1>\n");
+   (void) fprintf(stderr,   "       %s [-help]\n\n", progname);
+
+   exit(ERROR_STATUS);
+}