/*------------------------------------------------------------------------- * * 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 /*------------------------------------------------------------------------- * 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=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; }