summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/h4toh5anno.c635
-rw-r--r--tools/h4toh5image.c712
-rw-r--r--tools/h4toh5main.c1538
-rw-r--r--tools/h4toh5main.h56
-rw-r--r--tools/h4toh5pal.c167
-rw-r--r--tools/h4toh5sds.c892
-rw-r--r--tools/h4toh5util.c1618
-rw-r--r--tools/h4toh5util.h188
-rw-r--r--tools/h4toh5vdata.c788
-rw-r--r--tools/h4toh5vgroup.c768
-rw-r--r--tools/testh4toh5213
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