/*------------------------------------------------------------------------- * * 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" static int convert_zerosdsunlimit(int32 file_id, int32 sds_id, hid_t h5_group, hid_t h5_dimgroup, int h4_attr); /*------------------------------------------------------------------------- * 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,int h4_attr){ 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; int sds_empty; int32 istat; int i,j; 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; /* for checking compression */ sp_info_block_t info_block; int16 special_code; int32 access_id; uint16 sd_ref; int gzip_level; /* define variables 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; herr_t ret; /* define variables to handle transformation when the maximum memory buffer is set by users. */ int NUM_HSLAB_PERD; int32* h4slab_start; int32* h4slab_stride; int32* h4slab_stop; int32* h4slab_dims; int32* h4slab_edges; hsize_t* h5slab_offset; hsize_t* h5slab_count; int h4slab_count,h4slab_index; int32 slabsize; int32 count_slabdata; hid_t slabmemspace; /* if(memsize <=0) slabsize = -1;*/ if(MEMOPT != 0) slabsize = SLABSIZE*1000000; else slabsize = 0; 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. */ if(SDcheckempty(sds_id,&sds_empty)== FAIL) { printf("error in running SDcheckempty routine. \n"); return FAIL; } /*check whether the sds is created with unlimited dimension. */ /*obtain name,rank,dimsizes,datatype and num of attributes of sds */ if (SDgetinfo(sds_id,sdsname,&sds_rank,sds_dimsizes,&sds_dtype, &num_sdsattrs)==FAIL) { printf("unable to get information of sds h5dset.\n"); return FAIL; } if(sds_empty !=0) { if(sds_dimsizes[0]==0) { if(convert_zerosdsunlimit(file_id,sds_id,h5_group,h5_dimgroup,h4_attr)==FAIL){ printf("cannot convert unlimited dimension SDS with 0.\n"); return FAIL; } } else if(convert_sdsfillvalue(file_id,sds_id,h5_group,h5_dimgroup,h4_attr)==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. */ 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;i0 ) 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;isds_dimsizes[i]) h4slab_stop[i] = sds_dimsizes[i]; printf("h4slab_start[%d] %d\n",i,h4slab_start[i]); printf("h4slab_stop[%d] %d\n",i,h4slab_stop[i]); } count_slabdata = 1; for(i=0;i0 ) 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(chunk_dims); H5Sclose(h5d_sid); H5Pclose(create_plist); free(h5csds_name); return FAIL; } if(special_code >0){ if(HDget_special_info(access_id,&info_block)==FAIL){ printf("fail to get special info.\n"); free(chunk_dims); H5Sclose(h5d_sid); H5Pclose(create_plist); free(h5csds_name); 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