Mercurial > hg > minc-tools
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); -}