diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/h4toh5anno.c | 635 | ||||
-rw-r--r-- | tools/h4toh5image.c | 712 | ||||
-rw-r--r-- | tools/h4toh5main.c | 1538 | ||||
-rw-r--r-- | tools/h4toh5main.h | 56 | ||||
-rw-r--r-- | tools/h4toh5pal.c | 167 | ||||
-rw-r--r-- | tools/h4toh5sds.c | 892 | ||||
-rw-r--r-- | tools/h4toh5util.c | 1618 | ||||
-rw-r--r-- | tools/h4toh5util.h | 188 | ||||
-rw-r--r-- | tools/h4toh5vdata.c | 788 | ||||
-rw-r--r-- | tools/h4toh5vgroup.c | 768 | ||||
-rw-r--r-- | tools/testh4toh5 | 213 |
11 files changed, 7575 insertions, 0 deletions
diff --git a/tools/h4toh5anno.c b/tools/h4toh5anno.c new file mode 100644 index 0000000..6f11594 --- /dev/null +++ b/tools/h4toh5anno.c @@ -0,0 +1,635 @@ +#include "h4toh5main.h" + + +/*------------------------------------------------------------------------- + * Function: Annofil_h4_to_h5 + * + * Purpose: translate file annotation object into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: file identifier + h5_group: hdf5 group id + + *------------------------------------------------------------------------- + */ + +int Annofil_h4_to_h5(int32 file_id,hid_t h5group){ + + int32 an_id; + int32 ann_id; + int32 i; + + int32 ann_length; + + int32 n_file_label = 0; + int32 n_file_desc = 0; + int32 n_data_label = 0; + int32 n_data_desc = 0; + + int32 istat; + + char* ann_buf; + char anno_labelname[30]; + char anno_descname[30]; + char index_str[5]; + + hid_t h5_sid; + hid_t h5_aid; + hid_t sh5str_type; + hid_t sh5str1_type; + hid_t ret; + + an_id = ANstart(file_id); + + if(an_id < 0) { + printf("error in obtaining an_id. \n"); + return FAIL; + } + + istat = ANfileinfo(an_id,&n_file_label,&n_file_desc, + &n_data_label,&n_data_desc); + + if(istat == FAIL) { + printf("error getting file information.\n"); + ANend(file_id); + return FAIL; + } + + for (i = 0; i < n_file_label; i++) { + + ann_id = ANselect(an_id,i,AN_FILE_LABEL); + if(ann_id == FAIL) { + printf("error in obtaining annotation id. \n"); + ANend(file_id); + return FAIL; + } + + ann_length = ANannlen(ann_id); + if(ann_length == FAIL) { + printf("error in obtaining annotation length. \n"); + ANend(file_id); + ANendaccess(ann_id); + return FAIL; + } + + ann_buf = malloc(ann_length + 1); + if(ann_buf == NULL) { + printf("error in allocating memory. \n"); + return FAIL; + } + bzero(ann_buf,(ann_length+1)*sizeof(char)); + istat = ANreadann(ann_id,ann_buf,ann_length+1); + + if(istat==FAIL) { + printf("fail to read file information. \n"); + ANend(file_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + h5_sid = H5Screate(H5S_SCALAR); + + if (h5_sid < 0) { + printf("failed to create attribute space for"); + printf(" HDF4 FILE ANNOTATION. \n"); + ANend(file_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + if ((sh5str_type = mkstr(ann_length+1,H5T_STR_NULLTERM))<0) { + printf("error in making string at FILE lABEL ANNO. \n"); + ANend(file_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + if(conv_int_str(i,index_str)== FAIL) { + printf("fail to convert integer into character format.\n"); + ANend(file_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + strcpy(anno_labelname,HDF4_FILE_LABEL); + strcat(anno_labelname,"_"); + strcat(anno_labelname,index_str); + + + h5_aid = H5Acreate(h5group,anno_labelname,sh5str_type, + h5_sid,H5P_DEFAULT); + + if (h5_aid <0) { + printf("failed to obtain attribute id for"); + printf(" File annotation. \n"); + ANend(file_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + ret = H5Awrite(h5_aid,sh5str_type,(void *)ann_buf); + + if (ret <0) { + printf("failed to obtain attribute.\n "); + ANend(file_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + ret = H5Sclose(h5_sid); + ret = H5Aclose(h5_aid); + free(ann_buf); + ANendaccess(ann_id); + + } + + for (i = 0; i < n_file_desc; i++) { + + ann_id = ANselect(an_id,i,AN_FILE_DESC); + if(ann_id == FAIL) { + printf("error in obtaining annotation id. \n"); + ANend(an_id); + return FAIL; + } + + ann_length = ANannlen(ann_id); + + if(ann_length == FAIL) { + printf("error in obtaining annotation length. \n"); + ANend(an_id); + ANendaccess(ann_id); + return FAIL; + } + + ann_buf = malloc(ann_length+1); + if(ann_buf == NULL) { + printf("error in allocating memory. \n"); + ANend(an_id); + ANendaccess(ann_id); + return FAIL; + } + bzero(ann_buf,ann_length+1); + + istat = ANreadann(ann_id,ann_buf,ann_length+1); + + if(istat == FAIL) { + printf("error reading file information. \n"); + ANend(an_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + if ((sh5str1_type = mkstr(ann_length+1,H5T_STR_NULLTERM))<0) { + printf("error in making string at FILE DESC. \n"); + ANend(an_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + if(conv_int_str(i,index_str)==FAIL) { + printf("fail to convert integer into character format.\n"); + ANend(an_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + strcpy(anno_descname,HDF4_FILE_DESC); + strcat(anno_descname,"_"); + strcat(anno_descname,index_str); + + h5_sid = H5Screate(H5S_SCALAR); + + if (h5_sid < 0) { + printf("failed to create attribute space for"); + printf(" HDF4 FILE ANNOTATION. \n"); + ANend(an_id); + ANendaccess(ann_id); + free(ann_buf); + return FAIL; + } + + h5_aid = H5Acreate(h5group,anno_descname,sh5str1_type, + h5_sid,H5P_DEFAULT); + + if (h5_aid <0) { + + printf("failed to obtain attribute id for"); + printf(" File annotation. \n"); + ANend(an_id); + ANendaccess(ann_id); + H5Sclose(h5_sid); + free(ann_buf); + return FAIL; + } + + ret = H5Awrite(h5_aid,sh5str1_type,(void *)ann_buf); + + if (ret <0) { + printf("failed to obtain attribute.\n "); + ANend(an_id); + ANendaccess(ann_id); + H5Sclose(h5_sid); + H5Aclose(h5_aid); + free(ann_buf); + return FAIL; + } + + ret = H5Sclose(h5_sid); + ret = H5Aclose(h5_aid); + free(ann_buf); + ANendaccess(ann_id); + } + ANend(an_id); + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: Annoobj_h4_to_h5 + * + * Purpose: translate annotation object into attribute of hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: file identifier + obj_ref: object reference + obj_tag: object tag + h5group: hdf5 group + + *------------------------------------------------------------------------- + */ +int Annoobj_h4_to_h5(int32 file_id,int32 obj_ref, int32 obj_tag, + hid_t h5group){ + + int32 an_id; + int32 ann_id; + int32 i; + int32 status; + int32 ann_length; + + int32 n_file_label =-1; + int32 n_file_desc =-1; + int32 n_data_label =-1; + int32 n_data_desc =-1; + + int num_lab_anno; + int num_des_anno; + int32 istat; + int32* des_anno_list; + int32* lab_anno_list; + + char* ann_buf; + char* ann_obj_name; + char ann_labelname[30]; + + char index_str[5]; + + hid_t h5_sid; + hid_t h5_aid; + hid_t sh5str_type; + hid_t ret; + + an_id = ANstart(file_id); + if(an_id == FAIL) { + printf("fail to start annotation interface.\n"); + return FAIL; + } + + istat = ANfileinfo(an_id,&n_file_label,&n_file_desc, + &n_data_label,&n_data_desc); + + if(istat == FAIL ) { + printf("error getting file information.\n"); + ANend(an_id); + return FAIL; + } + + num_lab_anno = ANnumann(an_id,AN_DATA_LABEL,obj_tag,obj_ref); + num_des_anno = ANnumann(an_id,AN_DATA_DESC,obj_tag,obj_ref); + + if (num_lab_anno == FAIL) { + printf("error getting number of annotation data label.\n"); + ANend(an_id); + return FAIL; + } + + if (num_des_anno == FAIL) { + printf("error getting number of annotation object label.\n"); + ANend(an_id); + return FAIL; + } + + if(num_lab_anno != 0) { + + for(i=0; i<num_lab_anno;i++) { + ann_id = ANselect(an_id,i,AN_DATA_LABEL); + + if(ann_id == FAIL) { + printf("error in obtaining annotation id.\n"); + ANend(an_id); + return FAIL; + } + + ann_length = ANannlen(ann_id); + if(ann_length == FAIL) { + printf("error in getting annotation length. \n"); + ANendaccess(ann_id); + ANend(an_id); + return FAIL; + } + + ann_buf = malloc(ann_length+1); + if(ann_buf == NULL) { + printf("error in allocating annotation memory.\n"); + ANendaccess(ann_id); + ANend(an_id); + return FAIL; + } + bzero(ann_buf,(ann_length+1)*sizeof(char)); + status = ANreadann(ann_id,ann_buf,ann_length+1); + if(status == FAIL) { + printf("error in reading data.\n"); + ANendaccess(ann_id); + ANend(an_id); + free(ann_buf); + return FAIL; + } + /* printf("ann_buf %s\n",ann_buf);*/ + status = ANendaccess(ann_id); + + h5_sid = H5Screate(H5S_SCALAR); + + if (h5_sid < 0) { + printf("failed to create attribute space for"); + printf(" HDF4 FILE ANNOTATION. \n"); + ANend(an_id); + free(lab_anno_list); + free(ann_buf); + return FAIL; + } + + if ((sh5str_type = mkstr(ann_length+1,H5T_STR_NULLTERM))<0) { + printf("error in making string at OBJ LABEL. \n"); + ANend(an_id); + free(lab_anno_list); + free(ann_buf); + return FAIL; + } + + if(conv_int_str(i,index_str)== FAIL) { + printf("fail to convert annotation index into character format.\n"); + ANend(an_id); + free(lab_anno_list); + free(ann_buf); + return FAIL; + } + + /* obtain annotation object name. The name is defined based on object tag + */ + ann_obj_name = trans_tag_name(obj_tag,AN_DATA_LABEL); + + if(ann_obj_name != NULL) + strcpy(ann_labelname,ann_obj_name); + + strcat(ann_labelname,"_"); + strcat(ann_labelname,index_str); + + h5_aid = H5Acreate(h5group,ann_labelname,sh5str_type, + h5_sid,H5P_DEFAULT); + + if (h5_aid <0) { + + printf("failed to obtain attribute id for"); + printf(" file annotation. \n"); + ANend(an_id); + free(lab_anno_list); + free(ann_buf); + free(ann_obj_name); + return FAIL; + } + + ret = H5Awrite(h5_aid,sh5str_type,(void *)ann_buf); + + if (ret <0) { + printf("failed to obtain attribute.\n "); + ANend(an_id); + free(lab_anno_list); + free(ann_buf); + free(ann_obj_name); + return FAIL; + } + + ret = H5Sclose(h5_sid); + ret = H5Aclose(h5_aid); + free(ann_obj_name); + free(ann_buf); + } + } + + if(num_des_anno != 0) { + + + for (i = 0; i< num_des_anno;i++) { + + ann_id = ANselect(an_id,i,AN_DATA_DESC); + if(ann_id == FAIL) { + printf("error in obtaining annotation id.\n"); + ANend(an_id); + return FAIL; + } + ann_length = ANannlen(ann_id); + if(ann_length == FAIL) { + printf("error in getting annotation length. \n"); + ANendaccess(ann_id); + ANend(an_id); + return FAIL; + } + + ann_buf = malloc(ann_length+1); + + if(ann_buf == NULL) { + printf("error in allocating annotation memory.\n"); + ANendaccess(ann_id); + ANend(an_id); + return FAIL; + } + + bzero(ann_buf,(ann_length+1)*sizeof(char)); + ANreadann(ann_id,ann_buf,ann_length+1); + + if ((sh5str_type = mkstr(ann_length+1,H5T_STR_NULLTERM))<0) { + printf("error in making string at OBJECT DESC. \n"); + ANend(an_id); + free(des_anno_list); + free(ann_buf); + return FAIL; + } + + if(conv_int_str(i,index_str)== FAIL) { + printf("fail to convert annotation index into character format.\n"); + ANend(an_id); + free(ann_buf); + free(des_anno_list); + return FAIL; + } + ann_obj_name = trans_tag_name(obj_tag,AN_DATA_DESC); + if(ann_obj_name == NULL) { + printf("error in obtaining tag name. \n"); + ANend(an_id); + free(ann_buf); + free(des_anno_list); + return FAIL; + } + + strcpy(ann_labelname,ann_obj_name); + strcat(ann_labelname,"_"); + strcat(ann_labelname,index_str); + + h5_sid = H5Screate(H5S_SCALAR); + + if (h5_sid < 0) { + printf("failed to create attribute space for"); + printf(" HDF4 OBJECT ANNOTATION. \n"); + ANend(an_id); + free(des_anno_list); + free(ann_buf); + free(ann_obj_name); + return FAIL; + } + + h5_aid = H5Acreate(h5group,ann_labelname,sh5str_type, + h5_sid,H5P_DEFAULT); + + if (h5_aid <0) { + + ANend(an_id); + free(ann_buf); + free(des_anno_list); + free(ann_obj_name); + printf("failed to obtain attribute id for "); + printf("File annotation. \n"); + return FAIL; + } + + ret = H5Awrite(h5_aid,sh5str_type,(void *)ann_buf); + + if (ret <0) { + printf("failed to obtain attribute.\n "); + ANend(an_id); + free(ann_buf); + free(des_anno_list); + free(ann_obj_name); + return FAIL; + } + ret = H5Sclose(h5_sid); + ret = H5Aclose(h5_aid); + free(ann_obj_name); + /* printf("ann_buf %s\n",ann_buf);*/ + free(ann_buf); + } + + } + ANend(an_id); + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: trans_tag_name + * + * Purpose: in annotation routine, + translate annotation object tag into corresponding HDF5 object + name. + + * + * Return: NULL if failed, HDF5 object name if successful. + * + * In : + obj_tag: hdf4 object tag + annot_type: hdf4 annotation type + + *------------------------------------------------------------------------- + */ +char* trans_tag_name(int32 obj_tag,ann_type annot_type){ + + char* obj_name; + + obj_name = malloc(strlen(HDF4_VGROUP_LABEL)+1); + + if(obj_name == NULL) { + printf("error in obtaining tag name. \n"); + return NULL; + } + + if (obj_tag == DFTAG_NDG || obj_tag == DFTAG_SDG || obj_tag == DFTAG_SD) { + + if(annot_type == AN_DATA_LABEL) + strcpy(obj_name,HDF4_SDS_LABEL); + + else if(annot_type == AN_DATA_DESC) + strcpy(obj_name,HDF4_SDS_DESC); + else + return NULL; + } + + else if(obj_tag == DFTAG_RIG || obj_tag == DFTAG_RI || obj_tag == DFTAG_RI8) + { + if(annot_type == AN_DATA_LABEL) + strcpy(obj_name,HDF4_IMAGE_LABEL); + else if(annot_type == AN_DATA_DESC) + strcpy(obj_name,HDF4_IMAGE_DESC); + else + return NULL; + } + + else if(obj_tag == DFTAG_VG) { + if(annot_type == AN_DATA_LABEL) + strcpy(obj_name,HDF4_VGROUP_LABEL); + else if(annot_type == AN_DATA_DESC) + strcpy(obj_name,HDF4_VGROUP_DESC); + else + return NULL; + } + + else if(obj_tag == DFTAG_VS || obj_tag == DFTAG_VH) { + if(annot_type == AN_DATA_LABEL) + strcpy(obj_name,HDF4_VDATA_LABEL); + else if(annot_type == AN_DATA_DESC) + strcpy(obj_name,HDF4_VDATA_DESC); + else + return NULL; + } + + else if(obj_tag == DFTAG_LUT) { + if(annot_type == AN_DATA_LABEL) + strcpy(obj_name,HDF4_PAL_LABEL); + else if(annot_type == AN_DATA_DESC) + strcpy(obj_name,HDF4_PAL_DESC); + else + return NULL; + } + return obj_name; +} + + + + + + + + + + + diff --git a/tools/h4toh5image.c b/tools/h4toh5image.c new file mode 100644 index 0000000..ad04dae --- /dev/null +++ b/tools/h4toh5image.c @@ -0,0 +1,712 @@ + +#include "h4toh5main.h" +/*------------------------------------------------------------------------- + * Function: Image_h4_to_h5 + * + * Purpose: translate Image object into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + ri_id: RI identifier + h5_group: hdf5 group id + h5_palgroup: hdf5 palette group id + + *------------------------------------------------------------------------- + */ + +int Image_h4_to_h5(int32 file_id,int32 ri_id,hid_t h5_group,hid_t h5_palgroup) { + + int32 istat; + int32 ngrattrs; + int32 ncomp; + int check_gloattr; + int32 start[2]; + int32 edges[2]; + int32 dimsizes[2]; + uint16 gr_ref; + int32 image_dtype; + + int check_imagename; + int i; + char image_name[MAX_GR_NAME]; + char grlabel[MAX_GR_NAME]; + char image_class[MAX_GR_NAME]; + char* h5cimage_name; + void* image_data; + + /* define varibles for hdf5. */ + + hid_t h5ty_id; + hid_t h5memtype; + + hid_t h5_ctype; + hid_t h5_cmemtype; + + hid_t h5d_sid; + hid_t h5dset; + + size_t h4size; + size_t h4memsize; + size_t fielddim[1]; + hsize_t h5dims[2]; + herr_t ret; + + + /* Obtain information of the image.*/ + + istat = GRgetiminfo(ri_id, image_name, &ncomp, &image_dtype, + NULL, dimsizes, &ngrattrs); + + if(istat == FAIL) { + printf("Cannot obtain GR info. at Image routine.\n"); + return FAIL; + } + + /* data type transferring from hdf4 to hdf5. */ + if(h4type_to_h5type(image_dtype,&h5memtype,&h4memsize, + &h4size,&h5ty_id)== FAIL) { + printf("failed to translate image datatype. \n"); + return FAIL; + } + + /* check whether the datatype is string. */ + if (h5ty_id == H5T_STRING) { + /* rechange string datatype into numerical datatype.*/ + + if(h5string_to_int(image_dtype,&h5memtype,h4memsize, + &h5ty_id)== FAIL) { + printf("error in translating H5T_STRING to int.\n"); + return FAIL; + } + } + + start[0] = 0; + start[1] = 0; + edges[0] = dimsizes[0]; + edges[1] = dimsizes[1]; + + image_data = malloc(h4memsize*dimsizes[0]*dimsizes[1]*ncomp); + + if(image_data == NULL) { + printf("error in allocating memory for image data. \n"); + return FAIL; + } + + istat = GRreadimage(ri_id, start, NULL, edges, (VOIDP)image_data); + + if (istat == FAIL) { + printf("error in reading images.\n"); + free(image_data); + return FAIL; + } + + for (i=0;i<2;i++) + h5dims[i] = edges[i]-start[i]; + + gr_ref = GRidtoref(ri_id); + if(gr_ref == 0) { + printf("error in obtaining gr reference number. \n"); + free(image_data); + return FAIL; + } + + /* obtaining absolute path of image name.*/ + + check_imagename = -10; + h5cimage_name = get_name(gr_ref,2*num_images,gr_hashtab,&check_imagename); + + if (h5cimage_name == NULL && check_imagename == 0 ) { + printf("error,cannot find image name.\n"); + free(image_data); + return FAIL; + } + + if (h5cimage_name == NULL && check_imagename == -1) { + printf("error,image name is not defined.\n"); + free(image_data); + return FAIL; + } + + if (h5cimage_name == NULL && check_imagename == -2) { + printf("error,not enough memory for get_name. \n"); + free(image_data); + return FAIL; + } + + /**** check number of component of the image object, + and transfer HDF4 object into HDF5 object. ****/ + + if (ncomp <= 0) { + printf("error in obtaining image component\n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + if (ncomp == 1) { + + h5d_sid = H5Screate_simple(2,h5dims,NULL); + + if(h5d_sid <0) { + printf("error in creating space for dataset. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + h5dset = H5Dcreate(h5_group,h5cimage_name,h5ty_id,h5d_sid,H5P_DEFAULT); + + if(h5dset < 0) { + printf("error in creating hdf5 dataset converted from images. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + if (H5Dwrite(h5dset,h5memtype,h5d_sid,h5d_sid,H5P_DEFAULT, + image_data)<0) { + printf("error writing data for hdf5 dataset converted from images.\n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + } + + else { /* compound datatype. */ + + h5_ctype = H5Tcreate(H5T_COMPOUND,ncomp*h4size); + if (h5_ctype < 0) { + printf("error in generating hdf5 compound data type. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + h5_cmemtype = H5Tcreate(H5T_COMPOUND,ncomp*h4memsize); + if (h5_cmemtype < 0) { + printf("error in generating hdf5 memory compound data type. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + /* if(h4size != h4memsize) printf("h4size/h4memsize %d\n",h4size/h4memsize);*/ + + fielddim[0] = ncomp; + + ret = H5Tinsert_array(h5_ctype,"HDF4Image_data",0,1,fielddim,NULL, + h5ty_id); + if(ret < 0) { + printf("error in inserting array of compound datatype. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + ret = H5Tinsert_array(h5_cmemtype,"HDF4Image_data",0,1,fielddim,NULL, + h5memtype); + if(ret < 0) { + printf("error in inserting array of compound datatype at memory. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + h5d_sid = H5Screate_simple(2,h5dims,NULL); + if(h5d_sid < 0) { + printf("error in creating space. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + h5dset = H5Dcreate(h5_group,h5cimage_name,h5_ctype,h5d_sid, + H5P_DEFAULT); + if(h5dset < 0) { + printf("error in creating dataset. \n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + if (H5Dwrite(h5dset,h5_cmemtype,h5d_sid,h5d_sid,H5P_DEFAULT, + (void *)image_data)<0) { + printf("error writing data\n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + ret = H5Tclose(h5_ctype); + if(ret < 0) { + printf("error in closing h5_ctype. \n"); + } + ret = H5Tclose(h5_cmemtype); + if(ret <0) { + printf("error in closing h5_cmemtype. \n"); + } + } + +/* convert image annotation into attribute of image dataset. + Since there is no routines to find the exact tag of image object, + we will check three possible object tags of image objects, that is: + DFTAG_RIG,DFTAG_RI,DFTAG_RI8. If the object tag of image object is + falling out of this scope, we will not convert annotations into + hdf5 attributes; it is user's responsibility to make sure object tags + for image objects are only one of the above three tags.*/ + + if(Annoobj_h4_to_h5(file_id,gr_ref,DFTAG_RIG,h5dset)== FAIL){ + printf("failed to convert image annotation into hdf5 attribute.\n"); + free(image_data); + free(h5cimage_name); + return FAIL; + } + + if(Annoobj_h4_to_h5(file_id,gr_ref,DFTAG_RI,h5dset)== FAIL){ + printf("failed to convert image annotation into hdf5 attribute.\n"); + free(h5cimage_name); + free(image_data); + return FAIL; + } + + if(Annoobj_h4_to_h5(file_id,gr_ref,DFTAG_RI8,h5dset)== FAIL){ + printf("failed to convert image annotation into hdf5 attribute.\n"); + free(h5cimage_name); + free(image_data); + return FAIL; + } + + + /************************************/ + /* translate GR attributes into HDF5 dataset attribute.*/ + + check_gloattr = 0; + if(gr_tranattrs(ri_id,h5dset,ngrattrs,check_gloattr)==FAIL){ + printf(" cannot obtain attributes. \n"); + return FAIL; + } + + /* deal with h5dset predefined and user-defined attributes. + Obtain the name and data type and the total number of attributes. + Data attribute at hdf4 is only one-dimensional array. */ + + if (ncomp == 1 && h4size == 1) + strcpy(grlabel,RAST8LABEL); + else if(ncomp == 3 && h4size == 1) + strcpy(grlabel,RAST24LABEL); + else + strcpy(grlabel,GRLABEL); + + strcpy(image_class,IM_CLASS); + + /* transfer hdf4 predefined attributes into hdf5 dataset.*/ + if(h4_transpredattrs(h5dset,HDF4_OBJECT_TYPE,grlabel)==FAIL){ + printf("error in getting hdf4 image type attribute \n"); + free(h5cimage_name); + return FAIL; + } + + if(h4_transpredattrs(h5dset,HDF4_OBJECT_NAME,image_name)==FAIL){ + printf("error in getting hdf4 image name attribute. \n"); + free(h5cimage_name); + return FAIL; + } + + if(h4_transpredattrs(h5dset,HDF4_IMAGE_CLASS,image_class)==FAIL){ + printf("error in getting hdf4 image class attribute. \n"); + free(h5cimage_name); + return FAIL; + } + + gr_ref = GRidtoref(ri_id); + + if(gr_ref == 0) { + printf("error in obtaining reference number of GR.\n"); + free(h5cimage_name); + return FAIL; + } + + if(h4_transnumattr(h5dset,HDF4_REF_NUM,gr_ref)==FAIL) { + printf("error in getting hdf4 image number attribute.\n"); + free(h5cimage_name); + return FAIL; + } + + /* deal with palette. */ + + if(gr_palette(file_id,ri_id,h5dset,h5_palgroup)== FAIL) { + printf("error in translating palette into h5 dataset.\n"); + free(h5cimage_name); + return FAIL; + } + + + ret = H5Sclose(h5d_sid); + ret = H5Dclose(h5dset); + istat = GRendaccess(ri_id); + if(image_data != NULL) free(image_data); + if(h5cimage_name != NULL) free(h5cimage_name); + return SUCCEED; +} + +/**** palette routine. ****/ +/*------------------------------------------------------------------------- + * Function: gr_palette + * + * Purpose: translate palette into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: HDF4 identifier + ri: raster image id + h5dset: hdf5 dataset + h5_palgroup: hdf5 palette group + + Out: + *------------------------------------------------------------------------- + */ + +int gr_palette(int32 file_id,int32 ri_id,hid_t h5dset,hid_t h5_palgroup) { + + int32 pal_id; + uint16 pal_ref; + char palref_str[MAXREF_LENGTH]; + char palg_name[MAX_GR_NAME]; + char image_index[MAX_GR_NAME]; + int check_pal; + int check_palname; + int pal_stat; + char* h5pal_name; + + + /* get palette id */ + pal_id = GRgetlutid(ri_id,0); + if(pal_id == FAIL) { + printf("error in obtaining palette id. \n"); + return FAIL; + } + + pal_ref = GRluttoref(pal_id); + + if(pal_ref >0) { + + /* convert reference number into string format. */ + if(conv_int_str(pal_ref,palref_str)==FAIL) { + printf("error in converting palette reference number into string.\n"); + return FAIL; + } + + /* check whether this palette has been looked up already. */ + check_pal = lookup(pal_ref,PAL_HASHSIZE,pal_hashtab); + + if( check_pal < 0) { + printf("error at looking up palette table. \n"); + return FAIL; + } + + /* if check_pal equals to 1, this palette has already been + converted into hdf5 dataset, just obtain the palette name. + if check_pal equals to 0, we will do the converting. */ + + if(check_pal == 1) { + + h5pal_name = get_name(pal_ref,PAL_HASHSIZE,pal_hashtab, + &check_palname); + + if (h5pal_name == NULL && check_palname == 0 ) { + printf("error,cannot find group\n"); + return FAIL; + } + + if (h5pal_name == NULL && check_palname == -1 ) { + printf("error,group name is not defined.\n"); + return FAIL; + } + + } + + if(check_pal == 0) { + /* do converting. */ + strcpy(palg_name,HDF4_PALG); + + /* obtain hdf5 dataset name converted from palette, + no name for hdf4 palette.*/ + h5pal_name = get_obj_aboname(NULL,palref_str,palg_name,HDF4_PALETTE); + if(h5pal_name == NULL) { + printf("error in getting hdf5 palette name.\n"); + return FAIL; + } + + if(set_name(pal_ref,PAL_HASHSIZE,pal_hashtab,h5pal_name)==FAIL) { + printf("error in setting object name.\n"); + free(h5pal_name); + return FAIL; + } + + pal_stat = Palette_h4_to_h5(file_id,pal_id,h5_palgroup,h5pal_name); + + if(pal_stat == FAIL) { + printf("error occurring in transferring palette into dataset. \n"); + free(h5pal_name); + return FAIL; + } + + } + + if(create_pal_objref(h5dset,h5_palgroup,h5pal_name)== FAIL) { + printf("error in creating palette object reference.\n"); + free(h5pal_name); + return FAIL; + } + + if(h5pal_name != NULL) free(h5pal_name); + + strcpy(image_index,HDF4_IMAGE_INDEXED); + if(h4_transpredattrs(h5dset,HDF4_IMAGE_SUBCLASS,image_index)== FAIL) { + printf("failed to transfer hdf4 image indexed.\n"); + return FAIL; + } + } + return SUCCEED; +} +/***** end of palette application. *****/ +/*------------------------------------------------------------------------- + * Function: gr_tranattrs + * + * Purpose: translate attributes of Image object into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + sri_id: RI identifier + sh5_dset: hdf5 dataset + snum_grattrs: number of attribute + check_gloflag: flag to check whether this attribute belongs + to gr interface. + + Out: + *------------------------------------------------------------------------- + */ +int gr_tranattrs(int32 sri_id, hid_t sh5_dset,int snum_grattrs, + int check_gloflag) { + + char sgratrr_name[2*MAX_NC_NAME]; + char grglo[MAX_NC_NAME]; + char* grrepattr_name; + int32 count_sgradata; + int32 sgr_atype; + size_t sh4_amemsize; + size_t sh4_asize; + + hid_t sh5a_sid; + hid_t sh5a_id; + hid_t sh5_atype; + hid_t sh5_amemtype; + hid_t sh5str_type; + hid_t sh5str_memtype; + hsize_t sh5dims[MAX_VAR_DIMS]; + void* sgr_adata; + herr_t sret; + int i; + + + for (i =0;i <snum_grattrs;i++) { + + if (GRattrinfo(sri_id,i,sgratrr_name,&sgr_atype,&count_sgradata)==FAIL){ + printf("unable to obtain attribute information. \n"); + return FAIL; + } + + /*convert datatype for attribute. */ + + if(h4type_to_h5type(sgr_atype,&sh5_amemtype,&sh4_amemsize, + &sh4_asize,&sh5_atype)==FAIL){ + printf("unable to do type transferring.\n"); + return FAIL; + } + + sgr_adata = malloc(sh4_amemsize*count_sgradata); + + if(GRgetattr(sri_id,i,(VOIDP)sgr_adata)==FAIL){ + printf("unable to get GR attributes. \n"); + return FAIL; + } + + /* if attribute doesn't have name, a default name is set. */ + if(sgratrr_name[0] == '\0') { + grrepattr_name = trans_obj_name(DFTAG_RIG,i); + strcpy(sgratrr_name,grrepattr_name); + free(grrepattr_name); + } + + /* if the sds attribute is a file attribute. */ + if(check_gloflag == 1){ + strcpy(grglo,GLOIMAGE); + strcat(sgratrr_name,"_"); + strcat(sgratrr_name,grglo); + } + /* now do attribute-transferring. + 1. deal with string data type + 2. set attribute space. + 3. get attribute name, set property list. */ + + if (sh5_atype == H5T_STRING) { + + sh5a_sid = H5Screate(H5S_SCALAR); + + if (sh5a_sid < 0) { + printf("failed to create attribute space for IMAGE. \n"); + return FAIL; + } + + if ((sh5str_type = mkstr(count_sgradata*sh4_asize,H5T_STR_NULLTERM))<0){ + printf("error in making string for image attribute \n"); + return FAIL; + } + + /* check this line later. */ + if ((sh5str_memtype = mkstr(count_sgradata*sh4_amemsize, + H5T_STR_NULLTERM))<0){ + printf("error in making memory string. \n"); + return FAIL; + } + + sh5a_id = H5Acreate(sh5_dset,sgratrr_name,sh5str_type,sh5a_sid, + H5P_DEFAULT); + if (sh5a_id <0) { + printf("failed to obtain attribute id for IMAGE. \n"); + return FAIL; + } + + sret = H5Awrite(sh5a_id,sh5str_memtype,(void *)sgr_adata); + + if (sret <0) { + printf("failed to obtain attribute of IMAGE.\n "); + return FAIL; + } + + sret = H5Sclose(sh5a_sid); + sret = H5Aclose(sh5a_id); + } + + else { + + if (count_sgradata == 1) { + + sh5a_sid = H5Screate(H5S_SCALAR); + + if (sh5a_sid < 0) { + printf("failed to create space id. \n"); + return FAIL; + } + } + else { + + sh5dims[0] = count_sgradata; + sh5a_sid = H5Screate_simple(1,sh5dims,NULL); + + if (sh5a_sid < 0) { + printf("failed to create attribute space. \n"); + return FAIL; + } + } + + sh5a_id = H5Acreate(sh5_dset,sgratrr_name,sh5_atype,sh5a_sid, + H5P_DEFAULT); + + if(sh5a_id <0) { + printf("failed to obtain attribute id. \n"); + return FAIL; + } + + sret = H5Awrite(sh5a_id,sh5_amemtype,(void *)sgr_adata); + + if(sret <0) { + printf("failed to obtain attribute.\n "); + return FAIL; + } + sret = H5Aclose(sh5a_id); + sret = H5Sclose(sh5a_sid); + + } + + free(sgr_adata); + + } + + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: create_pal_objref + * + * Purpose: create object reference for palette + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + h5dset: hdf5 dataset + h5_palgroup: hdf5 palette group + h5pal_name: hdf5 palette name + + Out: + *------------------------------------------------------------------------- + */ + +int create_pal_objref(hid_t h5dset,hid_t h5_palgroup,char *h5pal_name){ + + hobj_ref_t pal_refdat; + hsize_t pal_refDims[1]; + hid_t pal_refSpace; + hid_t pal_refType; + hid_t attribID; + herr_t ret; + + pal_refDims[0] = 1; + pal_refSpace = H5Screate_simple(1,pal_refDims,NULL); + + if(pal_refSpace < 0) { + printf("error in obtaining reference space. \n"); + return FAIL; + } + + pal_refType = H5Tcopy(H5T_STD_REF_OBJ); + if(pal_refType < 0) { + printf("error in obtaining reference type. \n"); + H5Sclose(pal_refSpace); + return FAIL; + } + + ret = H5Rcreate(&pal_refdat,h5_palgroup,h5pal_name, + H5R_OBJECT,-1); + if(ret < 0) { + printf("error in creating reference space. \n"); + H5Sclose(pal_refSpace); + H5Tclose(pal_refType); + return FAIL; + } + + attribID = H5Acreate(h5dset,PALETTE,pal_refType,pal_refSpace, + H5P_DEFAULT); + + if(attribID < 0) { + printf("error in obtaining attribute ID. \n"); + H5Sclose(pal_refSpace); + H5Tclose(pal_refType); + return FAIL; + } + + ret = H5Awrite(attribID,pal_refType,(void *)&pal_refdat); + + + H5Sclose(pal_refSpace); + if(H5Tclose(pal_refType)<0) { + printf("error closing palette reference type.\n"); + H5Aclose(attribID); + } + H5Aclose(attribID); + return SUCCEED; +} diff --git a/tools/h4toh5main.c b/tools/h4toh5main.c new file mode 100644 index 0000000..ca8d7fd --- /dev/null +++ b/tools/h4toh5main.c @@ -0,0 +1,1538 @@ +/*** This file is the main program of converter. ***/ + +#include "h4toh5main.h" + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: driver routine to handle all objects of hdf4 file. + * + * Return: FAIL if failed, SUCCEED if successful. + + Modfication: + *------------------------------------------------------------------------- + */ + +int main(int argc, char ** argv) { + + char *h5_filename=NULL; + char *h4_filename=NULL; + char *h5_extension; + int status = 0; + + + argc--; + argv++; + + if (argc == 0) { + fprintf(stderr,"\nError: Invalid Arguments\n"); + PrintOptions_h4toh5(); + return -1; + } + + /* take care -h (help) option first */ + { int i; + for (i=0; i < argc; i++) + if ( HDstrcmp(argv[i],"-h") == 0 ) { + PrintOptions_h4toh5(); + return 0; + } + } + + + switch(argc) { + + case 0: + + PrintOptions_h4toh5(); + break; + + case 1: /* h4toh5 file1 */ + h4_filename = argv[0]; + + if (test_file(h4_filename,O_EXCL,292) != 0 ) { + /* 292 Decimal - 0444 Octal, a+r */ + printf("the current hdf4 file name is not set properly.\n"); + status = -1; + break; + } + if (test_dir(h4_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h4_filename); + status = -1; + break; + } + + h5_extension = HDstrdup("h5"); + h5_filename = BuildFilename(h4_filename,h5_extension); + if (h5_filename == NULL) { + printf("error in creating hdf5 file name.\n"); + status = -1; + break; + } + + if (test_file(h5_filename,O_CREAT|O_EXCL,436) != 0) { + /* 436 Decimal - 0664 Octal, ug+rw,o+r */ + printf("permission of hdf5 file is not set properly.\n"); + status = -1; + break; + } + + /*0. check whether this file is a hdf file. */ + + if(!Hishdf(h4_filename)){ + printf("error: not an hdf file. \n"); + printf("the file will not be converted. \n"); + return FAIL; + } + + + status = h4toh5(h4_filename, h5_filename); + + if ( status == FAIL ) { + printf("error in converting %s into %s\n",h4_filename,h5_filename); + break; + } + if (h5_filename != NULL) { + free(h5_filename); + } + + break; + + case 2: /* h5toh4 file_in file_out */ + h4_filename = argv[0]; + h5_filename = argv[1]; + + if (test_file(h4_filename,O_EXCL,292) != 0 ) { + /* 292 Decimal - 0444 Octal, a+r */ + printf("permission of hdf4 file is not set properly.\n"); + status = -1; + break; + } + + if (test_dir(h4_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h4_filename); + status = -1; + break; + } + + if (test_file(h5_filename,O_CREAT|O_RDWR,436) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */ + printf("permission of hdf5 file is not set properly.\n"); + status = -1; + break; + } + if (test_dir(h4_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h4_filename); + status = -1; + break; + } + + /*0. check whether this file is a hdf file. */ + + if(!Hishdf(h4_filename)){ + printf("error: not an hdf file. \n"); + printf("the file will not be converted. \n"); + return FAIL; + } + + status = h4toh5(h4_filename, h5_filename); + if ( status == FAIL ) { + printf("error in converting %sinto %s\n",h4_filename,h5_filename); + break; + } + break; + + default: + break; + } + + return status; + +} + +/*------------------------------------------------------------------------- + * Function: h4toh5 + * + * Purpose: This routine checks out arguments sent, makes sure that hdf4 + file is valid, makes sure filename for hdf5 file is correct, + and then call h4toh5(). + + *------------------------------------------------------------------------- + */ +int h4toh5(char*filename4, char*filename5) { + + /* define variables for hdf4. */ + int32 istat ; /* hdf4 library routine return value. */ + int32 file_id;/* file identfier of hdf file.*/ + int32 sd_id;/* sd interface identifer*/ + int32 gr_id;/* gr interface identifer*/ + int check_glo; + + /* define variables for hdf5. */ + hid_t file5_id;/* hdf5 file identifier. */ + hid_t h5_root;/* new hdf5 root group identifier.*/ + + hid_t h5_dimg;/* hdf5 dimensional scale group identifier. */ + hid_t h5_palg;/* hdf5 palette group identifier. */ + + + + + /*1. open the current hdf4 file. */ + + file_id = Hopen(filename4, DFACC_READ, 0); + if(file_id == FAIL) { + printf("error: no such hdf4 files. \n"); + return FAIL; + } + + /* open sd interface.*/ + sd_id = SDstart(filename4,DFACC_READ); + if(sd_id == FAIL) { + printf("error: cannot start SD interface. \n"); + Hclose(file_id); + return FAIL; + } + + /* open gr interface.*/ + gr_id = GRstart(file_id); + if(gr_id == FAIL) { + printf("error in obtaining gr id. \n"); + SDend(sd_id); + Hclose(file_id); + return FAIL; + } + + /* open V interface. */ + istat = Vstart(file_id); + if(istat == FAIL) { + printf("error in starting V interface. \n"); + SDend(sd_id); + GRend(gr_id); + Hclose(file_id); + return FAIL; + } + + /* 2. obtain number of hdf4 objects(sds,image,vdata,vgroup,palette) + in this hdf4 file. */ + + if(get_numof_hdf4obj(filename4,file_id) == FAIL) { + printf("error in obtaining number of hdf4 objects.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + return FAIL; + } + + /* set up global hash tables for hdf4 objects. */ + if(set_hashtables() == FAIL){ + printf("error in setting hashtables. \n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + return FAIL; + } + + /* create hdf5 file. */ + file5_id = H5Fcreate(filename5,H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT); + + if (file5_id < 0) { + fprintf(stderr, "unable to create hdf5 file \n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + free_allhashmemory(); + return FAIL; + } + + /* Initialize hdf5 group interface. */ + h5_root = H5Gopen(file5_id,"/"); + + if(h5_root < 0) { + printf("error in opening hdf5 root group. \n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /**** build up helper groups(dimensional scale and palette) ****/ + if(set_helpgroups(h5_root,&h5_dimg,&h5_palg)==FAIL) { + printf("error setting up dimensional scale and palette groups.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /* convert global sds attributes into global attributes under root group.*/ + check_glo = 1; + + if(sds_transattrs(sd_id, h5_root,num_glsdsattrs,check_glo)==FAIL) { + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + + /* convert global image attributes into global attributes under root group.*/ + check_glo = 1; + + if(gr_tranattrs(gr_id, h5_root,num_glgrattrs,check_glo)==FAIL) { + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /* convert all objects in lone vgroups into corresponding hdf5 objects. */ + if(h4toh5lonevgs(file_id,sd_id,h5_root,h5_dimg,h5_palg)== FAIL) { + printf("error in translating lone vgroup into hdf5 objects.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + +/*convert all objects in group rings into corresponding hdf5 objects. */ + if(h4toh5vgrings(file_id,sd_id,h5_root,h5_dimg,h5_palg) == FAIL){ + printf("error in translating vgroup rings into hdf5 objects.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /*convert all independent lone vdata into corresponding hdf5 datasets with + compound data type. */ + if(h4toh5lonevds(file_id,h5_root) == FAIL){ + printf("error in translating lone independent vdata into hdf5 objects.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /*** convert hdf file annotations into hdf5 attributes under the root.***/ + if(Annofil_h4_to_h5(file_id,h5_root) == FAIL) { + printf("error in translating file annotations into root attributes.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /*** deal with untouched sds objects.convert them into hdf5 datasets under root group.***/ + + if(h4toh5unvisitedsds(file_id,sd_id,h5_root,h5_dimg) == FAIL) { + printf("error in converting unvisited sds objects into hdf5 file.\n"); SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + /*** deal with untouched image objects. convert them into hdf5 datasets under root group. ***/ + + if(h4toh5unvisitedimages(file_id,h5_root,h5_palg) == FAIL) { + printf("error in converting unvisited image objects into hdf5 file.\n"); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + free_allhashmemory(); + return FAIL; + } + + free_allhashmemory(); + SDend(sd_id); + GRend(gr_id); + Vend(file_id); + Hclose(file_id); + if(num_sds >0) H5Gclose(h5_dimg); + if(num_images >0) H5Gclose(h5_palg); + H5Gclose(h5_root); + H5Fclose(file5_id); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: get_numof_hdf4obj + * + * Purpose: get number or estimated number of hdf4 objects + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: hdf file identifier + filename: hdf file name + Out: + Modification: + *------------------------------------------------------------------------- + */ +int get_numof_hdf4obj(char*filename,int32 file_id) { + + int32 sd_id;/* sd interface identifer*/ + int32 gr_id;/* gr interface identifer*/ + int num_lonevd;/* number of lone vdata*/ + int num_lonevg;/* number of lone vgroup.*/ + int32 istat; + + estnum_vg = 0; + estnum_vd = 0; + num_sds = 0; + num_images = 0; + num_objects = 0; + + /* obtain number of sds and number of global sds attribute. */ + + sd_id = SDstart(filename,DFACC_READ); + if(sd_id == FAIL) { + printf("error: cannot start SD interface. \n"); + return FAIL; + } + + if(SDfileinfo(sd_id,&num_sds,&num_glsdsattrs) == FAIL) { + printf("error in obtaining SDS information from the file.\n"); + return FAIL; + } + + + /* obtain number of images and number of global image attributes.*/ + + gr_id = GRstart(file_id); + if(gr_id == FAIL) { + printf("error in obtaining gr id. \n"); + return FAIL; + } + + if(GRfileinfo(gr_id,&num_images,&num_glgrattrs) == FAIL) { + printf("error in obtaining GR information from the file. \n"); + return FAIL; + } + + /* obtain number of lone vgroup and lone vdata. */ + + istat = Vstart(file_id); + if (istat == FAIL) { + fprintf(stderr, "unable to start hdf4 V interface.\n"); + return FAIL; + } + + num_lonevd = VSlone(file_id,NULL,0); + if(num_lonevd == FAIL) { + printf("error in obtaining lone vdata number. \n"); + return FAIL; + } + + num_lonevg = Vlone(file_id,NULL,0); + if(num_lonevg == FAIL) { + printf("error in obtaining lone vgroup number. \n"); + return FAIL; + } + + /* intelligent guess of the total number of vgroups,total number of + independent vdata. */ + + estnum_vg = 6* num_lonevg; + estnum_vd = 4* num_lonevd; + + /* set the size of name hashtable to num_objects. */ + num_objects = estnum_vg + estnum_vd + num_sds + num_images; + + return SUCCEED; +} + + + +/*------------------------------------------------------------------------- + * Function: set_helpgroups + * + * Purpose: get number or estimated number of hdf4 objects + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + h5root: hdf5 group identifier + h5dimgptr: h5 dimensional group pointer + h5palgptr: h5 palette group pointer + Modification: + *------------------------------------------------------------------------- + */ + +int set_helpgroups(hid_t h5root,hid_t* h5dimgptr,hid_t* h5palgptr){ + + hid_t h5_dimg;/* hdf5 dimensional scale group identifier. */ + hid_t h5_palg;/* hdf5 palette group identifier. */ + + /*1. dimensional scale group.*/ + + if(num_sds > 0) { + h5_dimg = H5Gcreate(h5root,HDF4_DIMG,0); + if (h5_dimg <0) { + printf("error in creating hdf5 dimensional scale group. \n"); + return FAIL; + } + + *h5dimgptr = h5_dimg; + } + + /*2. palette group.*/ + + if(num_images >0) { + h5_palg = H5Gcreate(h5root,HDF4_PALG,0); + if(h5_palg <0) { + printf("error in creating hdf5 palette group. \n"); + H5Gclose(h5_dimg); + return FAIL; + } + + *h5palgptr = h5_palg; + } + + return SUCCEED; + +} + + +/*------------------------------------------------------------------------- + * Function: set_hashtables + * + * Purpose: set up hashtables + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + + Out: + Modification: + *------------------------------------------------------------------------- + */ +int set_hashtables(void) { + + if(num_sds != 0) { + sds_hashtab = malloc(sizeof(struct table)*2*num_sds); + if(init_tab(2*num_sds,sds_hashtab)== FAIL){ + printf("cannot initialize sds hashing table. \n"); + return FAIL; + } + } + + if(num_images != 0) { + gr_hashtab = malloc(sizeof(struct table)*2*num_images); + if(init_tab(2*num_images,gr_hashtab) == FAIL){ + printf("cannot initialize image hashing table. \n"); + return FAIL; + } + } + + /*hashtable is made to be fixed for dimensional scale and palette.*/ + + if(num_sds != 0) { + dim_hashtab = malloc(sizeof(struct name_table)*DIM_HASHSIZE); + if(init_nametab(DIM_HASHSIZE,dim_hashtab) == FAIL) { + printf("can not initialize dimension hashing table.\n"); + return FAIL; + } + } + + /* initialize the palette table */ + if(num_images != 0){ + pal_hashtab = malloc(sizeof(struct table)*PAL_HASHSIZE); + if(init_tab(PAL_HASHSIZE,pal_hashtab) == FAIL) { + printf("can not initialize palette hashing table.\n"); + return FAIL; + } + } + + /* initialize the vgroup table */ + if(estnum_vg > 0) { + vg_hashtab = malloc(sizeof(struct table)*estnum_vg); + } + else { + estnum_vg = VG_DEFHASHSIZE; + vg_hashtab = malloc(sizeof(struct table)*estnum_vg); + } + if(init_tab(estnum_vg,vg_hashtab) == FAIL) { + printf("error in allocating memory for vgroup hashing table.\n"); + return FAIL; + } + + /* initialize the vdata table.*/ + if(estnum_vd > 0) { + vd_hashtab = malloc(sizeof(struct table)*estnum_vd); + } + else { + estnum_vd = VD_DEFHASHSIZE; + vd_hashtab = malloc(sizeof(struct table)*estnum_vd); + } + + if(init_tab(estnum_vd,vd_hashtab)== FAIL) { + printf("cannot initialize vdata hashing table.\n"); + return FAIL; + } + + /* The name hashtable is only for dealing with name clashing, + num_objects is the size of the hash table. */ + + if(num_objects != 0){ + name_hashtab = malloc(sizeof(struct name_table)*num_objects); + if(init_nametab(num_objects,name_hashtab)== FAIL) { + printf("cannot initialize name hashing table. \n"); + return FAIL; + } + } + + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: h4toh5lonevgs + * + * Purpose: Recursively convert hdf4 objects in lone vgroups into + corresponding hdf5 datasets + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : file_id: hdf file id + sd_id: hdf sd interface id + h5group: hdf5 group id + h5_dimg: hdf5 dimensional scale group id + h5_palg: hdf5 palette group id + + Out: + Modification: + *------------------------------------------------------------------------- + */ +int h4toh5lonevgs(int32 file_id,int32 sd_id,hid_t h5group,hid_t h5_dimg,hid_t h5_palg) { + + int32 vgroup_id; + int num_lonevg; /* number of lone vgroup.*/ + int32 *ref_array; + int32 istat; + char vgroup_name[VGNAMELENMAX]; + char* cor_vgroupname; + char vgroup_class[VGNAMELENMAX]; + char refstr[MAXREF_LENGTH]; + int check_vgroup; + int check_tabst; + int lone_vg_number; + char *h5cgroup_name; + + istat = Vstart(file_id); + if (istat == FAIL) { + fprintf(stderr, "unable to start hdf4 V interface.\n"); + return FAIL; + } + + num_lonevg = Vlone(file_id,NULL,0); + + if (num_lonevg == FAIL) { + printf("error in obtaining lone vgroup number. \n"); + return FAIL; + } + + /* obtain object reference array. */ + + ref_array = (int32 *)malloc(sizeof(int32) *num_lonevg); + + if(ref_array == NULL) { + printf("error in allocating memory for ref_array.\n"); + return FAIL; + } + + num_lonevg = Vlone(file_id,ref_array,num_lonevg); + + /* walk through every lone group in the file */ + + for(lone_vg_number = 0; lone_vg_number < num_lonevg; + lone_vg_number++) { + + vgroup_id = Vattach(file_id,ref_array[lone_vg_number],"r"); + + if(vgroup_id ==FAIL) { + printf("error in attaching lone vgroup.\n"); + free(ref_array); + return FAIL; + } + + /*obtain group name and class name.*/ + bzero(vgroup_class,VGNAMELENMAX); + istat = Vgetclass(vgroup_id,vgroup_class); + if(istat == FAIL) { + printf("error in getting vgroup class.\n"); + free(ref_array); + Vdetach(vgroup_id); + return FAIL; + } + + bzero(vgroup_name,VGNAMELENMAX); + istat = Vgetname(vgroup_id,vgroup_name); + if(istat == FAIL ) { + printf("error in getting vgroup name. \n"); + Vdetach(vgroup_id); + free(ref_array); + return FAIL; + } + + /* check for CDF0.0 and RIG0.0, if yes + don't go into this group.*/ + + if(strcmp(vgroup_class,_HDF_CDF)==0) { + Vdetach(vgroup_id); + continue; + } + if(strcmp(vgroup_class,GR_NAME)==0) { + Vdetach(vgroup_id); + continue; + } + + /* converting integer number into string format. */ + if(conv_int_str(ref_array[lone_vg_number],refstr) == FAIL) { + printf("ref. is negative, error in converting\n"); + Vdetach(vgroup_id); + free(ref_array); + return FAIL; + } + + /* checking whether vgroup name contains ORI_SLASH, changing into CHA_SLASH.*/ + cor_vgroupname = correct_name(vgroup_name); + if(cor_vgroupname == NULL) { + printf("error in generating corrected vgroup name. \n"); + Vdetach(vgroup_id); + free(ref_array); + return FAIL; + } + + /* obtaining group name of the converted lone vgroup. In this call, + we will deal with cases such as name clashing and no available vgroup + name. */ + + h5cgroup_name = get_obj_aboname(cor_vgroupname,refstr,NULL,HDF4_VGROUP); + + if(h5cgroup_name == NULL) { + printf("error in getting group name.\n"); + Vdetach(vgroup_id); + free(ref_array); + free(cor_vgroupname); + return FAIL; + } + + /* printf("h5cgroup_name %s\n",h5cgroup_name);*/ + free(cor_vgroupname); + + /* updating lookup table for vgroups.*/ + + check_vgroup = lookup(ref_array[lone_vg_number],estnum_vg,vg_hashtab); + + if(check_vgroup == 0) { /* adding this vgroup into the list. */ + + check_tabst = set_name(ref_array[lone_vg_number],estnum_vg, + vg_hashtab,h5cgroup_name); + if(check_tabst == FAIL) { + printf("not enough memory to be allocated for vgroup name. \n"); + Vdetach(vgroup_id); + free(h5cgroup_name); + free(ref_array); + return FAIL; + } + } + + /* this line is for debugging. */ + + if(check_vgroup == 1){ + fprintf(stderr,"this vgroup should not be touched. \n"); + Vdetach(vgroup_id); + free(h5cgroup_name); + free(ref_array); + return FAIL; + } + + if(Vgroup_h4_to_h5(file_id,vgroup_id,sd_id,h5group,h5_dimg,h5_palg)==FAIL){ + printf("error in translating vgroup into hdf5 objects.\n"); + Vdetach(vgroup_id); + free(h5cgroup_name); + free(ref_array); + return FAIL; + } + + Vdetach(vgroup_id); + free(h5cgroup_name); + } + free(ref_array); + return SUCCEED; +} + + + +/*------------------------------------------------------------------------- + * Function: h4toh5vgrings + * + * Purpose: Recursively convert objects at special hdf4 vgroups + (vgroup rings) + into objects of corresponding hdf5 groups. The strategy here + is to arbitrily grab any vgroup in the group ring and put it + under hdf5 root. + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : file_id: hdf file id + sd_id: hdf sds id + h5group: hdf5 group id + h5_dimg: hdf5 dimensional scale group id + h5_palg: hdf5 palette group id + + Out: + Modification: + *------------------------------------------------------------------------- + */ + +int h4toh5vgrings(int32 file_id,int32 sd_id,hid_t h5group,hid_t h5_dimg,hid_t h5_palg){ + + int32 vgroup_id; + int32 ref_num; + char vgroup_name[VGNAMELENMAX]; + char* cor_vgroupname; + char vgroup_class[VGNAMELENMAX]; + char refstr[MAXREF_LENGTH]; + int check_vgroup; + int32 istat; + char *h5cgroup_name; + + ref_num = Vgetid(file_id,-1); + + while (ref_num != -1) { + + /* if we find a group that is not touched, grab it under root group.*/ + + check_vgroup = lookup(ref_num,estnum_vg,vg_hashtab); + + if (check_vgroup == 0){ + + vgroup_id = Vattach(file_id,ref_num,"r"); + if(vgroup_id ==FAIL) { + printf("error in attaching group in a group ring. \n"); + return FAIL; + } + + bzero(vgroup_name,VGNAMELENMAX); + istat = Vgetname(vgroup_id,vgroup_name); + if(istat ==FAIL) { + printf("error in obtaining vgroup names. \n"); + Vdetach(vgroup_id); + return FAIL; + } + + bzero(vgroup_class,VGNAMELENMAX); + if(Vgetclass(vgroup_id,vgroup_class) == FAIL) { + printf("error in obtaining vgroup class name. \n"); + Vdetach(vgroup_id); + return FAIL; + } + + /* do nothing for those predefined attribute.*/ + + if(vgroup_class != NULL) { + + if(strcmp(vgroup_class,_HDF_ATTRIBUTE)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + + if(strcmp(vgroup_class,_HDF_VARIABLE)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + + if(strcmp(vgroup_class,_HDF_DIMENSION)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + + if(strcmp(vgroup_class,_HDF_UDIMENSION)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + + if(strcmp(vgroup_class,_HDF_CDF)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + + if(strcmp(vgroup_class,GR_NAME)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + + if(strcmp(vgroup_class,RI_NAME)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + } + + if(vgroup_name != NULL) { + if(strcmp(vgroup_name,GR_NAME)==0) { + ref_num = Vgetid(file_id,ref_num); + Vdetach(vgroup_id); + continue; + } + } + + /* convert reference number into string format. */ + if(conv_int_str(ref_num,refstr) == FAIL) { + printf("ref. is negative, error in converting\n"); + Vdetach(vgroup_id); + return FAIL; + } + + /* checking whether vgroup name contains ORI_SLASH, changing into CHA_SLASH.*/ + cor_vgroupname = correct_name(vgroup_name); + if(cor_vgroupname == NULL) { + printf("error in generating corrected vgroup name. \n"); + Vdetach(vgroup_id); + return FAIL; + } + /* obtain the hdf5 group name. */ + h5cgroup_name = get_obj_aboname(cor_vgroupname,refstr,NULL,HDF4_VGROUP); + + if(h5cgroup_name == NULL) { + printf("error in getting vgroup name.\n"); + Vdetach(vgroup_id); + free(cor_vgroupname); + return FAIL; + } + + free(cor_vgroupname); + if(set_name(ref_num,estnum_vg,vg_hashtab,h5cgroup_name)==FAIL) { + printf("error in setting h5 group name.\n"); + Vdetach(vgroup_id); + free(h5cgroup_name); + return FAIL; + } + + if(Vgroup_h4_to_h5(file_id,vgroup_id,sd_id,h5group,h5_dimg,h5_palg) + ==FAIL){ + + printf("error in translating vgroup into hdf5 group\n"); + Vdetach(vgroup_id); + free(h5cgroup_name); + return FAIL; + } + + Vdetach(vgroup_id); + free(h5cgroup_name); + } + ref_num = Vgetid(file_id,ref_num); + } + return SUCCEED; + +} + + +/*------------------------------------------------------------------------- + * Function: h4toh5lonevds + * + * Purpose: convert hdf4 lone vdata into + the corresponding hdf5 datasets + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : file_id: hdf file id + h5group: hdf5 group id + + Out: + Modification: + *------------------------------------------------------------------------- + */ +int h4toh5lonevds(int32 file_id, hid_t h5group){ + + int32 vdata_id; + int32 *ref_vdata_array; + int32 vdata_tag; + int32 vdata_ref; + int32 istat; + char vdata_name[VGNAMELENMAX]; + char* cor_vdataname; + char vdata_class[VGNAMELENMAX]; + char refstr[MAXREF_LENGTH]; + int check_vdata; + int lone_vd_number; + int num_lonevd; + char *h5cvdata_name; + + num_lonevd = VSlone(file_id,NULL,0); + + if (num_lonevd == FAIL) { + printf("error in obtaining lone vgroup number. \n"); + return FAIL; + } + + if (num_lonevd > 0) { + + ref_vdata_array = (int32 *)malloc(sizeof(int32) *(num_lonevd)); + + num_lonevd = VSlone(file_id,ref_vdata_array,num_lonevd); + if(num_lonevd == FAIL) { + printf("error in obtaining lone vdata number the second time.\n"); + free(ref_vdata_array); + } + /* walk through all lone vdatas. */ + + for(lone_vd_number = 0; lone_vd_number < num_lonevd;lone_vd_number++) + { + vdata_id = VSattach(file_id,ref_vdata_array[lone_vd_number],"r"); + + if(vdata_id == FAIL) { + printf("error in obtaining vdata id for lone vdata.\n"); + free(ref_vdata_array); + } + + /* Make sure this vdata is not an attribute of other hdf4 objects.*/ + + if(!VSisattr(vdata_id)) { + vdata_ref = VSQueryref(vdata_id); + if(vdata_ref == FAIL) { + printf("error in getting vdata reference number.\n"); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + + vdata_tag = VSQuerytag(vdata_id); + if(vdata_tag == FAIL){ + printf("error in getting vdata tag.\n"); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + + bzero(vdata_class,VGNAMELENMAX); + istat = VSgetclass(vdata_id,vdata_class); + if(istat == FAIL) { + printf("error in getting vdata class name.\n"); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + + bzero(vdata_name,VGNAMELENMAX); + istat = VSQueryname(vdata_id,vdata_name); + if(istat == FAIL) { + printf("error in getting vdata name. \n"); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + + /* converting reference number into string format.*/ + if(conv_int_str(ref_vdata_array[lone_vd_number],refstr)==FAIL) { + printf("error in converting int to string.\n"); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + /* checking whether vdata name contains ORI_SLASH, changing into CHA_SLASH.*/ + cor_vdataname = correct_name(vdata_name); + if(cor_vdataname == NULL) { + printf("error in generating corrected vgroup name. \n"); + VSdetach(vdata_id); + free(ref_vdata_array); + return FAIL; + } + /* obtaining hdf5 dataset name that is converted from hdf4 vdata.*/ + h5cvdata_name = get_obj_aboname(cor_vdataname,refstr,NULL,HDF4_VDATA); + if(h5cvdata_name == NULL) { + printf("error in getting vdata name.\n"); + free(ref_vdata_array); + VSdetach(vdata_id); + free(cor_vdataname); + return FAIL; + } + + free(cor_vdataname); + check_vdata = lookup(ref_vdata_array[lone_vd_number],estnum_vd, + vd_hashtab); + if(check_vdata == 1){ + printf("lone vdata should not be checked before.\n"); + free(h5cvdata_name); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + + if(set_name(ref_vdata_array[lone_vd_number],estnum_vd,vd_hashtab, + h5cvdata_name)==FAIL) { + printf("error in setting lone vdata name. \n"); + free(ref_vdata_array); + free(h5cvdata_name); + VSdetach(vdata_id); + return FAIL; + } + + if(Vdata_h4_to_h5(file_id,vdata_id,h5group)== FAIL) { + printf("error in translating independent vdata into"); + printf(" hdf5 datasets.\n"); + free(h5cvdata_name); + free(ref_vdata_array); + VSdetach(vdata_id); + return FAIL; + } + free(h5cvdata_name); + } + + VSdetach(vdata_id); + } + free(ref_vdata_array); + } + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: h4toh5unvisitedsds + * + * Purpose: convert unvisited sds objects into hdf5 datasets and put these + datasets under hdf5 root group + This routine will cover old hdf file that doesn't have vgroups. + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + sd_id: hdf sds id + h5root: hdf5 root id + h5_dimg: hdf5 dimensional scale group id + + Out: + Modification: + *------------------------------------------------------------------------- + */ + + +int h4toh5unvisitedsds(int32 file_id,int32 sd_id,hid_t h5root,hid_t h5_dimg) { + + int i; + int32 sds_id;/* sd dataset identifer*/ + int32 sds_rank;/* sds dataset dimension rank.*/ + int32 sds_dimsizes[DIM_HASHSIZE];/* array that contains the size of the each dimension in sds dataset.*/ + int32 sds_dtype;/*sds dataset datatype.*/ + int32 num_sdsattrs;/* number of sds attributes. */ + char sds_name[MAX_NC_NAME];/* sds name.*/ + char* cor_sdsname; + int32 obj_ref; /* obj reference number assigned to sds and images.*/ + char refstr[MAXREF_LENGTH];/*object reference number in character string format.*/ + int check_sds;/* flag to check whether this sds is visited. 1 for visited and 0 for non-visited.*/ + char *h5csds_name;/* absolute path name of hdf5 dataset transferred from old sds.*/ + + if(sd_id == FAIL) { + printf("error: cannot start SD interface. \n"); + return FAIL; + } + + /* check all sds objects. */ + for(i=0;i<num_sds;i++){ + + sds_id = SDselect(sd_id,i); + + if (sds_id == FAIL) { + printf("error in obtaining sd id.\n"); + return FAIL; + } + + /* if this sds is dimensional scale, the converting should be ignored. */ + if(SDiscoordvar(sds_id)) continue; + + /* obtain sds information. */ + if(SDgetinfo(sds_id,sds_name,&sds_rank,sds_dimsizes, + &sds_dtype,&num_sdsattrs)== FAIL) { + printf("error in obtaining SD info at "); + printf("the unvisited sds routine.\n"); + SDendaccess(sds_id); + return FAIL; + } + + /* obtain object reference number of the current sds dataset.*/ + obj_ref = SDidtoref(sds_id); + if(obj_ref == FAIL) { + printf("error in obtaining sds object reference at "); + printf("the unvisited sds routine.\n"); + SDendaccess(sds_id); + return FAIL; + } + + /* convert object reference number into string format. */ + if(conv_int_str(obj_ref,refstr) == FAIL) { + printf("error in converting integer into string.\n"); + SDendaccess(sds_id); + return FAIL; + } + + /* check whether the current sds is visited or not. */ + check_sds = lookup(obj_ref,2*num_sds,sds_hashtab); + + /* if not visited, we will do the convertion. */ + + if(check_sds == 0) { + /* since different hdf sds may hold the same name and it is also + legal that sds may not have a name; but for hdf5 dataset, + it must hold a name, so we will use get_obj_aboname to guarrtte + that each new hdf5 dataset converted from + sds objects will have a disabiguous name. */ + + /* checking whether vgroup name contains ORI_SLASH, changing into CHA_SLASH.*/ + cor_sdsname = correct_name(sds_name); + if(cor_sdsname == NULL) { + printf("error in generating corrected sds name. \n"); + SDendaccess(sds_id); + return FAIL; + } + h5csds_name = get_obj_aboname(cor_sdsname,refstr,NULL,HDF4_SDS); + if(h5csds_name == NULL) { + printf("error in obtaining sds name.\n"); + SDendaccess(sds_id); + free(cor_sdsname); + return FAIL; + } + free(cor_sdsname); + /* put this name into hashtable. */ + if(set_name(obj_ref,2*num_sds,sds_hashtab,h5csds_name)==FAIL) { + printf("error in setting object name.\n"); + SDendaccess(sds_id); + free(h5csds_name); + return FAIL; + } + + /* do the convertion from sds into hdf5 dataset.*/ + if(Sds_h4_to_h5(file_id,sds_id,h5root,h5_dimg)== FAIL){ + printf("error in translating sds into hdf5 dataset.\n"); + SDendaccess(sds_id); + free(h5csds_name); + return FAIL; + } + free(h5csds_name); + } + SDendaccess(sds_id); + } + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: h4toh5unvisitedimages + * + * Purpose: convert unvisited images into hdf5 dataset and put it + under hdf5 root group + This routine will cover old hdf file. + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: hdf file id + h5_root: hdf5 root id + h5_palg: hdf5 palette group id + + Out: + Modification: + *------------------------------------------------------------------------- + */ +int h4toh5unvisitedimages(int32 file_id,hid_t h5_root,hid_t h5_palg) { + + int i; + int32 istat; + int32 gr_id; + int32 ri_id;/*raster image identifer.*/ + char image_name[MAX_GR_NAME];/* image name.*/ + char* cor_imagename; + int check_image;/* flag to check whether this image is visited. 1 for visited and 0 for non-visited.*/ + int32 obj_ref; /* obj reference number assigned to sds and images.*/ + char refstr[MAXREF_LENGTH];/*object reference number in character string format.*/ + char *h5cimage_name;/* absolute path name of hdf5 dataset transferred from old image.*/ + + gr_id = GRstart(file_id); + if(gr_id == FAIL) { + printf("error in obtaining gr id. \n"); + return FAIL; + } + + /* check all images. */ + for (i=0;i<num_images;i++) { + + ri_id = GRselect(gr_id,i); + if(ri_id ==FAIL) { + printf("error in selecting gr interface.\n"); + return FAIL; + } + + /* obtain information of GR */ + istat = GRgetiminfo(ri_id, image_name, NULL, NULL, NULL, NULL, NULL); + + if(istat == FAIL) { + printf("error in getting GR images.\n"); + GRendaccess(ri_id); + return FAIL; + } + + /* obtain object reference number and convert it into string format. */ + obj_ref = GRidtoref(ri_id); + if(obj_ref == 0) { + printf("error in obtaining image reference number"); + printf(" at h4toh5unvisitedimages routine.\n"); + GRendaccess(ri_id); + return FAIL; + } + + if(conv_int_str(obj_ref,refstr)== FAIL) { + printf("error in converting object reference number"); + printf(" into string at h4toh5unvisitedimages routine.\n"); + GRendaccess(ri_id); + return FAIL; + } + + /* check whether the current image is visited or not. */ + check_image = lookup(obj_ref,2*num_images,gr_hashtab); + + if(check_image == 0) { + + /* since different hdf image may hold the same name and it is + also legal that an image may not have a name; but for hdf5 + dataset, it must hold a name, so we will use get_obj_aboname + to guarrtte that each new hdf5 dataset converted from + image objects will have a disabiguous name. */ + + /* checking whether vgroup name contains ORI_SLASH, + changing into CHA_SLASH.*/ + + cor_imagename = correct_name(image_name); + if(cor_imagename == NULL) { + printf("error in generating corrected image name. \n"); + GRendaccess(ri_id); + return FAIL; + } + h5cimage_name = get_obj_aboname(cor_imagename,refstr,NULL, + HDF4_IMAGE); + if(h5cimage_name == NULL) { + printf("error in getting image name.\n"); + GRendaccess(ri_id); + free(cor_imagename); + return FAIL; + } + free(cor_imagename); + + if(set_name(obj_ref,2*num_images,gr_hashtab,h5cimage_name)==FAIL) { + printf("error setting image name.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + return FAIL; + } + + /* do the convertion from the image into hdf5 dataset.*/ + if(Image_h4_to_h5(file_id,ri_id,h5_root,h5_palg)== FAIL) { + printf("error in transferring image name into hdf5 dataset.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + return FAIL; + } + free(h5cimage_name); + } + GRendaccess(ri_id); + } + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: free_allhashmemory() + * + * Purpose: free memory allocated for all hashtables + * + * Return: + * + * In : + + + Out: + Modification: + *------------------------------------------------------------------------- + */ + +void free_allhashmemory(){ + + if(estnum_vg != 0) freetable(estnum_vg,vg_hashtab); + if(estnum_vd != 0) freetable(estnum_vd,vd_hashtab); + + if(num_sds !=0) { + freetable(2*num_sds,sds_hashtab); + freenametable(DIM_HASHSIZE,dim_hashtab); + } + + if(num_images !=0) { + freetable(2*num_images,gr_hashtab); + freetable(PAL_HASHSIZE,pal_hashtab); + } + + if(num_objects !=0) freenametable(num_objects,name_hashtab); + +} + +void PrintOptions_h4toh5(void) +{ + fprintf(stderr,"\nh4toh5 -h (gives this print-out)\n"); + fprintf(stderr,"h4toh5 file.hdf file.h5\n"); + fprintf(stderr,"h4toh5 file.hdf\n"); +} + +/********The following routines are adapted from h5toh4 converter. *******/ +/***************************************************************************** + + Routine: test_file + + Description: Test a file for read/write - ability. + + Input: filename - Unix filename + + Output: function return, global variable - errno + +*****************************************************************************/ + +int test_file(char *filename,int oflag,mode_t mode) +{ + int fid; + + errno = 0; + + fid = open(filename, oflag, mode); + if (fid < 0) { + perror(filename); + } + close(fid); + + return errno; + +} + + +/***************************************************************************** + + Routine: test_dir + + Description: Test pathway to determine if it is a directory + + Input: path - pathname given + + Output: function return TRUE/FALSE + +*****************************************************************************/ + +int test_dir(char *path) +{ + + struct stat buf; + struct stat *buf_ptr; + int idir; + + buf_ptr = &buf; + + idir = stat(path, buf_ptr); + if (idir < 0) { + if (errno == 2) { + return 0; + } else { + perror(path); + } + } + + return S_ISDIR(buf_ptr->st_mode); +} + +/***************************************************************************** + + Routine: BuildFilename() + + Description: Build a filename with new extension + + Input: filename - present filename + ext - extension to root of filename + + Output: (filename:r).ext + +*****************************************************************************/ + +char *BuildFilename(char *filename, char *ext) +{ + /* build outgoing filename */ + + char *filename_out; + char *lastper_ptr, *lastdir_ptr; + int root_len; + + lastper_ptr = strrchr(filename,'.'); + lastdir_ptr = strrchr(filename,'/'); + + if ( lastper_ptr <= lastdir_ptr ) { /* no extension */ + root_len = strlen(filename); + } else { /* existing extension */ + root_len = (int)(lastper_ptr - filename); + } + + filename_out = (char *)HDmalloc(root_len + strlen(ext) + 2); + filename_out = strncpy(filename_out, filename, (size_t)root_len); + filename_out[root_len] = '\0'; + filename_out = strcat(filename_out,"."); + filename_out = strcat(filename_out,ext); + + return filename_out; +} + + diff --git a/tools/h4toh5main.h b/tools/h4toh5main.h new file mode 100644 index 0000000..8966011 --- /dev/null +++ b/tools/h4toh5main.h @@ -0,0 +1,56 @@ +#include "hdf.h" +#include "mfhdf.h" +#include "hdf5.h" +#include "h4toh5util.h" +#include <fcntl.h> +#include <errno.h> +/* subroutines adapted from h5toh4 tools and used for h4toh5main.c */ +void PrintOptions_h4toh5(void); +int test_file(char *filename,int oflag,mode_t mode); +int test_dir(char *); +char *BuildFilename(char *filename, char *ext); + +int h4toh5(char*,char*); +int get_numof_hdf4obj(char*,int32); +int set_hashtables(void); +int set_helpgroups(hid_t,hid_t*,hid_t*); +int h4toh5lonevds(int32,hid_t); +int h4toh5lonevgs(int32,int32,hid_t,hid_t,hid_t); +int h4toh5vgrings(int32,int32,hid_t,hid_t,hid_t); +int h4toh5unvisitedimages(int32,hid_t,hid_t); +int h4toh5unvisitedsds(int32,int32,hid_t,hid_t); +void free_allhashmemory(void); + +/*subroutines for h4toh5vgroup.c*/ + +int Vgroup_h4_to_h5(int32,int32,int32,hid_t,hid_t,hid_t); +int convert_vgroup(int32,int32, int32,char* ,hid_t,hid_t,hid_t); +int convert_vdata(int32,int32,char*,hid_t); +int convert_sds(int32,int32,int32,char*,hid_t,hid_t); +int convert_image(int32,int32,char*,hid_t,hid_t); + +/*subroutines for h4toh5vdata.c*/ + +int Vdata_h4_to_h5(int32,int32,hid_t); +int vdata_transattrs(int32,hid_t,int,int,char*); +int gen_h5comptype(int32,int32,size_t *,size_t*,hid_t*,hid_t*,hid_t,hid_t); + +/* subroutines for h4toh5sds.c*/ +int Sds_h4_to_h5(int32,int32,hid_t,hid_t); +int sds_transattrs(int32, hid_t,int,int); +int sdsdim_to_h5dataset(int32,int32,hid_t,hid_t,int32); + + +/*subroutines for h4toh5image.c*/ +int Image_h4_to_h5(int32,int32,hid_t,hid_t); +int gr_tranattrs(int32, hid_t,int,int); +int gr_palette(int32,int32,hid_t,hid_t); +int create_pal_objref(hid_t ,hid_t ,char *); + +/*subroutines for h4toh5anno.c*/ +char* trans_tag_name(int32,ann_type); +int Annofil_h4_to_h5(int32,hid_t); +int Annoobj_h4_to_h5(int32,int32,int32,hid_t); + +/*subroutines for h4toh5pal.c*/ +int Palette_h4_to_h5(int32,int32 ,hid_t,char *); diff --git a/tools/h4toh5pal.c b/tools/h4toh5pal.c new file mode 100644 index 0000000..fc59cce --- /dev/null +++ b/tools/h4toh5pal.c @@ -0,0 +1,167 @@ +#include "h4toh5main.h" + + +/*------------------------------------------------------------------------- + * Function: Palette_h4_to_h5 + * + * Purpose: translate palette into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: file id + pal_id: PALETTE identifier + h5_g: hdf5 group id + pal_name: path name of the group where all palettes are in + + *------------------------------------------------------------------------- + */ + +int Palette_h4_to_h5(int32 file_id,int32 pal_id,hid_t h5g,char*pal_name) { + + int32 ncomp; + int32 pal_ref; + int32 pal_type; + int32 interlace_mode; + int32 num_entries; + void* pal_data; + size_t h4memsize; + size_t h4size; + + char palette_label[MAX_NC_NAME]; + char palette_class[MAX_NC_NAME]; + char palette_type[MAX_NC_NAME]; + + hid_t h5memtype; + hid_t h5type; + hid_t h5d_sid; + hid_t h5dset; + hsize_t h5dims[2]; + + pal_ref = GRluttoref(pal_id); + + if(pal_ref <0) { + printf("error in obtaining palette.\n"); + return FAIL; + } + + /* no palette, just return. */ + if(pal_ref == 0) return SUCCEED; + + if(GRgetlutinfo(pal_id,&ncomp,&pal_type,&interlace_mode,&num_entries)==FAIL) { + printf("error in getting palette information.\n"); + return FAIL; + } + + if(h4type_to_h5type(pal_type,&h5memtype,&h4memsize,&h4size,&h5type)== FAIL) { + fprintf(stderr,"failed to translate image datatype. \n"); + return FAIL; + } + + /* according to mapping document, data type for palette will always be + uint8. */ + + if (h5type == H5T_STRING) { + if(h5string_to_int(DFNT_UCHAR8,&h5memtype,h4memsize,&h5type)==FAIL) { + fprintf(stderr,"failed to translate H5T_STRING to int8."); + return FAIL; + } + } + + h5dims[0] = num_entries; + h5dims[1] = ncomp; + + pal_data = malloc(h4memsize*ncomp*num_entries); + + if (pal_data == NULL) { + printf("error in allocating memory for palette data.\n"); + return FAIL; + } + + if (GRreadlut(pal_id,(VOIDP)pal_data)==FAIL) { + printf("error in reading palette data. \n"); + free(pal_data); + return FAIL; + } + + h5d_sid = H5Screate_simple(2,h5dims,NULL); + + if (h5d_sid <0) { + printf("error in creating space.\n"); + free(pal_data); + return FAIL; + } + + h5dset = H5Dcreate(h5g,pal_name,h5type,h5d_sid,H5P_DEFAULT); + + if (h5dset < 0) { + printf("error in creating dataset. \n"); + free(pal_data); + H5Sclose(h5d_sid); + return FAIL; + } + + if (H5Dwrite(h5dset,h5memtype,h5d_sid,h5d_sid,H5P_DEFAULT, + (void *)pal_data)<0) { + fprintf(stdout,"error writing data for palette data\n"); + free(pal_data); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + return FAIL; + } + free(pal_data); + + + strcpy(palette_label,PALABEL); + strcpy(palette_class,PALETTE); + strcpy(palette_type,PAL_TYPE); + + /* convert palette annotation into attribute of palette dataset. + Since there are no routines to find the exact tag of palette object, + we will check three possible object tags of palette objects, that is: + DFTAG_LUT. If the object tag of palette object is + falling out of this scope, we will not convert annotations into + hdf5 attributes; it is user's responsibility to make sure that object tags + for palette objects are DFTAG_LUT.*/ + + if(Annoobj_h4_to_h5(file_id,pal_ref,DFTAG_LUT,h5dset)== FAIL){ + printf("failed to convert palette annotation into hdf5 attribute.\n"); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + return FAIL; + } + + if(h4_transpredattrs(h5dset,HDF4_OBJECT_TYPE,palette_label)==FAIL) { + printf("unable to transfer palette label to HDF4 OBJECT TYPE.\n"); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + return FAIL; + } + + if(h4_transpredattrs(h5dset,HDF4_PALETTE_CLASS,palette_class)==FAIL){ + printf("unable to transfer palette class to HDF4 PALETTE CLASS.\n"); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + return FAIL; + } + + if(h4_transpredattrs(h5dset,HDF4_PALETTE_TYPE,palette_type)==FAIL){ + printf("unable to transfer palette type to HDF4 PALETTE TYPE.\n"); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + return FAIL; + } + + if(h4_transnumattr(h5dset,HDF4_REF_NUM,pal_ref)==FAIL) { + printf("unable to transfer palette reference number to HDF4 REF. NUM.\n"); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + return FAIL; + } + return SUCCEED; +} + + + + + diff --git a/tools/h4toh5sds.c b/tools/h4toh5sds.c new file mode 100644 index 0000000..6d16938 --- /dev/null +++ b/tools/h4toh5sds.c @@ -0,0 +1,892 @@ +#include "h4toh5main.h" +/*------------------------------------------------------------------------- + * Function: Sds_h4_to_h5 + * + * Purpose: translate SDS object into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + sds_id: SDS identifier + h5_group: hdf5 group id + h5_dimgroup: hdf5 dimension group id + dim_pathname: dimensional path name + + *------------------------------------------------------------------------- + */ +int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){ + + int32 sds_dtype; + int32 sds_rank; + int32 sds_dimsizes[MAX_VAR_DIMS]; + int32* sds_start; + int32* sds_edge; + int32* sds_stride; + int32 count_sdsdata; + int32 sds_ref; + int32 istat; + int i; + int empty; + int32 num_sdsattrs; + void* sds_data; + + int check_sdsname; + int check_gloattr; + + char sdsname[MAX_NC_NAME]; + char sdslabel[MAX_NC_NAME]; + size_t h4size; + size_t h4memsize; + + /* define varibles for hdf5. */ + + hid_t h5dset; + hid_t h5d_sid; + hid_t h5ty_id; + hid_t h5_memtype; + hid_t h5str_type; + hid_t h5str_memtype; + + hsize_t h5dims[MAX_VAR_DIMS]; + char* h5csds_name; + + herr_t ret; + + /* check whether the sds is empty. */ +#if 0 + if(SDcheckempty(sds_id,&empty)== FAIL) { + printf("error in running SDcheckempty routine. \n"); + return FAIL; + } + printf("empty %d\n",empty); + + if(empty != 0) return SUCCEED; +#endif + + /*check whether the sds is created with unlimited dimension. */ + + if(SDisrecord(sds_id)) { + if (SDgetinfo(sds_id,sdsname,&sds_rank,sds_dimsizes,&sds_dtype, + &num_sdsattrs)==FAIL) { + printf("unable to get information of sds h5dset.\n"); + return FAIL; + } + + } + else { + /*obtain name,rank,dimsizes,datatype and num of attributes of sds */ + if (SDgetinfo(sds_id,sdsname,&sds_rank,sds_dimsizes,&sds_dtype, + &num_sdsattrs)==FAIL) { + printf("unable to get information of sds h5dset.\n"); + return FAIL; + } + } + + /* if(sdsname !=NULL) printf("sdsname %s\n",sdsname);*/ + + /* obtain start,edge, stride and number of sds data. */ + + sds_start = malloc(sizeof(int32)*sds_rank); + if(sds_start == NULL) { + printf("error in allocating memory for sds start.\n"); + return FAIL; + } + + sds_edge = malloc(sizeof(int32)*sds_rank); + if(sds_edge == NULL) { + printf("error in allocating memory for sds edge.\n"); + free(sds_start); + return FAIL; + } + + sds_stride = malloc(sizeof(int32)*sds_rank); + if(sds_stride == NULL) { + printf("error in allocating memory for sds stride. \n"); + free(sds_start); + free(sds_edge); + return FAIL; + } + + count_sdsdata = 1; + for (i=0;i<sds_rank;i++){ + sds_stride[i] = 1; + sds_start[i] = 0; + sds_edge[i] = sds_dimsizes[i]; + count_sdsdata = count_sdsdata*sds_dimsizes[i]; + + } + + for (i=0;i<sds_rank;i++) + h5dims[i] = sds_edge[i]-sds_start[i]; + + /* convert hdf4 data type to hdf5 data type. */ + if (h4type_to_h5type(sds_dtype,&h5_memtype,&h4memsize,&h4size, + &h5ty_id) == FAIL) { + printf("failed to translate datatype. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + return FAIL; + } + + /* check whether the datatype is string, if we find string format, + we will change them back into integer format.*/ + + if (h5ty_id == H5T_STRING) { + /* rechange string datatype into numerical datatype.*/ + + if(h5string_to_int(sds_dtype,&h5_memtype,h4memsize, + &h5ty_id)== FAIL) { + printf("error in translating H5T_STRING to int.\n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + return FAIL; + } + } + + + sds_data = malloc(h4memsize*count_sdsdata); + if(sds_data == NULL) { + printf("error in allocating memory. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + return FAIL; + } + + istat = SDreaddata(sds_id, sds_start, sds_stride, sds_edge, + (VOIDP)sds_data); + if (istat == FAIL) { + printf("unable to read data from h5dset. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + /* obtaining reference number and name of h5 dataset + corresponding to sds. */ + + sds_ref = SDidtoref(sds_id); + if(sds_ref == FAIL) { + printf("error in obtaining sds reference number. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + h5csds_name = get_name(sds_ref,2*num_sds,sds_hashtab,&check_sdsname); + + if (h5csds_name == NULL && check_sdsname == 0 ) { + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf("error,cannot find sds name \n"); + return FAIL; + } + + if (h5csds_name == NULL && check_sdsname == -1) { + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf("error,sds name is not defined.\n"); + return FAIL; + } + + if (h5csds_name == NULL && check_sdsname == -2) { + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf("error,not enough memory for allocating sds name.\n"); + return FAIL; + } + + h5d_sid = H5Screate_simple(sds_rank,h5dims,NULL); + + if (h5d_sid < 0) { + printf("failed to create hdf5 data space converted from SDS. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + h5dset = H5Dcreate(h5_group,h5csds_name,h5ty_id,h5d_sid,H5P_DEFAULT); + + if (h5dset < 0) { + printf("failed to create hdf5 dataset converted from SDS. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + H5Sclose(h5d_sid); + return FAIL; + } + + if (H5Dwrite(h5dset,h5_memtype,h5d_sid,h5d_sid,H5P_DEFAULT, + (void *)sds_data)<0) { + printf("failed to write data into hdf5 dataset"); + printf(" converted from SDS.\n"); + H5Sclose(h5d_sid); + H5Dclose(h5dset); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + + /* convert sds annotation into attribute of sds dataset. + Since there is no routines to find the exact tag of sds object, + we will check three possible object tags of sds objects, that is: + DFTAG_SD,DFTAG_SDG,DFTAG_NDG. If the object tag of sds object is + falling out of this scope, we will not convert annotations into + hdf5 attributes; it is user's responsibility to make sure object tags + for sds objects are only one of the above three tags.*/ + + if(Annoobj_h4_to_h5(file_id,sds_ref,DFTAG_SD,h5dset)== FAIL){ + printf("failed to convert sds annotation into hdf5 attribute.\n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + if(Annoobj_h4_to_h5(file_id,sds_ref,DFTAG_SDG,h5dset)== FAIL){ + printf("failed to convert sds annotation into hdf5 attribute.\n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + if(Annoobj_h4_to_h5(file_id,sds_ref,DFTAG_NDG,h5dset)== FAIL){ + printf("failed to convert sds annotation into hdf5 attribute.\n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + + /* convert sds dimensional scale dataset into hdf5 dataset. */ + if(sdsdim_to_h5dataset(sds_id,sds_rank,h5dset,h5_dimgroup,sds_dimsizes[0]) == FAIL) { + printf("failed to convert dimensional scale to hdf5 dataset. \n"); + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + return FAIL; + } + check_gloattr = 0; + if (sds_transattrs(sds_id,h5dset,num_sdsattrs,check_gloattr)==FAIL) { + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf(" Error in obtaining sds attributes. \n"); + return FAIL; + } + + /********************************************/ + /* handle extra attributes of sds : sds label, object type + and reference num */ + + strcpy(sdslabel,SDSLABEL); + + if(h4_transpredattrs(h5dset,HDF4_OBJECT_TYPE,sdslabel)==FAIL) { + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf("unable to transfer sds label to HDF4 OBJECT TYPE.\n"); + return FAIL; + } + + if(sdsname != NULL) { + if(h4_transpredattrs(h5dset,HDF4_OBJECT_NAME,sdsname)==FAIL){ + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf("unable to transfer sds name to HDF5 dataset attribute.\n"); + return FAIL; + } + } + + if(h4_transnumattr(h5dset,HDF4_REF_NUM,sds_ref)==FAIL){ + free(sds_start); + free(sds_edge); + free(sds_stride); + free(sds_data); + printf("unable to transfer sds ref. to HDF5 dataset attribute.\n"); + return FAIL; + } + + istat = SDendaccess(sds_id); + ret = H5Sclose(h5d_sid); + ret = H5Dclose(h5dset); + free(h5csds_name); + free(sds_data); + free(sds_start); + free(sds_edge); + free(sds_stride); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: sds_transattrs + * + * Purpose: translate attribute of HDF4 SDS object into + hdf5 dataset attribute + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + ssds_id: SDS identifier + sh5_dset: hdf5 dataset + snum_sdsattrs: number of sds attribute + check_gloflag: a flag that check whether the attribute is + a file attribute or a sds id or a dimensional scale id. + + *------------------------------------------------------------------------- + */ + +int sds_transattrs(int32 ssds_id, hid_t sh5_dset,int snum_sdsattrs, + int check_gloflag) { + + char ssdsatrr_name[2*MAX_NC_NAME]; + char sdsglo[MAX_NC_NAME]; + char* sdsrepattr_name; + int32 count_ssdsadata; + int32 ssds_atype; + size_t sh4_amemsize; + size_t sh4_asize; + hid_t sh5a_sid; + hid_t sh5a_id; + hid_t sh5_atype; + hid_t sh5_amemtype; + hid_t sh5str_type; + hid_t sh5str_memtype; + hsize_t sh5dims[MAX_VAR_DIMS]; + void* ssds_adata; + herr_t sret; + int i; + + for (i = 0;i < snum_sdsattrs; i++) { + + if (SDattrinfo(ssds_id,i,ssdsatrr_name,&ssds_atype, + &count_ssdsadata)==FAIL){ + printf("unable to obtain SDS attribute information. \n"); + return FAIL; + } + + /* make a table for the attribute type, to do the corresponding type. */ + + if(h4type_to_h5type(ssds_atype,&sh5_amemtype,&sh4_amemsize, + &sh4_asize,&sh5_atype)== FAIL) { + printf("fail to translate sds attribute data type from H4 to H5. \n"); + return FAIL; + } + + + ssds_adata = malloc(sh4_amemsize * count_ssdsadata); + if(ssds_adata == NULL) { + printf("error, cannot allocate memory for sds attribute data. \n"); + return FAIL; + } + + if(SDreadattr(ssds_id,i,(VOIDP)ssds_adata)== FAIL) { + printf("error in reading attributes of sds object. \n"); + free(ssds_adata); + return FAIL; + } + + /* if attribute doesn't have name, a default name is set. */ + if(ssdsatrr_name[0] == '\0') { + sdsrepattr_name = trans_obj_name(DFTAG_NDG,i); + strcpy(ssdsatrr_name,sdsrepattr_name); + free(sdsrepattr_name); + } + + /* if the sds attribute is a file attribute. */ + if(check_gloflag == 1){ + strcpy(sdsglo,GLOSDS); + strcat(ssdsatrr_name,"_"); + strcat(ssdsatrr_name,sdsglo); + } + + /* now do attribute-transferring. + 1. deal with string data type + 2. set attribute space. + 3. get attribute name, set property list. */ + + if (sh5_atype == H5T_STRING) { + + sh5a_sid = H5Screate(H5S_SCALAR); + + if (sh5a_sid < 0) { + printf("failed to create attribute space for"); + printf(" HDF4_OBJECT_TYPE SDS. \n"); + free(ssds_adata); + return FAIL; + } + + if ((sh5str_type = mkstr(count_ssdsadata, + H5T_STR_NULLTERM))<0) { + printf("error in making string. \n"); + H5Sclose(sh5a_sid); + free(ssds_adata); + return FAIL; + } + + /* check this line later. */ + if ((sh5str_memtype = mkstr(count_ssdsadata*sh4_amemsize, + H5T_STR_NULLTERM))<0) { + printf("error in making memory string. \n"); + H5Sclose(sh5a_sid); + free(ssds_adata); + return FAIL; + } + + sh5a_id = H5Acreate(sh5_dset,ssdsatrr_name,sh5str_type, + sh5a_sid,H5P_DEFAULT); + + if (sh5a_id <0) { + printf("failed to obtain attribute id for"); + printf(" HDF4_OBJECT_TYPE SDS. \n"); + H5Sclose(sh5a_sid); + free(ssds_adata); + return FAIL; + } + + sret = H5Awrite(sh5a_id,sh5str_memtype,(void *)ssds_adata); + + if (sret <0) { + printf("failed to write attribute data for"); + printf(" HDF4_OBJECT_TYPE SDS. \n"); + H5Sclose(sh5a_sid); + H5Aclose(sh5a_id); + free(ssds_adata); + return FAIL; + } + + sret = H5Sclose(sh5a_sid); + sret = H5Aclose(sh5a_id); + } + + else { + + if(count_ssdsadata == 1) { + + sh5a_sid = H5Screate(H5S_SCALAR); + if (sh5a_sid < 0) { + printf("failed to create space id. \n"); + free(ssds_adata); + return FAIL; + } + } + else { + sh5dims[0] = count_ssdsadata; + sh5a_sid = H5Screate_simple(1,sh5dims,NULL); + + if (sh5a_sid < 0) { + printf("failed to create attribute space. \n"); + free(ssds_adata); + return FAIL; + } + } + sh5a_id = H5Acreate(sh5_dset,ssdsatrr_name,sh5_atype, + sh5a_sid,H5P_DEFAULT); + + if(sh5a_id <0) { + printf("failed to obtain attribute id. \n"); + H5Sclose(sh5a_sid); + free(ssds_adata); + return FAIL; + } + + sret = H5Awrite(sh5a_id,sh5_amemtype,(void *)ssds_adata); + + if(sret <0) { + printf("failed to write attribute data.\n "); + H5Sclose(sh5a_sid); + H5Aclose(sh5a_id); + free(ssds_adata); + return FAIL; + } + sret = H5Sclose(sh5a_sid); + sret = H5Aclose(sh5a_id); + } + free(ssds_adata); + } + return SUCCEED; +} +/****************sdsdim_to_h5dataset******************* + + * Purpose: translate dimensional scale dataset into + hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + sds_id: SDS identifier + sds_rank: number of sds dimensions + Out: + Modification: + + *------------------------------------------------------------------------- + */ + +int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset, + hid_t sh5_dimgroup,int32 firstdimsize) { + + int32 sdsdim_id; + int32 sdsdim_type = 0; + int32 sds_dimscasize[1]; + int32 sds_dimrank; + int32 istat; + int i; + int j; + int k; + + int check_gloattr; + int32 num_sdsdimattrs; + int empty; + int check_sdsdim; + void* dim_scadata; + + char sdsdim_name[MAX_NC_NAME]; + char sds_name[MAX_NC_NAME]; + char* cor_sdsdimname; + size_t h4dim_memsize; + size_t h4dim_size; + + /* define varibles for hdf5. */ + + hid_t h5dim_dset; + hid_t h5dim_sid; + + hid_t h5dim_tid; + hid_t h5dim_memtype; + + hid_t h5dim_nameaid; + hid_t h5dim_namesid; + + hid_t h5str_dimntype; + + hid_t attr_refSpace; + hid_t attr_refType; + hid_t attribID; + + hsize_t h5dimscas[1]; + hsize_t h5dim_dims[1]; + hsize_t attr_refDims[1]; + hobj_ref_t dim_refdat; + hobj_ref_t* alldim_refdat; + + char* h5sdsdim_name; + char h5sdsdim_allname[MAX_VAR_DIMS * MAX_NC_NAME]; + char h5newsdsdim_name[MAX_NC_NAME]; + char h5dimpath_name[MAX_NC_NAME]; + herr_t ret; + + h5dim_dims[0] = (hsize_t)sds_rank; + j = 0; + k = 0; + + for (i = 0; i<sds_rank;i++) { + + sdsdim_id = SDgetdimid(sds_id,i); + + if(sdsdim_id == FAIL) { + printf("error in obtaining sds dimension id. \n"); + return FAIL; + } + + + istat = SDdiminfo(sdsdim_id,sdsdim_name,sds_dimscasize, + &sdsdim_type,&num_sdsdimattrs); + + if (istat == FAIL) { + printf("sds get dim. information failed. \n"); + SDendaccess(sdsdim_id); + return FAIL; + } + + if(sds_dimscasize[0] == 0) sds_dimscasize[0] = firstdimsize; + + /* if this sds has no dimensional scale data. skip it.*/ + /* if(sdsdim_type == 0) continue;*/ + + + /* check whether this dimensional scale dataset is looked up. */ + check_sdsdim = lookup_name(sdsdim_name,DIM_HASHSIZE,dim_hashtab); + + strcpy(h5dimpath_name,HDF4_DIMG); + + /* checking whether sds dimension scale name contains ORI_SLASH, changing into CHA_SLASH.*/ + + cor_sdsdimname = correct_name(sdsdim_name); + if(cor_sdsdimname == NULL) { + printf("error in generating corrected sds dimensional scale name.\n"); + SDendaccess(sdsdim_id); + return FAIL; + } + + h5sdsdim_name = get_obj_aboname(cor_sdsdimname,NULL,h5dimpath_name,NULL); + if (h5sdsdim_name == NULL) { + printf("error in getting hdf5 sds dimension name.\n"); + SDendaccess(sdsdim_id); + free(cor_sdsdimname); + return FAIL; + } + free(cor_sdsdimname); + strcpy(&h5sdsdim_allname[k*MAX_NC_NAME],h5sdsdim_name); + + /*if it is not touched, get name of the dimensional scale data. */ + if (check_sdsdim == 1){/* the dimension is touched. */ + free(h5sdsdim_name); + SDendaccess(sdsdim_id); + j = j + 1; + k = k + 1; + continue; + } + + if (check_sdsdim != 0) { + printf("error in checking sds dimensions.\n"); + SDendaccess(sdsdim_id); + free(h5sdsdim_name); + return FAIL; + } + + /* if this sds has no dimensional scale data. skip it.*/ + if(sdsdim_type == 0) { + k = k + 1; + + continue; + } + if(h4type_to_h5type(sdsdim_type,&h5dim_memtype,&h4dim_memsize, + &h4dim_size,&h5dim_tid)== FAIL) { + printf("error in transferring sds dimension data type.\n"); + SDendaccess(sdsdim_id); + free(h5sdsdim_name); + return FAIL; + } + + /* dimensional scale dataset cannot be H5T_STRING data type. + So transferring back to int8 */ + + if (h5dim_tid == H5T_STRING) { + if(h5string_to_int(sdsdim_type,&h5dim_memtype,h4dim_memsize, + &h5dim_tid)==FAIL){ + printf("error in translating from string to int. \n"); + SDendaccess(sdsdim_id); + free(h5sdsdim_name); + return FAIL; + } + } + + dim_scadata = malloc(h4dim_memsize*sds_dimscasize[0]); + istat = SDgetdimscale(sdsdim_id,(VOIDP)dim_scadata); + + if (istat == FAIL) { + printf("sds get dim. scale failed. \n"); + SDendaccess(sdsdim_id); + free(h5sdsdim_name); + free(dim_scadata); + return FAIL; + } + + h5dimscas[0] = sds_dimscasize[0]; + h5dim_sid = H5Screate_simple(1,h5dimscas,NULL); + + if(h5dim_sid <0) { + printf("error in creating space. \n"); + SDendaccess(sdsdim_id); + free(h5sdsdim_name); + free(dim_scadata); + return FAIL; + } + + /* create h5 dataset under group HDF4_DIMG*/ + h5dim_dset = H5Dcreate(sh5_dimgroup,h5sdsdim_name,h5dim_tid, + h5dim_sid,H5P_DEFAULT); + + if(h5dim_dset <0) { + printf("error in creating dataset. \n"); + free(h5sdsdim_name); + free(dim_scadata); + SDendaccess(sdsdim_id); + H5Sclose(h5dim_sid); + return FAIL; + } + + if (H5Dwrite(h5dim_dset,h5dim_memtype,h5dim_sid,h5dim_sid, + H5P_DEFAULT,(void *)dim_scadata)<0) { + printf("error writing data\n"); + free(h5sdsdim_name); + free(dim_scadata); + SDendaccess(sdsdim_id); + H5Sclose(h5dim_sid); + H5Dclose(h5dim_dset); + return FAIL; + } + + check_gloattr = 0; + if(sds_transattrs(sdsdim_id,h5dim_dset,num_sdsdimattrs,check_gloattr) + == FAIL){ + printf("error in transferring attributes. \n"); + free(h5sdsdim_name); + free(dim_scadata); + SDendaccess(sdsdim_id); + H5Sclose(h5dim_sid); + H5Dclose(h5dim_dset); + return FAIL; + } + SDendaccess(sdsdim_id); + free(dim_scadata); + free(h5sdsdim_name); + ret = H5Sclose(h5dim_sid); + ret = H5Dclose(h5dim_dset); + j = j + 1; + k = k + 1; + } + + /*1. create object reference number to dimensional scale dataset. + 2. store absolute name of dimensional name into + dimensional list. */ + + if ( j != 0) { + + h5dim_dims[0] = j; + attr_refDims[0] = j; + attr_refSpace = H5Screate_simple(1,attr_refDims,NULL); + attr_refType = H5Tcopy(H5T_STD_REF_OBJ); + alldim_refdat = calloc(j,sizeof(hobj_ref_t)); + + if(alldim_refdat == NULL) { + printf("error in allocating memory. \n"); + H5Sclose(attr_refSpace); + H5Tclose(attr_refType); + return FAIL; + } + + for(i=0;i<j;i++){ + bzero(h5newsdsdim_name,MAX_NC_NAME); + strcpy(h5newsdsdim_name,&h5sdsdim_allname[i*MAX_NC_NAME]); + ret = H5Rcreate(&dim_refdat,sh5_dimgroup,h5newsdsdim_name, + H5R_OBJECT,-1); + if(ret <0) { + free(alldim_refdat); + H5Sclose(attr_refSpace); + H5Tclose(attr_refType); + printf("error in generating H5 reference. \n"); + return FAIL; + } + alldim_refdat[i] = dim_refdat; + } + + attribID = H5Acreate(sh5dset,DIMSCALE,attr_refType,attr_refSpace, + H5P_DEFAULT); + if(attribID < 0) { + free(alldim_refdat); + H5Sclose(attr_refSpace); + H5Tclose(attr_refType); + H5Aclose(attribID); + printf("error in generating H5 attribute ID. \n"); + return FAIL; + } + ret = H5Awrite(attribID,attr_refType,(void *)alldim_refdat); + H5Sclose(attr_refSpace); + H5Tclose(attr_refType); + H5Aclose(attribID); + free(alldim_refdat); + } + + if(k!=0) { + h5dim_namesid = H5Screate_simple(1,h5dim_dims,NULL); + + if(h5dim_namesid <0) { + printf("error in creating sds dimensionlist space.\n"); + return FAIL; + } + + h5str_dimntype = mkstr(MAX_NC_NAME,H5T_STR_NULLTERM); + if(h5str_dimntype < 0) { + H5Sclose(h5dim_namesid); + printf("error in generating H5T_STRING type.\n"); + return FAIL; + } + + h5dim_nameaid = H5Acreate(sh5dset,HDF4_DIMENSION_LIST,h5str_dimntype, + h5dim_namesid,H5P_DEFAULT); + + if(h5dim_nameaid <0) { + H5Sclose(h5dim_namesid); + printf("error in creating sds dimensionlist id.\n"); + return FAIL; + } + + ret = H5Awrite(h5dim_nameaid,h5str_dimntype,h5sdsdim_allname); + + if(ret < 0) { + H5Sclose(h5dim_namesid); + H5Aclose(h5dim_nameaid); + printf("error in writing sds dimensionlist. \n"); + return FAIL; + } + + ret = H5Sclose(h5dim_namesid); + ret = H5Aclose(h5dim_nameaid); + + } + return SUCCEED; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/h4toh5util.c b/tools/h4toh5util.c new file mode 100644 index 0000000..f401354 --- /dev/null +++ b/tools/h4toh5util.c @@ -0,0 +1,1618 @@ +#include "h4toh5util.h" + +/*------------------------------------------------------------------------- + * Function: h5string_to_int + * + * Purpose: This function will convert H5T_STRING into integer. + This is for cases the user define the numerical datatype int8 + as DFNT_CHAR8 and DFNT_UCHAR8 + + * Errors: will return error message to the interface. + * Return: FAIL if failed, SUCCEED if success. + * + * In : h4type: HDF4 datatype. + h4memsize: the real memory size of h4type. + + * Out: h5memtype: pointer of which value should be h5memtype(the real + data type stored at the memory). + h5type: pointer of which value should be h5type(the hdf5 + type stored at the disk). + * + *------------------------------------------------------------------------- + */ + +int h5string_to_int(const int32 h4type, hid_t* h5memtype, + const size_t h4memsize,hid_t* h5type) { + + switch(h4type) { + + case DFNT_CHAR8: + + *h5type = H5T_STD_I8BE; + if (h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_SCHAR; + else if(h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + + case DFNT_UCHAR8: + + *h5type = H5T_STD_U8BE; + if (h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + } + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: h4type_to_h5type + * + * Purpose: this function will convert HDF4 datatype into HDF5 datatype + The converter includes file to file datatype and datasize + conversion, file to memory datatype and datasize conversion. + Check the mapping document for details. + + * Errors: will return error message to the interface. + * Return: false, FAIL. otherwise,SUCCEED. + * + * In : h4type: HDF4 datatype. + * Out: h4size: the file(disk) size of h4type. + h4memsize: the real memory size of h4type. + * h5memtype: pointer of which value should be h5memtype(the real + type stored at the memory). + h5type: pointer of which value should be h5type(the hdf5 + type that is stored at the disk). + * + * + *------------------------------------------------------------------------- + */ +int h4type_to_h5type(const int32 h4type, hid_t* h5memtype, + size_t* h4memsize,size_t* h4size, hid_t *h5type) +{ + + switch (h4type) { + + case DFNT_CHAR8: + + *h4size = 1; + *h4memsize = sizeof(int8); + /* assume DFNT_CHAR8 C type character. */ + *h5memtype = H5T_STRING; + *h5type = H5T_STRING; + break; + + case DFNT_UCHAR8: + + *h4size = 1; + *h4memsize = sizeof(int8); + *h5memtype = H5T_STRING; + *h5type = H5T_STRING; + break; + + case DFNT_INT8: + + *h4size = 1; + *h5type = H5T_STD_I8BE; + *h4memsize = sizeof(int8); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_SCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_UINT8: + + *h4size =1; + *h5type = H5T_STD_U8BE; + *h4memsize = sizeof(int8); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_NINT8: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 1; + *h5type = H5T_NATIVE_SCHAR; + *h4memsize = sizeof(int8); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_SCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_NUINT8: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 1; + *h5type = H5T_NATIVE_UCHAR; + *h4memsize = sizeof(int8); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_LINT8: + *h4size = 1; + *h5type = H5T_STD_I8LE; + *h4memsize = sizeof(int8); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_LUINT8: + *h4size = 1; + *h5type = H5T_STD_U8LE; + *h4memsize = sizeof(int8); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_INT16: + *h4size = 2; + *h5type = H5T_STD_I16BE; + *h4memsize = sizeof(int16); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_CHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_UINT16: + *h4size = 2; + *h5type = H5T_STD_U16BE; + *h4memsize = sizeof(int16); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_NINT16: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 2; + *h5type = H5T_NATIVE_SHORT; + *h4memsize = sizeof(int16); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_CHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_NUINT16: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 2; + *h5type = H5T_NATIVE_USHORT; + *h4memsize = sizeof(int16); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_LINT16: + *h4size = 2; + *h5type = H5T_STD_I16LE; + *h4memsize = sizeof(int16); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_LUINT16: + *h4size = 2; + *h5type = H5T_STD_U16LE; + *h4memsize = sizeof(int16); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_INT32: + *h4size = 4; + *h5type = H5T_STD_I32BE; + *h4memsize = sizeof(int32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_CHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_UINT32: + *h4size = 4; + *h5type = H5T_STD_U32BE; + *h4memsize = sizeof(int32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_NINT32: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 4; + *h5type = H5T_NATIVE_INT; + *h4memsize = sizeof(int32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_CHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_NUINT32: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size =4; + *h5type = H5T_NATIVE_UINT; + *h4memsize = sizeof(int32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_LINT32: + *h4size =4; + *h5type = H5T_STD_I32LE; + *h4memsize = sizeof(int32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_CHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_SHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_INT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_LONG; + else return FAIL; + break; + + case DFNT_LUINT32: + *h4size =4; + *h5type = H5T_STD_U32LE; + *h4memsize = sizeof(int32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_CHAR)) + *h5memtype = H5T_NATIVE_UCHAR; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_SHORT)) + *h5memtype = H5T_NATIVE_USHORT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_INT)) + *h5memtype = H5T_NATIVE_UINT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_LONG)) + *h5memtype = H5T_NATIVE_ULONG; + else return FAIL; + break; + + case DFNT_FLOAT32: + *h4size =4; + *h5type = H5T_IEEE_F32BE; + *h4memsize = sizeof(float32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) + *h5memtype = H5T_NATIVE_FLOAT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) + *h5memtype = H5T_NATIVE_DOUBLE; + else return FAIL; + break; + + case DFNT_FLOAT64: + *h4size = 8; + *h5type = H5T_IEEE_F64BE; + *h4memsize = sizeof(float64); + if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) + *h5memtype = H5T_NATIVE_FLOAT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) + *h5memtype = H5T_NATIVE_DOUBLE; + else return FAIL; + break; + + case DFNT_NFLOAT32: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 4; + *h5type = H5T_NATIVE_FLOAT; + *h4memsize = sizeof(float32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) + *h5memtype = H5T_NATIVE_FLOAT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) + *h5memtype = H5T_NATIVE_DOUBLE; + else return FAIL; + break; + + case DFNT_NFLOAT64: + printf("warning, Native HDF datatype is encountered"); + printf(" the converting results may not be correct.\n"); + *h4size = 8; + *h5type = H5T_NATIVE_DOUBLE; + *h4memsize = sizeof(float64); + if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) + *h5memtype = H5T_NATIVE_FLOAT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) + *h5memtype = H5T_NATIVE_DOUBLE; + else return FAIL; + break; + + case DFNT_LFLOAT32: + *h4size = 4; + *h5type = H5T_IEEE_F32LE; + *h4memsize = sizeof(float32); + if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) + *h5memtype = H5T_NATIVE_FLOAT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) + *h5memtype = H5T_NATIVE_DOUBLE; + else return FAIL; + break; + + case DFNT_LFLOAT64: + *h4size = 8; + *h5type = H5T_IEEE_F64LE; + *h4memsize = sizeof(float64); + if(*h4memsize == H5Tget_size(H5T_NATIVE_FLOAT)) + *h5memtype = H5T_NATIVE_FLOAT; + else if(*h4memsize == H5Tget_size(H5T_NATIVE_DOUBLE)) + *h5memtype = H5T_NATIVE_DOUBLE; + else return FAIL; + break; + + default: + return FAIL; + } + return SUCCEED; +} +/*------------------------------------------------------------------------- + * Function: conv_int_str + * + * Purpose: this function will convert numerical number into the + string format for a reference(<=65536). + * Return: SUCCEED if success, FAIL if failed. + * + * In : num: an unsigned digital number that is not greater than 65536. + + * Out: str_num: character string format of the number. + + * + * + *------------------------------------------------------------------------- + */ + +int conv_int_str(uint16 num, char* str_num) { + + /* the maximum reference number is 65536. */ + + int d0,d1,d2,d3,d4; + int i; + + if(str_num == NULL) { + printf(" memory for str_num should be allocated.\n"); + return FAIL; + } + + for (i=0;i<5;i++) + str_num[i] = '\0'; + + if((num/10000)!=0) { + d4 = num/10000; + str_num[4]= (char)(d4+48); + d3 = (num-d4*10000)/1000; + str_num[3]= (char)(d3+48); + d2 =(num-d4*10000-d3*1000)/100; + str_num[2]= (char)(d2+48); + d1 =(num-d4*10000-d3*1000-d2*100)/10; + str_num[1] =(char)(d1+48); + d0= num-d4*10000-d3*1000-d2*100-d1*10; + str_num[0] =(char)(d0+48); + } + + else if ((num/1000)!=0){ + + d3 = num/1000; + str_num[3] =(char)(d3+48); + d2 =(num-d3*1000)/100; + str_num[2]=(char)(d2+48); + d1 =(num-d3*1000-d2*100)/10; + str_num[1]=(char)(d1+48); + d0 =num-d3*1000-d2*100-d1*10; + str_num[0] =(char)(d0+48); + } + else if ((num/100)!=0){ + + d2 =num/100; + str_num[2]=(char)(d2+48); + d1 =(num-d2*100)/10; + str_num[1]=(char)(d1+48); + d0 =num-d2*100-d1*10; + str_num[0] =(char)(d0+48); + } + else if((num/10)!=0) { + d1= num/10; + str_num[1]=(char)(d1+48); + d0 = num%10; + str_num[0]=(char)(d0+48); + } + else + str_num[0] =(char)(num+48); + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: lookup + * + * Purpose: this function will use objref as a key to check whether + * the current object is touched. + + * Return: 1, the object is found. 0,the object is not found. + -1, the table doesn't exist. + * + * In : objref: reference number of the current object. + SIZE: the hashtable SIZE. + hashtab: pointer to the hash table. + + *------------------------------------------------------------------------- + */ + +int lookup(int objref,int SIZE,struct table*hashtab) { + + struct table *np; + if(hashtab == NULL) { + printf("the table doesn't exist. \n"); + return -1; + } + np = hashtab+objref%SIZE; + + for (np = hashtab+objref%SIZE; np!=NULL;np=np->next){ + if (np->ref == objref){ + return 1; + } + } + return 0; +} + +/*------------------------------------------------------------------------- + * Function: init_tab + * + * Purpose: this function will initialize the hash table. + * + + * Return: SUCCEED, table is initialzed. FAIL,otherwise. + * + * In : + SIZE: the hashtable SIZE. + hashtab: pointer to the hash table. + + *------------------------------------------------------------------------- + */ + +int init_tab(int SIZE,struct table *hashtab) { + + int i; + if(hashtab == NULL) { + printf("memory for hashing table is not allocated.\n"); + return FAIL; + } + for (i = 0;i < SIZE; i++) { + (hashtab+i%SIZE)->ref = -1; + (hashtab+i%SIZE)->next = NULL; + (hashtab+i%SIZE)->name = NULL; + } + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: init_nametab + * + * Purpose: this function will initialize the name hash table. + * + + * Return: SUCCEED, table is initialzed. FAIL,otherwise. + * + * In : + SIZE: the hashtable SIZE. + name_hashtab: pointer to the hash table. + + *------------------------------------------------------------------------- + */ +int init_nametab(int SIZE, struct name_table * name_hashtab) { + + int i; + + if(name_hashtab == NULL) { + printf("cannot allocate memory for name hashing table.\n"); + return FAIL; + } + for (i=0;i < SIZE; i++) { + (name_hashtab+i%SIZE)->name = NULL; + (name_hashtab+i%SIZE)->next = NULL; + } + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: get_name + * + * Purpose: obtain the name of the object + * + * Return: the object name + * + * In : objref: reference number of the current object. + SIZE: the hashtable SIZE. + hashtab: pointer to the hash table + pcheck_get: a flag to check errors + + *------------------------------------------------------------------------- + */ + +char* get_name(int objref,int SIZE,struct table*hashtab, int* pcheck_get) { + + struct table *np; + char* tempname; + + np = hashtab+objref%SIZE; + + for (np = hashtab+objref%SIZE; np!=NULL;np=np->next){ + + if (np->ref==objref){ + + if (np->name == NULL) { + *pcheck_get = -1; + return NULL; + } + + else { + tempname = malloc(strlen(np->name)+1); + if(tempname == NULL) { + *pcheck_get = -2; + return NULL; + } + strcpy(tempname,np->name); + return tempname; + } + } + } + + *pcheck_get = 0; + return NULL; +} + + +/*------------------------------------------------------------------------- + * Function: set_name + * + * Purpose: store the name of the object into the hash table + * + * Return: SUCCEED: the name is either set before or set in this routine + * FAIL: the name is not set properly + * + * In : objref: reference number of the current object + SIZE: the hashtable SIZE + hashtab: hash table + namein: object name + + *------------------------------------------------------------------------- + */ + + +int set_name(int objref,int SIZE,struct table*hashtab, char* namein) { + + struct table *np; + struct table *temptr; + + temptr = malloc(sizeof(struct table)); + if(temptr == NULL) { + printf("not enough memory to be allocated. \n"); + return FAIL; + } + + np = hashtab+objref%SIZE; + if(namein == NULL) { + printf("error in inputting name into the table.\n"); + return FAIL; + } + + for (np = hashtab+objref%SIZE; np!= NULL;np = np->next){ + if (np->ref==objref){ + /* the name is set already, don't do anything.*/ + return SUCCEED; + } + if (np->next == NULL) { + np->next = temptr; + temptr->ref = objref; + temptr->next = NULL; + temptr->name = malloc(strlen(namein)+1); + if(temptr->name == NULL) { + printf("error in allocating memory. \n"); + return FAIL; + } + strcpy(temptr->name,namein); + return SUCCEED; + } + } + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: lookup_name + * + * Purpose: 1. look up whether the same name is used for different objects + 2. then update the table + * + * Return: 1, if the name is in the name hash table. + 0, if the name is to be added into the name table. + -1, otherwise. + * + * In : + size: the hashtable SIZE. + nametab: name hash table + name: the name to be looked up + + *------------------------------------------------------------------------- + */ + +int lookup_name(char* name, int size,struct name_table *nametab) { + + /* temporary pointer of the name table that points to the beginning + address of the current bucket.*/ + struct name_table *np; + + /* temporary pointer of the added name table.*/ + struct name_table *temptr; + + if(name == NULL) { + printf("the name to be looked up is NULL.\n"); + return -1; + } + + temptr = malloc(sizeof(struct name_table)); + if(temptr == NULL) { + printf("not enough memory to be allocated. \n"); + return -1; + } + + np = nametab+hash_fun(name,size); + + temptr->name = malloc(strlen(name)+1); + if(temptr->name == NULL) { + printf("not enough memory to be allocated to table name.\n"); + return -1; + } + + /* look through the linked list starting from the current bucket. + If the name is found, return 1, otherwise, return 0 + after inserting the new bucket. */ + + for(np = nametab+hash_fun(name,size); np!= NULL;np = np->next) { + if(np->name == NULL) { + np->name = malloc(strlen(name)+1); + if(np->name == NULL) { + printf("cannot allocate memory for object name.\n"); + return -1; + } + strcpy(np->name,name); + free(temptr->name); + free(temptr); + return 0; + } + if(strcmp(name,np->name)==0){ + free(temptr->name); + free(temptr); + return 1; + } + if (np->next == NULL) { + np->next = temptr; + temptr->next = NULL; + strcpy(temptr->name,name); + return 0; + } + } + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: hash_fun + * + * Purpose: to get the hash value based on the key + * + * Return: No. of the hashtable + * + * In : name: object name + size: the hashtable size. + + *------------------------------------------------------------------------- + */ +int hash_fun(char *name,int size) { + +int hashval; + + for (hashval = 0;*name !='\0';) + hashval += *name++; + return(hashval%size); + +} + +/*------------------------------------------------------------------------- + * Function: freenametable + * + * Purpose: free the memory of hash table + * + * Return: 0 + * + * In : + SIZE: the hashtable SIZE. + nametab: hash table of the name + + *------------------------------------------------------------------------- + */ +int freenametable(int SIZE,struct name_table *nametab) { + + struct name_table *np,*temptr,*temptr1; + int i; + + if(nametab == NULL) return 0; + /* we first free the additional linked items of the hashtable, + and then free the whole hash table. */ + for (i = 0;i < SIZE; i++) { + np = nametab+i; + temptr1 = np->next; + while(temptr1 != NULL) { + temptr = temptr1; + temptr1 = temptr1->next; + free(temptr->name); + free(temptr); + } + if(np->name !=NULL) free(np->name); + } + free(nametab); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: freetable + * + * Purpose: free the memory of hash table + * + * Return: 0 + * + * In : + SIZE: the hashtable SIZE. + nametab: hash table + + *------------------------------------------------------------------------- + */ +int freetable(int SIZE,struct table *hashtab) { + + struct table *np,*temptr,*temptr1; + int i; + if(hashtab == NULL) return 0; + + /* we first free the additional linked items of the hashtable, + and then free the whole hash table. */ + for (i =0;i < SIZE; i++) { + np = hashtab+i; + temptr1 = np->next; + while(temptr1 != NULL) { + temptr = temptr1; + temptr1 = temptr1->next; + free(temptr->name); + free(temptr); + } + if(np->name != NULL) free(np->name); + } + + free(hashtab); + return 0; +} + +/*------------------------------------------------------------------------- + * Function: mkstr + * + * Purpose: make hdf5 string type + * + * Return: type + * + * In : + size: String Size + H5T_str_t: pad + + *------------------------------------------------------------------------- + */ + +hid_t mkstr(int size, H5T_str_t pad) { + + hid_t type; + + if((type=H5Tcopy(H5T_C_S1))<0) return -1; + if((H5Tset_size(type,size))<0) return -1; + if((H5Tset_strpad(type,pad))<0) return -1; + + return type; +} + +/*------------------------------------------------------------------------- + * Function: h4_transnumattr + * + * Purpose: translate reference number into hdf5 attribute + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + h5g: hdf5 group id + refname: reference name + group_ref: reference number + + *------------------------------------------------------------------------- + */ +int h4_transnumattr(hid_t h5g,const char *refname,uint16 group_ref) { + + hid_t h5memtype; + hid_t h5a_id; + hid_t h5a_sid; + herr_t ret; + + h5a_sid = H5Screate(H5S_SCALAR); + + if (h5a_sid < 0) { + fprintf(stderr,"failed to create attribute space for HDF4_REF_NUM. \n"); + return FAIL; + } + + h5a_id = H5Acreate(h5g,refname,H5T_STD_U16BE,h5a_sid,H5P_DEFAULT); + + if(h5a_id <0) { + fprintf(stderr,"failed to obtain attribute id for HDF4_REF_NUM. \n"); + H5Sclose(h5a_sid); + return FAIL; + } + + if(H5Tget_size(H5T_NATIVE_CHAR)== sizeof(uint16)) + h5memtype = H5T_NATIVE_UCHAR; + else if(H5Tget_size(H5T_NATIVE_SHORT)== sizeof(uint16)) + h5memtype = H5T_NATIVE_USHORT; + else if(H5Tget_size(H5T_NATIVE_INT) == sizeof(uint16)) + h5memtype = H5T_NATIVE_UINT; + else if(H5Tget_size(H5T_NATIVE_LONG)== sizeof(uint16)) + h5memtype = H5T_NATIVE_ULONG; + + ret = H5Awrite(h5a_id,h5memtype,(void *)&group_ref); + + if(ret <0) { + printf("failed to obtain attribute.\n "); + H5Sclose(h5a_sid); + H5Aclose(h5a_id); + return FAIL; + } + + ret = H5Sclose(h5a_sid); + ret = H5Aclose(h5a_id); + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: h4_transpredattrs + * + * Purpose: translate predefined attributes into hdf5 attribute + * predefined attributes include HDF4 OBJECT TYPE, + HDF4 OBJECT NAME, HDF4 CLASS etc. They are all in + H5T_STRING format. + + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + h5g: group id + attrname: attribute name + data: attribute data + + *------------------------------------------------------------------------- + */ +int h4_transpredattrs(hid_t h5g,const char *attrname,char*data){ + + hsize_t h5str_size; + hid_t h5a_id; + hid_t h5a_sid; + hid_t h5str_type; + herr_t ret; + + if(data == NULL) { + printf("attribute data is not available.\n"); + return FAIL; + } + + h5str_size = strlen(data); + + if ((h5str_type = mkstr(h5str_size,H5T_STR_NULLTERM))<0) { + printf("error in making string for predefined ATTR. \n"); + return FAIL; + } + + h5a_sid = H5Screate(H5S_SCALAR); + + if (h5a_sid < 0) { + printf("failed to create attribute space for HDF4_OBJECT. \n"); + return FAIL; + } + + h5a_id = H5Acreate(h5g,attrname,h5str_type,h5a_sid,H5P_DEFAULT); + + if(h5a_id <0) { + fprintf(stderr,"failed to obtain attribute id for HDF4_OBJECT. \n"); + H5Sclose(h5a_sid); + return FAIL; + } + + ret = H5Awrite(h5a_id,h5str_type,(void *)data); + + if(ret <0) { + fprintf(stderr,"failed to obtain attribute.\n "); + H5Aclose(h5a_id); + H5Sclose(h5a_sid); + return FAIL; + } + ret = H5Sclose(h5a_sid); + ret = H5Aclose(h5a_id); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: vg_transattrs + * + * Purpose: translate predefined vgroup attributes into hdf5 attribute + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + h4vg: hdf4 vgroup id + h5g: hdf5 group id + + *------------------------------------------------------------------------- + */ + +int vg_transattrs(int32 h4vg,hid_t h5g) { + + /* define variables for hdf4. */ + char vgroup_name[VGNAMELENMAX]; + char vgroup_class[VGNAMELENMAX]; + char vgattr_name[MAX_NC_NAME]; + char obtype[MAX_NC_NAME]; + + int32 vgroup_cref; + int32 num_vgattr; + int32 count_vgattr; + int32 vg_atype; + int32 attr_size; + + size_t sh4_size; + size_t sh4_amemsize; + + /* define variables for hdf5. */ + hid_t sh5a_sid; + hid_t sh5a_id; + hid_t sh5_atype; + hid_t sh5_amemtype; + hid_t sh5str_type; + hid_t sh5str_memtype; + hsize_t sh5dims[MAX_VAR_DIMS]; + void* vg_adata; + herr_t sret; + int i; + + num_vgattr = Vnattrs(h4vg); + + for (i = 0;i <num_vgattr;i++) { + + if (Vattrinfo(h4vg,i,vgattr_name,&vg_atype, + &count_vgattr,&attr_size)== FAIL){ + printf("unable to obtain attribute information. \n"); + return FAIL; + } + + /* convert attribute datatype into the corresponding hdf5 datatype */ + + if(h4type_to_h5type(vg_atype,&sh5_amemtype,&sh4_amemsize, + &sh4_size,&sh5_atype)==FAIL){ + printf("unable to do data type converting.\n"); + return FAIL; + } + + vg_adata = malloc(sh4_amemsize*count_vgattr); + + if(vg_adata == NULL) { + printf("error in allocating vgroup attribute data. \n"); + return FAIL; + } + + if(Vgetattr(h4vg,i,(VOIDP)vg_adata)==FAIL){ + printf("unable to get attribute.\n"); + free(vg_adata); + return FAIL; + } + + /* if the attribute doesn't have a name, a default name is set. */ + if(vgattr_name[0] == '\0') + strcpy(vgattr_name,trans_obj_name(DFTAG_VG,i)); + + /* now do attribute-transferring. + 1. deal with string data type + 2. set attribute space. + 3. get attribute name, set property list. */ + + if (sh5_atype == H5T_STRING ) { + + sh5a_sid = H5Screate(H5S_SCALAR); + + if (sh5a_sid < 0) { + printf("failed to create attribute space "); + printf("for HDF4_OBJECT_TYPE SDS. \n"); + free(vg_adata); + return FAIL; + } + + if ((sh5str_type = mkstr(count_vgattr*sh4_size,H5T_STR_NULLTERM))<0) { + fprintf(stderr,"error in making string for VGROUP ATTR. \n"); + free(vg_adata); + return FAIL; + } + + /* check this line later. */ + if ((sh5str_memtype = mkstr(count_vgattr*sh4_amemsize, + H5T_STR_NULLTERM))<0){ + fprintf(stderr,"error in making memory string for VGROUP ATTR. \n"); + free(vg_adata); + return FAIL; + } + + sh5a_id = H5Acreate(h5g,vgattr_name,sh5str_type,sh5a_sid,H5P_DEFAULT); + + if (sh5a_id <0) { + printf("failed to obtain attribute id"); + printf(" for HDF4_OBJECT_TYPE VGROUP. \n"); + free(vg_adata); + return FAIL; + } + sret = H5Awrite(sh5a_id,sh5str_memtype,(void *)vg_adata); + + if (sret <0) { + fprintf(stderr,"failed to obtain attribute.\n "); + free(vg_adata); + return FAIL; + } + sret = H5Sclose(sh5a_sid); + sret = H5Aclose(sh5a_id); + } + + else { + + if (count_vgattr == 1) { + sh5a_sid = H5Screate(H5S_SCALAR); + if (sh5a_sid < 0) { + fprintf(stderr,"failed to create space id. \n"); + free(vg_adata); + return FAIL; + } + } + + else { + + sh5dims[0] = count_vgattr; + sh5a_sid = H5Screate_simple(1,sh5dims,NULL); + if (sh5a_sid < 0) { + fprintf(stderr,"failed to create vgroup attribute space. \n"); + free(vg_adata); + return FAIL; + } + } + + sh5a_id = H5Acreate(h5g,vgattr_name,sh5_atype,sh5a_sid,H5P_DEFAULT); + + if(sh5a_id <0) { + fprintf(stderr,"failed to obtain attribute id. \n"); + free(vg_adata); + H5Sclose(sh5a_sid); + return FAIL; + } + sret = H5Awrite(sh5a_id,sh5_amemtype,(void *)vg_adata); + + if(sret < 0) { + fprintf(stderr,"failed to obtain attribute.\n "); + free(vg_adata); + H5Sclose(sh5a_sid); + H5Aclose(sh5a_id); + return FAIL; + } + + sret = H5Sclose(sh5a_sid); + sret = H5Aclose(sh5a_id); + } + free(vg_adata); + } + + /*** check this line later. ***/ + strcpy(obtype,VGROUPLABEL); + vgroup_class[0] = '\0'; + + /* ignore CDF0.0 and RIG0.0 vgroups. */ + if(Vgetclass(h4vg,vgroup_class) == SUCCEED){ + if(vgroup_class[0] != '\0') { + if(!strcmp(vgroup_class,_HDF_CDF)|| + !strcmp(vgroup_class,GR_NAME)) + return SUCCEED; + } + } + + /* transfer predefined attributes. */ + if(h4_transpredattrs(h5g,HDF4_OBJECT_TYPE,obtype)==FAIL){ + printf("error in data attribute transferring.\n"); + return FAIL; + } + + if(Vgetname(h4vg,vgroup_name) == SUCCEED){ + if(vgroup_name[0] != '\0') { + if(h4_transpredattrs(h5g,HDF4_OBJECT_NAME,vgroup_name)==FAIL){ + printf("error in data attribute transferring.\n"); + return FAIL; + } + } + } + + if(vgroup_class[0] !='\0') { + if(h4_transpredattrs(h5g,HDF4_VGROUP_CLASS,vgroup_class)==FAIL){ + printf("error in data attribute transferring.\n"); + return FAIL; + } + } + + vgroup_cref = VQueryref(h4vg); + if(vgroup_cref == FAIL) { + printf("failed to obtain group reference number.\n"); + return FAIL; + } + + if(h4_transnumattr(h5g,HDF4_REF_NUM,vgroup_cref)==FAIL){ + printf("error in data attribute transferring.\n"); + return FAIL; + } + + return SUCCEED; +} + + +/*------------------------------------------------------------------------- + * Function: get_obj_aboname + * + * Purpose: get absolute path name of hdf5 object + In this function, we will deal with name clashing. + If we find an object name(by using lookup_name routine) + that has already been used, + we will remake name for this object. We will follow + object type(vgroup,sds,image,palette, vdata) plus reference + number to make it unique. + * + * Return: NULL if failed, object name if successful. + * + * In : + obj_name: relative object name + ref_str: reference number in character format + path_name: absolute path + objstr: object type in character format + + *------------------------------------------------------------------------- + */ + +char* get_obj_aboname(char* obj_name,char* refstr,char* path_name, + const char*objstr ) { + + char *abo_objname; + int check_name; + char check_char; + + /* sometimes although the object name is not NULL, but it is empty. + We will use make_objname_no under this situation. */ + if(obj_name != NULL) check_char = *obj_name; + /* obtain the absolute name of the object. */ + if (obj_name == NULL || check_char == '\0') + abo_objname = make_objname_no(refstr,path_name,objstr); + else + abo_objname = make_objname_yes(obj_name,path_name); + + /* look up the name and see whether there is name clashing here. + if yes, remake the object name.*/ + check_name = lookup_name(abo_objname,num_objects,name_hashtab); + + if(check_name == 1) { + + if(objstr != NULL && refstr != NULL){ + free(abo_objname); + + if(path_name != NULL) { + abo_objname= malloc(strlen(path_name)+strlen(objstr)+ + strlen(refstr)+3); + if(abo_objname == NULL) { + printf("error in allocating memory. \n"); + return NULL; + } + bzero(abo_objname,strlen(path_name)+strlen(objstr)+ + strlen(refstr)+3); + strcpy(abo_objname,path_name); + strcat(abo_objname,"/"); + strcat(abo_objname,objstr); + strcat(abo_objname,"_"); + strcat(abo_objname,refstr); + } + + else { + abo_objname= malloc(strlen(objstr)+strlen(refstr)+3); + if(abo_objname == NULL) { + printf("error in allocating memory. \n"); + return NULL; + } + bzero(abo_objname,strlen(objstr)+strlen(refstr)+3); + strcat(abo_objname,"/"); + strcat(abo_objname,objstr); + strcat(abo_objname,"_"); + strcat(abo_objname,refstr); + } + } + } + return abo_objname; +} + +/*------------------------------------------------------------------------- + * Function: make_objname_no + * + * Purpose: get absolute path name of hdf5 object when object name is + not defined. + We will use path name and + object type(vgroup,sds,image,palette, vdata) plus reference + number to make it unique. + * + * Return: NULL if failed, object name if successful. + * + * In : + ref_str: reference number in character format + path_name: absolute path + objstr: object type in character format + + *------------------------------------------------------------------------- + */ + +char* make_objname_no(char* refstr,char* path_name,const char*objstr) { + + char *new_objname; + + if(objstr == NULL || refstr == NULL) { + printf("error, object type and ref. number should be defined.\n"); + return NULL; + } + + if (path_name == NULL) {/* under root group. */ + + new_objname= malloc(strlen(objstr)+strlen(refstr)+3); + if(new_objname == NULL) { + printf("error in allocating memory. \n"); + return NULL; + } + bzero(new_objname,strlen(objstr)+strlen(refstr)+3); + strcpy(new_objname,"/"); + strcat(new_objname,objstr); + strcat(new_objname,"_"); + strcat(new_objname,refstr); + } + + else { + + new_objname= malloc(strlen(path_name)+strlen(objstr)+strlen(refstr)+3); + if(new_objname == NULL) { + printf("error in allocating memory. \n"); + return NULL; + } + bzero(new_objname,strlen(path_name)+strlen(objstr)+strlen(refstr)+3); + strcpy(new_objname,path_name); + strcat(new_objname,"/"); + strcat(new_objname,objstr); + strcat(new_objname,"_"); + strcat(new_objname,refstr); + } + + return new_objname; +} + +/*------------------------------------------------------------------------- + * Function: make_objname_yes + * + * Purpose: get absolute path name of hdf5 object when object name is + defined. + + * + * Return: NULL if failed, object name if successful. + * + * In : obj_name: object name + path_name: absolute path + + *------------------------------------------------------------------------- + */ + +char* make_objname_yes(char* obj_name,char* path_name){ + + char*new_objname; + + if(path_name == NULL) { + new_objname = malloc(strlen(obj_name)+2); + if(new_objname == NULL) { + printf("error in allocating memory. \n"); + return NULL; + } + bzero(new_objname,strlen(obj_name)+2); + strcpy(new_objname,"/"); + strcat(new_objname,obj_name); + } + else { + new_objname = malloc(strlen(path_name)+strlen(obj_name)+2); + if(new_objname == NULL) { + printf("error in allocating memory. \n"); + return NULL; + } + bzero(new_objname,strlen(path_name)+strlen(obj_name)+2); + strcpy(new_objname,path_name); + strcat(new_objname,"/"); + strcat(new_objname,obj_name); + } + return new_objname; +} + +/*------------------------------------------------------------------------- + * Function: trans_obj_name + * + * Purpose: obtain hdf4 attribute name from hdf4 object type + plus ATTR plus reference number. + * + * Return: object name; + * + * In : + obj_tag: hdf4 tag + index : hdf5 group id + + *------------------------------------------------------------------------- + */ +char* trans_obj_name(int32 obj_tag,int32 index) { + + char* obj_name; + char indstr[5]; + + obj_name = malloc(strlen(HDF4_PALETTE)+strlen(ATTR)+8); + if(obj_name == NULL) { + printf("cannot allocate memory for object name. \n"); + return NULL; + } + bzero(obj_name,strlen(HDF4_PALETTE)+strlen(ATTR)+8); + + if(conv_int_str(index,indstr)== FAIL) { + printf("indstr is not allocated. \n"); + return NULL; + } + + switch(obj_tag) { + + case DFTAG_SD: + case DFTAG_NDG: + case DFTAG_SDG: + strcpy(obj_name,HDF4_SDS); + break; + + case DFTAG_RIG: + case DFTAG_RI: + case DFTAG_RI8: + strcpy(obj_name,HDF4_IMAGE); + break; + + case DFTAG_VG: + strcpy(obj_name,HDF4_VGROUP); + break; + + case DFTAG_VH: + case DFTAG_VS: + strcpy(obj_name,HDF4_VDATA); + break; + + case DFTAG_LUT: + strcpy(obj_name,HDF4_PALETTE); + break; + + default: + printf("error, object tag is transferred out of limits. \n"); + free(obj_name); + return NULL; + } + + strcat(obj_name,"_"); + strcat(obj_name,ATTR); + strcat(obj_name,"_"); + strcat(obj_name,indstr); + + return obj_name; +} +/*------------------------------------------------------------------------- + * Function: freehashmemory + * + * Purpose: free memories allocated for hash tables. + + * + * Return: NULL + * + * In : + + + *------------------------------------------------------------------------- + */ + +void freehashmemory(void){ + + if(estnum_vg != 0) freetable(estnum_vg,vg_hashtab); + if(estnum_vd != 0) freetable(estnum_vd,vd_hashtab); + + if(num_sds !=0) { + freetable(2*num_sds,sds_hashtab); + freenametable(DIM_HASHSIZE,dim_hashtab); + } + + if(num_images !=0) { + freetable(2*num_images,gr_hashtab); + freetable(PAL_HASHSIZE,pal_hashtab); + } + + if(num_objects !=0) freenametable(num_objects,name_hashtab); + +} + +/*------------------------------------------------------------------------- + * Function: correct_name + * + * Purpose: modify the hdf4 object name when the name contains '/'. Change + this character into '_'. + + * + * Return: the corrected name + * + * In : old name + + + *------------------------------------------------------------------------- + */ +char *correct_name(char* oldname){ + + char * cptr; + char * newname; + + if(oldname == NULL) { + printf("inputting name is wrong.\n"); + return NULL; + } + + newname = malloc(strlen(oldname)+1); + bzero(newname,strlen(oldname)+1); + newname = strncpy(newname, oldname, strlen(oldname)); + + while(strchr(newname,ORI_SLASH)!= NULL){ + cptr = strchr(newname,ORI_SLASH); + *cptr = CHA_SLASH; + } + + return newname; +} + + + + + + + + + + + + + + + + diff --git a/tools/h4toh5util.h b/tools/h4toh5util.h new file mode 100644 index 0000000..cd6bcf4 --- /dev/null +++ b/tools/h4toh5util.h @@ -0,0 +1,188 @@ +#ifndef UTILITY_H +#define UTILITY_H +#include "hdf5.h" +#include "hdf.h" + +/**********************************************/ +/*************** section I *******************/ +/*This section of the file describes reserved +name and global parameters used in h4-h5 +converter.*/ +/*********************************************/ + +/* 0. if "/" is found in hdf4 object name, we will use another + character "_" to replace it. */ + +#define ORI_SLASH '/' +#define CHA_SLASH '_' + +/* 1. character string used for default attribute name. */ +#define ATTR "ATTR" + +/* 2. Predefined HDF5 Attribute name for HDF4 file */ + +#define HDF4_OBJECT_NAME "HDF4_OBJECT_NAME" +#define HDF4_OBJECT_TYPE "HDF4_OBJECT_TYPE" +#define HDF4_REF_NUM "HDF4_REF_NUM" +#define HDF4_VGROUP_CLASS "HDF4_VGROUP_CLASS" +#define HDF4_IMAGE_CLASS "HDF4_IMAGE_CLASS" +#define HDF4_IMAGE_SUBCLASS "HDF4_IMAGE_SUBCLASS" +#define HDF4_PALETTE_CLASS "HDF4_PALETTE_CLASS" +#define HDF4_PALETTE_TYPE "PAL_TYPE" +#define PAL_TYPE "STANDARD8" + +/* 3. reserved name for HDF5 object name when meeting with name clashing. */ + +#define HDF4_VGROUP "HDF4_VGROUP" +#define HDF4_PALETTE "HDF4_PALETTE" +#define HDF4_SDS "HDF4_SDS" +#define HDF4_VDATA "HDF4_VDATA" +#define HDF4_IMAGE "HDF4_IMAGE" +#define HDF4_DIMSCALE "HDF4_DIMSCALE" + +/* 4. global palette and dimension_list name. */ +#define HDF4_IMAGE_PALETTE "HDF4_IMAGE_PALETTE" +#define HDF4_DIMENSION_LIST "HDF4_DIMENSION_LIST" +#define PALETTE "PALETTE" + +#define DIMSCALE "DIMSCALE" + +/* 5. define affix GLOBAL for dealing sds and image file attributes. */ +#define GLOSDS "GLOSDS" +#define GLOIMAGE "GLOIMAGE" + +/* 6. define HDF object label.*/ +#define SDSLABEL "SDS" +#define VDATALABEL "Vdata" +#define VGROUPLABEL "Vgroup" +#define GRLABEL "GR" +#define RAST8LABEL "raster8" +#define RAST24LABEL "raster24" +#define PALABEL "palette" + +/* 7. define HDF object class. */ +#define IM_CLASS "IMAGE" + +/* 8. reserved group name for HDF4 dimensional scale and palette. */ +#define HDF4_DIMG "/HDF4_DIMGROUP" +#define HDF4_PALG "/HDF4_PALGROUP" + +/* 9. reserved name for hdf4 file label,file description, object label, + object description. */ +#define HDF4_FILE_LABEL "HDF4_FILE_LABEL" +#define HDF4_FILE_DESC "HDF4_FILE_DESCRIPTION" +#define HDF4_OBJECT_LABEL "HDF4_OBJECT_LABEL" +#define HDF4_OBJECT_DESC "HDF4_OBJECT_DESCRIPTION" +#define HDF4_SDS_LABEL "HDF4_SDS_LABEL" +#define HDF4_SDS_DESC "HDF4_SDS_DESC" +#define HDF4_IMAGE_LABEL "HDF4_IMAGE_LABEL" +#define HDF4_IMAGE_DESC "HDF4_IMAGE_DESC" +#define HDF4_VDATA_LABEL "HDF4_VDATA_LABEL" +#define HDF4_VDATA_DESC "HDF4_VDATA_DESC" +#define HDF4_VGROUP_LABEL "HDF4_VGROUP_LABEL" +#define HDF4_VGROUP_DESC "HDF4_VGROUP_DESC" +#define HDF4_PAL_LABEL "HDF4_PAL_LABEL" +#define HDF4_PAL_DESC "HDF4_PAL_DESC" +#define HDF4_IMAGE_INDEXED "HDF4_IMAGE_INDEXED" + +/*10. palette and dimensional scale hash size and the + maximum length of object reference number in string format. + global variables of vgroup, vdata, sds, image and total number of + the object, number of global sds attributes and GR attributes.*/ + +#define PAL_HASHSIZE 64 +#define DIM_HASHSIZE 64 +#define VG_DEFHASHSIZE 64 +#define VD_DEFHASHSIZE 64 +#define MAXREF_LENGTH 5 + +int32 estnum_vg; +int32 estnum_vd; +int32 num_sds; +int32 num_images; +int num_objects; +int32 num_glsdsattrs; +int32 num_glgrattrs; + +/**********************************************/ +/*************** section II *******************/ +/*This section describes hash tables and their + functions used in h4-h5 converter.*/ +/*********************************************/ +/*define two kinds of hashtables. + 1. struct table will use object reference as the key to handle whether this + object is visited or not. + 2. struct name_table will use name as the key to handle name clashings and + dimensional scale dataset. +*/ + +struct table { + int ref; + struct table *next; + char *name; +}; + +struct name_table { + char *name; + struct name_table *next; +}; + +struct table* sds_hashtab; +struct table* gr_hashtab; +struct table* vg_hashtab; +struct table* vd_hashtab; +struct table* pal_hashtab; +struct name_table* name_hashtab; +struct name_table* dim_hashtab; + +/* look-up table, object reference is the key.*/ +int lookup(int,int,struct table*); + +/*look-up table, key is name. */ +int hash_fun(char*name,int size); +int lookup_name(char*, int,struct name_table*); + +/* routines that initialize the tables and name tables.*/ +int init_tab(int,struct table*); +int init_nametab(int,struct name_table*); + +/* get name and set name for table. */ +char* get_name(int,int,struct table *,int*); +int set_name(int,int,struct table *,char*); + +/* free table routines. */ +int freetable(int,struct table *); +int freenametable(int, struct name_table*); +void freehashmemory(void); + +/**********************************************/ +/*************** section III *******************/ +/*This section describes other common routines and their + functions used in h4-h5 converter.*/ +/*********************************************/ + +/* this routine defines the convertion of data type from h4 to h5. */ +herr_t h4type_to_h5type(const int32 h4type, hid_t* h5memtype, + size_t* h4memsize, size_t* h4size, hid_t *h5type); + +/* routines for translating predefined hdf4 attributes into hdf5 attributes*/ +int h4_transpredattrs(hid_t ,const char *,char*data); +int h4_transnumattr(hid_t h5g,const char *,uint16 group_ref); +int vg_transattrs(int32,hid_t); + +/*string and int conversion routines.*/ +hid_t mkstr(int size, H5T_str_t pad); +herr_t h5string_to_int(const int32, hid_t*,const size_t,hid_t* ); +int conv_int_str(uint16, char*); + +char* trans_obj_name(int32,int32); +char* get_obj_aboname(char*,char*,char*,const char*); +char* make_objname_no(char*,char*,const char*); +char* make_objname_yes(char*,char*); +char* correct_name(char*); + +#endif + + + + diff --git a/tools/h4toh5vdata.c b/tools/h4toh5vdata.c new file mode 100644 index 0000000..ff23ce9 --- /dev/null +++ b/tools/h4toh5vdata.c @@ -0,0 +1,788 @@ + +#include "h4toh5main.h" + +/*------------------------------------------------------------------------- + * Function: Vdata_h4_to_h5 + * + * Purpose: translate Vdata object into hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + vdata_id: RI identifier + group_id: hdf5 group id + Out: + + Modification: + *------------------------------------------------------------------------- + */ + +int Vdata_h4_to_h5(int32 file_id,int32 vdata_id, hid_t group_id) { + + /* define variables for hdf4. */ + + int32 istat; + int32 n_records; + + int32 vdata_ref; + int32 vdata_tag; + + int32 interlace_mode; + + int32 vdata_size; + int32 vdatamem_size; + + int32 field_index; + int32 fieldorder; + int32 fieldtype; + + int i; + int32 nfields; + int num_vd_attrs; + int num_vd_field_attrs; + + VOIDP vd_data; + + char vdlabel[10]; + char vdata_name[MAX_NC_NAME]; + char fieldname[MAX_NC_NAME]; + char vdata_class[VSNAMELENMAX]; + char field_name_list[VSFIELDMAX*FIELDNAMELENMAX]; + + /* define varibles for hdf5. */ + + hid_t h5d_sid; + hid_t h5dset; + + hid_t h5_ctype; + hid_t h5_cmemtype; + + hid_t* h5memtype = NULL; + hid_t* h5type = NULL; + + size_t* h4memsize = NULL; + size_t* h4size = NULL; + hsize_t h5_vddims[1]; + char* h5cvdata_name; + + int check_vdname; + + + /* get absolute path of vdata name. */ + + vdata_ref = VSQueryref(vdata_id); + if (vdata_ref == FAIL) { + printf("error in getting reference number. \n"); + return FAIL; + } + + vdata_tag = VSQuerytag(vdata_id); + if (vdata_tag == FAIL) { + printf("error in getting object tag number. \n"); + return FAIL; + } + + /* get the class name */ + + if(VSgetclass(vdata_id,vdata_class) == FAIL) { + printf("error in obtaining class name. \n"); + return FAIL; + } + + /* get number of record,field_name,Size of a record and + Name of the vdata*/ + + if(VSQueryvsize(vdata_id,&vdata_size)==FAIL) { + printf("error in getting size of vdata. \n"); + return FAIL; + } + + if(vdata_size == 0) {/* empty vdata set. */ + return SUCCEED; + } + + /* obtain number of records, field name list, vdata name. */ + if(VSinquire(vdata_id,&n_records,&interlace_mode, + field_name_list,&vdata_size,vdata_name) == FAIL) { + printf("error in inquiring vdata. \n"); + return FAIL; + } + + vdatamem_size = 0; + nfields = VFnfields(vdata_id); + + if (nfields == FAIL) { + printf("error in obtaining number of vdata fields. \n"); + return FAIL; + } + + h5memtype = calloc(nfields,sizeof(hid_t)); + h5type = calloc(nfields,sizeof(hid_t)); + h4memsize = calloc(nfields,sizeof(size_t)); + h4size = calloc(nfields,sizeof(size_t)); + + for (i=0;i<nfields;i++) { + + /* obtain field type. */ + fieldtype = VFfieldtype(vdata_id,i); + if(fieldtype == FAIL){ + printf("error in obtaining field type. \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + return FAIL; + } + + /* obtain field order.*/ + fieldorder = VFfieldorder(vdata_id,i); + /* printf("fieldorder %d\n",fieldorder);*/ + if(fieldorder == FAIL){ + printf("error in obtaining field order. \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + return FAIL; + } + + /* datatype conversion from hdf4 to hdf5. + the corresponding memory data type is also converted.*/ + if(h4type_to_h5type(fieldtype,&h5memtype[i],&h4memsize[i], + &h4size[i],&h5type[i])== FAIL){ + printf("error in doing datatype conversion at vdata routine. \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + return FAIL; + } + + vdatamem_size +=fieldorder*h4memsize[i]; + + } + + + + /* printf("vdatamem_size %d\n",vdatamem_size); + printf("vdata_size %d\n",vdata_size);*/ + vd_data = malloc(vdatamem_size*n_records); + + istat = VSsetfields(vdata_id,field_name_list); + + if(istat == FAIL) { + printf("error setting fields of vdata.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + istat = VSread(vdata_id,(uint8*)vd_data,n_records,FULL_INTERLACE); + + if(istat == FAIL) { + printf("error in obtaining vdata. \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + for (i=0;i<nfields;i++) { + /* obtain field order.*/ + fieldorder = VFfieldorder(vdata_id,i); + /* printf("%d again fieldorder %d\n",i,fieldorder);*/ + if(fieldorder == FAIL){ + printf("error in obtaining field order. \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + return FAIL; + } + } + /* create hdf5 compound datatype for both memory and file.*/ + + h5_ctype = H5Tcreate(H5T_COMPOUND, (size_t)vdata_size); + h5_cmemtype = H5Tcreate(H5T_COMPOUND,(size_t)vdatamem_size); + + if(gen_h5comptype(vdata_id,nfields,h4size,h4memsize,h5type,h5memtype, + h5_ctype,h5_cmemtype)==FAIL){ + printf("error in generating h5 compound data type.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + h5_vddims[0] = n_records; + h5d_sid = H5Screate_simple(1,h5_vddims,NULL); + + if(h5d_sid <0){ + printf("error in obtaining space id.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + /* choose a number that is not returned from the func.*/ + check_vdname = -3; + + /* obtain hdf5 vdata name. */ + h5cvdata_name = get_name(vdata_ref,estnum_vd,vd_hashtab,&check_vdname); + + if (h5cvdata_name == NULL && check_vdname == 0 ) { + printf("error,cannot find vdata \n"); + return FAIL; + } + + if (h5cvdata_name == NULL && check_vdname == -1) { + printf("error,group name is not defined.\n"); + return FAIL; + } + + if (h5cvdata_name == NULL && check_vdname == -2 ) { + printf("cannot allocate memory for vdata.\n"); + return FAIL; + } + + h5dset = H5Dcreate(group_id,h5cvdata_name,h5_ctype,h5d_sid,H5P_DEFAULT); + if(h5dset <0) { + printf("error in obtaining dataset.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + free(h5cvdata_name); + return FAIL; + } + free(h5cvdata_name); + + if(H5Dwrite(h5dset,h5_cmemtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,vd_data)<0){ + printf("error in writing dataset converted from vdata.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + /* handle vdata attributes and vdata field attributes. */ + + num_vd_attrs = VSfnattrs(vdata_id,_HDF_VDATA); + + if (num_vd_attrs == FAIL) { + printf("error in obtaining attributes of vdata.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + /* when field_index = -1, only transfer vdata attribute.*/ + + field_index = -1; + if(vdata_transattrs(vdata_id,h5dset,num_vd_attrs,field_index,NULL)==FAIL){ + printf("error in translating vdata attibutes.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + for (i =0;i< nfields;i++) { + + if(VFfieldname(vdata_id,i)== NULL) { + printf("error in obtaining field name. \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + strcpy(fieldname,VFfieldname(vdata_id,i)); + num_vd_field_attrs = VSfnattrs(vdata_id,i); + if(num_vd_field_attrs == FAIL){ + printf("error in number of vd field attribute \n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + if(vdata_transattrs(vdata_id,h5dset,num_vd_field_attrs,i,fieldname) + ==FAIL){ + printf("error in transfering vdata attributes.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + } + /* converting annotations of vdata into corresponding hdf5 attribute.*/ + if( Annoobj_h4_to_h5(file_id,vdata_ref,vdata_tag,h5dset)== FAIL){ + printf("fail to convert HDF4 VDATA annotation into hdf5 attributes.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + /* converting predefined attributes. */ + strcpy(vdlabel,VDATALABEL); + if(h4_transpredattrs(h5dset,HDF4_OBJECT_TYPE,vdlabel)==FAIL){ + printf("error in transfering vdata attributes.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + if(vdata_name != NULL) { + if(h4_transpredattrs(h5dset,HDF4_OBJECT_NAME,vdata_name)==FAIL){ + printf("error in transfering vdata attributes.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + } + + if(h4_transnumattr(h5dset,HDF4_REF_NUM,vdata_ref)==FAIL){ + printf("error in transfering vdata attributes.\n"); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return FAIL; + } + + H5Sclose(h5d_sid); + H5Dclose(h5dset); + VSdetach(vdata_id); + free(h5memtype); + free(h5type); + free(h4memsize); + free(h4size); + free(vd_data); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: vdata_transattrs + * + * Purpose: translate Vdata attributes into attributes of the + corresponding hdf5 dataset + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + vdata_id: vdata identifier + h5dset: hdf5 dataset + snum_vdattrs: number of vd attributes + field_index: index of vdata fields + attr_name: vdata(or vdata field) attribute name + Out: + Modifications: + + *------------------------------------------------------------------------- + */ + +int vdata_transattrs(int32 vdata_id,hid_t h5dset,int snum_vdattrs, + int field_index,char* attr_name){ + + char svdattr_name[2*MAX_NC_NAME]; + char* svdrepattr_name; + char refstr[MAXREF_LENGTH]; + + int32 count_svdadata; + int32 svd_atype; + + size_t sh4_amemsize; + size_t sh4_asize; + + hid_t sh5a_sid; + hid_t sh5a_id; + hid_t sh5_atype; + hid_t sh5_amemtype; + hid_t sh5str_type; + hid_t sh5str_memtype; + + hsize_t sh5dims[1]; + void* svd_adata; + herr_t sret; + int i; + + /* separate vdata attribute from vdata field attributes. */ + + if (field_index < -1) { + printf("error: check_field should be either -1(vdata) or "); + printf(">=0(vdata field).\n"); + return FAIL; + } + + for (i = 0;i < snum_vdattrs; i++) { + + /* if the field_index is 0, no field attribute exists, only + VDATA attributes are converted.*/ + + if (VSattrinfo(vdata_id,field_index,i,svdattr_name,&svd_atype, + &count_svdadata,NULL)== FAIL){ + printf("unable to obtain attribute information. \n"); + return FAIL; + } + + if(svdattr_name[0] == '\0') { + svdrepattr_name = trans_obj_name(DFTAG_VG,i); + strcpy(svdattr_name,svdrepattr_name); + free(svdrepattr_name); + } + + if (field_index == -1); + + else if (field_index != -1 && attr_name != NULL) { + + strcat(svdattr_name,":"); + strcat(svdattr_name,attr_name); + } + + else { + + strcat(svdattr_name,":"); + strcat(svdattr_name,"HDF4_VDATA_ATTR_"); + if(conv_int_str(field_index,refstr)==FAIL) { + printf("error in converting vdata field index to string.\n"); + return FAIL; + } + strcat(svdattr_name,refstr); + + } + + /* converting attribute data type into the corresponding hdf5 data type */ + + if(h4type_to_h5type(svd_atype,&sh5_amemtype,&sh4_amemsize, + &sh4_asize,&sh5_atype)==FAIL){ + printf("fail to translate vdata attribute datatype from H4 to H5.\n"); + return FAIL; + } + + svd_adata = malloc(sh4_amemsize * count_svdadata); + + if(svd_adata == NULL) { + printf("fail to allocate memory for vdata attribute data.\n"); + return FAIL; + } + + if(VSgetattr(vdata_id,field_index,i,(VOIDP)svd_adata)==FAIL){ + printf("error in getting attributes of vdata. \n"); + free(svd_adata); + return FAIL; + } + + /* now do attribute-transferring: + 1. deal with string data type + 2. set attribute space + 3. get attribute name */ + + if (sh5_atype == H5T_STRING) { + + if ((sh5str_type = mkstr(count_svdadata, + H5T_STR_NULLTERM))<0) { + printf("error in making string for vdata attribute. \n"); + free(svd_adata); + return FAIL; + } + + if ((sh5str_memtype = mkstr(count_svdadata*sh4_amemsize, + H5T_STR_NULLTERM))<0) { + printf("error in making memory string for vdata attribute. \n"); + free(svd_adata); + return FAIL; + } + + sh5a_sid = H5Screate(H5S_SCALAR); + + if (sh5a_sid < 0) { + printf("failed to create attribute space for "); + printf("HDF4_OBJECT_TYPE VDATA. \n"); + free(svd_adata); + return FAIL; + } + + + sh5a_id = H5Acreate(h5dset,svdattr_name,sh5str_type, + sh5a_sid,H5P_DEFAULT); + + if (sh5a_id <0) { + printf("failed to obtain attribute id for"); + printf(" HDF4_OBJECT_TYPE VDATA. \n"); + H5Sclose(sh5a_sid); + free(svd_adata); + return FAIL; + } + + sret = H5Awrite(sh5a_id,sh5str_memtype,(void *)svd_adata); + + if (sret <0) { + printf("fail to write vdata attr into hdf5 dataset attr\n "); + H5Sclose(sh5a_sid); + H5Aclose(sh5a_id); + free(svd_adata); + return FAIL; + } + + free(svd_adata); + sret = H5Sclose(sh5a_sid); + sret = H5Aclose(sh5a_id); + } + + else { + + if(count_svdadata == 1) { + sh5a_sid = H5Screate(H5S_SCALAR); + + if (sh5a_sid < 0) { + printf("failed to create scalar space id for hdf5 attribute "); + printf("of dataset converted from attribute of VDATA.\n"); + free(svd_adata); + return FAIL; + } + } + else { + sh5dims[0] = count_svdadata; + sh5a_sid = H5Screate_simple(1,sh5dims,NULL); + + if (sh5a_sid < 0) { + printf("failed to create simple space id for hdf5 attribute "); + printf("of dataset converted from attribute of VDATA.\n"); + free(svd_adata); + return FAIL; + } + } + + sh5a_id = H5Acreate(h5dset,svdattr_name,sh5_atype, + sh5a_sid,H5P_DEFAULT); + + if(sh5a_id <0) { + printf("failed to create attribute id for hdf5 attribute "); + printf("of dataset converted from attribute of VDATA.\n"); + H5Sclose(sh5a_sid); + free(svd_adata); + return FAIL; + } + + sret = H5Awrite(sh5a_id,sh5_amemtype,(void *)svd_adata); + + if(sret <0) { + printf("failed to write attribute data for hdf5 attribute "); + printf("of dataset converted from attribute of VDATA.\n"); + H5Sclose(sh5a_sid); + H5Aclose(sh5a_id); + free(svd_adata); + return FAIL; + } + + sret = H5Aclose(sh5a_id); + sret = H5Sclose(sh5a_sid); + free(svd_adata); + } + } + return SUCCEED; +} +/*------------------------------------------------------------------------- + * Function: gen_h5comptype + * + * Purpose: generate hdf5 compound data type + + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + vdata_id: vdata identifier + nfields: number of fields + sh4size: pointer to datatype size in memory + sh4memsize: pointer to datatype size in memory + sh5type: pointer to hdf5 datatype + sh5memtype: pointer to actual hdf5 datatype in memory + h5_ctype: hdf5 compound datatype + h5_cmemtype: hdf5 compound datatype in memory + Out: + Modifications: + + *------------------------------------------------------------------------- + */ + +int gen_h5comptype(int32 vdata_id,int32 nfields, + size_t* sh4size,size_t* sh4memsize, + hid_t* sh5type,hid_t* sh5memtype, + hid_t h5_ctype,hid_t h5_cmemtype) { + + /*char fieldname[MAX_NC_NAME]; + char* temp_fieldname;*/ + char* fieldname; + int32 fieldorder; + int32 fieldsize; + size_t fil_offset; + size_t mem_offset; + size_t fieldsizef; + size_t fielddim[1]; + hid_t h5str_type; + int i; + + fil_offset = 0; + mem_offset = 0; + fieldsizef = 0; + + + + for (i =0;i< nfields;i++) { + + fieldname = NULL; + fieldorder = VFfieldorder(vdata_id,i); + /* printf(" %d fieldorder%d\n",i,fieldorder);*/ + if(fieldorder == FAIL){ + printf("error in obtaining fieldorder.\n"); + return FAIL; + } + /* temp_fieldname = VFfieldname(vdata_id,i); + if(temp_fieldname== NULL) { + printf("fail to obtain Vdata field name. \n"); + return FAIL; + } + + strncpy(fieldname,temp_fieldname,strlen(temp_fieldname)); + + + free(temp_fieldname);*/ + + fieldname = VFfieldname(vdata_id,i); + if(fieldname == NULL){ + printf("fail to obtain Vdata field name. \n"); + return FAIL; + } + + + fieldsize = VFfieldesize(vdata_id,i); + if(fieldsize == FAIL) { + printf("error in obtaining fieldsize of vdata field.\n"); + return FAIL; + } + + if(sh5type[i] == H5T_STRING) { + /* printf("sh4size in the string %d\n",sh4size[i]); + printf("fieldsize in the string %d\n",fieldsize);*/ + if ((h5str_type = mkstr(sh4size[i],H5T_STR_NULLTERM))<0) { + printf("error in making string of hdf5 string. \n"); + return FAIL; + } + sh5type[i] = h5str_type; + } + + if (sh5memtype[i] == H5T_STRING) { + + if((h5str_type = mkstr(sh4memsize[i],H5T_STR_NULLTERM))<0){ + printf("error in making string for VDATA in memory. \n"); + return FAIL; + } + sh5memtype[i] = h5str_type; + + } + + fielddim[0] = fieldorder; + + /* if field type is an array, use H5Tinsert_array.*/ + + if (fielddim[0] == 1) { + + /* printf("i%d,sh5type[i] %d\n",i,sh5type[i]); + printf("i%d,fieldname%s\n",i,fieldname); + printf("i%d,fil_offset%d\n",i,fil_offset);*/ + if(H5Tinsert(h5_ctype,fieldname,fil_offset,sh5type[i])<0) { + printf("error inserting hdf5 compound datatype while "); + printf("converting vdata.\n"); + return FAIL; + } + + /* printf("i%d,sh5memtype[i] %d\n",i,sh5memtype[i]); + printf("i%d,fieldname%s\n",i,fieldname); + printf("i%d,mem_offset%d\n",i,mem_offset);*/ + if(H5Tinsert(h5_cmemtype,fieldname,mem_offset,sh5memtype[i])<0){ + printf("error inserting hdf5 compound datatype of memory"); + printf(" while converting vdata.\n"); + return FAIL; + } + } + + else { + + if(H5Tinsert_array(h5_ctype,fieldname,fil_offset,1,fielddim, + NULL,sh5type[i])<0) { + printf("error inserting array into hdf5 compound datatype. \n"); + return FAIL; + } + /* printf("i%d,sh5memtype[i] %d\n",i,sh5memtype[i]); + printf("i%d,fielddim[0]%d\n",i,fielddim[0]); + printf("i%d,fieldname%s\n",i,fieldname); + printf("i%d,mem_offset%d\n",i,mem_offset);*/ + if(H5Tinsert_array(h5_cmemtype,fieldname,mem_offset,1,fielddim, + NULL,sh5memtype[i])<0) { + printf("error inserting array into hdf5 compound datatype for memory. \n"); + return FAIL; + } + + + } + + /* fieldsizef = (size_t)fieldsize; + fil_offset = fil_offset + fieldsizef; + mem_offset = mem_offset + sh4memsize[i];*/ + + fil_offset = fil_offset + sh4size[i]*fieldorder; + mem_offset = mem_offset + sh4memsize[i]*fieldorder; + /* free(fieldname);*/ + } + + return SUCCEED; +} + + + + + + + + + + + + + + diff --git a/tools/h4toh5vgroup.c b/tools/h4toh5vgroup.c new file mode 100644 index 0000000..14e1c0f --- /dev/null +++ b/tools/h4toh5vgroup.c @@ -0,0 +1,768 @@ +/*** This file is the main program of converter. ***/ + +#include "h4toh5main.h" + + +/*------------------------------------------------------------------------- + * Function: Vgroup_h4_to_h5 + * + * Purpose: translate different Vgroup objects: vgroup,vdata,sds,image + into hdf5 datasets and recursively call the routine + * + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: hdf4 file identifier + vgroup_id: hdf4 vgroup id + sd_id: sd interface id + h5_group: hdf5 group id + h5_dimgroup: hdf5 dimensional scale group id + h5_palgroup: hdf5 palette group id + Out: + + Modification: + *------------------------------------------------------------------------- + */ + +int Vgroup_h4_to_h5(int32 file_id,int32 vgroup_id,int32 sd_id,hid_t h5_group,hid_t h5_dimgroup,hid_t h5_palgroup) + +{ + + int32 vgroup_tag; + int32 vgroup_ref; + int32 obj_tag; + int32 obj_ref; + int32 num_gobjects; + int i; + + char refstr[5]; + char vgroup_class[VGNAMELENMAX]; + char vgroup_name[VGNAMELENMAX]; + + char* h5pgroup_name; + + int check_vgname; + hid_t h5_pgroup; + + vgroup_tag = VQuerytag(vgroup_id); + if(vgroup_tag == FAIL) { + printf("error in obtaining vgroup tag.\n"); + return FAIL; + } + + vgroup_ref = VQueryref(vgroup_id); + if(vgroup_ref == FAIL) { + printf("error in obtaining vgroup reference.\n"); + return FAIL; + } + + if(Vgetname(vgroup_id,vgroup_name) == FAIL) { + printf("error in obtaining vgroup name.\n"); + return FAIL; + } + + if(Vgetclass(vgroup_id,vgroup_class) == FAIL) { + printf("error in obtaining vgroup class name. \n"); + return FAIL; + } + + /*** ignore reserved HDF group ***/ + + if(vgroup_class != NULL) { + if(strcmp(vgroup_class,_HDF_ATTRIBUTE)==0) return SUCCEED; + if(strcmp(vgroup_class,_HDF_VARIABLE)==0) return SUCCEED; + if(strcmp(vgroup_class,_HDF_DIMENSION)==0) return SUCCEED; + if(strcmp(vgroup_class,_HDF_UDIMENSION)==0) return SUCCEED; + if(strcmp(vgroup_class,_HDF_CDF)==0) return SUCCEED; + if(strcmp(vgroup_class,GR_NAME)==0) return SUCCEED; + if(strcmp(vgroup_class,RI_NAME)==0) return SUCCEED; + } + + if(vgroup_name != NULL) + if(strcmp(vgroup_name,GR_NAME)==0) return SUCCEED; + + h5pgroup_name = get_name(vgroup_ref,estnum_vg,vg_hashtab,&check_vgname); + + if(h5pgroup_name == NULL && check_vgname == 0 ) { + printf("error,cannot find group\n"); + return FAIL; + } + + if(h5pgroup_name == NULL && check_vgname ==-1 ) { + printf("error,group name is not defined.\n"); + return FAIL; + } + + /* create a hdf5 group under h5_group.*/ + + h5_pgroup = H5Gcreate(h5_group,h5pgroup_name,0); + + if(h5_pgroup < 0) { + printf("error in creating group. \n"); + free(h5pgroup_name); + return FAIL; + } + + /* vgroup attributes into corresponding hdf5 group attributes.*/ + if(vg_transattrs(vgroup_id,h5_pgroup)==FAIL) { + printf("error in translating vgroup attributes into hdf5 group attr.\n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + + num_gobjects = Vntagrefs(vgroup_id); + + if(num_gobjects == FAIL) { + printf("error in obtaining number of objects in the vgroup. \n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + + if(Annoobj_h4_to_h5(file_id,vgroup_ref,vgroup_tag,h5_pgroup)==FAIL) { + printf("error in obtaining annotation of the vgroup.\n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + + for( i = 0;i<num_gobjects;i++) { + + if(Vgettagref(vgroup_id,i,&obj_tag,&obj_ref)==FAIL) { + printf("failed to get object tag and ref of the current"); + printf(" object in this vgroup.\n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + + if(conv_int_str(obj_ref,refstr)== FAIL) { + printf("failed to convert object reference number "); + printf("into string format at vgroup_h4_to_h5 routine.\n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + + if (Visvg(vgroup_id,obj_ref)) { + + if(convert_vgroup(file_id,sd_id,obj_ref,h5pgroup_name,h5_pgroup, + h5_dimgroup,h5_palgroup)== FAIL) { + printf("convert_vgroup routine failed,"); + printf("cannot convert vgroup into hdf5 group successfully.\n"); + free(h5pgroup_name); + H5Gclose(h5_pgroup); + return FAIL; + } + + + + } + /* the object is independent vdata. */ + else if(Visvs(vgroup_id,obj_ref)) { + if(convert_vdata(file_id,obj_ref,h5pgroup_name,h5_pgroup)==FAIL){ + printf("fail to convert vdata into hdf5 dataset.\n"); + free(h5pgroup_name); + H5Gclose(h5_pgroup); + return FAIL; + } + } + else if(obj_tag == DFTAG_NDG || obj_tag == DFTAG_SDG) { + if(convert_sds(file_id,sd_id,obj_ref,h5pgroup_name,h5_pgroup, + h5_dimgroup)==FAIL){ + printf("fail to convert sds into hdf5 dataset.\n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + } + else if(obj_tag == DFTAG_RIG) { + if(convert_image(file_id,obj_ref,h5pgroup_name, + h5_pgroup,h5_palgroup)==FAIL){ + printf("fail to convert image into hdf5 dataset.\n"); + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return FAIL; + } + } + } + + H5Gclose(h5_pgroup); + free(h5pgroup_name); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: convert_vgroup + * + * Purpose: subroutine interface for better modularity of vgroup_h4_to_h5 + * In this routine, 1) h5 vgroup name is obtained; + 2) vgroup_h4_to_h5 is called again for + unvisited vgroups + 3) HardLink is created for visited vgroups + + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: hdf4 file identifier + sd_id: sd interface id + obj_ref: object reference number + h5pgroup_name: h5 group name + h5_pgroup: hdf5 group id + h5_dimgroup: hdf5 dimensional scale group id + h5_palgroup: hdf5 palette group id + + *------------------------------------------------------------------------- + */ + +int convert_vgroup(int32 file_id,int32 sd_id, int32 obj_ref, + char* h5pgroup_name,hid_t h5_pgroup,hid_t h5_dimgroup, + hid_t h5_palgroup) { + + int32 vgroup_cid; + int32 istat; + int check_vgname; + char refstr[MAXREF_LENGTH]; + char cvgroup_name[VGNAMELENMAX]; + char* cor_cvgroupname; + char* h5cgroup_name; + char* h5lgroup_name; + int check_vgroup; + + if(conv_int_str(obj_ref,refstr)== FAIL) { + printf("converting integer into string format.\n"); + return FAIL; + } + + vgroup_cid = Vattach(file_id,obj_ref,"r"); + if(vgroup_cid == FAIL) { + printf("error in getting vgroup id.\n"); + return FAIL; + } + + /* recursively obtain information from the group*/ + /* check whether it is looked up, if yes, create a hard link.*/ + + istat = Vgetname(vgroup_cid,cvgroup_name); + if(istat == FAIL) { + printf("failed to get the name of vgroup.\n"); + Vdetach(vgroup_cid); + return FAIL; + } + + /* look up vg hashtable and see whether this object is touched.*/ + check_vgroup = lookup(obj_ref,estnum_vg,vg_hashtab); + + /* if this vgroup has not been touched, convert it into hdf5 group. + else create a hard link to the existing group.*/ + + cor_cvgroupname = correct_name(cvgroup_name); + if(cor_cvgroupname == NULL) { + printf("error in generating corrected vgroup name. \n"); + Vdetach(vgroup_cid); + return FAIL; + } + if(check_vgroup == 0) { + + /* checking whether vgroup name contains ORI_SLASH, changing into CHA_SLASH.*/ + + h5cgroup_name = get_obj_aboname(cor_cvgroupname,refstr,h5pgroup_name, + HDF4_VGROUP); + if(h5cgroup_name == NULL) { + printf("error in getting the group name.\n"); + Vdetach(vgroup_cid); + free(cor_cvgroupname); + return FAIL; + } + + free(cor_cvgroupname); + if(set_name(obj_ref,estnum_vg,vg_hashtab,h5cgroup_name)== FAIL) { + printf("error in setting group name.\n"); + Vdetach(vgroup_cid); + free(h5cgroup_name); + return FAIL; + } + if(Vgroup_h4_to_h5(file_id,vgroup_cid,sd_id,h5_pgroup, + h5_dimgroup,h5_palgroup)== FAIL) { + printf("error in transferring vgroup into hdf5 group.\n"); + Vdetach(vgroup_cid); + free(h5cgroup_name); + return FAIL; + } + free(h5cgroup_name); + + } + + else { + + h5cgroup_name = get_name(obj_ref,estnum_vg,vg_hashtab,&check_vgname); + if(h5cgroup_name == NULL && check_vgname ==0 ) { + printf("error,cannot find group\n"); + Vdetach(vgroup_cid); + return FAIL; + } + + if(h5cgroup_name == NULL && check_vgname == -1 ) { + printf("error,group name is not defined.\n"); + Vdetach(vgroup_cid); + return FAIL; + } + + /* create HL */ + + + h5lgroup_name = get_obj_aboname(cor_cvgroupname,refstr,h5pgroup_name, + HDF4_VGROUP); + if(h5lgroup_name == NULL) { + printf("failed to obtain group name.\n"); + Vdetach(vgroup_cid); + free(h5cgroup_name); + free(cor_cvgroupname); + return FAIL; + } + free(cor_cvgroupname); + if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5cgroup_name,h5lgroup_name)<0) { + printf("cannot make hard link for two groups.\n"); + Vdetach(vgroup_cid); + free(h5cgroup_name); + free(h5lgroup_name); + return FAIL; + } + free(h5cgroup_name); + free(h5lgroup_name); + } + + Vdetach(vgroup_cid); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: convert_vdata + * + * Purpose: subroutine interface for better modularity of vgroup_h4_to_h5 + * In this routine, 1) h5 vdata name is obtained; + 2) vdata_h4_to_h5 is called for unvisited + vdatas + 3) HardLink is created for visited vdatas + + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: hdf4 file identifier + obj_ref: object reference number + h5pgroup_name: h5 group name + h5_pgroup: hdf5 group id + + *------------------------------------------------------------------------- + */ + +int convert_vdata(int32 file_id,int32 obj_ref,char * h5pgroup_name, + hid_t h5_pgroup) { + + int32 vdata_id; + int check_vdata; + int check_vdname; + int32 istat; + char refstr[5]; + char cvdata_name[VGNAMELENMAX]; + char* cor_cvdataname; + char* h5cvdata_name; + char* h5lvdata_name; + + vdata_id = VSattach(file_id,obj_ref,"r"); + if(vdata_id == FAIL) { + printf("error in attaching vdata. \n"); + return FAIL; + } + + if(conv_int_str(obj_ref,refstr)== FAIL) { + printf("converting integer into string format.\n"); + VSdetach(vdata_id); + return FAIL; + } + + istat = VSisattr(vdata_id); + if (istat == FAIL) { + printf("error in checking vdata attribute. \n"); + VSdetach(vdata_id); + return FAIL; + } + + if(istat); /*ignore, attributes can be retrieved later.*/ + + else { /* independent vdata, read in */ + + check_vdata = lookup(obj_ref,estnum_vd,vd_hashtab); + + if(check_vdata < 0) { + printf("failed to look up the object.\n"); + VSdetach(vdata_id); + return FAIL; + } + + if(VSQueryname(vdata_id,cvdata_name)==FAIL) { + printf("error in querying name. \n"); + VSdetach(vdata_id); + return FAIL; + } + + cor_cvdataname = correct_name(cvdata_name); + if(cor_cvdataname == NULL) { + printf("error in generating corrected vdata name. \n"); + VSdetach(vdata_id); + return FAIL; + } + if(check_vdata ==0) { + h5cvdata_name = get_obj_aboname(cor_cvdataname,refstr,h5pgroup_name, + HDF4_VDATA); + if(h5cvdata_name == NULL) { + printf("cannot obtain the converted hdf5 dataset name from vdata.\n"); + VSdetach(vdata_id); + free(cor_cvdataname); + return FAIL; + } + free(cor_cvdataname); + if(set_name(obj_ref,estnum_vd,vd_hashtab,h5cvdata_name)== FAIL){ + printf("failed to obtain vdata name.\n"); + VSdetach(vdata_id); + free(h5cvdata_name); + return FAIL; + } + + if(Vdata_h4_to_h5(file_id,vdata_id,h5_pgroup)==FAIL){ + printf("failed to transfer vdata into hdf5 dataset.\n"); + VSdetach(vdata_id); + free(h5cvdata_name); + return FAIL; + } + free(h5cvdata_name); + } + + else { + + h5cvdata_name = get_name(obj_ref,estnum_vd,vd_hashtab, + &check_vdname); + + if(h5cvdata_name == NULL && check_vdname ==0 ){ + printf("error,cannot find vdata\n"); + VSdetach(vdata_id); + return FAIL; + } + if(h5cvdata_name == NULL && check_vdname ==-1 ){ + printf("error,vdata name is not defined.\n"); + VSdetach(vdata_id); + return FAIL; + } + /*... ADD in the code. create HL, + for the time being, we will use absolute path. */ + + h5lvdata_name = get_obj_aboname(cor_cvdataname,refstr,h5pgroup_name, + HDF4_VDATA); + if(h5lvdata_name == NULL) { + printf("error in obtaining vdata name.\n"); + VSdetach(vdata_id); + free(h5cvdata_name); + free(cor_cvdataname); + return FAIL; + } + free(cor_cvdataname); + if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5cvdata_name,h5lvdata_name)){ + printf("error in creating hardlink for hdf5 dataset"); + printf(" converted from vdata.\n"); + VSdetach(vdata_id); + free(h5cvdata_name); + free(h5lvdata_name); + return FAIL; + } + free(h5cvdata_name); + free(h5lvdata_name); + } + VSdetach(vdata_id); + } + + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: convert_sds + * + * Purpose: subroutine interface for better modularity of vgroup_h4_to_h5 + * In this routine, 1) h5 sds name is obtained; + 2) sds_h4_to_h5 is called for unvisited + sds objects + 3) HardLink is created for visited sds + + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + sd_id: hdf4 sds identifier + obj_ref: object reference number + h5_dimgroup: h5 dimensional scale group id + h5_pgroup: hdf5 group id + + *------------------------------------------------------------------------- + */ +int convert_sds(int32 file_id,int32 sd_id,int32 obj_ref,char * h5pgroup_name, + hid_t h5_pgroup,hid_t h5_dimgroup) { + + int32 sd_index; + int32 sds_id; + int32 sds_rank; + int32 sds_dimsizes[DIM_HASHSIZE]; + int32 sds_dtype; + int32 num_sdsattrs; + char sds_name[MAX_NC_NAME]; + char* cor_sdsname; + int check_sds; + int check_sdsname; + char refstr[5]; + char* h5csds_name; + char* h5lsds_name; + + sd_index = SDreftoindex(sd_id,obj_ref); + if(sd_index == FAIL){ + printf("error in obtaining reference number of sds.\n"); + return FAIL; + } + + sds_id = SDselect(sd_id,sd_index); + + if(sds_id == FAIL){ + printf("error in obtaining sd id.\n"); + return FAIL; + } + + if(SDgetinfo(sds_id,sds_name,&sds_rank,sds_dimsizes, + &sds_dtype,&num_sdsattrs)==FAIL) { + printf("error in obtaining SD info.\n"); + SDendaccess(sds_id); + return FAIL; + } + + /* check whether this sds is touched. */ + check_sds = lookup(obj_ref,2*num_sds,sds_hashtab); + + cor_sdsname = correct_name(sds_name); + if(cor_sdsname == NULL) { + printf("error in generating corrected sds name. \n"); + SDendaccess(sds_id); + return FAIL; + } + if(check_sds == 0) { + + /* obtain the absolute name of sds object, deal with the name clashing by + looking up things in the "name hashing table".*/ + + h5csds_name = get_obj_aboname(cor_sdsname,refstr,h5pgroup_name,HDF4_SDS); + if(h5csds_name == NULL) { + printf("error in obtaining sds name.\n"); + SDendaccess(sds_id); + free(cor_sdsname); + return FAIL; + } + free(cor_sdsname); + /* put the absolute path of sds into "hashing table".*/ + if(set_name(obj_ref,2*num_sds,sds_hashtab,h5csds_name)==FAIL) { + printf("error in setting object name.\n"); + SDendaccess(sds_id); + free(h5csds_name); + return FAIL; + } + /* convert the sds object into hdf5 dataset.*/ + if(Sds_h4_to_h5(file_id,sds_id,h5_pgroup,h5_dimgroup)==FAIL){ + printf("error in translating sds into hdf5 dataset.\n"); + SDendaccess(sds_id); + free(h5csds_name); + return FAIL; + } + free(h5csds_name); + } + else { + /* if the object has been touched, create a hard link instead.*/ + h5csds_name = get_name(obj_ref,2*num_sds,sds_hashtab,&check_sdsname); + if(h5csds_name == NULL) { + printf("error in getting sds name \n"); + SDendaccess(sds_id); + return FAIL; + } + /*... ADD in the code. create HL, + for the time being, we will use absolute path. */ + h5lsds_name = get_obj_aboname(cor_sdsname,refstr,h5pgroup_name, + HDF4_SDS); + if(h5lsds_name == NULL) { + printf("error in getting sds link name.\n"); + SDendaccess(sds_id); + free(h5csds_name); + free(cor_sdsname); + return FAIL; + } + free(cor_sdsname); + if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5csds_name,h5lsds_name) <0) { + printf("error in getting hard link \n"); + SDendaccess(sds_id); + free(h5csds_name); + free(h5lsds_name); + return FAIL; + } + + free(h5csds_name); + free(h5lsds_name); + } + SDendaccess(sds_id); + return SUCCEED; +} + +/*------------------------------------------------------------------------- + * Function: convert_image + * + * Purpose: subroutine interface for better modularity of vgroup_h4_to_h5 + * In this routine, 1) h5 vdata name is obtained; + 2) image_h4_to_h5 is called for unvisited + images + 3) Hard Link is created for visited images + + * Return: FAIL if failed, SUCCEED if successful. + * + * In : + file_id: hdf4 file identifier + obj_ref: object reference number + h5pgroup_name: h5 group name + h5_pgroup: hdf5 group id + h5_palgroup: hdf5 palette group id + + *------------------------------------------------------------------------- + */ +int convert_image(int32 file_id,int32 obj_ref,char * h5pgroup_name, + hid_t h5_pgroup,hid_t h5_palgroup) { + + int32 gr_id; + int32 gr_index; + int32 ri_id; + int32 istat; + char* h5cimage_name; + char* h5limage_name; + char refstr[5]; + char image_name[MAX_GR_NAME]; + char* cor_imagename; + + int check_imagename; + int check_image; + + + gr_id = GRstart(file_id); + if(gr_id == FAIL) { + printf("error in obtaining gr id. \n"); + return FAIL; + } + + if(conv_int_str(obj_ref,refstr)== FAIL) { + printf("converting integer into string format.\n"); + return FAIL; + } + + gr_index= GRreftoindex(gr_id,obj_ref); + if(gr_index == FAIL) { + printf("error in getting gr index.\n"); + return FAIL; + } + + ri_id = GRselect(gr_id,gr_index); + if(ri_id == FAIL) { + printf("error in selecting gr interface.\n"); + return FAIL; + } + + istat = GRgetiminfo(ri_id, image_name, NULL, NULL, NULL, NULL, NULL); + + if(istat == FAIL) { + GRendaccess(ri_id); + printf("error in getting GR images.\n"); + return FAIL; + } + + /* checking whether image name contains ORI_SLASH, + changing into CHA_SLASH.*/ + + cor_imagename = correct_name(image_name); + if(cor_imagename == NULL) { + printf("error in generating corrected image name. \n"); + GRendaccess(ri_id); + return FAIL; + } + + /* check whether this image is touched. */ + check_image = lookup(obj_ref,2*num_images,gr_hashtab); + + if(check_image == 0) { + + /* obtain the absolute name of image object, deal with the name clashing by + looking up things in the "name hashing table".*/ + + h5cimage_name = get_obj_aboname(cor_imagename,refstr,h5pgroup_name, + HDF4_IMAGE); + if(h5cimage_name == NULL) { + printf("error in getting image name.\n"); + GRendaccess(ri_id); + free(cor_imagename); + return FAIL; + } + free(cor_imagename); + + if(set_name(obj_ref,2*num_images,gr_hashtab,h5cimage_name)==FAIL) { + printf("error setting image name.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + return FAIL; + } + if(Image_h4_to_h5(file_id,ri_id,h5_pgroup,h5_palgroup)==FAIL) { + printf("error in transferring image name into hdf5 dataset.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + return FAIL; + } + free(h5cimage_name); + } + + else{ + + /*if the object is visited, create HL. */ + + h5cimage_name = get_name(obj_ref,2*num_images,gr_hashtab, + &check_imagename); + + if(h5cimage_name == NULL) { + printf("error in getting image name into hdf5 dataset.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + return FAIL; + } + h5limage_name = get_obj_aboname(cor_imagename,refstr,h5pgroup_name, + HDF4_IMAGE); + + if(h5limage_name == NULL) { + printf("error in getting link image name into hdf5 dataset.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + free(cor_imagename); + return FAIL; + } + free(cor_imagename); + + if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5cimage_name,h5limage_name)<0){ + printf("error in linking two groups.\n"); + GRendaccess(ri_id); + free(h5cimage_name); + free(h5limage_name); + return FAIL; + } + free(h5cimage_name); + free(h5limage_name); + } + + GRendaccess(ri_id); + /* this is for efficient reason, we will comment out GRend. + GRend(gr_id);*/ + + return SUCCEED; +} diff --git a/tools/testh4toh5 b/tools/testh4toh5 new file mode 100644 index 0000000..8d8feb6 --- /dev/null +++ b/tools/testh4toh5 @@ -0,0 +1,213 @@ +#!/bin/sh + +h4toh5=./h4toh5 # a relative name +cmp='cmp -s' +diff='diff -c' + +RM='rm -f' +SED='sed ' +H5DUMP=${PWD}/h5dump # Use the h5dumper in the same tools directory + +# Verify if $H5DUMP is a valid command. +tmpfile=/tmp/testh4toh5.$$ +$H5DUMP -V > $tmpfile +if [ ! -s $tmpfile ]; then + echo " Could not run the '$H5DUMP' command. The test can still proceed" + echo " but it may fail if '$H5DUMP' is needed to verify the output." + echo " You can make sure '$H5DUMP' is among your shell PATH and run" + echo " the test again. You may also visit http://hdf.ncsa.uiuc.edu" + echo " or email hdfhelp@ncsa.uiuc.edu for more information." + H5DUMP=: +fi +$RM $tmpfile + +# The build (current) directory might be different than the source directory. +if test "X$srcdir" = X; then + srcdir=. +fi +mkdir testfiles >/dev/null 2>&1 + +SRCDIR="$srcdir/testfiles" +OUTDIR="./testfiles" + +nerrors=0 +verbose=yes + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +TESTING() +{ + SPACES=" " + echo "Testing $* $SPACES" |cut -c1-70 |tr -d '\012' +} + +# Run a test and print PASS or *FAIL*. If a test fails then increment +# the `nerrors' global variable and (if $verbose is set) display the +# difference between the actual and the expected hdf4 files. The +# expected hdf5 files are in testfiles/Expected directory. +# The actual hdf5 file is not removed if $HDF5_NOCLEANUP is to a non-null +# value. +CONVERT() +{ + # Run h4toh5 convert. + TESTING $h4toh5 $@ + + # + # Set up arguments to run the conversion test. + # The converter assumes all hdf4 files has the .hdf suffix as in the form + # of foo.hdf. It creates the corresponding hdf5 files with the .h5 suffix + # as in the form of foo.h5. One exception is that if exactly two file + # names are given, it treats the first argument as an hdf4 file and creates + # the corresponding hdf5 file with the name as the second argument, WITOUT + # any consideration of the suffix. (For this test script, in order to + # match the output hdf5 file with the expected hdf5 file, it expects the + # second file of the two-files tests has the .h5 suffix too.) + # + # If SRCDIR != OUTDIR, need to copy the input hdf4 files from the SRCDIR + # to the OUTDIR and transform the input file pathname because of the suffix + # convention mentioned above. This way, the hdf5 files are always created + # in the OUTDIR directory. + + INFILES="" + OUTFILES="" + MULTIRUN="" + + case "$1" in + "-m") # multiple files conversion + MULTIRUN="-m" + shift + for f in $* + do + if [ "$SRCDIR" != "$OUTDIR" ] + then + cp $SRCDIR/$f $OUTDIR/$f + fi + INFILES="$INFILES $f" + OUTFILES="$OUTFILES `basename $f .hdf`.h5" + shift + done + ;; + * ) # Single file conversion + case $# in + 1) if [ "$SRCDIR" != "$OUTDIR" ] + then + cp $SRCDIR/$1 $OUTDIR/$1 + fi + INFILES="$1" + OUTFILES="`basename $1 .hdf`.h5" + ;; + 2) # hdf4 file specified + if [ "$SRCDIR" != "$OUTDIR" ] + then + cp $SRCDIR/$1 $OUTDIR/$1 + fi + INFILES="$1" + OUTFILES="$2" + ;; + *) # Illegal + echo "Illegal arguments" + exit 1 + ;; + esac + ;; + esac + + # run the conversion and remove input files that have been copied over + ( + cd $OUTDIR + ../$h4toh5 $INFILES $OUTFILES 2>/dev/null + if [ "$SRCDIR" != "$OUTDIR" ] + then + $RM $INFILES + fi + ) + + # Verify results + result="passed" + for f in $OUTFILES + do + if $cmp $SRCDIR/Expected/$f $OUTDIR/$f + then + : + else + # Use h5dump to dump the files and verify the output. + outfile=`basename $f .h5` + expect_out=$outfile.expect + actual_out=$outfile.actual + + (cd $SRCDIR/Expected + $H5DUMP $outfile.h5 ) > $expect_out + (cd $OUTDIR + $H5DUMP $outfile.h5 ) > $actual_out + + if [ "passed" = $result -a ! -s $actual_out ] ; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + result=failed + test yes = "$verbose" && + echo " H5DUMP failed to produce valid output" + elif $cmp $expect_out $actual_out; then + : + else + if test "passed" = $result; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + result=failed + fi + test yes = "$verbose" && + echo " Actual result (*.actual) differs from expected result (*.expect)" && + $diff $expect_out $actual_out |sed 's/^/ /' + fi + fi + + # Clean up output file + if [ X = ${HDF5_NOCLEANUP:-X} ]; then + $RM $expect_out $actual_out + $RM $OUTDIR/$f + fi + done + if test "passed" = "$result"; then + echo " PASSED" + fi +} + + + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + +$RM $OUTDIR/*.hdf $OUTDIR/*.tmp + +# +# The HDF5 filenames are created based upon the HDF4 filenames +# without the extension. +# + +# test for converting H5 groups to H4 Vgroups. +#CONVERT vg.hdf + + +# +# The test for conversion are the same as above with the only difference +# being that the HDF5 filenames are given explicitly. +# + +$RM $OUTDIR/*.tmp +CONVERT vg.hdf vg.h5 + +# +# Again, the test for conversion are the same as the first set of test. +# Here, multiple conversion are done on HDF4 files at one time. +# + +$RM $OUTDIR/*.hdf $OUTDIR/*.tmp +#CONVERT -m vg.hdf + +if test $nerrors -eq 0 ; then + echo "All h4toh5 tests passed." +fi + +exit $nerrors |