summaryrefslogtreecommitdiffstats
path: root/tools/h4toh5
diff options
context:
space:
mode:
authorBill Wendling <wendling@ncsa.uiuc.edu>2001-02-22 21:53:30 (GMT)
committerBill Wendling <wendling@ncsa.uiuc.edu>2001-02-22 21:53:30 (GMT)
commit416a86e3ce3b967553003267a6e77c037e21815f (patch)
tree8f5ab1478acd23215c797b66730b784609c9c297 /tools/h4toh5
parent20061988ec9daa96b5d5b9aaed75af587d582a0e (diff)
downloadhdf5-416a86e3ce3b967553003267a6e77c037e21815f.zip
hdf5-416a86e3ce3b967553003267a6e77c037e21815f.tar.gz
hdf5-416a86e3ce3b967553003267a6e77c037e21815f.tar.bz2
[svn-r3488] Purpose:
Code Movement Description: Moved tools code into their own special subdirectories. Platforms tested: Linux, Kelgia
Diffstat (limited to 'tools/h4toh5')
-rw-r--r--tools/h4toh5/Dependencies0
-rw-r--r--tools/h4toh5/Makefile.in60
-rw-r--r--tools/h4toh5/h4toh5anno.c665
-rw-r--r--tools/h4toh5/h4toh5image.c861
-rw-r--r--tools/h4toh5/h4toh5main.c1629
-rw-r--r--tools/h4toh5/h4toh5main.h109
-rw-r--r--tools/h4toh5/h4toh5pal.c202
-rw-r--r--tools/h4toh5/h4toh5sds.c1096
-rw-r--r--tools/h4toh5/h4toh5test.c3944
-rw-r--r--tools/h4toh5/h4toh5util.c1633
-rw-r--r--tools/h4toh5/h4toh5util.h232
-rw-r--r--tools/h4toh5/h4toh5vdata.c831
-rw-r--r--tools/h4toh5/h4toh5vgroup.c812
-rwxr-xr-xtools/h4toh5/testh4toh5.sh249
14 files changed, 12323 insertions, 0 deletions
diff --git a/tools/h4toh5/Dependencies b/tools/h4toh5/Dependencies
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/h4toh5/Dependencies
diff --git a/tools/h4toh5/Makefile.in b/tools/h4toh5/Makefile.in
new file mode 100644
index 0000000..71019e2
--- /dev/null
+++ b/tools/h4toh5/Makefile.in
@@ -0,0 +1,60 @@
+## HDF5 Library Makefile(.in)
+##
+## Copyright (C) 2001 National Center for Supercomputing Applications.
+## All rights reserved.
+##
+##
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+SUBDIRS=
+@COMMENCE@
+
+## Add include directory to the C preprocessor flags, add -lh5tools and
+## -lhdf5 to the list of libraries.
+##
+CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src \
+ -I$(top_srcdir)/tools/lib @CPPFLAGS@
+
+## Test programs and scripts.
+##
+TEST_PROGS=
+TEST_SCRIPTS=@TESTH4TOH5@
+
+## These are our main targets: library and tools.
+##
+LIBTOOLS=../lib/libh5tools.la
+LIBHDF5=$(top_builddir)/src/libhdf5.la
+
+PUB_PROGS=@H4TOH5@
+PROGS=$(PUB_PROGS) $(TEST_PROGS) @H4TOH5TEST@
+
+## Source and object files for h4toh5 converter.
+##
+PROG_SRC=h4toh5main.c h4toh5vgroup.c h4toh5vdata.c h4toh5sds.c \
+ h4toh5image.c h4toh5pal.c h4toh5anno.c h4toh5util.c
+PROG_OBJ=$(PROG_SRC:.c=.lo)
+
+PRIVATE_HDR=h4toh5main.h h4toh5util.h
+
+## Source and object files for the tests
+##
+TEST_SRC=h4toh5test.c
+TEST_OBJ=$(TEST_SRC:.c=.lo)
+
+## Programs have to be built before they can be tested!
+##
+check test _test: $(PROGS)
+
+## How to build the programs... They all depend on the hdf5 library and
+## the tools library compiled in this directory.
+##
+$(PROGS): $(LIBTOOLS) $(LIBHDF5)
+
+h4toh5test: h4toh5test.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ h4toh5test.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+h4toh5: $(PROG_OBJ)
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ $(PROG_OBJ) $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+@CONCLUDE@
diff --git a/tools/h4toh5/h4toh5anno.c b/tools/h4toh5/h4toh5anno.c
new file mode 100644
index 0000000..cd09e26
--- /dev/null
+++ b/tools/h4toh5/h4toh5anno.c
@@ -0,0 +1,665 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+converting an hdf4 annotation into an hdf5 attribute of the corresponding object.
+
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+#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((size_t)ann_length + 1);
+ if(ann_buf == NULL) {
+ printf("error in allocating memory. \n");
+ return FAIL;
+ }
+ h4toh5_ZeroMemory(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_SPACEPAD))<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((size_t)ann_length+1);
+ if(ann_buf == NULL) {
+ printf("error in allocating memory. \n");
+ ANend(an_id);
+ ANendaccess(ann_id);
+ return FAIL;
+ }
+ h4toh5_ZeroMemory(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_SPACEPAD))<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=NULL;
+ int32* lab_anno_list=NULL;
+
+ 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((size_t)ann_length+1);
+ if(ann_buf == NULL) {
+ printf("error in allocating annotation memory.\n");
+ ANendaccess(ann_id);
+ ANend(an_id);
+ return FAIL;
+ }
+ h4toh5_ZeroMemory(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;
+ }
+
+ 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_SPACEPAD))<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((size_t)ann_length+1);
+
+ if(ann_buf == NULL) {
+ printf("error in allocating annotation memory.\n");
+ ANendaccess(ann_id);
+ ANend(an_id);
+ return FAIL;
+ }
+
+ h4toh5_ZeroMemory(ann_buf,(ann_length+1)*sizeof(char));
+ ANreadann(ann_id,ann_buf,ann_length+1);
+
+ if ((sh5str_type = mkstr(ann_length+1,H5T_STR_SPACEPAD))<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);
+
+ 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/h4toh5/h4toh5image.c b/tools/h4toh5/h4toh5image.c
new file mode 100644
index 0000000..8fbbdc0
--- /dev/null
+++ b/tools/h4toh5/h4toh5image.c
@@ -0,0 +1,861 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+converting an hdf4 image object into an hdf5 dataset, for three component image, this object will be converted into an hdf5 dataset with compound data type.
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+#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;
+ HDF_CHUNK_DEF c_def_out;
+ int32 chunk_dims[2];
+ int32 c_flags;
+
+ /* 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;
+ hsize_t fielddim[1];
+ hsize_t h5dims[2];
+ herr_t ret;
+ hid_t create_plist;
+
+ /* zeroing out memory.*/
+
+ h4toh5_ZeroMemory(image_name,MAX_GR_NAME);
+ h4toh5_ZeroMemory(image_class,MAX_GR_NAME);
+ h4toh5_ZeroMemory(grlabel,MAX_GR_NAME);
+
+ /* Obtain information of the image.*/
+
+ if(GRgetchunkinfo(ri_id,&c_def_out,&c_flags)==FAIL){
+ printf("error in getting chunking information. \n");
+ return FAIL;
+ }
+
+ 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;
+ }
+
+ /* change the order of image dimension:
+ due to the difference of hdf4 image specification and
+ hdf5 image specification. */
+
+
+
+ h5dims[0] = edges[1]-start[1];
+ h5dims[1] = edges[0]-start[0];
+
+ 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;
+ }
+
+ /* create property list. */
+
+ create_plist = H5Pcreate(H5P_DATASET_CREATE);
+
+ if(c_flags == HDF_CHUNK || c_flags == (HDF_CHUNK | HDF_COMP)
+ || c_flags == (HDF_CHUNK | HDF_NBIT) ){
+
+ chunk_dims[0] = c_def_out.chunk_lengths[0];
+ chunk_dims[1] = c_def_out.chunk_lengths[1];
+
+ if(H5Pset_chunk(create_plist, 2, (hsize_t *)chunk_dims)<0) {
+ printf("failed to set up chunking information for ");
+ printf("property list.\n");
+ free(image_data);
+ H5Pclose(create_plist);
+ 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,create_plist);
+
+ if(h5dset < 0) {
+ printf("error in creating hdf5 dataset converted from images. \n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+
+ fielddim[0] = ncomp;
+
+ {
+ hid_t arr_type; /* Array datatype for inserting fields */
+
+ /* Create array datatype */
+ if((arr_type=H5Tarray_create(h5ty_id,1,fielddim,NULL))<0) {
+ printf("error creating array datatype.\n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ ret = H5Tinsert(h5_ctype,"HDF4Image_data",0,arr_type);
+ if(ret < 0) {
+ printf("error in inserting array of compound datatype. \n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ /* Close array datatype */
+ if(H5Tclose(arr_type)<0) {
+ printf("error closing array datatype.\n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ /* Create array datatype */
+ if((arr_type=H5Tarray_create(h5memtype,1,fielddim,NULL))<0) {
+ printf("error creating array datatype.\n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ ret = H5Tinsert(h5_cmemtype,"HDF4Image_data",0,arr_type);
+ if(ret < 0) {
+ printf("error in inserting array of compound datatype at memory. \n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ /* Close array datatype */
+ if(H5Tclose(arr_type)<0) {
+ printf("error closing array datatype.\n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ h5dset = H5Dcreate(h5_group,h5cimage_name,h5_ctype,h5d_sid,
+ create_plist);
+ if(h5dset < 0) {
+ printf("error in creating dataset. \n");
+ free(image_data);
+ free(h5cimage_name);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ 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);
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ 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);
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ 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");
+ free(image_data);
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ 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");
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ free(h5cimage_name);
+ free(image_data);
+ return FAIL;
+ }
+
+ if(h4_transpredattrs(h5dset,HDF4_OBJECT_NAME,image_name)==FAIL){
+ printf("error in getting hdf4 image name attribute. \n");
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ free(h5cimage_name);
+ free(image_data);
+ return FAIL;
+ }
+
+ if(h4_transpredattrs(h5dset,HDF4_IMAGE_CLASS,image_class)==FAIL){
+ printf("error in getting hdf4 image class attribute. \n");
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ free(h5cimage_name);
+ free(image_data);
+ return FAIL;
+ }
+
+ gr_ref = GRidtoref(ri_id);
+
+ if(gr_ref == 0) {
+ printf("error in obtaining reference number of GR.\n");
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ free(h5cimage_name);
+ free(image_data);
+ return FAIL;
+ }
+
+ if(h4_transnumattr(h5dset,HDF4_REF_NUM,gr_ref)==FAIL) {
+ printf("error in getting hdf4 image number attribute.\n");
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ free(h5cimage_name);
+ free(image_data);
+ 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");
+ H5Pclose(create_plist);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ free(h5cimage_name);
+ free(image_data);
+ return FAIL;
+ }
+
+ ret = H5Pclose(create_plist);
+ ret = H5Sclose(h5d_sid);
+ ret = H5Dclose(h5dset);
+ istat = GRendaccess(ri_id);
+ free(image_data);
+ 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=NULL;
+
+
+ /* 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_SPACEPAD))<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_SPACEPAD))<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/h4toh5/h4toh5main.c b/tools/h4toh5/h4toh5main.c
new file mode 100644
index 0000000..e9ef567
--- /dev/null
+++ b/tools/h4toh5/h4toh5main.c
@@ -0,0 +1,1629 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+This file describes the main driver of hdf to hdf5 converter. It checks
+the inputting parameters, initializes the global tables, sets up the root level
+hdf5 structure and also check the special case fof vgroup loops at HDF file.
+
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+
+#include "h4toh5main.h"
+
+int32 estnum_vg;
+int32 estnum_vd;
+int32 num_sds;
+int32 num_images;
+int num_objects;
+int32 num_glsdsattrs;
+int32 num_glgrattrs;
+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;
+
+/*-------------------------------------------------------------------------
+ * 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 FAIL;
+ }
+
+ /* take care -h (help) option first */
+ { int i;
+ for (i=0; i < argc; i++)
+ if ( HDstrcmp(argv[i],"-h") == 0 ) {
+ PrintOptions_h4toh5();
+ return SUCCEED;
+ }
+ }
+
+
+ switch(argc) {
+
+ case 0:
+
+ PrintOptions_h4toh5();
+ break;
+
+ case 1: /* h4toh5 file1 */
+ h4_filename = argv[0];
+#ifndef WIN32
+ 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;
+ }
+#endif
+ /*0. check whether this file is an hdf file. */
+
+ if(!Hishdf(h4_filename)){
+ printf("error: not an hdf file. \n");
+ printf("the file will not be converted. \n");
+ 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;
+ }
+#ifndef WIN32
+ 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;
+ }
+#endif
+ 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) {
+ HDfree(h5_filename);
+ }
+
+ break;
+
+ case 2: /* h4toh5 file_in file_out */
+
+ h4_filename = argv[0];
+ h5_filename = argv[1];
+
+#ifndef WIN32
+ 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;
+ }
+
+#endif
+ /*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");
+ status = -1;
+ break;
+ }
+
+#ifndef WIN32
+ 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;
+ }
+
+#endif
+ 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
+
+ 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=(-1);/* 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");
+ if(h5_dimg>0) 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. */
+
+ /* if no lone vgroup, quit from this function. */
+ if(num_lonevg == 0)
+ return SUCCEED;
+
+ 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.*/
+ h4toh5_ZeroMemory(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;
+ }
+
+ h4toh5_ZeroMemory(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;
+ }
+
+ /* free memory of corrected 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 should never fail, if failed, something is wrong with converter or hdf library. */
+
+ 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;
+ }
+
+ h4toh5_ZeroMemory(vgroup_name,VGNAMELENMAX);
+ istat = Vgetname(vgroup_id,vgroup_name);
+ if(istat ==FAIL) {
+ printf("error in obtaining vgroup names. \n");
+ Vdetach(vgroup_id);
+ return FAIL;
+ }
+
+ h4toh5_ZeroMemory(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[0] != '\0') {
+
+ 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[0] != '\0') {
+ 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)) {
+
+ h4toh5_ZeroMemory(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;
+ }
+
+
+ if(!strncmp(vdata_class,_HDF_CHK_TBL_CLASS,strlen(_HDF_CHK_TBL_CLASS))){
+
+ VSdetach(vdata_id);
+ continue;
+ }
+
+ 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;
+ }
+
+
+ h4toh5_ZeroMemory(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);
+
+ /* check_vdata should be 1, if it is 1, either converter or hdf lib has bugs. */
+ 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. dimensional scale will be converted separately. */
+ 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 assure
+ 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);
+
+}
+
+
+
+/********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;
+}
+
+
+/*****************************************************************************
+
+ Routine: PrintOptions_h4toh5()
+
+ Description: This routine prints the acceptable argument formats out to stderr.
+
+ Input: None
+
+ Output: output to stderr
+
+*****************************************************************************/
+
+void PrintOptions_h4toh5(void)
+{
+ fprintf(stderr,"\nUsage: ");
+ fprintf(stderr,"\n h4toh5 -h (gives this print-out)\n");
+ fprintf(stderr," h4toh5 input.hdf output.h5\n");
+ fprintf(stderr," h4toh5 input.hdf\n");
+}
+
+
+
+
+
diff --git a/tools/h4toh5/h4toh5main.h b/tools/h4toh5/h4toh5main.h
new file mode 100644
index 0000000..2bb6c88
--- /dev/null
+++ b/tools/h4toh5/h4toh5main.h
@@ -0,0 +1,109 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+including declarations of subroutines of all .c files excluding h4toh5util.c.
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+
+#ifndef H4TOH5MAIN_H
+#define H4TOH5MAIN_H
+#include "hdf.h"
+#include "mfhdf.h"
+#include "hdf5.h"
+#include "h4toh5util.h"
+#include <fcntl.h>
+#include <errno.h>
+#endif
+
+/* For windows support.*/
+#if WIN32
+typedef unsigned int mode_t;
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode)&0xF000) == S_IFDIR)
+#endif
+
+/* subroutines to check initial settings and inputting parameters.
+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);
+
+/* subroutines for h4toh5main.c */
+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/h4toh5/h4toh5pal.c b/tools/h4toh5/h4toh5pal.c
new file mode 100644
index 0000000..556ecdc
--- /dev/null
+++ b/tools/h4toh5/h4toh5pal.c
@@ -0,0 +1,202 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+Converting an hdf4 palette object into a hdf5 dataset.
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+#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_PAL_NAME];
+ char palette_class[MAX_PAL_NAME];
+ char palette_type[MAX_PAL_NAME];
+ char palette_colormodel[MAX_PAL_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(pal_type,&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);
+ strcpy(palette_colormodel,RGB);
+ /* 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_transpredattrs(h5dset,PAL_COLORMODEL,palette_colormodel)==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/h4toh5/h4toh5sds.c b/tools/h4toh5/h4toh5sds.c
new file mode 100644
index 0000000..89e5ddf
--- /dev/null
+++ b/tools/h4toh5/h4toh5sds.c
@@ -0,0 +1,1096 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+Converting an hdf4 sds object into an hdf5 dataset.
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+#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;
+ intn sds_empty;
+ int32 istat;
+ int i;
+ 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;
+ HDF_CHUNK_DEF c_def_out;
+ hsize_t* chunk_dims;
+ int32 c_flags;
+
+ /* define varibles for hdf5. */
+
+ hid_t h5dset;
+ hid_t h5d_sid;
+ hid_t h5ty_id;
+ hid_t h5_memtype;
+ hid_t create_plist;
+ hsize_t h5dims[MAX_VAR_DIMS];
+ hsize_t max_h5dims[MAX_VAR_DIMS];
+
+ char* h5csds_name;
+
+ herr_t ret;
+ /* zeroing out the memory for sdsname and sdslabel.*/
+
+ h4toh5_ZeroMemory(sdsname,MAX_NC_NAME);
+ h4toh5_ZeroMemory(sdslabel,MAX_NC_NAME);
+ /* check whether the sds is empty. */
+
+ if(SDcheckempty(sds_id,&sds_empty)== FAIL) {
+ printf("error in running SDcheckempty routine. \n");
+ return FAIL;
+ }
+
+ if(sds_empty != 0) return SUCCEED;
+
+
+ /*check whether the sds is created with unlimited dimension. */
+
+ if(SDgetchunkinfo(sds_id,&c_def_out, &c_flags)== FAIL) {
+ printf("error in getting chunking information. \n");
+ return FAIL;
+ }
+
+ /*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;
+ }
+
+ /* 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];
+ max_h5dims[i] = h5dims[i];
+ }
+ if(SDisrecord(sds_id)) max_h5dims[0] = H5S_UNLIMITED;
+
+ /* 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,max_h5dims);
+
+ 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;
+ }
+
+ /* create property list. */
+
+ create_plist = H5Pcreate(H5P_DATASET_CREATE);
+ chunk_dims = malloc(sizeof(hsize_t)*sds_rank);
+
+ /* if the sds is not chunked, but with unlimited dimension, we have to
+ provide a chunk size for the corresponding hdf5 dataset. we will choose
+ 1/2 dimension size right now. */
+
+ if(c_flags == HDF_NONE && SDisrecord(sds_id))
+ {
+ for(i=0;i<sds_rank;i++){
+ chunk_dims[i] = (hsize_t)(h5dims[i]/2);
+ }
+ if(H5Pset_chunk(create_plist, sds_rank, chunk_dims)<0) {
+ printf("failed to set up chunking information for ");
+ printf("property list.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ }
+ if(c_flags == HDF_CHUNK || c_flags == (HDF_CHUNK | HDF_COMP)
+ || c_flags == (HDF_CHUNK | HDF_NBIT) ){
+
+ for(i=0;i<sds_rank;i++)
+ chunk_dims[i] = (hsize_t)c_def_out.chunk_lengths[i];
+
+ if(H5Pset_chunk(create_plist, sds_rank, chunk_dims)<0) {
+ printf("failed to set up chunking information for ");
+ printf("property list.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+ }
+
+
+ h5dset = H5Dcreate(h5_group,h5csds_name,h5ty_id,h5d_sid,create_plist);
+
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ printf("unable to transfer sds label to HDF4 OBJECT TYPE.\n");
+ return FAIL;
+ }
+
+ if(sdsname[0] != '\0') {
+ if(h4_transpredattrs(h5dset,HDF4_OBJECT_NAME,sdsname)==FAIL){
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ 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);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ printf("unable to transfer sds ref. to HDF5 dataset attribute.\n");
+ return FAIL;
+ }
+
+ istat = SDendaccess(sds_id);
+ ret = H5Pclose(create_plist);
+ ret = H5Sclose(h5d_sid);
+ ret = H5Dclose(h5dset);
+ free(sds_data);
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(chunk_dims);
+ 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_SPACEPAD))<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_SPACEPAD))<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 istat;
+ int i;
+ int count_h5objref;/* this counter updates the number of h5 object reference. */
+ int count_h5attrname;/*this counter updates the number of h5 dimensional name attribute.*/
+
+ int check_gloattr;
+ int32 num_sdsdimattrs;
+ int check_sdsdim;
+ void* dim_scadata;
+
+ char sdsdim_name[MAX_NC_NAME+1];
+ char* cor_sdsdimname;
+ size_t h4dim_memsize;
+ size_t h4dim_size;
+
+ HDF_CHUNK_DEF c_def_out;
+ int32 c_flags;
+
+ /* 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;
+ hid_t create_plist;
+
+ hsize_t h5dimscas[1];
+ hsize_t max_h5dimscas[1];
+ hsize_t h5dim_dims[1];
+ hsize_t attr_refDims[1];
+ hsize_t h5dim_chunkdim[1];
+ hobj_ref_t dim_refdat;
+
+ hobj_ref_t* alldim_refdat;
+
+ char* h5sdsdim_name;
+ char h5sdsdim_allname[MAX_VAR_DIMS * MAX_DIM_NAME];
+ char h5newsdsdim_name[MAX_DIM_NAME];
+ char h5dimpath_name[MAX_DIM_NAME];
+ herr_t ret;
+
+
+ /*zero out memory for h5sdsdim_allname and h5dimpath_name */
+ h4toh5_ZeroMemory(h5sdsdim_allname,(MAX_VAR_DIMS*MAX_DIM_NAME)*sizeof(char));
+ h4toh5_ZeroMemory(h5dimpath_name,MAX_DIM_NAME*sizeof(char));
+
+ /*check whether the sds is created with unlimited dimension. */
+
+ if(SDgetchunkinfo(sds_id,&c_def_out, &c_flags)== FAIL) {
+ printf("error in getting chunking information. \n");
+ return FAIL;
+ }
+
+ /* initialize the dimensional number of sds dimensions, h5dim_dims
+ is used for grabbing hdf5 dimensional name list and object reference
+ list. */
+ h5dim_dims[0] = (hsize_t)sds_rank;
+ count_h5objref = 0;
+ count_h5attrname = 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;
+ }
+
+ /* for unlimited sds dimension, grab the current dimensional size. */
+ if(sds_dimscasize[0] == 0) sds_dimscasize[0] = firstdimsize;
+
+ /* 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;
+ }
+
+ /* generating hdf5 dimensional scale name. */
+ 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[count_h5attrname*MAX_DIM_NAME],h5sdsdim_name);
+
+ /* here we should add some comments for fakedim0--name. It seems that
+ hdf4(netcdf) will use unique fake dimension name, fakedim + unique
+ number, so check_sdsdim will never be 1 if the dimension name is fake
+ name. Under this case, count_h5objref and count_h5attrname
+ will not increase if this dimension doesnot
+ have dimensional scale data. That assures the object reference of sds is
+ correct. */
+
+ /*if this dimension is not touched, get name of the dimensional scale data. */
+ if (check_sdsdim == 1){/* the dimension is touched, skip this one.*/
+ free(h5sdsdim_name);
+ SDendaccess(sdsdim_id);
+ count_h5objref = count_h5objref + 1;
+ count_h5attrname = count_h5attrname + 1;
+ continue;
+ }
+
+ if (check_sdsdim != 0) {
+ printf("error in checking sds dimensions.\n");
+ SDendaccess(sdsdim_id);
+ free(h5sdsdim_name);
+ return FAIL;
+ }
+
+ /* if this sds dimension has no dimensional scale data. skip it.*/
+ if(sdsdim_type == 0)
+ continue;
+
+
+ /* get h5 dimensional scale data type. */
+ 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;
+ }
+ }
+
+ /* get the dimensional scale data. */
+ 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;
+ }
+
+ /* set dimensional scale size properly. */
+ h5dimscas[0] = sds_dimscasize[0];
+
+ /* only set for the first dimension if SDS is unlimited dimension. */
+ if(SDisrecord(sds_id) && i == 0)
+ max_h5dimscas[0] = H5S_UNLIMITED;
+ else
+ max_h5dimscas[0] = h5dimscas[0];
+
+ h5dim_sid = H5Screate_simple(1,h5dimscas,max_h5dimscas);
+
+ if(h5dim_sid <0) {
+ printf("error in creating space. \n");
+ SDendaccess(sdsdim_id);
+ free(h5sdsdim_name);
+ free(dim_scadata);
+ return FAIL;
+ }
+
+ /* create property list, for chunked sds or unlimited dimension cases */
+
+ create_plist = H5Pcreate(H5P_DATASET_CREATE);
+
+ if(create_plist == -1) {
+ printf("failed to create property list. \n");
+ SDendaccess(sdsdim_id);
+ free(h5sdsdim_name);
+ free(dim_scadata);
+ H5Sclose(h5dim_sid);
+ }
+
+
+ if(c_flags == HDF_NONE && SDisrecord(sds_id) && i == 0)
+ {
+ h5dim_chunkdim[0] = (hsize_t)(h5dimscas[0]/2);
+
+ if(H5Pset_chunk(create_plist,1, h5dim_chunkdim)<0) {
+ printf("failed to set up chunking information for ");
+ printf("dimensional scale property list.\n");
+ SDendaccess(sdsdim_id);
+ free(h5sdsdim_name);
+ free(dim_scadata);
+ H5Sclose(h5dim_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ }
+
+ if(c_flags == HDF_CHUNK || c_flags == (HDF_CHUNK | HDF_COMP)
+ || c_flags == (HDF_CHUNK | HDF_NBIT) ){
+
+ h5dim_chunkdim[0] = (hsize_t)c_def_out.chunk_lengths[0];
+
+ if(H5Pset_chunk(create_plist,1, h5dim_chunkdim)<0) {
+ printf("failed to set up chunking information for ");
+ printf("property list.\n");
+ SDendaccess(sdsdim_id);
+ free(h5sdsdim_name);
+ free(dim_scadata);
+ H5Sclose(h5dim_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+ }
+
+ /* create h5 dataset under group HDF4_DIMG*/
+ h5dim_dset = H5Dcreate(sh5_dimgroup,h5sdsdim_name,h5dim_tid,
+ h5dim_sid,create_plist);
+
+ if(h5dim_dset <0) {
+ printf("error in creating dataset. \n");
+ free(h5sdsdim_name);
+ free(dim_scadata);
+ SDendaccess(sdsdim_id);
+ H5Sclose(h5dim_sid);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ 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);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+ SDendaccess(sdsdim_id);
+ free(dim_scadata);
+ free(h5sdsdim_name);
+ ret = H5Sclose(h5dim_sid);
+ ret = H5Dclose(h5dim_dset);
+ ret = H5Pclose(create_plist);
+ count_h5objref = count_h5objref + 1;
+ count_h5attrname =count_h5attrname + 1;
+ }
+
+ /*1. create object reference number to dimensional scale dataset.
+ 2. store absolute name of dimensional name into
+ dimensional list. */
+
+ if ( count_h5objref != 0) {
+
+ h5dim_dims[0] = count_h5objref;
+ attr_refDims[0] = count_h5objref;
+ attr_refSpace = H5Screate_simple(1,attr_refDims,NULL);
+ attr_refType = H5Tcopy(H5T_STD_REF_OBJ);
+ alldim_refdat = calloc((size_t)count_h5objref,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<count_h5objref;i++){
+ h4toh5_ZeroMemory(h5newsdsdim_name,MAX_DIM_NAME);
+ strcpy(h5newsdsdim_name,&h5sdsdim_allname[i*MAX_DIM_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(count_h5attrname!= 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_DIM_NAME,H5T_STR_SPACEPAD);
+ 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/h4toh5/h4toh5test.c b/tools/h4toh5/h4toh5test.c
new file mode 100644
index 0000000..1f21b63
--- /dev/null
+++ b/tools/h4toh5/h4toh5test.c
@@ -0,0 +1,3944 @@
+/*** this code is to generate various hdf files to test h4toh5 converter and h4toh5 lib API. The code itself is NOT optimizied but try to consider various cases that examine how converter works. */
+
+#include "hdf.h"
+#include "mfhdf.h"
+#include <stdio.h>
+
+
+#define FILESDS1 "sds_typ_test.hdf"
+#define FILESDS2 "sds_dim_test.hdf"
+#define FILESDS3 "sds_attr_test.hdf"
+#define FILEGR "gr_typ_test.hdf"
+#define FILERAS8 "ras_8_test.hdf"
+#define FILERAS24 "ras_24_test.hdf"
+#define FILEGRPAL "image_attr_test.hdf"
+#define FILEVD "vdata_test.hdf"
+#define FILECLASHVG "vgnameclash_test.hdf"
+#define FILECLASHSDS "sdsnameclash_test.hdf"
+#define FILECLASHVD "vdnameclash_test.hdf"
+#define FILECLASHGR "grnameclash_test.hdf"
+#define FILELOOP "vg_loop_test.hdf"
+#define FILEHL "vg_hl_test.hdf"
+#define FILEVG "vg_all_test.hdf"
+#define FILEANNO "anno_test.hdf"
+
+/* for testing sds*/
+#define TYP_RANK 3
+#define TYP_DIMSIZE 4
+#define INT8_UPLIMIT 0x7E
+#define UINT8_UPLIMIT 0xFC
+#define INT16_UPLIMIT 0x7FFE
+#define UINT16_UPLIMIT 0xFFFC
+#define INT32_UPLIMIT 0x7FFFFFFE
+#define UINT32_UPLIMIT 0xFFFFFFFC
+#define ATT_SIZE 10
+
+/* for testing image*/
+#define X_LENGTH 10
+#define Y_LENGTH 5
+#define NUM_COLORS 256
+#define F_ATT1_NAME "File Attribute"
+#define RI_ATT1_NAME "Image Attribute"
+#define F_ATT1_VAL "Contents of First FILE Attribute"
+#define F_ATT1_N_VALUES 32
+#define RI_ATT1_VAL "Contents of IMAGE's First Attribute"
+#define RI_ATT1_N_VALUES 35
+
+/* for testing vdata*/
+#define NRECORDS 10
+#define FIELD_1 "Temp"
+#define FIELD_2 "Height"
+#define FIELD_3 "Speed"
+#define FIELD_4 "Ident"
+#define FIELD_5 "Position"
+#define FIELD_NAMES "Temp,Height,Speed,Ident,Position"
+#define FIELD_VDNAMES "Temp,Height"
+
+/*for testing vgroup*/
+#define VGATTR_NAME "Vgroup attribute 1"
+int test_sdstyp(void);
+int test_sdsdim(void);
+int test_sdsattr(void);
+int test_grtyp(void);
+int test_ras8(void);
+int test_ras24(void);
+int test_imageattr(void);
+int test_vdata(void);
+int test_vgnameclash(void);
+int test_sdsnameclash(void);
+int test_grnameclash(void);
+int test_vdnameclash(void);
+int test_vgloop(void);
+int test_vghl(void);
+int test_vgall(void);
+int test_anno(void);
+
+int main(void) {
+ if(test_sdstyp()== FAIL) {
+ printf("failed to create sds_typ_test.hdf file.\n");
+ return FAIL;
+ }
+ if(test_sdsdim()== FAIL) {
+ printf("failed to create sds_dim_test.hdf file. \n");
+ return FAIL;
+ }
+ if(test_sdsattr()== FAIL) {
+ printf("failed to create sds_attr_test.hdf file. \n");
+ return FAIL;
+ }
+ if(test_grtyp()==FAIL) {
+ printf("failed to create gr_typ_test.hdf file. \n");
+ return FAIL;
+ }
+
+ if(test_ras8()==FAIL) {
+ printf("failed to create ras8_test.hdf file.\n");
+ return FAIL;
+ }
+
+ if(test_ras24()==FAIL) {
+ printf("failed to create ras24_test.hdf file.\n");
+ return FAIL;
+ }
+ if(test_imageattr()== FAIL) {
+ printf("failed to create image_attr_test.hdf file.\n");
+ return FAIL;
+ }
+
+ if(test_vdata()== FAIL) {
+ printf("failed to create vdata_test.hdf file.\n");
+ return FAIL;
+ }
+
+ if(test_vgnameclash()==FAIL) {
+ printf("failed to create vg_nameclash.hdf file.\n");
+ return FAIL;
+ }
+
+ if(test_sdsnameclash()==FAIL) {
+ printf("failed to create sds_nameclash.hdf file.\n");
+ return FAIL;
+ }
+
+ if(test_grnameclash()==FAIL) {
+ printf("failed to create gr_nameclash.hdf file. \n");
+ return FAIL;
+ }
+
+ if(test_vdnameclash()==FAIL) {
+ printf("failed to create vd_nameclash.hdf file.\n");
+ return FAIL;
+ }
+ if(test_vgloop()==FAIL) {
+ printf("failed to create vg_loop.hdf file. \n");
+ return FAIL;
+ }
+ if(test_vghl()==FAIL) {
+ printf("failed to create vg_hl.hdf file. \n");
+ return FAIL;
+ }
+ if(test_vgall()==FAIL) {
+ printf("failed to create vg_all.hdf file. \n");
+ return FAIL;
+ }
+ if(test_anno()==FAIL) {
+ printf("failed to create vg_anno.hdf file. \n");
+ return FAIL;
+ }
+ return 0;
+}
+
+/* this subroutine will hdf file with typical sds objects,
+
+ The rank is TYP_RANK, each dimensional size is TYP_DIMSIZE.
+ Datatype we are testing is:
+ char,
+ int8,
+ int16,
+ int32,
+ uint16,
+ uint32,
+ lint16,
+ lint32,
+ luint32,
+ float32,
+ float64,
+
+*/
+int test_sdstyp(){
+
+ int32 file_id,sds_id;
+ int32 i,j,k;
+ int32 typ_start[TYP_RANK],typ_edges[TYP_RANK],typ_stride[TYP_RANK];
+ char8 typchar_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int8 typint8_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int16 typint16_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 typint32_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ uint16 typuint16_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 typlint32_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ uint32 typluint32_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ float32 typfloat32_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ float64 typfloat64_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ float64 typlfloat64_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 typ_dims[TYP_RANK];
+ int32 CUB_SIZE;
+ int istat;
+ /* TYPICAL sds array, we limit the dimensional size for testing purpose. */
+
+ CUB_SIZE = (TYP_DIMSIZE-1)*(TYP_DIMSIZE-1)*(TYP_DIMSIZE-1);
+
+ /* 1. data type is char */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++){
+ typchar_array[i][j][k]=(char) (i+j+k);
+ }
+
+ /* data type is int8 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typint8_array[i][j][k]= (int8)(INT8_UPLIMIT-i*j*k*2/CUB_SIZE*INT8_UPLIMIT +1);
+
+ /* data type is int16 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typint16_array[i][j][k]= (int16)(INT16_UPLIMIT-i*j*k*2/CUB_SIZE*INT16_UPLIMIT +1);
+
+ /* data type is uint16 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typuint16_array[i][j][k]= (uint16)(UINT16_UPLIMIT-i*j*k*2/CUB_SIZE*(UINT16_UPLIMIT/2)+1);
+
+ /* data type is int32 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typint32_array[i][j][k]= INT32_UPLIMIT-i*j*k*2/CUB_SIZE*INT32_UPLIMIT +1;
+
+ /*data type is little-endian int32*/
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typlint32_array[i][j][k]= INT32_UPLIMIT-i*j*k*2/CUB_SIZE*INT32_UPLIMIT +1;
+
+ /* data type is unsigned little-endian int32*/
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typluint32_array[i][j][k]= (uint32)(UINT32_UPLIMIT-i*j*k/CUB_SIZE*UINT32_UPLIMIT+1);
+
+ /* data type is float32 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typfloat32_array[i][j][k]= 1.0+i+j+k;
+
+ /* data type is float64 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typfloat64_array[i][j][k]= 1.0+i+j+k;
+
+ /* data type is lfloat64 */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typlfloat64_array[i][j][k]= 1.0+i+j+k;
+
+ for(i=0;i<TYP_RANK;i++){
+ typ_dims[i] = TYP_DIMSIZE;
+ typ_start[i] = 0;
+ typ_edges[i] = TYP_DIMSIZE;
+ typ_stride[i] = 1;
+ }
+
+ file_id = SDstart(FILESDS1,DFACC_CREATE);
+
+ if(file_id == FAIL) {
+ printf (" open file failed\n");
+ return FAIL;
+ }
+
+ /* we also test different dimensional scale setting for typical array. */
+ sds_id = SDcreate(file_id,"sds_char",DFNT_CHAR8,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typchar_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_int8",DFNT_INT8,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typint8_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_int16",DFNT_INT16,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typint16_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_int32",DFNT_INT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typint32_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_uint16",DFNT_UINT16,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typuint16_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_lint32",DFNT_LINT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typlint32_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_luint32",DFNT_LUINT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typluint32_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_float32",DFNT_FLOAT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typfloat32_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_float64",DFNT_FLOAT64,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typfloat64_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(file_id,"sds_lfloat64",DFNT_LFLOAT64,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typlfloat64_array);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+ SDend(file_id);
+ return 0;
+}
+/* generating a hdf file with sds dimensional scale dataset in it.
+ both limited and unlimited dimensions are provided.*/
+int test_sdsdim() {
+
+ int32 file_id,sds_id,dim_id;
+ int32 i,j,k;
+ int32 typ_start[TYP_RANK],typ_edges[TYP_RANK],typ_stride[TYP_RANK];
+ int32 typ_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 typ_dims[TYP_RANK];
+ int32 dim_sca0[TYP_DIMSIZE];
+ int32 istat;
+
+ char dim_name0[] = "dim0";
+ char dim_name1[] = "dim1";
+ char dim_name2[] = "dim2";
+
+ char unldim_name0[] ="unldim0";
+ char unldim_name1[]="unldim1";
+ char unldim_name2[]="unldim2";
+
+ /* typical sds array. */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typ_array[i][j][k] = i+j+k;
+
+ for (i=0;i<TYP_DIMSIZE;i++)
+ dim_sca0[i] = i;
+
+
+ for(i=0;i<TYP_RANK;i++){
+ typ_dims[i] = TYP_DIMSIZE;
+ typ_start[i] = 0;
+ typ_edges[i] = TYP_DIMSIZE;
+ typ_stride[i] = 1;
+ }
+
+ file_id = SDstart(FILESDS2,DFACC_CREATE);
+
+ if(file_id == FAIL){
+ printf (" open file failed\n");
+ return FAIL;
+ }
+
+ /* testing for normal dimensional scale dataset. */
+ sds_id = SDcreate(file_id,"sds_dimnor",DFNT_INT32,TYP_RANK,typ_dims);
+
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+
+
+ istat=SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typ_array);
+
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+
+ for (i =0;i<TYP_RANK;i++){
+ dim_id = SDgetdimid(sds_id,i);
+
+ if(dim_id == FAIL) {
+ printf("failed to generate dimensional id.\n");
+ return FAIL;
+ }
+
+ switch(i) {
+
+ case 0:
+ istat = SDsetdimname(dim_id,dim_name0);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat =SDsetdimscale(dim_id,typ_dims[0],DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ break;
+ case 1:
+ istat = SDsetdimname(dim_id,dim_name1);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat = SDsetdimscale(dim_id,typ_dims[1],DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ break;
+ case 2:
+ istat = SDsetdimname(dim_id,dim_name2);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat = SDsetdimscale(dim_id,typ_dims[2],DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ break;
+ }
+
+ }
+ SDendaccess(sds_id);
+
+ /* for unlimited dimensional scale data. */
+
+ typ_dims[0] = SD_UNLIMITED;
+
+ sds_id = SDcreate(file_id,"sds_dimunl",DFNT_INT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+
+ istat =SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typ_array);
+ if(istat == FAIL) {
+ printf("failed to write sds object. \n");
+ return FAIL;
+ }
+ for (i =0;i<TYP_RANK;i++){
+ dim_id = SDgetdimid(sds_id,i);
+ if(dim_id == FAIL) {
+ printf("failed to generate dimensional id.\n");
+ return FAIL;
+ }
+ switch(i) {
+
+ case 0:
+ istat= SDsetdimname(dim_id,unldim_name0);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ /* SDsetdimscale(dim_id,typ_dims[0],DFNT_INT32,(VOIDP)dim_sca0);*/
+ istat= SDsetdimscale(dim_id,TYP_DIMSIZE,DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ break;
+ case 1:
+ istat= SDsetdimname(dim_id,unldim_name1);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat = SDsetdimscale(dim_id,typ_dims[1],DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ break;
+ case 2:
+ istat = SDsetdimname(dim_id,unldim_name2);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat = SDsetdimscale(dim_id,typ_dims[2],DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ break;
+ }
+ }
+ SDendaccess(sds_id);
+
+ SDend(file_id);
+ return 0;
+}
+
+/* a hdf file that includes sds predefined attributes, dimensional
+ scale attributes and chunking and compress information*/
+int test_sdsattr() {
+
+ int32 file_id,sds_id,dim_id;
+ int32 i,j,k,comp_flag;
+ int32 typ_start[TYP_RANK],typ_edges[TYP_RANK],typ_stride[TYP_RANK];
+ int32 typ_array[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 typ_dims[TYP_RANK];
+ int32 fill_value;
+ int32 dim_sca0[TYP_DIMSIZE],dim_sca1[TYP_DIMSIZE];
+
+ HDF_CHUNK_DEF c_def;
+ int32 comp_type;
+ comp_info c_info;
+ int32 istat;
+ float64 cal;
+ float64 cal_err;
+ float64 offset;
+ float64 offset_err;
+
+ char* attr_value;
+ char* gloattr_value;
+ char label[] = "sds.label";
+ char unit[] = "sds.unit";
+ char format[] = "sds.format";
+ char coordsys[] = "sds.coord";
+
+ char dim_name0[] ="dim0";
+ char dim_name1[] ="dim1";
+ char dim_label[] ="dim.label";
+ char dim_unit[] ="dim.unit";
+ char dim_format[] ="dim.format";
+
+ /**** initial setting. ****/
+ cal = 1.0;
+ cal_err = 0.0;
+ offset = 0.0;
+ offset_err = 0.0;
+ fill_value = 999;
+
+
+ /* typical sds array. */
+ for (i=0;i<TYP_DIMSIZE;i++)
+ for (j=0;j<TYP_DIMSIZE;j++)
+ for (k=0;k<TYP_DIMSIZE;k++)
+ typ_array[i][j][k]= i+j+k;
+
+ attr_value = malloc(ATT_SIZE*sizeof(char));
+ if(attr_value == NULL) {
+ printf("failed to allocate memory. \n");
+ return FAIL;
+ }
+
+ gloattr_value = malloc(ATT_SIZE*sizeof(char));
+ if(gloattr_value == NULL) {
+ printf("failed to allocate memory. \n");
+ return FAIL;
+ }
+
+ strcpy(gloattr_value,"glo attr");
+ strcpy(attr_value,"test attr");
+
+ for(i=0;i<TYP_RANK;i++){
+ typ_dims[i] = TYP_DIMSIZE;
+ typ_start[i] = 0;
+ typ_edges[i] = TYP_DIMSIZE;
+ typ_stride[i] = 1;
+ }
+
+ for (i=0;i<TYP_DIMSIZE;i++){
+ dim_sca0[i] = i;
+ dim_sca1[i] = 2*i;
+ }
+ file_id = SDstart(FILESDS3,DFACC_CREATE);
+
+ if(file_id == FAIL) {
+ printf (" open file failed\n");
+ return FAIL;
+ }
+
+ istat = SDsetattr(file_id,"sds.gloattr",DFNT_CHAR8,10,(VOIDP)gloattr_value);
+ if(istat == FAIL) {
+ printf("failed to set attribute.\n");
+ return FAIL;
+ }
+
+ istat = SDsetfillmode(file_id,SD_NOFILL);
+
+ if (istat == FAIL) {
+ printf("error setting fill mode\n");
+ return FAIL;
+ }
+
+ sds_id = SDcreate(file_id,"sds_attr",DFNT_INT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+
+ istat = SDsetfillvalue(sds_id,(VOIDP)(&fill_value));
+ if (istat == FAIL){
+ printf("error setting fill value\n");
+ return FAIL;
+ }
+
+ istat = SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typ_array);
+
+ if(istat == FAIL) {
+ printf("failed to write sds data.\n");
+ return FAIL;
+ }
+ /*** write dataset attribute ***/
+
+ istat = SDsetattr(sds_id,"sds.attr",DFNT_CHAR8,10,(VOIDP)attr_value);
+ if(istat == FAIL) {
+ printf(" sds data attr. setting failed. \n");
+ return FAIL;
+ }
+ /*** write dataset predefined attribute ***/
+
+ istat = SDsetdatastrs(sds_id,label,unit,format,coordsys);
+ if(istat == FAIL) {
+ printf(" sds data predefined attr. setting failed. \n");
+ return FAIL;
+ }
+ /*** set calibration information. ***/
+
+ istat = SDsetcal(sds_id,cal,cal_err,offset,offset_err,DFNT_INT32);
+ if(istat == FAIL) {
+ printf(" sds data calibrating attr. setting failed. \n");
+ return FAIL;
+ }
+ for (i =0; i<TYP_RANK;i++) {
+ dim_id = SDgetdimid(sds_id,i);
+ if(dim_id == FAIL) {
+ printf("sds set dim id failed. \n");
+ return FAIL;
+ }
+ if (i==0) {
+ istat = SDsetdimname(dim_id,dim_name0);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat=SDsetdimscale(dim_id,typ_dims[0],DFNT_INT32,(VOIDP)dim_sca0);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ }
+ else {
+ istat = SDsetdimname(dim_id,dim_name1);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat = SDsetdimscale(dim_id,typ_dims[1],DFNT_INT32,(VOIDP)dim_sca1);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ }
+
+ istat = SDsetdimstrs(dim_id,dim_label,dim_unit,dim_format);
+ if(istat == FAIL) {
+ printf("sds set dim. predefined attr. failed. \n");
+ return FAIL;
+ }
+ istat = SDsetattr(dim_id,"sdsdim.attr",DFNT_CHAR8,10,(VOIDP)attr_value);
+
+ if(istat == FAIL) {
+ printf(" sds dim data attr. setting failed. \n");
+ return FAIL;
+ }
+ SDendaccess(dim_id);
+ }
+
+ SDendaccess(sds_id);
+
+
+ sds_id = SDcreate(file_id,"sds_compress",DFNT_INT32,TYP_RANK,typ_dims);
+ if(sds_id == FAIL) {
+ printf("failed to create object.\n");
+ return FAIL;
+ }
+ comp_type = COMP_CODE_DEFLATE;
+ c_info.deflate.level = 3;
+
+ c_def.comp.chunk_lengths[0] = 2;
+ c_def.comp.chunk_lengths[1] = 2;
+ c_def.comp.chunk_lengths[2] = 2;
+ c_def.comp.comp_type = COMP_CODE_DEFLATE;
+
+ comp_flag = HDF_CHUNK;
+
+ c_def.comp.cinfo.deflate.level = 3;
+
+ istat = SDsetchunk(sds_id,c_def,comp_flag);
+ if(istat == FAIL) {
+ printf("chunking is not setting properly. \n");
+ return FAIL;
+ }
+
+
+ istat = SDwritedata(sds_id,typ_start,typ_stride,typ_edges,(VOIDP)typ_array);
+ if(istat == FAIL) {
+ printf("SDS cannot write chunking and compression mode. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ SDend(file_id);
+ free(attr_value);
+ free(gloattr_value);
+ return 0;
+}
+
+/***** routines for generating gr datatype hdf testing file.
+ we are only generating one and three components for
+ datatype
+ uint32 and int16. ****/
+int test_grtyp() {
+
+ int32 gr_id, ri_id, file_id, il;
+ int32 ncomp;
+ int32 start[2], edges[2],dims[2];
+ uint32 image_data32[Y_LENGTH][X_LENGTH][3];
+ uint32 image_data321[Y_LENGTH][X_LENGTH];
+ int16 image_data16[Y_LENGTH][X_LENGTH][3];
+ int16 image_data161[Y_LENGTH][X_LENGTH];
+ intn i, j;
+ int32 CUB_SIZE;
+ int istat;
+
+ CUB_SIZE = (X_LENGTH-1)*(Y_LENGTH-1);
+
+ /* 3-component GR image data type UINT32*/
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data32[j][i][0] = UINT32_UPLIMIT - i*j*0/CUB_SIZE*(UINT32_UPLIMIT/2)+1;
+ image_data32[j][i][1] = UINT32_UPLIMIT - i*j*1/CUB_SIZE*(UINT32_UPLIMIT/2)+1;
+ image_data32[j][i][2] = UINT32_UPLIMIT - i*j*2/CUB_SIZE*(UINT32_UPLIMIT/2)+1;
+
+ }
+ }
+
+ /* 3-component GR image data type int16*/
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data16[j][i][0] = INT16_UPLIMIT - i*j*0/CUB_SIZE*(INT16_UPLIMIT/2)+1;
+ image_data16[j][i][1] = INT16_UPLIMIT - i*j*1/CUB_SIZE*(INT16_UPLIMIT/2)+1;
+ image_data16[j][i][2] = INT16_UPLIMIT - i*j*2/CUB_SIZE*(INT16_UPLIMIT/2)+1;
+
+ }
+ }
+
+ /* 1-component GR image data type uint32 */
+ for (j = 0; j < Y_LENGTH; j++)
+ for (i = 0; i < X_LENGTH; i++)
+ image_data321[j][i] = UINT32_UPLIMIT - i*j/CUB_SIZE*UINT32_UPLIMIT+1;
+
+ /* 1-component GR image data type int16*/
+ for (j = 0; j < Y_LENGTH; j++)
+ for (i = 0; i < X_LENGTH; i++)
+ image_data161[j][i] = INT16_UPLIMIT - i*j/CUB_SIZE*INT16_UPLIMIT+1;
+
+
+ /* Open the file. */
+ file_id = Hopen(FILEGR, DFACC_CREATE, 0);
+
+ if(file_id == FAIL) {
+ printf("fail to create GR file.\n");
+ return FAIL;
+ }
+ /* Initiate the GR interface. */
+ gr_id = GRstart(file_id);
+
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_uint32", ncomp, DFNT_UINT32, il, dims);
+
+ if(ri_id == FAIL) {
+ printf("fail to create RI interface.\n");
+ return FAIL;
+ }
+
+ /* Define the location, pattern, and size of the data set */
+ for (i = 0; i < 2; i++) {
+ start[i] = 0;
+ edges[i] = dims[i];
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data32);
+
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+
+ /* For number of components =3, data type is int16*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_int16", ncomp, DFNT_INT16, il, dims);
+
+ if(ri_id == FAIL) {
+ printf("fail to create RI interface.\n");
+ return FAIL;
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data16);
+
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+
+ /* For number of components =1, data type is uint32*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 1;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_uint321", ncomp, DFNT_UINT32, il, dims);
+ if(ri_id == FAIL) {
+ printf("fail to create RI interface.\n");
+ return FAIL;
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data321);
+
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+
+
+ /* For number of components = 1, data type is int16*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 1;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_int161", ncomp, DFNT_INT16, il, dims);
+
+ if(ri_id == FAIL) {
+ printf("fail to create RI interface.\n");
+ return FAIL;
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data161);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+ /* Terminate access to the GR interface. */
+ GRend(gr_id);
+
+ /* Close the file. */
+ Hclose(file_id);
+ return 0;
+}
+
+
+/***** routine to generate raster 8 bit data type hdf file. ****/
+int test_ras8() {
+
+ int32 gr_id, ri_id, file_id, il,istat;
+ int32 ncomp;
+ int32 start[2], edges[2],dims[2];
+ int8 image_data8[Y_LENGTH][X_LENGTH];
+ uint8 image_datau8[Y_LENGTH][X_LENGTH];
+ intn i, j;
+ int32 CUB_SIZE;
+
+ CUB_SIZE = (X_LENGTH-1)*(Y_LENGTH-1);
+
+ /* 1-component Raster-8 image data type uint8 */
+ for (j = 0; j < Y_LENGTH; j++)
+ for (i = 0; i < X_LENGTH; i++)
+ image_datau8[j][i] = UINT8_UPLIMIT - i*j/CUB_SIZE*UINT8_UPLIMIT+1;
+
+ /* 1-component Raster-8 image data type int8*/
+ for (j = 0; j < Y_LENGTH; j++)
+ for (i = 0; i < X_LENGTH; i++)
+ image_data8[j][i] = INT8_UPLIMIT - i*j/CUB_SIZE*INT8_UPLIMIT+1;
+
+ /* Open the file. */
+ file_id = Hopen(FILERAS8, DFACC_CREATE, 0);
+
+ if(file_id == FAIL) {
+ printf("fail to open raster 8 file.\n");
+ return FAIL;
+ }
+ /* Initiate the GR interface. */
+ gr_id = GRstart(file_id);
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+
+ /* For number of components = 1, data type is uint8*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 1;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_uint8", ncomp, DFNT_UINT8, il, dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR object.\n");
+ return FAIL;
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_datau8);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ istat = GRendaccess(ri_id);
+ if(istat == FAIL) {
+ printf("fail in ending RI interface.\n");
+ return FAIL;
+ }
+
+ /* For number of components = 1, data type is int8*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 1;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_int8", ncomp, DFNT_INT8, il, dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR object.\n");
+ return FAIL;
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data8);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+ /* Terminate access to the GR interface. */
+ GRend(gr_id);
+
+ /* Close the file. */
+ Hclose(file_id);
+ return 0;
+}
+
+/***** routine to generate raster 24 bit data type hdf file. ****/
+int test_ras24() {
+
+ int32 gr_id, ri_id, file_id, il;
+ int32 ncomp,istat;
+ int32 start[2], edges[2],dims[2];
+ int8 image_data24[Y_LENGTH][X_LENGTH][3];
+ uint8 image_datau24[Y_LENGTH][X_LENGTH][3];
+ intn i, j;
+ int32 CUB_SIZE;
+
+
+ CUB_SIZE = (X_LENGTH-1)*(Y_LENGTH-1);
+
+ /* 3-component Raster-8 image data type uint8 */
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_datau24[j][i][0] = UINT8_UPLIMIT - i*j*0/CUB_SIZE*UINT8_UPLIMIT+1;
+ image_datau24[j][i][1] = UINT8_UPLIMIT - i*j*1/CUB_SIZE*(UINT8_UPLIMIT/2)+1;
+ image_datau24[j][i][2] = UINT8_UPLIMIT - i*j*2/CUB_SIZE*(UINT8_UPLIMIT/2)+1;
+ }
+ }
+ /* 3-component Raster-8 image data type int8*/
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data24[j][i][0] = INT8_UPLIMIT - i*j*0/CUB_SIZE*INT8_UPLIMIT+1;
+ image_data24[j][i][1] = INT8_UPLIMIT - i*j*1/CUB_SIZE*(INT8_UPLIMIT/2)+1;
+ image_data24[j][i][2] = INT8_UPLIMIT - i*j*2/CUB_SIZE*(INT8_UPLIMIT/2)+1;
+
+ }
+ }
+
+ /* Open the file. */
+ file_id = Hopen(FILERAS24, DFACC_CREATE, 0);
+
+ if(file_id == FAIL) {
+ printf("fail to open the file. \n");
+ return FAIL;
+ }
+
+ /* Initiate the GR interface. */
+ gr_id = GRstart(file_id);
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+
+
+ /* For number of components = 3, data type is uint8*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_uint24", ncomp, DFNT_UINT8, il, dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR object.\n");
+ return FAIL;
+ }
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_datau24);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+
+
+ /* For number of components = 3, data type is int8*/
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_int24", ncomp, DFNT_INT8, il, dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR object.\n");
+ return FAIL;
+ }
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data24);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+ /* Terminate access to the GR interface. */
+ GRend(gr_id);
+
+ /* Close the file. */
+ Hclose(file_id);
+ return 0;
+}
+
+/* routine to generate image attribute file.*/
+int test_imageattr() {
+
+ int32 gr_id, ri_id, file_id, il,pal_id,istat;
+ int32 ncomp,data_type;
+ int32 start[2], edges[2],dims[2];
+ uint16 image_data[Y_LENGTH][X_LENGTH][3];
+
+ uint8 palette_data[NUM_COLORS * 3];
+ int32 num_comp,num_entries;
+ intn i, j;
+ char* ri_attrname;
+ char*file_attrname;
+
+ /* Open the file. */
+ file_id = Hopen(FILEGRPAL, DFACC_CREATE, 0);
+
+ /* Initiate the GR interface. */
+ gr_id = GRstart(file_id);
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ dims[0] = X_LENGTH;
+ dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_1", ncomp, DFNT_UINT16, il, dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR object.\n");
+ return FAIL;
+ }
+ /* Fill the stored-data array with values. */
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data[j][i][0] = i+j+1;
+ image_data[j][i][1] = (i+j)*2;
+ image_data[j][i][2] = (i+j)*3;
+ }
+ }
+
+ /* Define the location, pattern, and size of the data set */
+ for (i = 0; i < 2; i++) {
+ start[i] = 0;
+ edges[i] = dims[i];
+ }
+
+ /* set GR global attribute. */
+
+ file_attrname=malloc(strlen(F_ATT1_NAME));
+ strcpy(file_attrname,F_ATT1_NAME);
+ istat = GRsetattr(gr_id,file_attrname,DFNT_CHAR8,F_ATT1_N_VALUES,(VOIDP)F_ATT1_VAL);
+ if(istat == FAIL) {
+ printf("fail to set GR global attribute.\n");
+ return FAIL;
+ }
+ /* set GR attribute. */
+ ri_attrname=malloc(strlen(RI_ATT1_NAME));
+ strcpy(ri_attrname,RI_ATT1_NAME);
+ istat = GRsetattr(ri_id,ri_attrname,DFNT_CHAR8,RI_ATT1_N_VALUES,(VOIDP)RI_ATT1_VAL);
+ if(istat == FAIL) {
+ printf("fail to set GR attribute.\n");
+ return FAIL;
+ }
+ free(file_attrname);
+ free(ri_attrname);
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ /* Initialize the palette to grayscale. */
+ for (i = 0; i < NUM_COLORS; i++) {
+ palette_data[i * 3] = i;
+ palette_data[i * 3 + 1] = i;
+ palette_data[i * 3 + 2] = i;
+ }
+
+ /* Set palette characteristics. */
+ data_type = DFNT_UINT8;
+ num_entries = NUM_COLORS;
+ num_comp = 3;
+
+ /* Get the id for the palette. */
+ pal_id = GRgetlutid(ri_id,0 );
+ if(pal_id == FAIL) {
+ printf("fail to obtain palette id.\n");
+ return FAIL;
+ }
+
+ /* Write the palette to file. */
+ istat = GRwritelut(pal_id, num_comp, data_type,
+ 0, num_entries,
+ (VOIDP)palette_data);
+ if(istat == FAIL) {
+ printf("fail to write lookup table.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ GRendaccess(ri_id);
+
+ /* Terminate access to the GR interface. */
+ GRend(gr_id);
+
+ /* Close the file. */
+ Hclose(file_id);
+ return 0;
+}
+
+/* routines to generate vdata hdf testing file. */
+int test_vdata( )
+{
+
+ struct {
+ float32 temp;
+ int16 height;
+ float32 speed;
+ char ident[3];
+ float32 position[2];
+ } source[NRECORDS];
+
+ int32 file_id, vdata_id, istat, values[4] ={32, 16, 32, 8};
+ uint8 *databuf, *pntr;
+ int i,j, bufsize, recsize;
+ VOIDP fldbufpt[5];
+
+ /* Open the HDF file. */
+ file_id = Hopen(FILEVD, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open HDF file.\n");
+ return FAIL;
+ }
+
+ /* Initialize the Vset interface. */
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start V interface.\n");
+ return FAIL;
+ }
+
+ /* Create a new Vdata. */
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach Vdata.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define field1 \n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define field2 \n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_3, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define field3 \n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_4, DFNT_CHAR8, 3);
+ if(istat == FAIL) {
+ printf("fail to define field4 \n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_5, DFNT_FLOAT32,2);
+ if(istat == FAIL) {
+ printf("fail to define field5 \n");
+ return FAIL;
+ }
+
+ /* Set the Vdata name. */
+ istat=VSsetname(vdata_id, "Test Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name\n");
+ return FAIL;
+ }
+
+ /* Set the Vdata class. */
+ istat=VSsetclass(vdata_id, "Test Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class\n");
+ return FAIL;
+ }
+
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_NAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields of vdata.\n");
+ return FAIL;
+ }
+
+ recsize = (2 * sizeof(float32) + sizeof(int16))+ 2* sizeof(float32)
+ +3*sizeof(char);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc memory for vdata failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+ source[i].speed = 1.11 * (i+1);
+ source[i].ident[0] = 'A' + i;
+ source[i].ident[1] = 'a' + i;
+ source[i].ident[2] ='0'+i;
+ for (j=0; j< 2; j++)
+ source[i].position[j] = 1.0+j;
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ fldbufpt[2] = &source[i].speed;
+ fldbufpt[3] = &source[i].ident[0];
+ fldbufpt[4] = &source[i].position[0];
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+ /* Set Vdata attribute */
+ istat = VSsetattr (vdata_id, _HDF_VDATA, "vdata attr", DFNT_INT32, 4, (VOIDP)values);
+ if(istat == FAIL) {
+ printf("fail to set vdata attribute.\n");
+ return FAIL;
+ }
+ /* Set attribute for "speed" field */
+ istat = VSsetattr (vdata_id, 2, "field attr", DFNT_CHAR, 3, "MAX");
+ if(istat == FAIL) {
+ printf("fail to set vdata field attribute.\n");
+ return FAIL;
+ }
+ /*
+ * Terminate access to the Vdata, the Vset interface
+ * and the HDF file.
+ */
+ VSdetach(vdata_id);
+ Vend(file_id);
+ Hclose(file_id);
+ free(databuf);
+ return 0;
+}
+
+/* this routine will generate hdf file that has name clashings for different
+ vgroups.
+
+ two situations:
+ 1. two groups share the same name.
+ 2. one group doesn't have name.
+
+ */
+int test_vgnameclash() {
+
+ int32 file_id, vgroupa_ref, vgroupa_id,vgroupb_ref,vgroupb_id;
+ int32 vgroupc_id,vgroupc_ref;
+ int32 dim_sizes[TYP_RANK];
+ intn i, j;
+ int32 sd_id,sds_id;
+ int32 sds_ref;
+ int32 array_data[X_LENGTH][Y_LENGTH];
+ int32 start[TYP_RANK],edges[TYP_RANK],stride[TYP_RANK];
+ int istat;
+
+ for (i=0;i<X_LENGTH;i++){
+ for(j=0;j<Y_LENGTH;j++) {
+ array_data[i][j] =i+j;
+ }
+ }
+
+ dim_sizes[0] = X_LENGTH;
+ dim_sizes[1] = Y_LENGTH;
+
+ for (i=0;i<TYP_RANK;i++){
+ stride[i]=1;
+ start[i]=0;
+ edges[i]=dim_sizes[i];
+
+ }
+
+ /* Open the HDF file. */
+
+ /* We are testing name clashings for vgroups.*/
+
+ /* two situations:
+ 1. two groups share the same name.
+ 2. one group doesn't have name. */
+
+ file_id = Hopen(FILECLASHVG, DFACC_CREATE, 0);
+ if (file_id == FAIL) {
+ printf("fail to open vg_clash.hdf.\n");
+ return FAIL;
+ }
+
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start vgroup interface.\n");
+ return FAIL;
+ }
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+ vgroupc_ref = -1;
+ vgroupa_id = Vattach(file_id, vgroupa_ref, "w");
+ if(vgroupa_id == FAIL) {
+ printf("fail to attach groupa.\n");
+ return FAIL;
+ }
+ vgroupb_id = Vattach(file_id,vgroupb_ref,"w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach groupb.\n");
+ return FAIL;
+ }
+ vgroupc_id = Vattach(file_id,vgroupc_ref,"w");
+ if(vgroupc_id == FAIL) {
+ printf("fail to attach groupc.\n");
+ return FAIL;
+ }
+ istat=Vsetname(vgroupa_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+
+ istat=Vsetname(vgroupb_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupb.\n");
+ return FAIL;
+ }
+ sd_id = SDstart(FILECLASHVG,DFACC_WRITE);
+ if(sd_id == FAIL) {
+ printf("fail to start SD interface.\n");
+ return FAIL;
+ }
+
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("failed to transfer sds id to reference number.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupa_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add tag for reference.\n");
+ return FAIL;
+ }
+
+ SDendaccess(sds_id);
+ SDend(sd_id);
+ Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupb_id);
+ istat = Vdetach(vgroupc_id);
+ istat = Vend(file_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+
+/* This routine creates different SDS objects with name clashing.
+We are testing different SDS
+ 1. under the same group sharing the same name.
+ 2. one sds doesn't have name.
+ 3. different sds objects under different vgroups sharing the same name.
+ 4. sds objects under no specific groups share the same name.
+ 5. sds objects under no specific groups with no name. */
+
+
+int test_sdsnameclash() {
+
+
+ int32 file_id, vgroupa_ref, vgroupa_id,vgroupb_ref,vgroupb_id;
+ int32 dim_sizes[TYP_RANK];
+ int32 vgroupc_ref,vgroupc_id;
+ intn i, j,istat;
+ int32 sd_id,sds_id;
+ int32 sds_ref;
+ int32 array_data[X_LENGTH][Y_LENGTH];
+ int32 start[TYP_RANK],edges[TYP_RANK],stride[TYP_RANK];
+
+
+ for (i=0;i<X_LENGTH;i++){
+ for(j=0;j<Y_LENGTH;j++) {
+ array_data[i][j] =i+j;
+ }
+ }
+
+ dim_sizes[0] = X_LENGTH;
+ dim_sizes[1] = Y_LENGTH;
+
+ for (i=0;i<TYP_RANK;i++){
+ stride[i]=1;
+ start[i]=0;
+ edges[i]=dim_sizes[i];
+
+ }
+
+ /* Open the HDF file. */
+
+ file_id = Hopen(FILECLASHSDS, DFACC_CREATE, 0);
+ istat = Vstart(file_id);
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+ vgroupc_ref = -1;
+ vgroupa_id = Vattach(file_id,vgroupa_ref,"w");
+ if(vgroupa_id == FAIL) {
+ printf("fail to attach groupa.\n");
+ return FAIL;
+ }
+ vgroupb_id = Vattach(file_id,vgroupb_ref,"w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach groupb.\n");
+ return FAIL;
+ }
+ vgroupc_id = Vattach(file_id,vgroupc_ref,"w");
+ if(vgroupc_id == FAIL) {
+ printf("fail to attach groupc.\n");
+ return FAIL;
+ }
+ istat=Vsetname(vgroupa_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+ istat=Vsetname(vgroupb_id,"groupB");
+ if(istat == FAIL) {
+ printf("fail to set name for groupb.\n");
+ return FAIL;
+ }
+ Vsetname(vgroupc_id,"groupC");
+ if(istat == FAIL) {
+ printf("fail to set name for groupc.\n");
+ return FAIL;
+ }
+ sd_id = SDstart(FILECLASHSDS,DFACC_WRITE);
+ if(sd_id == FAIL) {
+ printf("fail to start SD interface.\n");
+ return FAIL;
+ }
+ /* putting one sds object under groupa. */
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("failed to transfer sds id to reference number.\n");
+ return FAIL;
+ }
+ /* a sds object with the name "sds" is put under group a.*/
+ istat = Vaddtagref(vgroupa_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add tag for reference.\n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ /* putting another sds with the same same "sds" under groupa.
+ It is legal for hdf lib. */
+
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("failed to transfer sds id to reference number.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupa_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add tag for reference.\n");
+ return FAIL;
+ }
+
+ SDendaccess(sds_id);
+
+ /* no sds name is given under groupc*/
+ sds_id = SDcreate(sd_id,NULL,DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("failed to transfer sds id to reference number.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupc_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add tag for reference.\n");
+ return FAIL;
+ }
+
+ SDendaccess(sds_id);
+
+ /* another no name sds object is put under group c. */
+ sds_id = SDcreate(sd_id,NULL,DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("failed to transfer sds id to reference number.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupc_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add tag for reference.\n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ /* another sds with the same name under groupb is given.*/
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("failed to transfer sds id to reference number.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupb_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add tag for reference.\n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ /* two sds share the same name under no specific groups.*/
+ sds_id = SDcreate(sd_id,"sds_independent",DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ sds_id = SDcreate(sd_id,"sds_independent",DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ /* another sds with no name and is not tagged with any group. */
+ sds_id = SDcreate(sd_id,NULL,DFNT_INT32,2,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("failed to create sds object.\n");
+ return FAIL;
+ }
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("failed to write sds data. \n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+
+ SDend(sd_id);
+ istat = Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupb_id);
+ istat = Vdetach(vgroupc_id);
+ istat = Vend(file_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+
+/*A routine to generate a testing file that deals with different
+name clashings for image.
+We are testing different Image
+ 1. under the same group sharing the same name.
+ 2. one image doesn't have name(not allowed)
+ 3. different image objects under different vgroups sharing the same name.
+ 4. image objects under no specific groups share the same name.
+ 5. image objects under no specific groups with no name(not allowed). */
+
+
+int test_grnameclash() {
+
+
+ int32 file_id, vgroupa_ref, vgroupa_id,vgroupb_ref,vgroupb_id,istat;
+ int32 dim_sizes[2];
+
+ int i, j;
+ int32 gr_id,ri_id,il,ncomp;
+ int32 gr_ref;
+ int32 start[2], edges[2];
+ uint32 image_data32[Y_LENGTH][X_LENGTH][3];
+
+ for (j=0;j<Y_LENGTH;j++){
+ for(i=0;i<X_LENGTH;i++) {
+ image_data32[j][i][0] = i;
+ image_data32[j][i][1] = j;
+ image_data32[j][i][2] = i+j;
+ }
+ }
+
+ dim_sizes[0] = X_LENGTH;
+ dim_sizes[1] = Y_LENGTH;
+
+
+ /* Open the HDF file. */
+
+ file_id = Hopen(FILECLASHGR, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open the file.\n");
+ return FAIL;
+ }
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start vgroup interface.\n");
+ return FAIL;
+ }
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+
+ vgroupa_id = Vattach(file_id,vgroupa_ref,"w");
+ if(vgroupa_id == FAIL) {
+ printf("fail to attach groupa.\n");
+ return FAIL;
+ }
+ vgroupb_id = Vattach(file_id,vgroupb_ref,"w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach groupb.\n");
+ return FAIL;
+ }
+
+ istat=Vsetname(vgroupa_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+
+ istat=Vsetname(vgroupb_id,"groupB");
+ if(istat == FAIL) {
+ printf("fail to set name for groupb.\n");
+ return FAIL;
+ }
+
+ gr_id = GRstart(file_id);
+
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+
+ /* Define the location, pattern, and size of the data set */
+ for (i = 0; i < 2; i++) {
+ start[i] = 0;
+ edges[i] = dim_sizes[i];
+ }
+ /* Define the number of components and dimensions of the image. */
+ ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+
+ /* Create the array. */
+ /* 1.1. put one image with the name "Imagea" under groupa.*/
+ ri_id = GRcreate(gr_id, "Imagea", ncomp, DFNT_UINT32, il, dim_sizes);
+ if(ri_id == FAIL) {
+ printf("fail to create GR interface.\n");
+ return FAIL;
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data32);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ gr_ref = GRidtoref(ri_id);
+ if(gr_ref == FAIL) {
+ printf("fail to convert ri_id into reference.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupa_id,DFTAG_RIG,gr_ref);
+ if(istat == FAIL) {
+ printf("fail to add gr object into vgroup a.\n");
+ return FAIL;
+ }
+ GRendaccess(ri_id);
+
+ /* 1.2 putting the same same image object under groupa. */
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Imagea", ncomp, DFNT_UINT32, il, dim_sizes);
+ if(ri_id == FAIL) {
+ printf("fail to create GR interface.\n");
+ return FAIL;
+ }
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data32);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ gr_ref = GRidtoref(ri_id);
+ if(gr_ref == FAIL) {
+ printf("fail to convert ri_id into reference.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupa_id,DFTAG_RIG,gr_ref);
+ if(istat == FAIL) {
+ printf("fail to add gr object into vgroup a.\n");
+ return FAIL;
+ }
+ GRendaccess(ri_id);
+
+
+ /* 2.0 no image name is given, it is illegal for hdf4 lib; therefore;
+ no test cases are given. */
+
+
+ /* 3.1 another image with the "imagea" under groupb is given.*/
+ ri_id = GRcreate(gr_id,"imagea", ncomp, DFNT_UINT32, il, dim_sizes);
+ if(ri_id == FAIL) {
+ printf("fail to create GR interface.\n");
+ return FAIL;
+ }
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data32);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ gr_ref = GRidtoref(ri_id);
+ if(gr_ref == FAIL) {
+ printf("fail to convert ri_id into reference.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupb_id,DFTAG_RIG,gr_ref);
+ if(istat == FAIL) {
+ printf("fail to add gr object into vgroup a.\n");
+ return FAIL;
+ }
+ GRendaccess(ri_id);
+
+ /* 4.0 two images share the same name under no specific groups.*/
+
+ ri_id = GRcreate(gr_id, "Image_independent", ncomp, DFNT_UINT32, il, dim_sizes);
+
+ if(ri_id == FAIL) {
+ printf("fail to create GR interface.\n");
+ return FAIL;
+ }
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data32);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ GRendaccess(ri_id);
+
+ ri_id = GRcreate(gr_id, "Image_independent", ncomp, DFNT_UINT32, il, dim_sizes);
+ if(ri_id == FAIL) {
+ printf("fail to create GR interface.\n");
+ return FAIL;
+ }
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, start, NULL, edges, (VOIDP)image_data32);
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+ GRendaccess(ri_id);
+ GRend(gr_id);
+ istat = Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupb_id);
+
+ istat = Vend(file_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+/* a routine that generates the name clashing for vdata object. some
+ redundant codes can found in this routine, it should be corrected later.
+
+ Cases:
+
+ 1. two independent Vdata with the same name not under any user-specified group.
+ 2. vdata without any names and not under any user-specified groups.
+ 3. different Vdata objects under the same vgroup sharing the same name.
+ 4. different Vdata objects under different vgroups sharing the same name.
+ 5. Vdata without any names under one user-specified group*/
+
+int test_vdnameclash() {
+
+ int32 file_id, vgroupa_ref, vgroupa_id,vgroupb_ref,vgroupb_id;
+ int32 vgroupc_id,vgroupc_ref,vd_ref;
+
+ struct {
+ float32 temp;
+ int16 height;
+ } source[NRECORDS];
+
+ int32 vdata_id, istat;
+ uint8 *databuf, *pntr;
+ int i, bufsize, recsize;
+ VOIDP fldbufpt[2];
+
+ /* Open the HDF file. */
+ file_id = Hopen(FILECLASHVD, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open the file.\n");
+ return FAIL;
+ }
+ /* Initialize the Vset interface. */
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start vgroup interface.\n");
+ return FAIL;
+ }
+
+ /* 1.0
+ Create an independent new Vdata with the name "Test Vset Name". */
+
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata id.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+
+ /* Set the Vdata name. */
+ istat=VSsetname(vdata_id, "Test Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name.\n");
+ return FAIL;
+ }
+
+ /* Set the Vdata class. */
+ istat=VSsetclass(vdata_id, "Test Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("fail to allocate memory for databuf");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+
+ free(databuf);
+ VSdetach(vdata_id);
+
+ /* 1.1
+ Create another independent Vdata with the name "Test Vset Name" */
+
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+ /* Set the Vdata name. */
+ istat=VSsetname(vdata_id, "Test Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name.\n");
+ return FAIL;
+ }
+ /* Set the Vdata class. */
+ istat=VSsetclass(vdata_id, "Test Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+ free(databuf);
+ VSdetach(vdata_id);
+
+ /* An independent Vdata without name not under any user-specified vgroup. */
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata id.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+ /* Set the Vdata class.
+ istat=VSsetclass(vdata_id, "Test Vset Class");*/
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+ free(databuf);
+ VSdetach(vdata_id);
+
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+ vgroupc_ref = -1;
+
+ /* 3. two vdata with the same name under groupa. */
+ vgroupa_id = Vattach(file_id, vgroupa_ref,"w");
+
+ Vsetname(vgroupa_id,"groupA");
+ /* Create a new Vdata. */
+ vdata_id = VSattach(file_id, -1, "w");
+
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+ /* Set the Vdata name. */
+ istat=VSsetname(vdata_id, "Test Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name. \n");
+ return FAIL;
+ }
+
+ /* Set the Vdata class. */
+ istat=VSsetclass(vdata_id, "Test Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+ free(databuf);
+ vd_ref = VSQueryref(vdata_id);
+ if(vd_ref == FAIL) {
+ printf("fail to query vdata.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupa_id,DFTAG_VH,vd_ref);
+ if(istat == FAIL){
+ printf("fail to add vdata into vgroup.\n");
+ return FAIL;
+ }
+ VSdetach(vdata_id);
+
+ /* Create a new Vdata. */
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+
+ /* Set the Vdata name. */
+ istat=VSsetname(vdata_id, "Test Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name.\n");
+ return FAIL;
+ }
+ /* Set the Vdata class. */
+ istat=VSsetclass(vdata_id, "Test Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+ free(databuf);
+ vd_ref = VSQueryref(vdata_id);
+ if(vd_ref== FAIL) {
+ printf("fail to query reference.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupa_id,DFTAG_VH,vd_ref);
+ if(istat == FAIL) {
+ printf("fail to add vdata into vgroup a.\n");
+ return FAIL;
+ }
+ VSdetach(vdata_id);
+
+
+ /*4. another vdata with the same name under groupb.*/
+ vgroupb_id = Vattach(file_id,vgroupb_ref,"w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach vgroup b.\n");
+ return FAIL;
+ }
+
+ istat=Vsetname(vgroupb_id,"groupB");
+ if(istat == FAIL) {
+ printf("fail to set group b name.\n");
+ return FAIL;
+ }
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+ /* Set the Vdata name. */
+ istat=VSsetname(vdata_id, "Test Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name.\n");
+ return FAIL;
+ }
+ /* Set the Vdata class. */
+ istat=VSsetclass(vdata_id, "Test Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+
+ free(databuf);
+ vd_ref = VSQueryref(vdata_id);
+ if(vd_ref == FAIL) {
+ printf("fail to query reference.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupb_id,DFTAG_VH,vd_ref);
+ if(istat == FAIL) {
+ printf("fail to add vdata into vgroup.\n");
+ return FAIL;
+ }
+
+ VSdetach(vdata_id);
+
+ /* 5. vdata without name under groupc. */
+ vgroupc_id = Vattach(file_id,vgroupc_ref,"w");
+ if(vgroupc_id == FAIL) {
+ printf("fail to attach vgroup c.\n");
+ return FAIL;
+ }
+ istat = Vsetname(vgroupc_id,"groupC");
+ if(istat == FAIL) {
+ printf("fail to set group c name.\n");
+ return FAIL;
+ }
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_VDNAMES);
+ if(istat == FAIL) {
+ printf("fail to set field name.\n");
+ return FAIL;
+ }
+
+ recsize = sizeof(float32) + sizeof(int16);
+
+ bufsize = recsize * NRECORDS;
+ databuf = (uint8 *) malloc((size_t)bufsize);
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+
+ }
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+
+ free(databuf);
+ vd_ref = VSQueryref(vdata_id);
+ if(vd_ref == FAIL) {
+ printf("fail to get reference number for vata.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupc_id,DFTAG_VH,vd_ref);
+ if(istat == FAIL) {
+ printf("fail to add vdata into groupc.\n");
+ return FAIL;
+ }
+ VSdetach(vdata_id);
+
+ istat = Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupb_id);
+ istat = Vdetach(vgroupc_id);
+ istat = Vend(file_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+
+/* a routine that generates a hdf file with vgroup loops.va->vb and vb->va */
+
+int test_vgloop() {
+
+ int32 file_id, vgroupa_ref, vgroupa_id, vgroupb_ref,vgroupb_id;
+ int32 istat,dims[TYP_RANK];
+ int i,j,k;
+
+ /*2. for sds */
+ int32 sd_id,sds_id;
+ int32 sds_ref;
+ int32 array_data[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 start[TYP_RANK],edges[TYP_RANK],stride[TYP_RANK];
+
+
+ for (i=0;i<TYP_DIMSIZE;i++){
+ for(j=0;j<TYP_DIMSIZE;j++) {
+ for(k=0;k<TYP_DIMSIZE;k++){
+ array_data[i][j][k] =i+j;
+ }
+ }
+ }
+
+ dims[0] = TYP_DIMSIZE;
+ dims[1] = TYP_DIMSIZE;
+ dims[2] = TYP_DIMSIZE;
+ for (i=0;i<TYP_RANK;i++){
+ stride[i]=1;
+ start[i]=0;
+ edges[i]=dims[i];
+
+ }
+
+ /* Open the HDF file. */
+
+ file_id = Hopen(FILELOOP, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open the file.\n");
+ return FAIL;
+ }
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start vdata interface.\n");
+ return FAIL;
+ }
+
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+ vgroupa_id = Vattach(file_id, vgroupa_ref, "w");
+ if(vgroupa_id == FAIL) {
+ printf("fail to attach group a.\n");
+ return FAIL;
+ }
+ vgroupb_id = Vattach(file_id, vgroupb_ref, "w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach groupb.\n");
+ return FAIL;
+ }
+ istat = Vsetname(vgroupa_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+ istat = Vsetname(vgroupb_id,"groupB");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+ istat = Vinsert(vgroupa_id,vgroupb_id);
+ if(istat == FAIL) {
+ printf("fail to insert groupb into groupa.\n");
+ return FAIL;
+ }
+
+ istat = Vinsert(vgroupb_id,vgroupa_id);
+ if(istat == FAIL) {
+ printf("fail to insert groupa into groupb.\n");
+ return FAIL;
+ }
+ sd_id = SDstart(FILELOOP,DFACC_WRITE);
+ if(sd_id == FAIL) {
+ printf("fail to start sd interface.\n");
+ return FAIL;
+ }
+
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,TYP_RANK,dims);
+ if(sds_id == FAIL) {
+ printf("fail to create sds interface.\n");
+ return FAIL;
+ }
+
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("fail to write sds data.\n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("fail to create sds reference.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupa_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add sds into vgroupa\n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+ SDend(sd_id);
+ istat = Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupb_id);
+ istat = Vend(file_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+
+/* a routine that creates a hdf file which has one sds under two
+ different vgroups. */
+int test_vghl() {
+
+ int32 file_id, vgroupa_ref, vgroupa_id, vgroupb_ref,vgroupb_id;
+ int32 istat,dims[TYP_RANK];
+ int i,j,k;
+
+ /*2. for sds */
+ int32 sd_id,sds_id;
+ int32 sds_ref;
+ int32 array_data[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 start[TYP_RANK],edges[TYP_RANK],stride[TYP_RANK];
+
+ for (i=0;i<TYP_DIMSIZE;i++){
+ for(j=0;j<TYP_DIMSIZE;j++) {
+ for(k=0;k<TYP_DIMSIZE;k++){
+ array_data[i][j][k] =i+j;
+ }
+ }
+ }
+
+ dims[0] = TYP_DIMSIZE;
+ dims[1] = TYP_DIMSIZE;
+ dims[2] = TYP_DIMSIZE;
+ for (i=0;i<TYP_RANK;i++){
+ stride[i]=1;
+ start[i]=0;
+ edges[i]=dims[i];
+
+ }
+
+ /* Open the HDF file. */
+
+ file_id = Hopen(FILEHL, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open hdf file.\n");
+ return FAIL;
+ }
+
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start vdata interface.\n");
+ return FAIL;
+ }
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+ vgroupa_id = Vattach(file_id, vgroupa_ref, "w");
+ if(vgroupa_id == FAIL) {
+ printf("fail to attach group a.\n");
+ return FAIL;
+ }
+ vgroupb_id = Vattach(file_id, vgroupb_ref, "w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach groupb.\n");
+ return FAIL;
+ }
+ istat = Vsetname(vgroupa_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+ istat = Vsetname(vgroupb_id,"groupB");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+ sd_id = SDstart(FILEHL,DFACC_WRITE);
+ if(sd_id == FAIL) {
+ printf("fail to start sd interface.\n");
+ return FAIL;
+ }
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,TYP_RANK,dims);
+ if(sds_id == FAIL) {
+ printf("fail to create sds interface.\n");
+ return FAIL;
+ }
+
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("fail to write sds data.\n");
+ return FAIL;
+ }
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("fail to create sds reference.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupa_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add sds into vgroupa\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupb_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add sds into vgroupb\n");
+ return FAIL;
+ }
+ SDendaccess(sds_id);
+ SDend(sd_id);
+ istat = Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupb_id);
+ istat = Vend(file_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+/* this is a comprehensive testing file for h4-h5 converter. It includes
+ annotation,vdata,image,sds,palette and vgroup objects*/
+/* the structure of the hdf5 file is as follows:
+ root
+ / \
+ gc ga<--
+ / \ |
+ gd gb--
+ /
+ ge
+
+ This file includes vdata,image and sds.
+
+*/
+int test_vgall() {
+
+ typedef struct {
+ float32 temp;
+ int16 height;
+ float32 speed;
+ char ident;
+ float32 position[2];
+ } source_t;
+
+ source_t source[NRECORDS];
+
+ int32 file_id, vgroupa_ref, vgroupa_id,istat;
+ int32 vgroupc_ref, vgroupc_id,vgroupb_ref,vgroupb_id;
+ int32 vgroupd_ref, vgroupd_id,vgroupe_ref,vgroupe_id;
+ int32 vdata_id,values[4]={32, 16, 32, 8};
+
+ intn i, j,k;
+
+ uint8 *databuf, *pntr;
+ int bufsize, recsize;
+ VOIDP fldbufpt[5];
+
+ /*2. for sds */
+ int32 sd_id,sds_id,dim_id;
+ int32 sds_ref;
+ int32 fill_value;
+ int32 array_data[TYP_DIMSIZE][TYP_DIMSIZE][TYP_DIMSIZE];
+ int32 dimo_sca[TYP_DIMSIZE];
+ int32 dim_sizes[TYP_RANK];
+ int32 start[TYP_RANK],edges[TYP_RANK],stride[TYP_RANK];
+ float64 cal;
+ float64 cal_err;
+ float64 offset;
+ float64 offset_err;
+
+ /*3. for image. */
+
+ int32 gr_id, ri_id, il,pal_id;
+ int32 image_ncomp,image_data_type;
+ int32 image_start[2], image_edges[2],image_dims[2];
+ int16 image_data[Y_LENGTH][X_LENGTH][3];
+ uint8 palette_data[NUM_COLORS*3];
+ int32 image_num_comp;
+ int32 image_num_entries;
+ int32 image_ref;
+
+ char* attr_value;
+
+ /*4. for annotation. */
+ int32 an_id,ann_id;
+ int32 group_tag,group_ref;
+
+ static char file_label[] = "This is a file label.";
+ static char file_desc[] = "This is a file description.";
+ static char data_label[] = "This is a data label.";
+ static char data_desc[] = "This is a data description.";
+
+ char label[] = "sds.label";
+ char unit[] = "sds.unit";
+ char format[] = "sds.format";
+ char coordsys[] = "sds.coord";
+
+ char dim_name0[] ="dim0";
+ char dim_name1[] ="dim1";
+ char dim_label[] ="dim.label";
+ char dim_unit[] ="dim.unit";
+ char dim_format[] ="dim.format";
+
+ /**** initial setting. ****/
+ cal = 1.0;
+ cal_err = 0.0;
+ offset = 0.0;
+ offset_err = 0.0;
+ fill_value = 999;
+
+ attr_value = malloc(ATT_SIZE*sizeof(char));
+ if(attr_value == NULL) {
+ printf("fail to allocate memory.\n");
+ return FAIL;
+ }
+ strcpy(attr_value,"test attr");
+
+ for (i=0;i<TYP_DIMSIZE;i++){
+ for(j=0;j<TYP_DIMSIZE;j++) {
+ for(k=0;k<TYP_DIMSIZE;k++) {
+ array_data[i][j][k]=i+j;
+ }
+ }
+ }
+
+ for (i=0;i<TYP_DIMSIZE;i++)
+ dimo_sca[i]= 2*i;
+
+ for (i=0;i<TYP_RANK;i++){
+ stride[i]=1;
+ start[i]=0;
+ dim_sizes[i] = TYP_DIMSIZE;
+ edges[i]=dim_sizes[i];
+
+ }
+
+ /* Open the HDF file. */
+
+ file_id = Hopen(FILEVG, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open the file.\n");
+ return FAIL;
+ }
+
+ /* create annotations. */
+
+ /* Initialize the AN interface and obtain an interface id. */
+ an_id = ANstart(file_id);
+ if(an_id == FAIL) {
+ printf("fail to start annotation interface.\n");
+ return FAIL;
+ }
+ /* Create a file label and obtain an annotation id. */
+ ann_id = ANcreatef(an_id, AN_FILE_LABEL);
+ if(ann_id == FAIL) {
+ printf("fail to create file annotion interface.\n");
+ return FAIL;
+ }
+
+ /* Write the file label to the file. */
+ istat = ANwriteann(ann_id, file_label, (int32)(strlen(file_label)));
+ if(istat == FAIL) {
+ printf("fail to write file annotation.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+
+ /* Create a file description. */
+ ann_id = ANcreatef(an_id, AN_FILE_DESC);
+ if(ann_id == FAIL) {
+ printf("fail to create file annotion interface.\n");
+ return FAIL;
+ }
+ /* Write the file description to the file. */
+ istat = ANwriteann(ann_id, file_desc, (int32)(strlen(file_desc)));
+ if(istat == FAIL) {
+ printf("fail to write file annotation.\n");
+ return FAIL;
+ }
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+
+ /* Initialize the Vset interface. */
+
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start vdata interface.\n");
+ return FAIL;
+ }
+ /** Create Vgroup VA and VB***/
+ vgroupa_ref = -1;
+ vgroupb_ref = -1;
+
+ /* Attach to the target vgroup. */
+ vgroupa_id = Vattach(file_id, vgroupa_ref, "w");
+ if(vgroupa_id == FAIL) {
+ printf("fail to attach group a.\n");
+ return FAIL;
+ }
+ istat=Vsetname(vgroupa_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupa.\n");
+ return FAIL;
+ }
+ /* Attach an attribute to the vgroup. */
+
+ istat = Vsetattr(vgroupa_id,"vgattr",DFNT_CHAR,5,"TESTa");
+ if(istat == FAIL) {
+ printf("fail to set attribute.\n");
+ return FAIL;
+ }
+
+ vgroupb_id = Vattach(file_id,vgroupb_ref,"w");
+ if(vgroupb_id == FAIL) {
+ printf("fail to attach group b.\n");
+ return FAIL;
+ }
+ Vsetname(vgroupb_id,"groupB");
+ if(istat == FAIL) {
+ printf("fail to set name for groupb.\n");
+ return FAIL;
+ }
+ /* adding annotation into the file. */
+ group_tag = VQuerytag(vgroupb_id);
+ if(group_tag == FAIL) {
+ printf("query groupb tag failed.\n");
+ return FAIL;
+ }
+ group_ref = VQueryref(vgroupb_id);
+ if(group_ref == FAIL) {
+ printf("query groupb ref failed.\n");
+ return FAIL;
+ }
+
+ /* Create a data label for the Vgroup just created. */
+ ann_id = ANcreate(an_id, (uint16)group_tag,(uint16)group_ref, AN_DATA_LABEL);
+ if(ann_id == FAIL) {
+ printf("AN create interface failed.\n");
+ return FAIL;
+ }
+
+ /* Write the data label to the file. */
+ istat = ANwriteann(ann_id, data_label, (int32)(strlen(data_label)));
+ if(istat == FAIL) {
+ printf("fail to write annotation.\n");
+ return FAIL;
+ }
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+
+ /* Create a data description for the Vgroup just created.*/
+ ann_id = ANcreate(an_id, (uint16)group_tag, (uint16)group_ref, AN_DATA_DESC);
+ if(ann_id == FAIL) {
+ printf("AN create interface failed.\n");
+ return FAIL;
+ }
+ /* Write the data description to the file. */
+ istat = ANwriteann(ann_id, data_desc, (int32)(strlen(data_desc)));
+ if(istat == FAIL) {
+ printf("fail to write annotation.\n");
+ return FAIL;
+ }
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+
+ /* Terminate access to the AN interface. */
+ istat = ANend(an_id);
+ /* end of annotations. */
+
+ istat = Vsetattr(vgroupb_id, VGATTR_NAME, DFNT_CHAR, 5, "TESTb");
+ if(istat == FAIL) {
+ printf("fail to set attribute.\n");
+ return FAIL;
+ }
+ istat = Vinsert(vgroupa_id,vgroupb_id);
+ if(istat == FAIL) {
+ printf("fail to insert groupb into groupa. \n");
+ return FAIL;
+ }
+
+ vgroupc_ref = -1;
+ vgroupd_ref = -1;
+ vgroupe_ref = -1;
+ vgroupc_id = Vattach(file_id,vgroupc_ref,"w");
+ if(vgroupc_id == FAIL) {
+ printf("fail to attach groupc into file.\n");
+ return FAIL;
+ }
+
+ istat= Vsetname(vgroupc_id,"groupA");
+ if(istat == FAIL) {
+ printf("fail to set name for groupA.\n");
+ return FAIL;
+ }
+
+ vgroupd_id = Vattach(file_id,vgroupd_ref,"w");
+ if(vgroupd_id == FAIL) {
+ printf("fail to attach groupd into the file.\n");
+ return FAIL;
+ }
+
+ istat= Vsetname(vgroupd_id,"groupD");
+ if(istat == FAIL) {
+ printf("fail to set name for groupD.\n");
+ return FAIL;
+ }
+ vgroupe_id = Vattach(file_id,vgroupe_ref,"w");
+ if(vgroupe_id == FAIL) {
+ printf("fail to attach groupe into the file.\n");
+ return FAIL;
+ }
+ istat=Vsetname(vgroupe_id,"groupE");
+ if(istat == FAIL) {
+ printf("fail to set name for groupD.\n");
+ return FAIL;
+ }
+ istat = Vinsert(vgroupc_id,vgroupd_id);
+ if(istat == FAIL) {
+ printf("fail to insert groupd into groupc.\n");
+ return FAIL;
+ }
+
+ istat = Vinsert(vgroupd_id,vgroupe_id);
+ if(istat == FAIL) {
+ printf("fail to insert groupe into groupd.\n");
+ return FAIL;
+ }
+ istat = Vinsert(vgroupe_id,vgroupc_id);
+ if(istat == FAIL) {
+ printf("fail to insert groupc into groupe.\n");
+ return FAIL;
+ }
+ /* Create a new Vdata. */
+
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata.\n");
+ return FAIL;
+ }
+ /* Define the field to write. */
+
+ istat = VSfdefine(vdata_id, FIELD_1, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 1.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_2, DFNT_INT16, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 2.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_3, DFNT_FLOAT32, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 3.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_4, DFNT_CHAR8, 1);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 4.\n");
+ return FAIL;
+ }
+ istat = VSfdefine(vdata_id, FIELD_5, DFNT_FLOAT32,2);
+ if(istat == FAIL) {
+ printf("fail to define vdata field 5.\n");
+ return FAIL;
+ }
+ /* Set the Vdata name. */
+ istat = VSsetname(vdata_id, "Example Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name.\n");
+ return FAIL;
+ }
+ /* Set the Vdata class. */
+ istat = VSsetclass(vdata_id, "Example Vset Class");
+ if(istat == FAIL) {
+ printf("fail to set vdata class.\n");
+ return FAIL;
+ }
+ /* Set the field names. */
+ istat = VSsetfields(vdata_id, FIELD_NAMES);
+ if(istat == FAIL) {
+ printf("fail to set fields.\n");
+ return FAIL;
+ }
+ recsize = (2 * sizeof(float32) + sizeof(int16)) +2* sizeof(float32)
+ +sizeof(char);
+ /********************debugging *********************/
+ /* + sizeof(char)); */
+
+ bufsize = recsize * NRECORDS;
+
+ databuf = (uint8 *) malloc((size_t)bufsize);
+
+ if (databuf == NULL) {
+ printf("malloc failed\n");
+ return FAIL;
+ }
+ pntr = databuf;
+
+ /* set record values */
+ for (i = 0; i < NRECORDS; i++) {
+ source[i].temp = 1.11 * (i+1);
+ source[i].height = i;
+ source[i].speed = 1.11 * (i+1);
+ source[i].ident = 'A' + i;
+ for (j=0; j< 2; j++)
+ source[i].position[j] = 1.0+j;
+
+ }
+
+ /* pack one record at a time */
+ for (i = 0; i< NRECORDS; i++) {
+ /* set field buf address */
+ fldbufpt[0] = &source[i].temp;
+ fldbufpt[1] = &source[i].height;
+ fldbufpt[2] = &source[i].speed;
+ fldbufpt[3] = &source[i].ident;
+ fldbufpt[4] = &source[i].position[0];
+ /* pack field data into databuf */
+ istat = VSfpack(vdata_id,_HDF_VSPACK,NULL,(VOIDP)pntr,
+ recsize, 1, NULL, fldbufpt);
+ if (istat == FAIL) {
+ printf("VSfpack failed in packing record %d\n", i);
+ return FAIL;
+ }
+ pntr = pntr + recsize;
+ }
+
+ /* Write the data to the Vset object. */
+ istat = VSwrite(vdata_id, databuf, NRECORDS, FULL_INTERLACE);
+ if(istat == FAIL) {
+ printf("fail to write vdata.\n");
+ return FAIL;
+ }
+ /* Set Vdata attribute */
+ istat = VSsetattr (vdata_id, _HDF_VDATA, "Fixed_type", DFNT_INT32, 4,
+ (VOIDP)values);
+ if(istat == FAIL) {
+ printf("fail to set vdata attribute.\n");
+ return FAIL;
+ }
+ /* Set attribute for "speed" field */
+ istat = VSsetattr (vdata_id, 2, "Symbol", DFNT_CHAR, 3, "MAX");
+ if(istat == FAIL) {
+ printf("fail to set speed attribute.\n");
+ return FAIL;
+ }
+
+ istat = VSdetach(vdata_id);
+ if(istat == FAIL) {
+ printf("fail to detach vdata.\n");
+ return FAIL;
+ }
+
+ /*** initialize another empty vdata set to test name clashings ***/
+
+ vdata_id = VSattach(file_id, -1, "w");
+ if(vdata_id == FAIL) {
+ printf("fail to attach vdata_id into file_id.\n");
+ return FAIL;
+ }
+
+ /* Set the Vdata name. */
+
+ istat = VSsetname(vdata_id, "Example Vset Name");
+ if(istat == FAIL) {
+ printf("fail to set vdata name.\n");
+ return FAIL;
+ }
+ istat = VSdetach(vdata_id);
+ if(istat == FAIL) {
+ printf("fail to detach vdata.\n");
+ return FAIL;
+ }
+
+ /* Initialize an independent Image interface. */
+ /************************************************/
+ gr_id = GRstart(file_id);
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+ image_ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ image_dims[0] = X_LENGTH;
+ image_dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_1", image_ncomp, DFNT_INT16, il,
+ image_dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR object.\n");
+ return FAIL;
+ }
+
+ /* Fill the stored-data array with values. */
+
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data[j][i][0] = (i + j) + 1;
+ image_data[j][i][1] = (i + j) + 1;
+ image_data[j][i][2] =(i+j)+1;
+ }
+ }
+
+ /* Define the location, pattern, and size of the data set */
+
+ for (i = 0; i < 2; i++) {
+ image_start[i] = 0;
+ image_edges[i] = image_dims[i];
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, image_start, NULL, image_edges,
+ (VOIDP)image_data);
+
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ /* Initialize the palette to grayscale. */
+ for (i = 0; i < NUM_COLORS; i++) {
+ palette_data[i * 3] = i;
+ palette_data[i * 3 + 1] = i;
+ palette_data[i * 3 + 2] = i;
+ }
+
+ /* Set palette characteristics. */
+
+ image_data_type = DFNT_UINT8;
+ image_num_entries = NUM_COLORS;
+ image_num_comp = 3;
+
+
+ /* Get the id for the palette. */
+ pal_id = GRgetlutid(ri_id,0 );
+ if(pal_id == FAIL) {
+ printf("fail to get palette id.\n");
+ return FAIL;
+ }
+
+ /* Write the palette to file. */
+ istat = GRwritelut(pal_id, image_num_comp, image_data_type,
+ 0, image_num_entries,(VOIDP)palette_data);
+ if(istat == FAIL) {
+ printf("fail to write palette.\n");
+ return FAIL;
+ }
+ image_ref = GRidtoref(ri_id);
+ if(image_ref == FAIL) {
+ printf("fail to get reference of image.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ istat = GRendaccess(ri_id);
+
+ /* Terminate access to the GR interface. */
+ istat = GRend(gr_id);
+
+
+ /*** III. setting SDS data and all SDS attributes. ***/
+
+ sd_id = SDstart(FILEVG,DFACC_WRITE);
+
+ if (sd_id == FAIL){
+ printf (" fail to open sd interface. \n");
+ return FAIL;
+ }
+
+ istat = SDsetfillmode(sd_id,SD_NOFILL);
+
+ if (istat == FAIL) {
+ printf("error setting fill mode\n");
+ return FAIL;
+ }
+ sds_id = SDcreate(sd_id,"sds",DFNT_INT32,3,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("fail to create sds objects.\n");
+ return FAIL;
+ }
+
+ istat = SDsetfillvalue(sds_id,(VOIDP)(&fill_value));
+
+ if (istat == FAIL){
+ printf("error setting fill value\n");
+ return FAIL;
+ }
+
+ /*** 3.1 write data. ***/
+
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+
+ if(istat == FAIL) {
+ printf(" sds data written failed. \n");
+ return FAIL;
+ }
+ /*** 3.2 write dataset attribute ***/
+
+ istat = SDsetattr(sds_id,"sds.attr",DFNT_CHAR8,10,(VOIDP)attr_value);
+ if(istat == FAIL) {
+ printf(" sds data attr. setting failed. \n");
+ return FAIL;
+ }
+ /*** 3.3 write dataset predefined attribute ***/
+
+ istat = SDsetdatastrs(sds_id,label,unit,format,coordsys);
+ if(istat == FAIL) {
+ printf(" sds data predefined attr. setting failed. \n");
+ return FAIL;
+ }
+ /*** 3.4 set calibration information. ***/
+
+ istat = SDsetcal(sds_id,cal,cal_err,offset,offset_err,DFNT_INT32);
+ if(istat == FAIL) {
+ printf(" sds data calibrating attr. setting failed. \n");
+ return FAIL;
+ }
+
+ /*** 3.5 write down dimension scale dataset. ***/
+
+ for (i =0; i<TYP_RANK;i++) {
+ dim_id = SDgetdimid(sds_id,i);
+ if(dim_id <0) {
+ printf("sds set dim id failed. \n");
+ return FAIL;
+ }
+ if (i==0) {
+ istat = SDsetdimname(dim_id,dim_name0);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat= SDsetdimscale(dim_id,dim_sizes[0],DFNT_INT32,(VOIDP)dimo_sca);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ }
+ else {
+ istat = SDsetdimname(dim_id,dim_name1);
+ if(istat == FAIL) {
+ printf("sds set dim.name failed. \n");
+ return FAIL;
+ }
+ istat = SDsetdimscale(dim_id,dim_sizes[1],DFNT_INT32,(VOIDP)dimo_sca);
+ if(istat == FAIL) {
+ printf("sds set dim. scale failed. \n");
+ return FAIL;
+ }
+ }
+
+ istat=SDsetdimstrs(dim_id,dim_label,dim_unit,dim_format);
+ if(istat == FAIL) {
+ printf("sds set dim. predefined attr. failed. \n");
+ return FAIL;
+ }
+ istat = SDsetattr(dim_id,"sdsdim.attr",DFNT_CHAR8,10,(VOIDP)attr_value);
+
+ if(istat == FAIL) {
+ printf(" sds dim data attr. setting failed. \n");
+ return FAIL;
+ }
+ SDendaccess(dim_id);
+ }
+
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("fail to transfer id to reference.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupb_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add reference into vgroup.\n");
+ return FAIL;
+ }
+
+ SDendaccess(sds_id);
+ SDend(sd_id);
+
+ sd_id = SDstart(FILEVG,DFACC_WRITE);
+
+ if (sd_id == FAIL){
+ printf (" open file failed\n");
+ return FAIL;
+ }
+ istat = SDsetfillmode(sd_id,SD_NOFILL);
+
+ if (istat == FAIL){
+ printf("error setting fill mode\n");
+ return FAIL;
+ }
+ sds_id = SDcreate(sd_id,"sds2",DFNT_INT32,3,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("fail to create sds id.\n");
+ return FAIL;
+ }
+ istat = SDsetfillvalue(sds_id,(VOIDP)(&fill_value));
+
+ if (istat == FAIL){
+ printf("error setting fill value\n");
+ return FAIL;
+ }
+ /*** 3.1 write data. ***/
+
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+ if(istat == FAIL) {
+ printf("fail to write sds data.\n");
+ return FAIL;
+ }
+
+ sds_ref = SDidtoref(sds_id);
+ if(sds_ref == FAIL) {
+ printf("fail to generate reference number.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupd_id,DFTAG_NDG,sds_ref);
+ if(istat == FAIL) {
+ printf("fail to add sds reference into groupd.\n");
+ return FAIL;
+ }
+
+ SDendaccess(sds_id);
+ SDend(sd_id);
+
+ sd_id = SDstart(FILEVG,DFACC_WRITE);
+ if (sd_id == FAIL) {
+ printf (" open file failed\n");
+ return FAIL;
+ }
+
+ istat = SDsetfillmode(sd_id,SD_NOFILL);
+
+ if (istat == FAIL) {
+ printf("error setting fill mode. \n");
+ return FAIL;
+ }
+
+ sds_id = SDcreate(sd_id,"sds2",DFNT_INT32,3,dim_sizes);
+ if(sds_id == FAIL) {
+ printf("error creating sds objects.\n");
+ return FAIL;
+ }
+
+ istat = SDsetfillvalue(sds_id,(VOIDP)(&fill_value));
+
+ if (istat == FAIL) {
+ printf("error setting fill value\n");
+ return FAIL;
+ }
+
+ /*** 3.1 write data. ***/
+
+ istat = SDwritedata(sds_id,start,stride,edges,(VOIDP)array_data);
+
+ if(istat == FAIL) {
+ printf("error writing sds object.\n");
+ return FAIL;
+ }
+
+ SDendaccess(sds_id);
+ SDend(sd_id);
+
+ gr_id = GRstart(file_id);
+ if(gr_id == FAIL) {
+ printf("error starting gr interface.\n");
+ return FAIL;
+ }
+
+ image_ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ image_dims[0] = X_LENGTH;
+ image_dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_1", image_ncomp, DFNT_INT16, il,
+ image_dims);
+
+ if(ri_id == FAIL) {
+ printf("fail to creat GR interface.\n");
+ return FAIL;
+ }
+
+ /* Fill the stored-data array with values. */
+
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data[j][i][0] = (i + j) + 2;
+ image_data[j][i][1] = (i + j) + 3;
+ image_data[j][i][2] =(i+j)+1;
+ }
+ }
+
+ /* Define the location, pattern, and size of the data set */
+
+ for (i = 0; i < 2; i++) {
+ image_start[i] = 0;
+ image_edges[i] = image_dims[i];
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, image_start, NULL, image_edges,
+ (VOIDP)image_data);
+
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ /* Initialize the palette to grayscale. */
+ for (i = 0; i < NUM_COLORS; i++) {
+ palette_data[i * 3] = i;
+ palette_data[i * 3 + 1] = i;
+ palette_data[i * 3 + 2] = i;
+ }
+
+ /* Set palette characteristics. */
+
+ image_data_type = DFNT_UINT8;
+ image_num_entries = NUM_COLORS;
+ image_num_comp = 3;
+
+
+ /* Get the id for the palette. */
+ pal_id = GRgetlutid(ri_id,0 );
+
+ if(pal_id == FAIL) {
+ printf("fail to get palette id.\n");
+ return FAIL;
+ }
+
+ /* Write the palette to file. */
+ istat = GRwritelut(pal_id, image_num_comp, image_data_type,
+ 0, image_num_entries,(VOIDP)palette_data);
+ if(istat == FAIL) {
+ printf("fail to write palette data.\n");
+ return FAIL;
+ }
+
+ image_ref = GRidtoref(ri_id);
+ if(image_ref == FAIL) {
+ printf("fail to obtain image reference number.\n");
+ return FAIL;
+ }
+ istat = Vaddtagref(vgroupd_id,DFTAG_RIG,image_ref);
+ if(istat == FAIL) {
+ printf("fail to add image into group vgroupd\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ istat = GRendaccess(ri_id);
+ if(istat == FAIL) {
+ printf("fail to end GR interface.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the GR interface. */
+ istat = GRend(gr_id);
+
+ gr_id = GRstart(file_id);
+ if(gr_id == FAIL) {
+ printf("fail to start GR interface.\n");
+ return FAIL;
+ }
+
+ image_ncomp = 3;
+ il = MFGR_INTERLACE_PIXEL;
+ image_dims[0] = X_LENGTH;
+ image_dims[1] = Y_LENGTH;
+
+ /* Create the array. */
+ ri_id = GRcreate(gr_id, "Image_2", image_ncomp, DFNT_INT16, il,
+ image_dims);
+ if(ri_id == FAIL) {
+ printf("fail to create GR interface.\n");
+ return FAIL;
+ }
+
+ /* Fill the stored-data array with values. */
+
+ for (j = 0; j < Y_LENGTH; j++) {
+ for (i = 0; i < X_LENGTH; i++) {
+ image_data[j][i][0] = (i + j) + 2;
+ image_data[j][i][1] = (i + j) + 3;
+ image_data[j][i][2] =(i+j)+1;
+ }
+ }
+
+ /* Define the location, pattern, and size of the data set */
+
+ for (i = 0; i < 2; i++) {
+ image_start[i] = 0;
+ image_edges[i] = image_dims[i];
+ }
+
+ /* Write the stored data to the image array. */
+ istat = GRwriteimage(ri_id, image_start, NULL, image_edges,
+ (VOIDP)image_data);
+
+ if(istat == FAIL) {
+ printf("fail to write image.\n");
+ return FAIL;
+ }
+
+ /* Initialize the palette to grayscale. */
+ for (i = 0; i < NUM_COLORS; i++) {
+ palette_data[i * 3] = i;
+ palette_data[i * 3 + 1] = i;
+ palette_data[i * 3 + 2] = i;
+ }
+
+ /* Set palette characteristics. */
+
+ image_data_type = DFNT_UINT8;
+ image_num_entries = NUM_COLORS;
+ image_num_comp = 3;
+
+
+ /* Get the id for the palette. */
+ pal_id = GRgetlutid(ri_id,0 );
+ if(pal_id == FAIL) {
+ printf("fail to obtain palette id.\n");
+ return FAIL;
+ }
+
+ /* Write the palette to file. */
+ istat = GRwritelut(pal_id, image_num_comp, image_data_type,
+ 0, image_num_entries,(VOIDP)palette_data);
+
+ if(istat == FAIL) {
+ printf("fail to write GR image.\n");
+ return FAIL;
+ }
+
+ image_ref = GRidtoref(ri_id);
+ if(image_ref == FAIL) {
+ printf("fail to generate image reference number.\n");
+ return FAIL;
+ }
+
+ istat = Vaddtagref(vgroupa_id,DFTAG_RIG,image_ref);
+ if(istat == FAIL) {
+ printf("fail to add image into vgroupa\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the image. */
+ istat = GRendaccess(ri_id);
+
+ /* Terminate access to the GR interface. */
+ istat = GRend(gr_id);
+
+ istat =Vdetach(vgroupb_id);
+ /* Detach from the vgroup, close the V interface and the file. */
+ istat = Vdetach(vgroupa_id);
+ istat = Vdetach(vgroupc_id);
+ istat = Vdetach(vgroupd_id);
+ istat = Vdetach(vgroupe_id);
+ istat = Vend(file_id);
+
+ istat = Hclose(file_id);
+ return 0;
+}
+/* this routine creates annotation for four cases:
+
+1. file label
+2. file description
+3. object label(vgroup)
+4. object description(vgroup)
+
+*/
+
+int test_anno() {
+
+ int32 file_id, an_id, ann_id, vgroup_id,istat;
+ uint16 obj_tag, obj_ref;
+ static char file_label[] = "This is a file label.";
+ static char file_desc[] = "This is a file description.";
+ static char data_labelvg[] = "This is a vgroup data label.";
+ static char data_descvg[] = "This is a vgroup data description.";
+
+ /* Create the HDF file. */
+ file_id = Hopen(FILEANNO, DFACC_CREATE, 0);
+ if(file_id == FAIL) {
+ printf("fail to open HDF file \n");
+ return FAIL;
+ }
+ /* Initialize the AN interface and obtain an interface id. */
+ an_id = ANstart(file_id);
+ if(an_id == FAIL) {
+ printf("fail to start annotation interface.\n");
+ return FAIL;
+ }
+
+ /* Create a file label and obtain an annotation id. */
+ ann_id = ANcreatef(an_id, AN_FILE_LABEL);
+ if(ann_id == FAIL) {
+ printf("fail to create annotation id.\n");
+ return FAIL;
+ }
+
+ /* Write the file label to the file. */
+ istat = ANwriteann(ann_id, file_label, (int32)(strlen(file_label)));
+ if(istat == FAIL) {
+ printf("fail to write annotation.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+
+ /* Create a file description. */
+ ann_id = ANcreatef(an_id, AN_FILE_DESC);
+ if(ann_id == FAIL) {
+ printf("fail to create annotation\n");
+ return FAIL;
+ }
+
+ /* Write the file description to the file. */
+ istat = ANwriteann(ann_id, file_desc, (int32)(strlen(file_desc)));
+ if(istat == FAIL) {
+ printf("fail to write annotation.\n");
+ return FAIL;
+ }
+
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+
+ /* Create a vgroup. */
+ istat = Vstart(file_id);
+ if(istat == FAIL) {
+ printf("fail to start v interface.\n");
+ return FAIL;
+ }
+
+ vgroup_id = Vattach(file_id, -1, "w");
+ if(vgroup_id == FAIL) {
+ printf("fail to attach vgroup \n");
+ return FAIL;
+ }
+
+ istat = Vsetname (vgroup_id, "Vgroup w/Annotations");
+ if(istat == FAIL) {
+ printf("fail to set group name\n");
+ return FAIL;
+ }
+ /* Get reference number of vgroup just created. */
+ obj_ref = Vfind (file_id, "Vgroup w/Annotations");
+ if(obj_ref == 0) {
+ printf("fail to set object reference.\n");
+ return FAIL;
+ }
+ obj_tag = DFTAG_VG;
+
+ /* Create a data label for the Vgroup just created. */
+ ann_id = ANcreate(an_id, (uint16)obj_tag, (uint16)obj_ref, AN_DATA_LABEL);
+ if(ann_id == FAIL) {
+ printf("fail to create annotation.\n");
+ return FAIL;
+ }
+ /* Write the data label to the file. */
+ istat = ANwriteann(ann_id, data_labelvg, (int)(strlen(data_labelvg)));
+ if(istat == FAIL){
+ printf("fail to write annotation.\n");
+ return FAIL;
+ }
+ istat = ANendaccess(ann_id);
+
+ obj_tag = DFTAG_VG;
+
+ /* Create a data description for the Vgroup just created.*/
+ ann_id = ANcreate(an_id, (uint16)obj_tag, (uint16)obj_ref, AN_DATA_DESC);
+ if(ann_id == FAIL) {
+ printf("fail to create annotation.\n");
+ return FAIL;
+ }
+
+ /* Write the data description to the file. */
+ istat = ANwriteann(ann_id, data_descvg, (int)(strlen(data_descvg)));
+ if(istat == FAIL) {
+ printf("fail to write annotation.\n");
+ return FAIL;
+ }
+ /* Terminate access to the annotation. */
+ istat = ANendaccess(ann_id);
+ istat = Vdetach(vgroup_id);
+ istat = Vend(file_id);
+ /* Close the file. */
+
+ /* Terminate access to the AN interface. */
+ istat = ANend(an_id);
+ istat = Hclose(file_id);
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/tools/h4toh5/h4toh5util.c b/tools/h4toh5/h4toh5util.c
new file mode 100644
index 0000000..879e8a9
--- /dev/null
+++ b/tools/h4toh5/h4toh5util.c
@@ -0,0 +1,1633 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+including all routines that are useful for other files.
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+
+#include "h4toh5util.h"
+
+
+/* Function h4toh5_ZeroMemory
+ Purpose: Zero out memory
+ return: None
+ In: size_t n(DWORD in windows)
+ void* s(PVOID in windows)
+*/
+void h4toh5_ZeroMemory(void*s,size_t n) {
+#ifdef WIN32
+ ZeroMemory(s,n);
+#else
+ bzero(s,n);
+#endif
+}
+
+/*-------------------------------------------------------------------------
+ * Function: h5string_to_int
+ *
+ * Purpose: This function will convert H5T_STRING into integer.
+ This is a correction routine when 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;
+ break;
+
+ 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;
+ break;
+ }
+ 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 result 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 result 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 result 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 result 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 result 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 result 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. */
+
+
+ if(str_num == NULL) {
+ printf(" memory for str_num should be allocated.\n");
+ return FAIL;
+ }
+
+ /* Adding this line will cause problems, investigating this later.
+h4toh5_ZeroMemory(str_num,strlen(str_num)+1);*/
+
+ sprintf(str_num,"%d",num);
+ 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;
+ }
+
+ if(nametab == NULL) {
+ printf("no name_table for this category of objects.\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_t)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=(-1);
+ 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_SPACEPAD))<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_SPACEPAD))<0) {
+ fprintf(stderr,"error in making string for VGROUP ATTR. \n");
+ free(vg_adata);
+ return FAIL;
+ }
+
+
+ if ((sh5str_memtype = mkstr(count_vgattr*sh4_amemsize,
+ H5T_STR_SPACEPAD))<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) {
+ /* name_clashing is found. */
+ 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;
+ }
+ h4toh5_ZeroMemory(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;
+ }
+ h4toh5_ZeroMemory(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 for object name. \n");
+ return NULL;
+ }
+ h4toh5_ZeroMemory(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;
+ }
+ h4toh5_ZeroMemory(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;
+ }
+ h4toh5_ZeroMemory(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;
+ }
+ h4toh5_ZeroMemory(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];
+
+ /* the reason why we allocate memory with strlen(HDF4_PALETTE) is
+ HDF4_PALETTE is the longest string among HDF4_??? */
+ obj_name = malloc(strlen(HDF4_PALETTE)+strlen(ATTR)+8);
+ if(obj_name == NULL) {
+ printf("cannot allocate memory for object name. \n");
+ return NULL;
+ }
+
+ h4toh5_ZeroMemory(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);
+ h4toh5_ZeroMemory(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/h4toh5/h4toh5util.h b/tools/h4toh5/h4toh5util.h
new file mode 100644
index 0000000..7e3def7
--- /dev/null
+++ b/tools/h4toh5/h4toh5util.h
@@ -0,0 +1,232 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+Including declarations of global variables,global hashtables,constant
+and utility subroutines of h4toh5util.c
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+
+#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, since "/" is a reserved symbol for hdf5. */
+
+#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 "CLASS"
+#define HDF4_IMAGE_SUBCLASS "IMAGE_SUBCLASS"
+#define HDF4_PALETTE_CLASS "CLASS"
+#define HDF4_PALETTE_TYPE "PAL_TYPE"
+#define PAL_TYPE "STANDARD8"
+#define PAL_COLORMODEL "PAL_COLORMODEL"
+#define RGB "RGB"
+/* 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 GLO for sds and image file attributes. these file attributes
+ will be put under root group. */
+#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 "IMAGE" CLASS required by image spec. */
+#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
+/*considering the string size of HDF4_DIMGROUP. we add this into 276.*/
+#define MAX_DIM_NAME 276
+#define MAX_PAL_NAME 32
+/*11. adding a specified vdata class name to deal with the situation when
+independent vdata is hdf chunking table _HDF_CHK_TBL_CLASS, if it becomes
+public constant for hdf lib, this constant can be released.*/
+#define _HDF_CHK_TBL_CLASS "_HDF_CHK_TBL_"
+
+extern int32 estnum_vg;
+extern int32 estnum_vd;
+extern int32 num_sds;
+extern int32 num_images;
+extern int num_objects;
+extern int32 num_glsdsattrs;
+extern 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 uses object reference as the key to handle whether this
+ object is visited or not.
+ 2. struct name_table uses object 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;
+};
+
+extern struct table* sds_hashtab;
+extern struct table* gr_hashtab;
+extern struct table* vg_hashtab;
+extern struct table* vd_hashtab;
+extern struct table* pal_hashtab;
+extern struct name_table* name_hashtab;
+extern struct name_table* dim_hashtab;
+
+/* routine for zeroing out the memory. */
+void h4toh5_ZeroMemory(void*s,size_t n);
+
+/* 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 conversion 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*);
+
+/* these routines were utility functions for other routines at h4toh5util.c */
+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/h4toh5/h4toh5vdata.c b/tools/h4toh5/h4toh5vdata.c
new file mode 100644
index 0000000..55a8bf9
--- /dev/null
+++ b/tools/h4toh5/h4toh5vdata.c
@@ -0,0 +1,831 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+Converting an hdf4 independent vdata object into an hdf5 dataset of compound dataset.
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+#include "h4toh5main.h"
+#include <assert.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;
+
+ /* Zeroing out memory for vdlabel,vdata_class,vdata_name */
+
+ h4toh5_ZeroMemory(vdata_name,MAX_NC_NAME);
+ h4toh5_ZeroMemory(fieldname,MAX_NC_NAME);
+ h4toh5_ZeroMemory(vdata_class,VSNAMELENMAX);
+ h4toh5_ZeroMemory(field_name_list,VSFIELDMAX*FIELDNAMELENMAX);
+ h4toh5_ZeroMemory(vdlabel,10);
+
+ /* 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;
+ vdata_size = 0;
+ nfields = VFnfields(vdata_id);
+
+ if (nfields == FAIL) {
+ printf("error in obtaining number of vdata fields. \n");
+ return FAIL;
+ }
+
+ assert(nfields>0);
+ h5memtype = calloc((size_t)nfields,sizeof(hid_t));
+ h5type = calloc((size_t)nfields,sizeof(hid_t));
+ h4memsize = calloc((size_t)nfields,sizeof(size_t));
+ h4size = calloc((size_t)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];
+ vdata_size +=fieldorder*h4size[i];
+
+ }
+
+ vd_data = malloc((size_t)(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);
+
+ 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[0] != '\0') {
+ 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;
+
+ /* zeroing out memory for svdattr_name and refstr */
+ h4toh5_ZeroMemory(svdattr_name,2*MAX_NC_NAME);
+ h4toh5_ZeroMemory(refstr,MAXREF_LENGTH);
+
+ /* 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_SPACEPAD))<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_SPACEPAD))<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;
+ int32 fieldorder;
+ size_t fil_offset;
+ size_t mem_offset;
+ hsize_t fielddim[1];
+ hid_t h5str_type;
+ int check_ifstr;/* flag to check if the h5 type is string.*/
+ int i;
+
+
+ check_ifstr = 0;
+ fil_offset = 0;
+ mem_offset = 0;
+
+
+ for (i =0;i< nfields;i++) {
+
+ fieldname = NULL;
+ fieldorder = VFfieldorder(vdata_id,i);
+
+ if(fieldorder == FAIL){
+ printf("error in obtaining fieldorder.\n");
+ return FAIL;
+ }
+
+ fieldname = VFfieldname(vdata_id,i);
+ if(fieldname == NULL){
+ printf("fail to obtain Vdata field name. \n");
+ return FAIL;
+ }
+
+
+ /* when vdata is a character array, we will write the whole
+ array as one hdf5 type string. */
+
+ if(sh5type[i] == H5T_STRING) {
+
+ if ((h5str_type = mkstr(sh4size[i]*fieldorder,H5T_STR_SPACEPAD))<0) {
+ printf("error in making string of hdf5 string. \n");
+ return FAIL;
+ }
+ sh5type[i] = h5str_type;
+ check_ifstr = 1;
+ }
+
+ if (sh5memtype[i] == H5T_STRING) {
+
+ if((h5str_type = mkstr(sh4memsize[i]*fieldorder,H5T_STR_SPACEPAD))<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.
+ When the data type is H5T_STRING,
+ we will treat the the vdata as a HDF5 scalar type.*/
+
+ if (fielddim[0] == 1 || check_ifstr == 1) {
+
+ if(H5Tinsert(h5_ctype,fieldname,fil_offset,sh5type[i])<0) {
+ printf("error inserting hdf5 compound datatype while ");
+ printf("converting vdata.\n");
+ return FAIL;
+ }
+
+ 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 {
+ hid_t arr_type; /* Array datatype for inserting fields */
+
+ /* Create array datatype */
+ if((arr_type=H5Tarray_create(sh5type[i],1,fielddim,NULL))<0) {
+ printf("error creating array datatype.\n");
+ return FAIL;
+ }
+
+ if(H5Tinsert(h5_ctype,fieldname,fil_offset,arr_type)<0) {
+ printf("error inserting array into hdf5 compound datatype. \n");
+ return FAIL;
+ }
+
+ /* Close array datatype */
+ if(H5Tclose(arr_type)<0) {
+ printf("error closing array datatype.\n");
+ return FAIL;
+ }
+
+ /* Create array datatype */
+ if((arr_type=H5Tarray_create(sh5memtype[i],1,fielddim,NULL))<0) {
+ printf("error creating array datatype.\n");
+ return FAIL;
+ }
+
+ if(H5Tinsert(h5_cmemtype,fieldname,mem_offset,arr_type)<0) {
+ printf("error inserting array into hdf5 compound datatype for memory. \n");
+ return FAIL;
+ }
+
+ /* Close array datatype */
+ if(H5Tclose(arr_type)<0) {
+ printf("error closing array datatype.\n");
+ return FAIL;
+ }
+
+
+ }
+
+ if( check_ifstr == 1) {
+ fil_offset = fil_offset + sh4size[i]*fieldorder;
+ mem_offset = mem_offset + sh4memsize[i]*fieldorder;
+ check_ifstr = 0;
+ }
+ else {
+
+ fil_offset = fil_offset + sh4size[i]*fieldorder;
+ mem_offset = mem_offset + sh4memsize[i]*fieldorder;
+ }
+
+ }
+
+ return SUCCEED;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/h4toh5/h4toh5vgroup.c b/tools/h4toh5/h4toh5vgroup.c
new file mode 100644
index 0000000..92a6735
--- /dev/null
+++ b/tools/h4toh5/h4toh5vgroup.c
@@ -0,0 +1,812 @@
+
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/******************************************************************************
+
+ Description:
+
+1. converter
+
+See HDF4 to HDF5 mapping specification at
+(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
+from HDF4 object to HDF5 object.
+
+The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
+
+2. this file
+
+converting an hdf4 vgroup object into a hdf5 group.
+
+Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
+
+
+*****************************************************************************/
+
+
+#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[MAXREF_LENGTH];
+ char vgroup_class[VGNAMELENMAX];
+ char vgroup_name[VGNAMELENMAX];
+
+ char* h5pgroup_name;
+
+ int check_vgname;
+ hid_t h5_pgroup;
+
+ /*zeroing out memory for vgroup_class and vgroup_name */
+ h4toh5_ZeroMemory(vgroup_class,VGNAMELENMAX);
+ h4toh5_ZeroMemory(vgroup_name,VGNAMELENMAX);
+
+ 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[MAXREF_LENGTH];
+ 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, dependent vdata(attributes, etc.)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;
+ }
+ /*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[MAXREF_LENGTH];
+ 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;
+ }
+
+ if(conv_int_str(obj_ref,refstr)== FAIL) {
+ printf("error in converting reference number into string type.\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[MAXREF_LENGTH];
+ 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/h4toh5/testh4toh5.sh b/tools/h4toh5/testh4toh5.sh
new file mode 100755
index 0000000..c2a196e
--- /dev/null
+++ b/tools/h4toh5/testh4toh5.sh
@@ -0,0 +1,249 @@
+#!/bin/sh
+#
+# Copyright (C) 2001 National Center for Supercomputing Applications.
+# All rights reserved.
+#
+# Test script for the h4toh5 tests.
+# Using the h4toh5 convert to convert a pre-created hdf file to
+# an hdf5 file (output file), then compare it with a pre-created
+# corresponding hdf5 file (expected file).
+# If the same, that particular test passes.
+# If not the same, the output file and expected file are processed
+# by the h5dump tool to see if they produce the same results.
+# If the same, the test passes.
+# If not, show the difference of the two results and report the test failed.
+#
+# h5dump is default to use the one just built. It can be overridden
+# by setting $H5DUMP to a different value such as /usr/local/bin/h5dump.
+
+H4TOH5=h4toh5 # The tool name
+H4TOH5_BIN=`pwd`/$H4TOH5 # The path of the tool binary
+
+CMP='cmp -s'
+DIFF='diff -c'
+
+RM='rm -f'
+SED='sed '
+H5DUMP=${H5DUMP:-`pwd`/'../h5dump/h5dump'} # Default to use the h5dumper
+ # in the same tools directory
+
+# Verify if $H5DUMP is a valid command.
+tmpfile=/tmp/testh4toh5.$$
+$H5DUMP -V > $tmpfile
+if test -s "$tmpfile"; then
+ :
+else
+ 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 -z "$srcdir"; then
+ srcdir=.
+fi
+
+mkdir ../testfiles >/dev/null 2>&1
+
+SRCDIR="$srcdir/../testfiles"
+OUTDIR="../testfiles/Results"
+
+test -d "$OUTDIR" || mkdir $OUTDIR
+
+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 test "$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 test "$SRCDIR" != "$OUTDIR"; then
+ cp $SRCDIR/$1 $OUTDIR/$1
+ fi
+ INFILES="$1"
+ OUTFILES="`basename $1 .hdf`.h5"
+ ;;
+
+ 2) # hdf4 file specified
+ if test "$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_BIN $INFILES $OUTFILES 2>/dev/null
+ if test "$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 test -z "$HDF5_NOCLEANUP"; 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 anno_test.hdf anno_test.h5
+CONVERT gr_typ_test.hdf gr_typ_test.h5
+CONVERT grnameclash_test.hdf grnameclash_test.h5
+CONVERT image_attr_test.hdf image_attr_test.h5
+#CONVERT image_maxsize.hdf image_maxsize.h5
+CONVERT ras_24_test.hdf ras_24_test.h5
+CONVERT ras_8_test.hdf ras_8_test.h5
+CONVERT sds_attr_test.hdf sds_attr_test.h5
+CONVERT sds_dim_test.hdf sds_dim_test.h5
+CONVERT sds_typ_test.hdf sds_typ_test.h5
+CONVERT sdsnameclash_test.hdf sdsnameclash_test.h5
+CONVERT vdata_test.hdf vdata_test.h5
+CONVERT vdnameclash_test.hdf vdnameclash_test.h5
+CONVERT vg_hl_test.hdf vg_hl_test.h5
+CONVERT vg_loop_test.hdf vg_loop_test.h5
+CONVERT vgnameclash_test.hdf vgnameclash_test.h5
+CONVERT vg_all_test.hdf vg_all_test.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
+
+$RM -r $OUTDIR
+exit $nerrors