changeset 1608:5371eb279b97

*** empty log message ***
author baghdadi <baghdadi>
date Wed, 24 Dec 2003 00:12:02 +0000
parents 73023a1ee6cb
children 46be815d62b7
files libsrc2/datatype.c libsrc2/dimension.c libsrc2/minc2.h libsrc2/minc2_private.h libsrc2/slice.c libsrc2/volprops.c libsrc2/volume.c
diffstat 7 files changed, 644 insertions(+), 385 deletions(-) [+]
line wrap: on
line diff
--- a/libsrc2/datatype.c
+++ b/libsrc2/datatype.c
@@ -74,7 +74,7 @@
 	/* TODO: handle this case for uniform records (arrays)? */
 	break;
     case H5T_COMPOUND:
-	/* TODO: handle this case for non-unform records? */
+	/* TODO: handle this case for non-uniform records? */
 	break;
     default:
 	result = MI_ERROR;
--- a/libsrc2/dimension.c
+++ b/libsrc2/dimension.c
@@ -37,8 +37,9 @@
 int 
 micopy_dimension(midimhandle_t dim_ptr, midimhandle_t *new_dim_ptr)
 {
+  int i;
   dimension *handle;
-  int i;
+  
   if (dim_ptr == NULL) {
     return (MI_ERROR);
   }
@@ -46,14 +47,16 @@
   /* Allocate storage for the structure
    */
   handle = (dimension *)malloc(sizeof(*handle));
-
+  if (handle == NULL) {
+    return (MI_ERROR);
+  }
   handle->attr = dim_ptr->attr;
   handle->class = dim_ptr->class;
-  if (handle->class == MI_DIMCLASS_SPATIAL) {
-    handle->cosines[0] = dim_ptr->cosines[0];
-    handle->cosines[1] = dim_ptr->cosines[1];
-    handle->cosines[2] = dim_ptr->cosines[2];
-  }
+  /* Copy direction cosines */
+  handle->direction_cosines[MI2_X] = dim_ptr->direction_cosines[0];
+  handle->direction_cosines[MI2_Y] = dim_ptr->direction_cosines[1];
+  handle->direction_cosines[MI2_Z] = dim_ptr->direction_cosines[2];
+ 
   switch (dim_ptr->flipping_order) {
   case MI_FILE_ORDER:
     handle->flipping_order = MI_FILE_ORDER;
@@ -64,14 +67,15 @@
   default:
     return (MI_ERROR);
   }
-  /* Explicitly allocate storage for name
-   */
-  handle->name =malloc(strlen(dim_ptr->name) + 1);
-  strcpy(handle->name, dim_ptr->name);
-  handle->size = dim_ptr->size;
+  
+  handle->name =strdup(dim_ptr->name);
+  handle->length = dim_ptr->length;
   if (dim_ptr->offsets != NULL) {
-    handle->offsets = (double *) malloc(dim_ptr->size*sizeof(double));
-    for (i=0; i < dim_ptr->size; i++) {
+    handle->offsets = (double *) malloc(dim_ptr->length*sizeof(double));
+    if (handle->offsets == NULL) {
+      return (MI_ERROR);
+    }
+    for (i=0; i < dim_ptr->length; i++) {
       handle->offsets[i] = dim_ptr->offsets[i];
     }
   }
@@ -80,20 +84,20 @@
   }
   handle->start = dim_ptr->start;
   handle->sampling_flag = dim_ptr->sampling_flag;
-  handle->separation = dim_ptr->separation;
+  handle->step = dim_ptr->step;
   if (dim_ptr->units != NULL) {
-    /* Explicitly allocate storage for units
-     */
-    handle->units =malloc(strlen(dim_ptr->units) + 1);
-    strcpy(handle->units, dim_ptr->units);
+    handle->units = strdup(dim_ptr->units);
   }
   else {
     handle->units = NULL;
   }
   handle->width = dim_ptr->width;
   if (dim_ptr->widths != NULL) {
-    handle->widths = (double *) malloc(dim_ptr->size*sizeof(double));
-    for (i=0; i < dim_ptr->size; i++) {
+    handle->widths = (double *) malloc(dim_ptr->length*sizeof(double));
+    if (handle->widths == NULL) {
+      return (MI_ERROR);
+    }
+    for (i=0; i < dim_ptr->length; i++) {
       handle->widths[i] = dim_ptr->widths[i];
     }
   }
@@ -112,55 +116,54 @@
 
 int 
 micreate_dimension(const char *name, midimclass_t class, midimattr_t attr, 
-		   unsigned long size, midimhandle_t *new_dim_ptr)
+		   unsigned long length, midimhandle_t *new_dim_ptr)
 {  
   
   dimension *handle;
- 
-  
-  /* Allocate space for the dimension
+  int i;
+  /* Allocate space for the new dimension
    */
   handle = (dimension *)malloc(sizeof(*handle));
-
   if (handle == NULL) {
     return (MI_ERROR);
   }
-
-  /* Explicitly allocate storage for name
-   */
+  /* Figure out whether the length of the name is valid
+     before allocating
+  */
   if (strlen(name) < MI2_CHAR_LENGTH) {
-    handle->name = malloc(strlen(name) + 1);
+    handle->name = strdup(name);
   }
   else {
     handle->name = malloc(MI2_CHAR_LENGTH);
+    /* copy (MI2_CHAR_LENGTH - 1) chars to handle->name */
+    strncpy(handle->name, name, MI2_CHAR_LENGTH - 1);
   }
-  strncpy(handle->name, name, MI2_CHAR_LENGTH - 1);
-  
+
   switch (class) {
   case MI_DIMCLASS_ANY:
     handle->class  = MI_DIMCLASS_ANY;
     break;
   case MI_DIMCLASS_SPATIAL:
     handle->class  = MI_DIMCLASS_SPATIAL;
-    if (name == "xspace") {
-      handle->cosines[MI2_X] = 1.0;
-      handle->cosines[MI2_Y] = 0.0;
-      handle->cosines[MI2_Z] = 0.0;
+    if (strcmp(name, "xspace") == 0) {
+      handle->direction_cosines[MI2_X] = 1.0;
+      handle->direction_cosines[MI2_Y] = 0.0;
+      handle->direction_cosines[MI2_Z] = 0.0;
     }
-    else if (name == "yspace") {
-      handle->cosines[MI2_X] = 0.0;
-      handle->cosines[MI2_Y] = 1.0;
-      handle->cosines[MI2_Z] = 0.0;
+    else if (strcmp(name, "yspace") == 0) {
+      handle->direction_cosines[MI2_X] = 0.0;
+      handle->direction_cosines[MI2_Y] = 1.0;
+      handle->direction_cosines[MI2_Z] = 0.0;
     }
-    else if (name == "zspace") {
-      handle->cosines[MI2_X] = 0.0;
-      handle->cosines[MI2_Y] = 0.0;
-      handle->cosines[MI2_Z] = 1.0;
+    else if (strcmp(name, "zspace") == 0) {
+      handle->direction_cosines[MI2_X] = 0.0;
+      handle->direction_cosines[MI2_Y] = 0.0;
+      handle->direction_cosines[MI2_Z] = 1.0;
     }
     else {
-      handle->cosines[MI2_X] = 1.0;
-      handle->cosines[MI2_Y] = 0.0;
-      handle->cosines[MI2_Z] = 0.0;
+      handle->direction_cosines[MI2_X] = 1.0;
+      handle->direction_cosines[MI2_Y] = 0.0;
+      handle->direction_cosines[MI2_Z] = 0.0;
     }
     break;
   case MI_DIMCLASS_TIME:
@@ -168,25 +171,25 @@
     break;
   case MI_DIMCLASS_SFREQUENCY:
     handle->class  = MI_DIMCLASS_SFREQUENCY;
-    if (name == "xfrequency") {
-      handle->cosines[MI2_X] = 1.0;
-      handle->cosines[MI2_Y] = 0.0;
-      handle->cosines[MI2_Z] = 0.0;
+    if (strcmp(name, "xfrequency") == 0) {
+      handle->direction_cosines[MI2_X] = 1.0;
+      handle->direction_cosines[MI2_Y] = 0.0;
+      handle->direction_cosines[MI2_Z] = 0.0;
     }
-    else if (name == "yfrequency") {
-      handle->cosines[MI2_X] = 0.0;
-      handle->cosines[MI2_Y] = 1.0;
-      handle->cosines[MI2_Z] = 0.0;
+    else if (strcmp(name, "yfrequency") == 0) {
+      handle->direction_cosines[MI2_X] = 0.0;
+      handle->direction_cosines[MI2_Y] = 1.0;
+      handle->direction_cosines[MI2_Z] = 0.0;
     }
-    else if (name == "zfrequency") {
-      handle->cosines[MI2_X] = 0.0;
-      handle->cosines[MI2_Y] = 0.0;
-      handle->cosines[MI2_Z] = 1.0;
+    else if (strcmp(name, "zfrequency") == 0) {
+      handle->direction_cosines[MI2_X] = 0.0;
+      handle->direction_cosines[MI2_Y] = 0.0;
+      handle->direction_cosines[MI2_Z] = 1.0;
     }
     else {
-      handle->cosines[MI2_X] = 1.0;
-      handle->cosines[MI2_Y] = 0.0;
-      handle->cosines[MI2_Z] = 0.0;
+      handle->direction_cosines[MI2_X] = 1.0;
+      handle->direction_cosines[MI2_Y] = 0.0;
+      handle->direction_cosines[MI2_Z] = 0.0;
     }
     break;
   case MI_DIMCLASS_TFREQUENCY:
@@ -201,32 +204,43 @@
   default:
     return (MI_ERROR);
   }
-  
+  /* "attr" can only be one of the following ,   
+     MI_DIMATTR_ALL is not valid for this function
+   */
   switch (attr) {
   case MI_DIMATTR_REGULARLY_SAMPLED:
     handle->attr = MI_DIMATTR_REGULARLY_SAMPLED;
     handle->sampling_flag = 1;
+    handle->offsets = NULL;
+    handle->widths = NULL;
     break;
   case MI_DIMATTR_NOT_REGULARLY_SAMPLED:
     handle->attr = MI_DIMATTR_NOT_REGULARLY_SAMPLED;
     handle->sampling_flag = 0;
+    handle->offsets = (double *) malloc(length *sizeof(double));
+    handle->widths = (double *) malloc(length *sizeof(double));
+    for (i=0; i< length; i++) {
+      handle->offsets[i] = 0;
+      handle->widths[i] = 1.0;
+    }
     break;
   default:
     return (MI_ERROR);
   }
   handle->start = 0.0;
-  handle->separation = 1.0;
+  handle->step = 1.0;
   handle->width = 1.0;
+
   handle->flipping_order = MI_FILE_ORDER;
   if (class != MI_DIMCLASS_SPATIAL && class != MI_DIMCLASS_SFREQUENCY ) {
-    handle->cosines[MI2_X] = 1.0;
-    handle->cosines[MI2_Y] = 0.0;
-    handle->cosines[MI2_Z] = 0.0;
+    handle->direction_cosines[MI2_X] = 1.0;
+    handle->direction_cosines[MI2_Y] = 0.0;
+    handle->direction_cosines[MI2_Z] = 0.0;
   }
-  handle->size = size;
-  handle->offsets = NULL;
-  handle->widths = NULL;
+  handle->length = length;
   handle->units = strdup("mm");
+  /* volume_handle is the only NULL value once the dimension is created.
+   */
   handle->volume_handle = NULL;
 
   *new_dim_ptr = handle;
@@ -237,18 +251,16 @@
 
 /*! Delete the dimension definition.
     Note: The original document stated that a dimension has to be
-    associated with a given volume before it can be deleted.
+    associated with a given volume before it can be deleted. This
+    feature was erased from the document and not considered here.
  */
 int 
 mifree_dimension_handle(midimhandle_t dim_ptr)
 {
-  // WHAT HAPPENS WITH HDF5 STUFF THAT WAS 
-  // CREATED BY CALLING micreate_dimension(..)
-
+  
   if (dim_ptr == NULL) {
     return (MI_ERROR);
   }
-  
   free(dim_ptr->name);
   if (dim_ptr->offsets != NULL) {
     free(dim_ptr->offsets);
@@ -263,7 +275,7 @@
 }
 
 /*! Retrieve the list of dimensions defined in a MINC volume, 
-    according to their class and attribute.
+    with the same class and attribute as given.
  */
 
 int 
@@ -271,44 +283,50 @@
 			miorder_t order, int array_length, 
 			midimhandle_t dimensions[])
 {
-
-  //LEFT THE DIMENSION ORDERING "miorder_t order"
-
+  // THE PARAMETER "miorder_t order" WAS NOT CONSIDERED WHEW WRITING
+  // THIS FUNCTION. MUST FIGURE OUT WHAT TO DO WITH IT
+  dimension *handle;
   
-  dimension *handle;
-  hid_t hdf_file;	
+  hid_t hdf_file, hdf_type;	
   hid_t hdf_dims_grp;
   hid_t dataset, attribute;
   hsize_t number_of_dims; 
   herr_t status;
-  int i, max_dims;
   char *name;
   ssize_t size_of_obj;
   midimclass_t dim_class;
   midimattr_t  dim_attr;
- 
+  double *direction_cosines;
+  
+  int i=0, j=0, max_dims;
+  
   if (volume == NULL) {
     return (MI_ERROR);
   }
  
   /* Get a handle to the actual HDF file 
-     */
+   */
   hdf_file = volume->hdf_id;  
   if (hdf_file < 0) {
     return (MI_ERROR);
   }
-  /* Try opening the DIMENSIONS GROUP
-     */
+
+  /* Try opening the DIMENSIONS GROUP /minc-2.0/dimensions
+   */
   hdf_dims_grp = H5Gopen(hdf_file, MI_FULLDIMENSIONS_PATH);
   if (hdf_dims_grp < 0 ) {
     return (MI_ERROR);
   }
-  /* How many objects are part of this dimensions group.
-     */
+  
+  /* How many dimensions (i.e., objects) are part of this dimensions group.
+   */
   status = H5Gget_num_objs(hdf_dims_grp, &number_of_dims);
   if (status < 0) {
     return (MI_ERROR);
   }
+  
+  /* Figure out if the array_length provided is legal.
+   */
   if (array_length > number_of_dims) {
     max_dims = number_of_dims;
   }
@@ -316,56 +334,213 @@
     max_dims = array_length;
   }
   
-  for (i=0; i<= max_dims; i++) {
+  /* Go through each dimension separately and figure out
+     which one has a matching class and attirbute.
+   */
+  for (i=0; i< max_dims; i++) {
+    /* Get the name of the dimension by providing its index
+       to the following function.
+     */
+    //PROBLEM FOUND WITH HDF H5Gget_objname_by_idx
+    // DOES NOT RETURN THE CORRECT SIZE OF THE OBJECT when name
+    // is set to NULL according to the documentation
+    // DOES NOT ALLOCATE SPACE FOR NAME
+    // LEFT malloc with MAX CHAR LENGTH until the problem is fixed
+    // EMAILED  Quincey Koziol DEC 22 /2003
+    name = malloc(MI2_CHAR_LENGTH);
     size_of_obj = H5Gget_objname_by_idx(hdf_dims_grp, i, name, MI2_CHAR_LENGTH);
-    if (size_of_obj < 0) {
+    
+    if (size_of_obj < 0 || name == NULL) {
       return (MI_ERROR);
     }
-    /* Open the dataset.
-       */
+    
+    /* Open the dataset /minc-2.0/dimensions/"name"
+     */
     dataset = H5Dopen(hdf_dims_grp, name);
     if (dataset < 0) {
       return (MI_ERROR);
     }
+    
     /* Attach to class attribute using its name
-       */
+     */
     attribute = H5Aopen_name(dataset, "class");
     if (attribute < 0) {
       return (MI_ERROR);
     }
-    status = H5Aread(attribute, H5T_NATIVE_UCHAR, &dim_class);
+    status = H5Aread(attribute, H5T_NATIVE_INT, &dim_class);
     if (status < 0) {
       return (MI_ERROR);
     }
-    if (dim_class == class) {
+
+    if(dim_class == class) {
+      
+      /* Attach to attr attribute using its name
+       */
       attribute = H5Aopen_name(dataset, "attr");
       if (attribute < 0) {
       return (MI_ERROR);
       }
-      status = H5Aread(attribute, H5T_NATIVE_UINT, &dim_attr);
+      status = H5Aread(attribute, H5T_NATIVE_INT, &dim_attr);
       if (status < 0) {
       return (MI_ERROR);
       }
+      
       if (dim_attr == attr || attr ==  MI_DIMATTR_ALL) {
-	handle = (dimension *)malloc(sizeof(*handle));
-	/* Explicitly allocate storage for name
-	 */
+	handle =  (dimension *)malloc(sizeof(*handle));
+	if (handle == NULL) {
+	  return (MI_ERROR);
+	}
+
+	handle->attr = dim_attr;
+	handle->class = dim_class;
+
+	/* Attach to direction_cosines attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "direction_cosines");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	direction_cosines = (double *) malloc(3 *sizeof(double));
+	status = H5Aread(attribute, H5T_NATIVE_DOUBLE, direction_cosines);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+	handle->direction_cosines[MI2_X] = direction_cosines[0];
+	handle->direction_cosines[MI2_Y] = direction_cosines[1];
+	handle->direction_cosines[MI2_Z] = direction_cosines[2];
+
+	/* Attach to flipping_order attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "flipping_order");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	status = H5Aread(attribute, H5T_NATIVE_INT, &handle->flipping_order);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+
 	if (strlen(name) < MI2_CHAR_LENGTH) {
-	  handle->name = malloc(strlen(name) + 1);
+	  handle->name = strdup(name);
 	} 
 	else {
-	  handle->name = malloc( MI2_CHAR_LENGTH );
+	  handle->name = malloc(MI2_CHAR_LENGTH);
+	  strncpy(handle->name, name, MI2_CHAR_LENGTH - 1);
+	}
+
+	/* Attach to length attribute using its name
+	 */
+	attribute = H5Aopen_name(dataset, "length");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	status = H5Aread(attribute, H5T_NATIVE_ULONG, &handle->length);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+	
+	if ( dim_attr == MI_DIMATTR_NOT_REGULARLY_SAMPLED) {
+	  /* Attach to offsets attribute using its name
+	     ONLY IF an IRREGULAR SAMPLE is specified.
+           */
+	  attribute = H5Aopen_name(dataset, "offsets");
+	  if (attribute < 0) {
+	    return (MI_ERROR);
+	  }
+	
+	  handle->offsets = (double *) malloc(handle->length *sizeof(double));
+	  status = H5Aread(attribute, H5T_NATIVE_DOUBLE, handle->offsets);
+	  if (status < 0) {
+	    return (MI_ERROR);
+	  }
+	  printf( " OFFSETS %f %f %f \n", handle->offsets[0], handle->offsets[1], handle->offsets[2]);
+	  /* Attach to widths attribute using its name
+	     ONLY IF an IRREGULAR SAMPLE is specified.
+           */
+	  attribute = H5Aopen_name(dataset, "widths");
+	  if (attribute < 0) {
+	    return (MI_ERROR);
+	  }
+	
+	  handle->widths = (double *) malloc(handle->length *sizeof(double));
+	  status = H5Aread(attribute, H5T_NATIVE_DOUBLE, handle->widths);
+	  if (status < 0) {
+	    return (MI_ERROR);
+	  }
+	  printf( " WIDTHS %f %f %f \n", handle->widths[0], handle->widths[1], handle->widths[2]);
+	}
+
+	/* Attach to sampling_flag attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "sampling_flag");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	status = H5Aread(attribute, H5T_NATIVE_INT, &handle->sampling_flag);
+	if (status < 0) {
+	  return (MI_ERROR);
 	}
-	strcpy(handle->name, name);
-	handle->class = dim_class;
-	handle->attr = dim_attr;
-	//FIND OUT WHETHER YOU NEED TO FILL THE REST OF THE FIELDS.
-	dimensions[i] = (dimension *)malloc(sizeof(*dimensions));
-	dimensions[i] = handle;
+
+	/* Attach to step attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "step");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	status = H5Aread(attribute, H5T_NATIVE_DOUBLE, &handle->step);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+	
+	/* Attach to start attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "start");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	status = H5Aread(attribute, H5T_NATIVE_DOUBLE, &handle->start);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+	
+	/* Attach to width attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "width");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	status = H5Aread(attribute, H5T_NATIVE_DOUBLE, &handle->width);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+
+	/* Attach to units attribute using its name
+         */
+	attribute = H5Aopen_name(dataset, "units");
+	if (attribute < 0) {
+	  return (MI_ERROR);
+	}
+	hdf_type = H5Tcopy(H5T_C_S1);
+	           H5Tset_size(hdf_type, MI2_CHAR_LENGTH);
+	handle->units = malloc(MI2_CHAR_LENGTH);
+	status = H5Aread(attribute, hdf_type, handle->units);
+	if (status < 0) {
+	  return (MI_ERROR);
+	}
+	printf(" UNITS IS %s \n", handle->units);
+
+	/* Set volume_handle (the volume each dimension
+	   is associated with). This is the only attribute of
+	   each dimension which is actually independent of HDF5  
+	 */
+	handle->volume_handle = volume;
+
+	dimensions[j] = handle;
+	j++;
       }
-    } // end of if 
+    } 
   }
-  //i = miicv_create();
+  
   return (MI_NOERROR);
 
   }
@@ -506,7 +681,7 @@
   switch (dimension->flipping_order) {
   case MI_FILE_ORDER:
     *file_order = MI_FILE_ORDER;
-    if (dimension->separation > 0) {
+    if (dimension->step > 0) {
       *sign = MI_POSITIVE;
     }
     else {
@@ -515,7 +690,7 @@
     break;
   case MI_COUNTER_FILE_ORDER:
     *file_order = MI_COUNTER_FILE_ORDER;
-    if (dimension->separation > 0) {
+    if (dimension->step > 0) {
       *sign = MI_NEGATIVE;
     }
     else {
@@ -524,7 +699,7 @@
     break;
   case MI_POSITIVE:
     *sign = MI_POSITIVE;
-    if (dimension->separation > 0) {
+    if (dimension->step > 0) {
       *file_order = MI_FILE_ORDER;
     }
     else {
@@ -533,7 +708,7 @@
     break;  
   case MI_NEGATIVE:
     *sign = MI_NEGATIVE;
-    if (dimension->separation > 0) {
+    if (dimension->step > 0) {
       *file_order = MI_COUNTER_FILE_ORDER;
     }
     else {
@@ -674,16 +849,16 @@
  */
 
 int 
-miget_dimension_cosines(midimhandle_t dimension, double cosines[3])
+miget_dimension_cosines(midimhandle_t dimension, double direction_cosines[3])
 {
   if (dimension == NULL || (dimension->class != MI_DIMCLASS_SPATIAL &&
                             dimension->class != MI_DIMCLASS_SFREQUENCY)){
     return (MI_ERROR);
   }
   
-  cosines[0] = dimension->cosines[0];
-  cosines[1] = dimension->cosines[1];
-  cosines[2] = dimension->cosines[2];
+  direction_cosines[0] = dimension->direction_cosines[0];
+  direction_cosines[1] = dimension->direction_cosines[1];
+  direction_cosines[2] = dimension->direction_cosines[2];
 
   return (MI_NOERROR);
 }
@@ -692,16 +867,16 @@
  */
 
 int 
-miset_dimension_cosines(midimhandle_t dimension, const double cosines[3])
+miset_dimension_cosines(midimhandle_t dimension, const double direction_cosines[3])
 {
   
   if (dimension == NULL || dimension->class != MI_DIMCLASS_SPATIAL) {
     return (MI_ERROR);
   }
   
-  dimension->cosines[0] = cosines[0];
-  dimension->cosines[1] = cosines[1];
-  dimension->cosines[2] = cosines[2];
+  dimension->direction_cosines[0] = direction_cosines[0];
+  dimension->direction_cosines[1] = direction_cosines[1];
+  dimension->direction_cosines[2] = direction_cosines[2];
 
   return (MI_NOERROR);
 }
@@ -715,9 +890,8 @@
   if (dimension == NULL) {
     return (MI_ERROR);
   }
-  
-  *name_ptr = malloc(MI2_CHAR_LENGTH);
-  strcpy(*name_ptr, dimension->name);
+
+  *name_ptr = strdup(dimension->name);
 
   return (MI_NOERROR);
 }
@@ -732,9 +906,8 @@
     return (MI_ERROR);
   }
  
-  if (strlen(name) + 1 <= MI2_CHAR_LENGTH) {
-    dimension->name = malloc(strlen(name) + 1);
-    strcpy(dimension->name, name);
+  if ((strlen(name) + 1) <= MI2_CHAR_LENGTH) {
+    dimension->name = strdup(name);
   }
   else {
     return (MI_ERROR);
@@ -753,11 +926,11 @@
   unsigned long  diff;
   int i, j=0;
 
-  if (dimension == NULL || start_position > dimension->size ) {
+  if (dimension == NULL || start_position > dimension->length ) {
     return (MI_ERROR);
   }
-  if ((start_position + array_length) > dimension->size) {
-    diff = dimension->size;
+  if ((start_position + array_length) > dimension->length) {
+    diff = dimension->length;
   }
   else {
     diff = array_length;
@@ -771,7 +944,7 @@
       /* For regularly sampled dimensions, the step value
 	 is added to each value to get the next value.
        */
-      offsets[j] = dimension->start + (i * dimension-> separation);
+      offsets[j] = dimension->start + (i * dimension->step);
       j++;
     }
   }
@@ -795,11 +968,11 @@
   int i, j=0;
   /* Check to see whether the dimension is regularly sampled.
    */
-  if (dimension == NULL || dimension->sampling_flag || start_position > dimension->size ) {
+  if (dimension == NULL || dimension->sampling_flag || start_position > dimension->length ) {
     return (MI_ERROR);
   }
-  if ((start_position + array_length) > dimension->size) {
-    diff = dimension->size;
+  if ((start_position + array_length) > dimension->length) {
+    diff = dimension->length;
   }
   else {
     diff = array_length;
@@ -807,7 +980,7 @@
   /* Allocate space for the offsets if not already done.
    */
   if (dimension->offsets == NULL) {
-    dimension->offsets = (double *) malloc(dimension->size*sizeof(double));
+    dimension->offsets = (double *) malloc(dimension->length*sizeof(double));
   }
   if (start_position == 0) {
     diff--;
@@ -858,10 +1031,10 @@
     return (MI_ERROR);
   }
   if (voxel_order == 0) {
-    *separation_ptr = dimension->separation;
+    *separation_ptr = dimension->step;
   }
   else {
-    *separation_ptr = -1 * dimension->separation;
+    *separation_ptr = -1 * dimension->step;
   }
   return (MI_NOERROR);
 }
@@ -878,7 +1051,7 @@
     return (MI_ERROR);
   }
   
-  dimension->separation = separation;
+  dimension->step = separation;
   /* If not explicitly set, the width will be assumed to be equal to the
      dimension's step size.
   */
@@ -928,7 +1101,7 @@
   if (dimension == NULL) {
     return (MI_ERROR);
   }
-  *size_ptr = dimension->size;
+  *size_ptr = dimension->length;
   return (MI_NOERROR);
 }
 
@@ -944,7 +1117,7 @@
   if (dimension == NULL || dimension->volume_handle != NULL) {
     return (MI_ERROR);
   }
-  dimension->size = size;
+  dimension->length = size;
   return (MI_NOERROR);
 }
 
@@ -956,7 +1129,7 @@
 		      unsigned long sizes[])
 {
   int i;
-  /* Allocated space for the sizes array.
+  /* Allocated space for the length array.
    */
   sizes  = (unsigned long *) malloc(array_length*sizeof(unsigned long));
   for(i=0; i<array_length; i++) {
@@ -984,7 +1157,7 @@
   }
   else {
     
-    *start_ptr = dimension->start + (dimension->separation * (dimension->size-1));
+    *start_ptr = dimension->start + (dimension->step * (dimension->length-1));
   }
   return (MI_NOERROR);
 }
@@ -1046,8 +1219,8 @@
     return (MI_ERROR);
   }
   
-  *units_ptr = malloc(strlen(dimension->units) + 1);
-  strcpy(*units_ptr, dimension->units);
+  *units_ptr = strdup(dimension->units);
+  
   return (MI_NOERROR);
 }
 
@@ -1061,15 +1234,13 @@
     return (MI_ERROR);
   }
   
-  if (dimension->units == NULL) {
-    dimension->units = malloc(strlen(units) + 1);
-  }
   if (strlen(units) + 1 <= MI2_CHAR_LENGTH) {
-    strcpy(dimension->units, units);
+    dimension->units = strdup(units);
   }
   else {
     return (MI_ERROR);
   }
+
   return (MI_NOERROR);
 }
 
@@ -1121,12 +1292,12 @@
   unsigned long  diff;
   int i, j = 0;
 
-  if (dimension == NULL || start_position > dimension->size) {
+  if (dimension == NULL || start_position > dimension->length) {
     return (MI_ERROR);
   }
   
-  if ((start_position + array_length) > dimension->size) {
-    diff = dimension->size;
+  if ((start_position + array_length) > dimension->length) {
+    diff = dimension->length;
   }
   else {
     diff = array_length;
@@ -1179,12 +1350,12 @@
   int i, j=0;
   /* Check to see whether the dimension is regularly sampled.
    */
-  if (dimension == NULL || dimension->sampling_flag || start_position > dimension->size) {
+  if (dimension == NULL || dimension->sampling_flag || start_position > dimension->length) {
     return (MI_ERROR);
   }
 
-  if ((start_position + array_length) > dimension->size) {
-    diff = dimension->size;
+  if ((start_position + array_length) > dimension->length) {
+    diff = dimension->length;
   }
   else {
     diff = array_length;
@@ -1192,7 +1363,7 @@
   /* Allocate space for widths array if not already done
    */
   if (dimension->widths == NULL) {
-    dimension->widths = (double *) malloc(dimension->size*sizeof(double));
+    dimension->widths = (double *) malloc(dimension->length*sizeof(double));
   }
   if (start_position == 0) {
     diff--;
@@ -1228,14 +1399,15 @@
   mivolumeprops_t props;
   double cosines[3];
   int n;
-  
+  midimhandle_t dimens[3];
    /* Turn off automatic error reporting - we'll take care of this
    * ourselves, thanks!
    */
   H5Eset_auto(NULL, NULL);
   
   r = minew_volume_props(&props);
-  
+  r = miset_props_compression_type(props, MI_COMPRESS_ZLIB);
+  r = miset_props_zlib_compression(props, 3);
   r = micreate_dimension("xspace",MI_DIMCLASS_SPATIAL,1, 10,&dimh);
   if (r < 0) {
     TESTRPT("failed", r);
@@ -1247,7 +1419,7 @@
     TESTRPT("failed", r);
   }
   dim[1]=dimh1;
-  r = micreate_dimension("zspace",MI_DIMCLASS_SPATIAL,1, 12,&dimh2);
+  r = micreate_dimension("zspace",MI_DIMCLASS_SPATIAL,2, 3,&dimh2);
   if (r < 0) {
     TESTRPT("failed", r);
   }
@@ -1255,7 +1427,7 @@
   if (r < 0) {
     TESTRPT("failed", r);
   }
-  printf( " %f %f %f \n", cosines[0], cosines[1], cosines[2]);
+  
   dim[2]=dimh2;
    r = micreate_dimension("zfrequency",MI_DIMCLASS_SFREQUENCY,1, 12,&dimh3);
   if (r < 0) {
@@ -1264,15 +1436,17 @@
   r = miget_dimension_cosines(dimh3, cosines);
   if (r < 0) {
     TESTRPT("failed", r);
-  }
-  printf( " %f %f %f \n", cosines[0], cosines[1], cosines[2]);
-  
+  } 
   dim[3]=dimh3;
   r = micreate_volume("test.h5", 4, dim, MI_TYPE_UBYTE, MI_CLASS_INT,props,&vol);
   if (r < 0) {
     TESTRPT("failed", r);
   }
-  
+  r = miget_volume_dimensions(vol, MI_DIMCLASS_SPATIAL, 0, 0, 4, dimens);
+  if (r < 0) {
+    TESTRPT("failed", r);
+  }
+  printf(" %s %s %s \n", dimens[0]->name, dimens[1]->name, dimens[2]->name);
   r = miget_volume_dimension_count(vol, MI_DIMCLASS_SPATIAL, MI_DIMATTR_ALL, &n);
   if (r < 0) {
     TESTRPT("failed", r);
@@ -1282,7 +1456,6 @@
   if (r < 0) {
     TESTRPT("failed", r);
   }
-
   r = miclose_volume(vol1);
   if (r < 0) {
     TESTRPT("failed", r);
--- a/libsrc2/minc2.h
+++ b/libsrc2/minc2.h
@@ -28,11 +28,14 @@
 #define MI_DIMATTR_NOT_REGULARLY_SAMPLED 0x2
 
 #define MI2_CHAR_LENGTH 128
-#define MI2_MAX_BLOCK_EDGES 3
+
+#define MI2_MAX_BLOCK_EDGES 3   /* Don't do 4D or greater chunks for now */
+#define MI2_CHUNK_SIZE 32	/* Length of chunk, per dimension */
 #define MAX_ZLIB_LEVEL 9
-#define MAX_VAR_DIMS 10
+
 #define MAX_PATH 32
 #define MAX_RESOLUTION_GROUP 16
+#define MAX_CD_ELEMENTS 100
 
 #define MI2_OPEN_READ 0x0001
 #define MI2_OPEN_RDWR 0x0002
@@ -40,13 +43,6 @@
 /************************************************************************
  * ENUMS, STRUCTS, and TYPEDEFS
  ************************************************************************/
-typedef int BOOLEAN;
-
-typedef enum {
-  MI_COMPRESS_NONE = 0,
-  MI_COMPRESS_ZLIB = 1,
-} micompression_t;
-
 struct volprops_struct;
 typedef struct volprops_struct volprops;
 typedef volprops *mivolumeprops_t;	/* opaque pointer to volume properties */
@@ -59,6 +55,7 @@
 typedef struct volumehandle_struct volumehandle;
 typedef volumehandle *mihandle_t;      /* opaque pointer to volume handle */
 
+
 typedef enum {
   MI_TYPE_BYTE = 1,		/* 8-bit signed integer */
   MI_TYPE_CHAR = 2,		/* ASCII text */
@@ -80,9 +77,9 @@
 typedef enum {
   MI_CLASS_REAL = 0,
   MI_CLASS_INT = 1,
-  MI_CLASS_LABEL = 2,
+  MI_CLASS_LABEL = 2,           /* enumerated data with a description for each value */
   MI_CLASS_COMPLEX = 3,
-  MI_CLASS_UNIFORM_RECORD = 4,
+  MI_CLASS_UNIFORM_RECORD = 4,   /*aggregate datatypes consisting of multiple values */
   MI_CLASS_NON_UNIFORM_RECORD = 5
 } miclass_t;
 
@@ -114,7 +111,14 @@
   MI_NEGATIVE           = 3,    /* check step if positive -> flip,
 				                 negative -> no flip */
 } miflipping_t;
- 
+
+typedef enum {
+  MI_COMPRESS_NONE = 0,
+  MI_COMPRESS_ZLIB = 1,
+} micompression_t;
+
+typedef int BOOLEAN;
+
 typedef unsigned int midimattr_t;
 
 typedef unsigned long misize_t;
@@ -139,8 +143,6 @@
   double imag;
 } midcomplex_t;
 
-
-
 /************************************************************************
  * FUNCTION DECLARATIONS
  ************************************************************************/
@@ -176,7 +178,7 @@
 extern int miget_volume_from_dimension(midimhandle_t dimension, mihandle_t *volume);
 extern int micopy_dimension(midimhandle_t dim_ptr, midimhandle_t *new_dim_ptr);
 extern int micreate_dimension(const char *name, midimclass_t class, midimattr_t attr, 
-			      unsigned long size, midimhandle_t *new_dim_ptr);
+			      unsigned long length, midimhandle_t *new_dim_ptr);
 extern int mifree_dimension_handle(midimhandle_t dim_ptr);
 extern int miget_volume_dimensions(mihandle_t volume, midimclass_t class, midimattr_t attr,
 				   miorder_t order, int array_length, 
@@ -189,8 +191,10 @@
 extern int miset_dimension_apparent_voxel_order(midimhandle_t dimension, miflipping_t flipping_order);
 extern int miget_dimension_class(midimhandle_t dimension, midimclass_t *class);
 extern int miset_dimension_class(midimhandle_t dimension, midimclass_t class);
-extern int miget_dimension_cosines(midimhandle_t dimension, double cosines[3]);
-extern int miset_dimension_cosines(midimhandle_t dimension, const double cosines[3]);
+extern int miget_dimension_direction_cosines(midimhandle_t dimension, 
+					     double direction_cosines[3]);
+extern int miset_dimension_direction_cosines(midimhandle_t dimension, 
+					     const double direction_cosines[3]);
 extern int miget_dimension_name(midimhandle_t dimension, char **name_ptr);
 extern int miset_dimension_name(midimhandle_t dimension, const char *name);
 extern int miget_dimension_offsets(midimhandle_t dimension, unsigned long array_length, 
@@ -202,10 +206,11 @@
 extern int miget_dimension_separation(midimhandle_t dimension, mivoxel_order_t voxel_order, 
 				      double *separation_ptr);
 extern int miset_dimension_separation(midimhandle_t dimension, double separation);
-extern int miget_dimension_separations(const midimhandle_t dimensions[], mivoxel_order_t voxel_order,
-				       int array_length, double separations[]);
+extern int miget_dimension_separations(const midimhandle_t dimensions[], 
+				 mivoxel_order_t voxel_order, int array_length, 
+				 double separations[]);
 extern int miset_dimension_separations(const midimhandle_t dimensions[], int array_length,
-				       const double separations[]);
+				 const double separations[]);
 extern int miget_dimension_size(midimhandle_t dimension, unsigned long *size_ptr);
 extern int miset_dimension_size(midimhandle_t dimension, unsigned long size);
 extern int miget_dimension_sizes(const midimhandle_t dimensions[], int array_length,
@@ -263,9 +268,7 @@
 extern int miset_props_blocking(mivolumeprops_t props, int edge_count, const int *edge_lengths);
 extern int miget_props_blocking(mivolumeprops_t props, int *edge_count, int *edge_lengths,
 				int max_lengths);
-
-extern int miset_props_uniform_record(mivolumeprops_t props, long record_length, char *record_name);                             
-extern int miset_props_non_uniform_record(mivolumeprops_t props, long record_length, char *record_name);
+extern int miset_props_record(mivolumeprops_t props, long record_length, char *record_name); 
 extern int miset_props_template(mivolumeprops_t props, int template_flag);
 
 /* SLICE/VOLUME SCALE FUNCTIONS */
--- a/libsrc2/minc2_private.h
+++ b/libsrc2/minc2_private.h
@@ -1,11 +1,26 @@
 /** The root of all MINC 2.0 objects in the HDF5 hierarchy.
  */
 #define MI_ROOT_PATH "/minc-2.0"
-//#define MI_ROOT_COMMENT "Root of the MINC 2.0 data hierarchy"
-//#define MI_INFO_NAME "info"
-//#define MI_INFO_COMMENT "Group holding directly accessible attributes"
+#define MI_ROOT_COMMENT "Root of the MINC 2.0 data hierarchy"
+
+#define MI_DIMAGE_PATH "image"
+
+
+#define MI_INFO_NAME "info"
+#define MI_INFO_COMMENT "Group holding directly accessible attributes"
+
 #define MI_DIMENSIONS_PATH "dimensions"
-//#define MI_DIMS_COMMENT "Group holding dimension variables"
+#define MI_DIMS_COMMENT "Group holding dimension variables"
+
+/** The fixed path to the full-resolution image data.
+ */
+#define MI_IMAGE_PATH MI_ROOT_PATH MI_DIMAGE_PATH
+#define MI_FULLIMAGE_PATH MI_IMAGE_PATH "/0"
+
+/** The fixed path to the dimension 
+ */
+#define MI_FULLDIMENSIONS_PATH MI_ROOT_PATH "/dimensions"
+
 
 #define MI2_3D 3
 #define MI2_X 0
@@ -15,23 +30,16 @@
 /** Size of a linear transform */
 #define MI2_LIN_XFM_SIZE 4
 
-/** The fixed path to the full-resolution image data.
- */
-#define MI_FULLIMAGE_PATH MI_ROOT_PATH "/image/0"
-
-/** The fixed path to the dimension 
- */
-#define MI_FULLDIMENSIONS_PATH MI_ROOT_PATH "/dimensions"
 
 /*! Volume properties  
  */
 struct volprops_struct{
   BOOLEAN enable_flag; //enable multi-res 
-  int depth;
+  int depth; //multi-res depth
   micompression_t compression_type;
   int zlib_level; 
-  int edge_count;
-  int *edge_lengths;
+  int edge_count; //how many chunks
+  int *edge_lengths; //size of each chunk
   int max_lengths;
   long record_length;
   char *record_name;
@@ -43,13 +51,13 @@
 struct dimension_struct{
   midimattr_t attr;
   midimclass_t class;
-  double cosines[3];
+  double direction_cosines[3];
   miflipping_t flipping_order;
   char *name;
   double *offsets;
   BOOLEAN sampling_flag;
-  double separation;
-  unsigned long size;
+  double step;
+  unsigned long length;
   double start;
   char *units;
   double width; 
--- a/libsrc2/slice.c
+++ b/libsrc2/slice.c
@@ -293,6 +293,31 @@
 
     return (MI_NOERROR);
 }
+
+/*! Function to get the volume's slice-scaling flag.
+ */
+int
+miget_slice_scaling_flag(mihandle_t volume, BOOLEAN *slice_scaling_flag)
+{
+    if (volume == NULL || slice_scaling_flag == NULL) {
+	return (MI_ERROR);
+    }
+    *slice_scaling_flag = volume->has_slice_scaling;
+    return (MI_NOERROR);
+}
+
+/*! Function to set the volume's slice-scaling flag.
+ */
+int
+miset_slice_scaling_flag(mihandle_t volume, BOOLEAN slice_scaling_flag)
+{
+    if (volume == NULL) {
+	return (MI_ERROR);
+    }
+    volume->has_slice_scaling = slice_scaling_flag;
+    return (MI_NOERROR);
+}
+
 #ifdef M2_TEST
 
 int
--- a/libsrc2/volprops.c
+++ b/libsrc2/volprops.c
@@ -25,7 +25,7 @@
   handle->depth = 0;
   handle->compression_type = MI_COMPRESS_NONE;
   handle->zlib_level = 0;
-  handle->edge_count = 0;
+  handle->edge_count = 1;
   handle->edge_lengths = NULL;
   handle->max_lengths = 0;
   handle->record_length = 0;
@@ -63,7 +63,13 @@
   volprops *handle;
   hid_t hdf_vol_dataset;
   hid_t hdf_plist;
-  
+  int nfilters;
+  unsigned int flags;
+  size_t cd_nelmts;
+  unsigned int cd_values[MAX_CD_ELEMENTS];
+  char fname[100];
+  int fcode;
+                    
   if (volume->hdf_id < 0) {
     return (MI_ERROR);
   }
@@ -75,13 +81,20 @@
   if (hdf_plist < 0) {
     return (MI_ERROR);
   }
+  handle = (volprops *)malloc(sizeof(*handle));
+  if (handle == NULL) {
+    return (MI_ERROR);
+  }
   /* Get the layout of the raw data for a dataset.
    */
   if (H5Pget_layout(hdf_plist) == H5D_CHUNKED) {
       hsize_t dims[MI2_MAX_BLOCK_EDGES];
       int i;
-      handle = (volprops *)malloc(sizeof(*handle));
+      /* Returns chunk dimensionality */
       handle->edge_count = H5Pget_chunk(hdf_plist, MI2_MAX_BLOCK_EDGES, dims);
+      if (handle->edge_count < 0) {
+	return (MI_ERROR);
+      }
       handle->edge_lengths = (int *)malloc(handle->edge_count*sizeof(int));
       if (handle->edge_lengths == NULL) {
 	  return (MI_ERROR);
@@ -89,10 +102,44 @@
       for (i = 0; i < handle->edge_count; i++) {
 	  handle->edge_lengths[i] = dims[i];
       }
+      /* Get the number of filters in the pipeline */
+      nfilters = H5Pget_nfilters(hdf_plist);
+      if (nfilters == 0) {
+	handle->zlib_level = 0;
+	handle->compression_type = MI_COMPRESS_NONE;
+      }
+      else {
+	for (i = 0; i < nfilters; i++) {
+	  cd_nelmts = MAX_CD_ELEMENTS;
+          fcode = H5Pget_filter(hdf_plist, i, &flags, &cd_nelmts,
+                                cd_values, sizeof(fname), fname);
+	  switch (fcode) {
+	  case H5Z_FILTER_DEFLATE:
+	    printf("Deflate");
+	    break;
+          case H5Z_FILTER_SHUFFLE:
+	    /* NOT SURE WHAT TO DO */
+	    printf("Shuffle");
+	    break;
+          case H5Z_FILTER_FLETCHER32:
+	    /* NOT SURE WHAT TO DO */
+	    printf("Fletcher32");
+	    break;
+          case H5Z_FILTER_SZIP:
+	    printf("SZip");
+	    break;
+          default:
+	    printf("Unknown(%d)", fcode);
+	    break;
+	  }
+	}
+      }
   }
   else {
-      handle->edge_count = 0;
+      handle->edge_count = 1;
       handle->edge_lengths = NULL;
+      handle->zlib_level = 0;
+      handle->compression_type = MI_COMPRESS_NONE;
   }
   
   *props = handle;
@@ -187,10 +234,15 @@
 }
 
 /*! Set compression type for a volume property list
+    Note that enabling compression will automatically 
+    enable blocking with default parameters. 
  */
 int
 miset_props_compression_type(mivolumeprops_t props, micompression_t compression_type)
 {
+ 
+  int edge_lengths[MI2_MAX_BLOCK_EDGES] = {MI2_CHUNK_SIZE, MI2_CHUNK_SIZE, MI2_CHUNK_SIZE};
+ 
  if (props == NULL) {
     return (MI_ERROR);
   }
@@ -200,6 +252,7 @@
    break;
  case MI_COMPRESS_ZLIB:
    props->compression_type = MI_COMPRESS_ZLIB;
+   miset_props_blocking(props, MI2_MAX_BLOCK_EDGES, edge_lengths);
    break;
  default:
    return (MI_ERROR);
@@ -212,6 +265,7 @@
 int 
 miget_props_compression_type(mivolumeprops_t props, micompression_t *compression_type)
 {
+
   if (props == NULL) {
     return (MI_ERROR);
   }
@@ -306,10 +360,10 @@
   return (MI_NOERROR);
 }
 
-/*! Set properties for uniform record dimension
+/*! Set properties for uniform/nonuniform record dimension
  */
 int 
-miset_props_uniform_record(mivolumeprops_t props, long record_length, char *record_name)
+miset_props_record(mivolumeprops_t props, long record_length, char *record_name)
 {
   if (props == NULL) {
     return (MI_ERROR);
@@ -321,29 +375,12 @@
       free(props->record_name);
       props->record_name = NULL;
   }
-  /* Explicitly allocate storage for name
-   */
-  props->record_name =malloc(strlen(record_name) + 1);
-  strcpy(props->record_name, record_name);
+  
+  props->record_name = strdup(record_name);
   
   return (MI_NOERROR);
 }
   
-/*! Set properties for non_uniform record dimension
- */
-/*
-int 
-miset_props_non_uniform_record(mivolumeprops_t props, long record_length, char *record_name)
-{
-  if (props == NULL) {
-    return (MI_ERROR);
-  }
-    props->record_length = record_length;
-    props->record_name = record_name;
-  
-    return (MI_NOERROR);
-}
-*/
 /*! Set the template volume flag
  */ 
 int
@@ -357,6 +394,7 @@
   return (MI_NOERROR);
 }
 
+
 #ifdef M2_TEST
 #define TESTRPT(msg, val) (error_cnt++, fprintf(stderr, \
                                   "Error reported on line #%d, %s: %d\n", \
--- a/libsrc2/volume.c
+++ b/libsrc2/volume.c
@@ -16,17 +16,20 @@
 		miclass_t volume_class, mivolumeprops_t create_props,
 		mihandle_t *volume)
 {
-  int i,j;
-  unsigned char v;
+  int i;
+  int stat;
   hid_t file_id;
   hid_t hdf_attr, hdf_type;
+  hid_t hdf_plist;
   hsize_t dim[1];
-  hsize_t dims[1];
-  hsize_t maxdims[1];
-  hid_t grp_root_id, grp_dimensions_id; 
+  hid_t grp_root_id, grp_image_id;
+  hid_t grp_fullimage_id, grp_dimensions_id; 
+
+  hid_t dimage_id = -1;
   hid_t dataset_id = -1;
   hid_t dataspace_id = -1;
-  hsize_t hdf_count[MAX_VAR_DIMS];
+  
+  hsize_t hdf_chunk_size[MI2_MAX_BLOCK_EDGES];
   volumehandle *handle;
   volprops *props_handle;
 
@@ -34,10 +37,10 @@
       dimensions == NULL || create_props == NULL) {
     return (MI_ERROR);
   }    
-  
   /* convert minc type to hdf type
    */
   hdf_type = mitype_to_hdftype(volume_type);
+
   /* Create file in HDF5 with the given filename and
      H5F_AA_TRUNC: Truncate file, if it already exists, 
                    erasing all data previously stored in the file.
@@ -47,6 +50,7 @@
   if (file_id < 0) {
     return (MI_ERROR);
   }
+  
   /* Try opening ROOT GROUP i.e. /minc-2.0 or CREATE ONE!
    */
   if ((grp_root_id = H5Gopen(file_id, MI_ROOT_PATH)) < 0) {
@@ -55,11 +59,86 @@
       return (MI_ERROR);
     }
   }
-  
-  /* Try opening DIMENSIONS GROUP i.e. /minc-2.0/dimensions or CREATE ONE!
+
+  /* Try opening IMAGE GROUP i.e. /minc-2.0/image/ or CREATE ONE!
+   */
+  if((grp_image_id = H5Gopen(grp_root_id, MI_IMAGE_PATH)) < 0) {
+    grp_image_id = H5Gcreate(grp_root_id, MI_IMAGE_PATH , 0);
+    if (grp_image_id < 0) {
+      return (MI_ERROR);
+    }
+  }
+
+  /* Try opening FULLIMAGE GROUP i.e. /minc-2.0/image/0 or CREATE ONE!
    */
-  if((grp_dimensions_id = H5Gopen(grp_root_id, MI_DIMENSIONS_PATH)) < 0) {
-    grp_dimensions_id = H5Gcreate(grp_root_id, MI_DIMENSIONS_PATH , 0);
+  if((grp_fullimage_id = H5Gopen(grp_image_id, MI_FULLIMAGE_PATH)) < 0) {
+    grp_fullimage_id = H5Gcreate(grp_image_id, MI_FULLIMAGE_PATH , 0);
+    if (grp_fullimage_id < 0) {
+      return (MI_ERROR);
+    }
+  }
+ 
+  /* Create dataset property list */
+  hdf_plist = H5Pcreate(H5P_DATASET_CREATE);
+  if (hdf_plist < 0) {
+    return (MI_ERROR);
+  }
+  
+  /* See if chunking and/or compression should be enabled */
+  if (create_props->compression_type == MI_COMPRESS_ZLIB ||
+      create_props->edge_count > 1) {
+
+    stat = H5Pset_layout(hdf_plist, H5D_CHUNKED); /* Chunked data */
+    if (stat < 0) {
+      return (MI_ERROR);
+    }
+    
+    for (i=0; i < create_props->edge_count; i++) {
+      hdf_chunk_size[i] = create_props->edge_lengths[i];
+    }
+    
+    /* Sets the size of the chunks used to store a chunked layout dataset */
+    stat = H5Pset_chunk(hdf_plist, create_props->edge_count, hdf_chunk_size);
+    if (stat < 0) {
+      return (MI_ERROR);
+    }
+    /* Sets compression method and compression level */
+    stat = H5Pset_deflate(hdf_plist, create_props->zlib_level);
+    if (stat < 0) {
+      return (MI_ERROR);
+    }
+
+     /* Create a SIMPLE dataspace  */
+    dataspace_id = H5Screate_simple(create_props->edge_count, hdf_chunk_size, NULL);			  
+    if (dataspace_id < 0) {
+    return (MI_ERROR);
+    }
+  }
+  else { /* No COMPRESSION or CHUNKING is enabled */
+    stat = H5Pset_layout(hdf_plist, H5D_CONTIGUOUS); /*  CONTIGUOUS data */
+    if (stat < 0) {
+      return (MI_ERROR);
+    }
+    /* Create a SCALAR dataspace  */
+    dataspace_id = H5Screate(H5S_SCALAR);
+    if (dataspace_id < 0) {
+    return (MI_ERROR);
+    }
+  }
+    
+  /* Try opening IMAGE dataset i.e. /minc-2.0/image/0/image or CREATE ONE!
+   */
+  if((dimage_id = H5Dopen(grp_fullimage_id, MI_DIMAGE_PATH)) < 0) {
+    dimage_id = H5Dcreate(grp_fullimage_id, MI_DIMAGE_PATH, hdf_type, dataspace_id, hdf_plist);
+    if (dimage_id < 0) {  
+      return (MI_ERROR);
+    }
+  }
+  
+   /* Try opening DIMENSIONS GROUP i.e. /minc-2.0/dimensions or CREATE ONE!
+   */
+  if((grp_dimensions_id = H5Gopen(grp_root_id, MI_FULLDIMENSIONS_PATH)) < 0) {
+    grp_dimensions_id = H5Gcreate(grp_root_id, MI_FULLDIMENSIONS_PATH , 0);
     if (grp_dimensions_id < 0) {
       return (MI_ERROR);
     }
@@ -67,7 +146,6 @@
    
   for (i=0; i < number_of_dimensions ; i++) {
     
-    dim[0] = dimensions[i]->size;
     if (dimensions[i]->attr == MI_DIMATTR_REGULARLY_SAMPLED) {
       /* Dimension variable for a regular dimension contains
 	 no meaningful data.
@@ -77,78 +155,54 @@
     else {
       /* Dimension variable for an irregular dimension contains
 	 a vector with the lengths equal to the sampled points
-	 alone the dimension.
+	 along the dimension.
       */
-      if (dimensions[i]->offsets != NULL) {
-	for (j = 0; j < dimensions[i]->size; j++) {
-	  hdf_count[j] = dimensions[i]->offsets[j];
-	}
-      }
-      else {
-	return (MI_ERROR);
-      }
-      dataspace_id = H5Screate_simple(dimensions[i]->size, hdf_count, NULL);
+      dim[0] = dimensions[i]->length;
+      dataspace_id = H5Screate_simple(1, dim, NULL);
     }
     if (dataspace_id < 0) {
       return (MI_ERROR);
     }
-    
-    /* Create a dataset in DIMENSIONS GROUP */
+  
+    /* Create a dataset(dimension's name) in DIMENSIONS GROUP */
     dataset_id = H5Dcreate(grp_dimensions_id, dimensions[i]->name, hdf_type, dataspace_id, H5P_DEFAULT);
-   
+    /* Create Dimension attribute  "attr" */
+   dataspace_id = H5Screate(H5S_SCALAR);
+   /* Create attribute. */
+   hdf_attr = H5Acreate(dataset_id, "attr", H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT);
+   if (hdf_attr < 0) {
+     return (MI_ERROR);
+   }
+  
+   /* Write data to the attribute. */
+   H5Awrite(hdf_attr, H5T_NATIVE_INT, &dimensions[i]->attr);
+   /* Close attribute dataspace. */
+   H5Sclose(dataspace_id); 
+   /* Close attribute. */
+   H5Aclose(hdf_attr);
+
    /* Create Dimension attribute  "class" */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "class");
    /* Create attribute. */
    hdf_attr = H5Acreate(dataset_id, "class", H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
-   switch (dimensions[i]->class) {
-   case MI_DIMCLASS_ANY:
-     v = 0;
-     break;
-   case MI_DIMCLASS_SPATIAL:
-     v = 1;
-     break;
-   case MI_DIMCLASS_TIME:
-     v = 2;
-     break;
-   case MI_DIMCLASS_SFREQUENCY:
-     v = 3;
-     break;
-   case MI_DIMCLASS_TFREQUENCY:
-     v = 4;
-     break;
-   case MI_DIMCLASS_USER:
-     v = 5;
-     break;
-   case MI_DIMCLASS_RECORD:
-     v = 6;
-     break;
-   default:
      return (MI_ERROR);
    }
    /* Write data to the attribute. */
-   H5Awrite(hdf_attr, hdf_type, &v);
+   H5Awrite(hdf_attr, H5T_NATIVE_INT, &dimensions[i]->class);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
    H5Aclose(hdf_attr);
    
-   /* Create Dimension attribute "cosines"  */
-   dims[0] = 3;
-   maxdims[0] = 3;
-   dataspace_id = H5Screate_simple(1, dims, maxdims);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "cosines");
-   
-   hdf_attr = H5Acreate(dataset_id, "cosines", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
+   /* Create Dimension attribute "direction_cosines"  */
+   dim[0] = 3;
+   dataspace_id = H5Screate_simple(1, dim, NULL);
+   hdf_attr = H5Acreate(dataset_id, "direction_cosines", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
-   H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, dimensions[i]->cosines);
+     return (MI_ERROR);
+   }
+   H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, dimensions[i]->direction_cosines);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
@@ -156,70 +210,62 @@
    
    /* Create Dimension flipping_order attribute */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "flipping_order");
- 
    hdf_attr = H5Acreate(dataset_id, "flipping_order", H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
-   switch (dimensions[i]->flipping_order) {
-   case MI_FILE_ORDER:
-     v = 0;
-     break;
-   case MI_COUNTER_FILE_ORDER:
-     v = 1;
-     break;
-   default:
      return (MI_ERROR);
    }
-   H5Awrite(hdf_attr, H5T_NATIVE_INT, &v);
+   H5Awrite(hdf_attr, H5T_NATIVE_INT, &dimensions[i]->flipping_order);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
    H5Aclose(hdf_attr);
+
+   if (dimensions[i]->offsets != NULL) {
+     /* Create Dimension attribute "offsets"  */
+     dim[0] = dimensions[i]->length;
+     dataspace_id = H5Screate_simple(1, dim, NULL);
+     hdf_attr = H5Acreate(dataset_id, "offsets", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
+     if (hdf_attr < 0) {
+       return (MI_ERROR);
+     }
+     H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, dimensions[i]->offsets);
+     /* Close attribute dataspace. */
+     H5Sclose(dataspace_id); 
+     /* Close attribute. */
+     H5Aclose(hdf_attr);
+   }
    
-
    /* Create Dimension attribute "sampling_flag" */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "sampling_flag");
-  
    hdf_attr = H5Acreate(dataset_id, "sampling_flag", H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
+     return (MI_ERROR);
+   }
    H5Awrite(hdf_attr, H5T_NATIVE_INT, &dimensions[i]->sampling_flag);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
    H5Aclose(hdf_attr);
 
-   /* Create Dimension attribute  "size" */
+   /* Create Dimension attribute  "length" */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "size");
- 
-   hdf_attr = H5Acreate(dataset_id, "size", H5T_NATIVE_ULONG, dataspace_id, H5P_DEFAULT);
+   hdf_attr = H5Acreate(dataset_id, "length", H5T_NATIVE_ULONG, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
-   H5Awrite(hdf_attr, H5T_NATIVE_ULONG, &dimensions[i]->size);
+     return (MI_ERROR);
+   }
+   H5Awrite(hdf_attr, H5T_NATIVE_ULONG, &dimensions[i]->length);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
    H5Aclose(hdf_attr);
    
-   /* Create Dimension attribute "separation" */
+   /* Create Dimension attribute "step" */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "separation");
- 
-   hdf_attr = H5Acreate(dataset_id, "separation", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
+   hdf_attr = H5Acreate(dataset_id, "step", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
 	return (MI_ERROR);
-    }
-   H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, &dimensions[i]->separation);
+   }
+   H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, &dimensions[i]->step);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
@@ -227,13 +273,10 @@
    
    /* Create Dimension start attribute */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "start");
-  
    hdf_attr = H5Acreate(dataset_id, "start", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
+     return (MI_ERROR);
+   }
    H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, &dimensions[i]->start);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
@@ -242,16 +285,13 @@
    
    /* Create Dimension attribute "units" */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "units");
-  
    hdf_type = H5Tcopy(H5T_C_S1);
-   H5Tset_size(hdf_type, (strlen(dimensions[i]->units) + 1));
-
+              H5Tset_size(hdf_type, (strlen(dimensions[i]->units) + 1));
    hdf_attr = H5Acreate(dataset_id, "units", hdf_type, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
+     return (MI_ERROR);
+   }
+   
    H5Awrite(hdf_attr, hdf_type, dimensions[i]->units);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
@@ -260,30 +300,22 @@
    
    /* Create Dimension attribute "width" */
    dataspace_id = H5Screate(H5S_SCALAR);
-   /* Delete attribute if it already exists. */
-   H5Adelete(dataset_id, "width");
-  
    hdf_attr = H5Acreate(dataset_id, "width", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
    if (hdf_attr < 0) {
-	return (MI_ERROR);
-    }
+     return (MI_ERROR);
+   }
    H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, &dimensions[i]->width);
    /* Close attribute dataspace. */
    H5Sclose(dataspace_id); 
    /* Close attribute. */
    H5Aclose(hdf_attr);
-   
    if (dimensions[i]->widths != NULL) {
-     /* Create Dimension direction attribute "widths" */
-     dims[0] = dimensions[i]->size;
-     maxdims[0] = dimensions[i]->size;
-     dataspace_id = H5Screate_simple(1, dims, maxdims);
-     /* Delete attribute if it already exists. */
-     H5Adelete(dataset_id, "widths");
-  
+     /* Create Dimension attribute "widths" */
+     dim[0] = dimensions[i]->length;
+     dataspace_id = H5Screate_simple(1, dim, NULL);
      hdf_attr = H5Acreate(dataset_id, "widths", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT);
      if (hdf_attr < 0) {
-	return (MI_ERROR);
+       return (MI_ERROR);
      }
      H5Awrite(hdf_attr, H5T_NATIVE_DOUBLE, dimensions[i]->widths);
      /* Close attribute dataspace. */
@@ -291,15 +323,20 @@
      /* Close attribute. */
      H5Aclose(hdf_attr);
    }
-    
   }
-  
   /* "mitype_to_hdftype" returns a copy of the datatype, so the returned value 
      must be explicitly freed with a call to H5Tclose().
-  */
+     Close all Groups and Datset.
+   */
   H5Tclose(hdf_type);
+  H5Sclose(dataspace_id);
+  H5Dclose(dimage_id);
   H5Gclose(grp_dimensions_id);
+  H5Pclose(hdf_plist);
+  H5Gclose(grp_fullimage_id);
+  H5Gclose(grp_image_id);
   H5Gclose(grp_root_id);
+  
 
   /* Allocate space for the volume handle
    */
@@ -420,6 +457,7 @@
  
   props_handle->max_lengths = create_props->max_lengths;
   props_handle->record_length = create_props->record_length;
+
   /* Explicitly allocate storage for name
    */
   if (create_props->record_name != NULL) {
@@ -431,7 +469,7 @@
   handle->create_props = props_handle;
   
   *volume = handle;
-
+ 
   return (MI_NOERROR);
 }
 
@@ -527,32 +565,6 @@
     return (MI_NOERROR);
 }
 
-//***************************** must move the following to the slice
-//functions section
-
-/*! Function to get the volume's slice-scaling flag.
- */
-int
-miget_slice_scaling_flag(mihandle_t volume, BOOLEAN *slice_scaling_flag)
-{
-    if (volume == NULL || slice_scaling_flag == NULL) {
-	return (MI_ERROR);
-    }
-    *slice_scaling_flag = volume->has_slice_scaling;
-    return (MI_NOERROR);
-}
-
-/*! Function to set the volume's slice-scaling flag.
- */
-int
-miset_slice_scaling_flag(mihandle_t volume, BOOLEAN slice_scaling_flag)
-{
-    if (volume == NULL) {
-	return (MI_ERROR);
-    }
-    volume->has_slice_scaling = slice_scaling_flag;
-    return (MI_NOERROR);
-}