/*-------------------------------------------------------------------------
*
* 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;
int h4_attr = 1;
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;
}
}
/* check whether the flag for HDF4 attributes is set.*/
{ int i;
for (i=0; i < argc; i++){
if ( HDstrcmp(argv[i],"-na") == 0 ) {
h4_attr = 0;
break;
}
}
}
switch(argc) {
case 0:
PrintOptions_h4toh5();
break;
case 1: /* two cases:
1. h4toh5 file1 without HDF4 specified attributes
this is the option where h4toh5 -na appears.
nothing is done.
2. h4toh5 file1 including HDF4 specified attributes.
this is the default behavior.
*/
if(HDstrcmp(argv[0],"-na")==0){
PrintOptions_h4toh5();
break;
}
if(gen_h4toh5(argv[0],NULL,h4_attr)<0){
status = -1;
return status;
}
break;
case 2: /* h4toh5 file_in file_out with HDF4 predefined attributes
h4toh5 file_in file_in.h5 without HDF4 predefined attributes*/
if(h4_attr !=0){
h4_filename = argv[0];
h5_filename = argv[1];
status = gen_h4toh5(h4_filename,h5_filename,h4_attr);
}
else
status = gen_h4toh5(argv[1],NULL,h4_attr);
if(status <0) return status;
break;
case 3:/* h4toh5 file_in file_out without HDF4 predefined attributes.*/
if(h4_attr==0){
h4_filename = argv[1];
h5_filename = argv[2];
status = gen_h4toh5(h4_filename,h5_filename,h4_attr);
if(status <0) return status;
}
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,int h4_attr) {
/* 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,h4_attr)== 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,h4_attr) == 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
|