summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/h4toh5/h4toh5sds.c1140
1 files changed, 830 insertions, 310 deletions
diff --git a/tools/h4toh5/h4toh5sds.c b/tools/h4toh5/h4toh5sds.c
index 89e5ddf..b488f78 100644
--- a/tools/h4toh5/h4toh5sds.c
+++ b/tools/h4toh5/h4toh5sds.c
@@ -72,6 +72,13 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
hsize_t* chunk_dims;
int32 c_flags;
+ /* for checking compression */
+
+ sp_info_block_t info_block;
+ int16 special_code;
+ int32 access_id;
+ uint16 sd_ref;
+ int gzip_level;
/* define varibles for hdf5. */
hid_t h5dset;
@@ -79,39 +86,47 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
hid_t h5ty_id;
hid_t h5_memtype;
hid_t create_plist;
+ hid_t write_plist;
hsize_t h5dims[MAX_VAR_DIMS];
hsize_t max_h5dims[MAX_VAR_DIMS];
-
+ hsize_t bufsize;
char* h5csds_name;
-
herr_t ret;
+
+ special_code = -1;
/* 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. */
+ /* 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;
-
+ printf("error in running SDcheckempty routine. \n");
+ return FAIL;
+ }
/*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");
+ if (SDgetinfo(sds_id,sdsname,&sds_rank,sds_dimsizes,&sds_dtype,
+ &num_sdsattrs)==FAIL) {
+ printf("unable to get information of sds h5dset.\n");
+ return FAIL;
+ }
+ if(sds_empty !=0) {
+ if(convert_sdsfillvalue(file_id,sds_id,h5_group,h5_dimgroup)==FAIL) {
+ printf("cannot convert fill value successfully.\n");
return FAIL;
}
+ return SUCCEED;
+ }
+
+ if(SDgetchunkinfo(sds_id,&c_def_out, &c_flags)== FAIL) {
+ printf("error in getting chunking information. \n");
+ return FAIL;
+ }
+
/* obtain start,edge, stride and number of sds data. */
@@ -138,31 +153,31 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
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];
+ 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];
+ 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;
+ &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.*/
+ /* 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.*/
@@ -177,6 +192,7 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
}
sds_data = malloc(h4memsize*count_sdsdata);
+
if(sds_data == NULL) {
printf("error in allocating memory. \n");
free(sds_start);
@@ -188,12 +204,12 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
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;
+ 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
@@ -211,30 +227,30 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
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;
+ 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;
+ 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;
+ 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);
@@ -253,50 +269,143 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
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. */
+
+ sd_ref = get_SDref(file_id,DFTAG_NDG,sds_ref);
+ if(sd_ref == 0)
+ sd_ref = get_SDref(file_id,DFTAG_SDG,sds_ref);
+ if(sd_ref >0 )
+ access_id = Hstartread(file_id,DFTAG_SD,sd_ref);
+
+ if(sd_ref == 0)
+ access_id = FAIL;
+
+ if(access_id != FAIL) {
+ istat = Hinquire(access_id,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&special_code);
+ if(istat == FAIL) {
+ printf("failed to inquire information \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(special_code >0){
+
+ if(HDget_special_info(access_id,&info_block)==FAIL){
+ printf("fail to get special info.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+
+ /* free(info_block.cdims);*/
+ if(info_block.key == SPECIAL_COMP) {
+
+ if(c_flags == HDF_NONE){
+ /* 1. if the first dimension is unlimited dimension,
+ we have to provide a chunking size.
+ 2. the current HDF5 will not handle compression case itself,
+ in order that the converted HDF5 is compressed, we have to
+ provide a chunking size. currently it is set to h5dim[i].*/
+
+ for(i=0;i<sds_rank;i++){
+ chunk_dims[i] = (hsize_t)(h5dims[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;
+ }
+
+ printf("okay compressed \n");
+ if(H5Pset_deflate(create_plist,GZIP_COMLEVEL)<0){
+ /* if(H5Pset_deflate(create_plist,2)<0){*/
+ printf("fail to set compression method for HDF5 file.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ }
+ }
+
+ }
+ else if(c_flags == HDF_NONE && SDisrecord(sds_id))
+ {
+ for(i=0;i<sds_rank;i++){
+ chunk_dims[i] = (hsize_t)(sds_dimsizes[i]);
+ }
+ if(H5Pset_chunk(create_plist, sds_rank, chunk_dims)<0) {
+ printf("failed to set up chunking information for ");
+ printf("property list.\n");
+ free(chunk_dims);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+ }
- 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;
}
- }
+ }
+
+ /* HDF4 can support various compression methods including simple RLE, NBIT, Skip Huffman, gzip,Jpeg , HDF5 currently only supports gzip compression.
+ By default, we will compress HDF5 dataset by using gzip compression if HDF5 file is compressed. */
+
+
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;
- }
+ if(c_def_out.comp.comp_type == COMP_CODE_RLE || c_def_out.comp.comp_type == COMP_CODE_NBIT || c_def_out.comp.comp_type == COMP_CODE_SKPHUFF || c_def_out.comp.comp_type == COMP_CODE_DEFLATE || c_def_out.comp.comp_type == COMP_CODE_JPEG) {
+
+ 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;
+ }
+ if(c_def_out.comp.comp_type == COMP_CODE_DEFLATE)
+ gzip_level = c_def_out.comp.cinfo.deflate.level;
+ else gzip_level = GZIP_COMLEVEL;
+ if(H5Pset_deflate(create_plist,gzip_level)<0){
+ printf("fail to set compression method for HDF5 file.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(sds_data);
+ free(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ }
+ }
}
-
-
+
h5dset = H5Dcreate(h5_group,h5csds_name,h5ty_id,h5d_sid,create_plist);
if (h5dset < 0) {
@@ -310,8 +419,24 @@ int Sds_h4_to_h5(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
H5Pclose(create_plist);
return FAIL;
}
-
- if (H5Dwrite(h5dset,h5_memtype,h5d_sid,h5d_sid,H5P_DEFAULT,
+
+ write_plist = H5Pcreate(H5P_DATASET_XFER);
+ bufsize = h4memsize;
+ for(i=1;i<sds_rank;i++)
+ bufsize *= h5dims[i];
+ if(H5Pset_buffer(write_plist,bufsize,NULL,NULL)<0) {
+ printf("fail to create data transfer 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 (H5Dwrite(h5dset,h5_memtype,h5d_sid,h5d_sid,write_plist,
(void *)sds_data)<0) {
printf("failed to write data into hdf5 dataset");
printf(" converted from SDS.\n");
@@ -501,149 +626,149 @@ int sds_transattrs(int32 ssds_id, hid_t sh5_dset,int snum_sdsattrs,
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;
- }
+ 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. */
+ /* 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;
- }
+ 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;
- }
+ 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);
- }
+ /* 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.
+ /* 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) {
+ 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 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);
+ printf("failed to create space id. \n");
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);
+ }
+ 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;
}
-
- 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);
+ }
+ 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);
+ 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;
}
@@ -670,7 +795,7 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
int32 sdsdim_type = 0;
int32 sds_dimscasize[1];
int32 istat;
- int i;
+ int i,k;
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.*/
@@ -686,6 +811,7 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
HDF_CHUNK_DEF c_def_out;
int32 c_flags;
+ int32* sdsdimempty;
/* define varibles for hdf5. */
@@ -708,6 +834,7 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
hsize_t h5dimscas[1];
hsize_t max_h5dimscas[1];
hsize_t h5dim_dims[1];
+ hsize_t h5dimname_dims[1];
hsize_t attr_refDims[1];
hsize_t h5dim_chunkdim[1];
hobj_ref_t dim_refdat;
@@ -720,7 +847,11 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
char h5dimpath_name[MAX_DIM_NAME];
herr_t ret;
-
+ sdsdimempty = malloc(sds_rank *sizeof(int32));
+
+ for(i=0;i<sds_rank;i++)
+ sdsdimempty[i] = 0;
+
/*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));
@@ -740,7 +871,7 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
count_h5attrname = 0;
for (i = 0; i<sds_rank;i++) {
-
+
sdsdim_id = SDgetdimid(sds_id,i);
if(sdsdim_id == FAIL) {
@@ -756,7 +887,10 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
SDendaccess(sdsdim_id);
return FAIL;
}
-
+ if(sdsdim_type == 0) {
+ if(strncmp(sdsdim_name,fakeDim,strlen(fakeDim))==0)
+ continue;
+ }
/* for unlimited sds dimension, grab the current dimensional size. */
if(sds_dimscasize[0] == 0) sds_dimscasize[0] = firstdimsize;
@@ -790,7 +924,7 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
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
+ will not increase if this dimension doesnot
have dimensional scale data. That assures the object reference of sds is
correct. */
@@ -810,11 +944,11 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
return FAIL;
}
- /* if this sds dimension has no dimensional scale data. skip it.*/
- if(sdsdim_type == 0)
- continue;
-
-
+ if(sdsdim_type == 0) {
+ count_h5attrname = count_h5attrname + 1;
+ sdsdimempty[i] = 1;
+ continue;
+ }
/* get h5 dimensional scale data type. */
if(h4type_to_h5type(sdsdim_type,&h5dim_memtype,&h4dim_memsize,
&h4dim_size,&h5dim_tid)== FAIL) {
@@ -825,7 +959,7 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
}
/* dimensional scale dataset cannot be H5T_STRING data type.
- So transferring back to int8 */
+ So transferring back to int8 */
if (h5dim_tid == H5T_STRING) {
if(h5string_to_int(sdsdim_type,&h5dim_memtype,h4dim_memsize,
@@ -870,50 +1004,50 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
/* create property list, for chunked sds or unlimited dimension cases */
- create_plist = H5Pcreate(H5P_DATASET_CREATE);
+ 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(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(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(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) ){
+ 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;
- }
- }
+ 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,
@@ -966,61 +1100,66 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
/*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;
+ 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;
+ }
+ k =0;
+ for(i=0;i<count_h5objref;i++){
+ h4toh5_ZeroMemory(h5newsdsdim_name,MAX_DIM_NAME);
+ if(sdsdimempty[i])
+ k = k +1;
+ strcpy(h5newsdsdim_name,&h5sdsdim_allname[k*MAX_DIM_NAME]);
- }
-
- 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);
+ 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;
+ k = k +1;
+ }
+
+ 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);
+ H5Sclose(attr_refSpace);
+ H5Tclose(attr_refType);
+ H5Aclose(attribID);
+ free(alldim_refdat);
}
if(count_h5attrname!= 0) {
- h5dim_namesid = H5Screate_simple(1,h5dim_dims,NULL);
+ h5dimname_dims[0] = count_h5attrname;
+
+ h5dim_namesid = H5Screate_simple(1,h5dimname_dims,NULL);
if(h5dim_namesid <0) {
printf("error in creating sds dimensionlist space.\n");
@@ -1056,30 +1195,411 @@ int sdsdim_to_h5dataset(int32 sds_id,int32 sds_rank,hid_t sh5dset,
ret = H5Aclose(h5dim_nameaid);
}
+ free(sdsdimempty);
return SUCCEED;
}
+int convert_sdsfillvalue(int32 file_id,int32 sds_id,hid_t h5_group,hid_t h5_dimgroup){
+
+
+ int32 sds_dtype;
+ int32 sds_rank;
+ int32 sds_dimsizes[MAX_VAR_DIMS];
+ int32* sds_start;
+ int32* sds_edge;
+ int32* sds_stride;
+ int32 count_sdsdata;
+ int32 sds_ref;
+ int32 istat;
+ int i;
+ int32 num_sdsattrs;
+ void* fill_value;
+
+ 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;
+ hid_t write_plist;
+ hsize_t h5dims[MAX_VAR_DIMS];
+ hsize_t max_h5dims[MAX_VAR_DIMS];
+ hsize_t bufsize;
+ char* h5csds_name;
+
+ 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];
+ }
+
+ /* 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;
+ }
+ }
+ /* Since we know this SDS dataset fills with fill value, so currently
+ we will comment this out. */
+ /*
+ 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;
+ }
+ */
+ fill_value = malloc(h4memsize);
+ h4toh5_ZeroMemory(fill_value,h4memsize*sizeof(char));
+ if(num_sdsattrs != 0)
+ if(SDgetfillvalue(sds_id,fill_value)==FAIL)
+ printf("unable to get fill value, fill value will be set to zero \n");
+
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ return FAIL;
+ }
+
+ /* set creation property list. */
+ create_plist = H5Pcreate(H5P_DATASET_CREATE);
+ if(create_plist <0) {
+ printf("failed to create hdf5 creation list.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ return FAIL;
+ }
+
+ if(H5Pset_fill_value(create_plist,h5ty_id,fill_value)<0){
+ printf("failed to set property list fill value.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ 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);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+ /* Before HDF5 library make the optimzation of dealing with fill value
+ data, leave this alone. */
+ /* write_plist = H5Pcreate(H5P_DATASET_XFER);
+ bufsize = h4memsize;
+ for(i=1;i<sds_rank;i++)
+ bufsize *= h5dims[i];
+
+ if(H5Pset_buffer(write_plist,bufsize,NULL,NULL)<0) {
+ printf("fail to create data transfer property list.\n");
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ H5Sclose(h5d_sid);
+ H5Pclose(create_plist);
+ return FAIL;
+ }
+ if (H5Dwrite(h5dset,h5_memtype,h5d_sid,h5d_sid,write_plist,
+ (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);
+ H5Pclose(write_plist);
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ 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);
+
+ 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);
+
+ 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);
+
+ 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(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(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(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(chunk_dims);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ printf("unable to transfer sds ref. to HDF5 dataset attribute.\n");
+ return FAIL;
+ }
+
+ free(sds_start);
+ free(sds_edge);
+ free(sds_stride);
+ free(fill_value);
+ H5Sclose(h5d_sid);
+ H5Dclose(h5dset);
+ H5Pclose(create_plist);
+ return SUCCEED;
+}
+
+
+uint16 get_SDref(int32 file_id,uint16 tag,int32 sds_ref){
+
+ DFdi di;
+ int32 found,GroupID;
+ int sd_ref = 0;
+
+
+ if((GroupID = DFdiread(file_id,tag,(uint16)sds_ref))<0){
+ printf("cannot find sd_ref\n");
+ return sd_ref;
+ }
+
+ found = 0;
+ di.tag = DFTAG_NULL;
+ di.ref = 0;
+ while((found == 0) &&(DFdiget(GroupID,&di.tag,&di.ref)==0)){
+ if(di.tag == DFTAG_SD)
+ found = 1;
+ }
+
+ sd_ref = di.ref;
+ if(!found)
+ printf("cannot find sd_ref\n");
+
+ DFdifree(GroupID);
+ return sd_ref;
+}