/****************************************************************************
* NCSA HDF *
* Software Development Group *
* National Center for Supercomputing Applications *
* University of Illinois at Urbana-Champaign *
* 605 E. Springfield, Champaign IL 61820 *
* *
* For conditions of distribution and use, see the accompanying *
* hdf/COPYING file. *
* *
****************************************************************************/
#include <assert.h>
#include "hdf.h"
#include "mfhdf.h"
#include "hdiff_list.h"
static
int is_reserved(char*vgroup_class);
static
char *get_path(char*path_name, char*obj_name);
static
int insert_an_data(int32 file_id,
int32 ref_in,
int32 tag_in,
ann_type type,
char *path);
/*-------------------------------------------------------------------------
* Function: Hgetlist
*
* Purpose: locate all HDF objects in the file and return a list of them
*
* Return: number of objects in the file, ok, -1 not ok
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 21, 2003
*
* Description:
*
* A main loop is used to locate all the objects in the file. This loop preserves the
* hierarchy of the file. The algorithm used is
* 1) Obtain the number of lone VGroups in the HDF file.
* 2) Do a loop for each one of these groups. In each iteration a table is updated
* with the tag/reference pair of an object.
* 2.1) Obtain the pairs of tag/references for the group
* 2.2) Switch between the tag of the current object. Four cases are possible:
* 1) Object is a group: recursively repeat the process (obtain the pairs of
* tag/references for this group and do another tag switch).
* Add the object to the table.
* 2) Object is a dataset: Add the object to the table.
* 3) Object is an image: Add the object to the table.
* 4) Object is a vdata: Add the object to the table.
* 3) Read all the HDF interfaces (SDS, GR and VS), checking for objects that are
* already in the table (meaning they belong to a previous inspected group,
* and should not be added). These objects belong to a root group.
* 4) Read all global attributes and annotations.
*
*-------------------------------------------------------------------------
*/
int Hgetlist (const char* fname, dtable_t *table)
{
int32 file_id,
sd_id,
gr_id;
int n_objs=0;
/* open the file for read */
if ((file_id = Hopen (fname,DFACC_READ,(int16)0))==FAIL)
{
printf("Cannot open file <%s>\n",fname);
return FAIL;
}
/* initialize the SD interface */
if ((sd_id = SDstart (fname, DFACC_READ))==FAIL){
printf( "Could not start SD for <%s>\n",fname);
return FAIL;
}
/* initialize the GR interface */
if ((gr_id = GRstart (file_id))==FAIL){
printf( "Could not start GR for <%s>\n",fname);
return FAIL;
}
/* iterate tru HDF interfaces */
hdiff_list_vg (fname,file_id,sd_id,gr_id,table);
hdiff_list_gr (fname,file_id,gr_id,table);
hdiff_list_sds(fname,file_id,sd_id,table);
hdiff_list_vs (fname,file_id,table);
hdiff_list_glb(fname,file_id,sd_id,gr_id,table);
hdiff_list_an (fname,file_id,table);
/* close */
if (GRend (gr_id)==FAIL) {
printf( "Failed to close GR interface <%s>\n", fname);
return FAIL;
}
if (SDend (sd_id)==FAIL) {
printf( "Failed to close SD interface <%s>\n", fname);
return FAIL;
}
if (Hclose (file_id) == FAIL ) {
printf( "Failed to close file <%s>\n", fname);
return FAIL;
}
n_objs=table->nobjs;
return n_objs;
}
/*-------------------------------------------------------------------------
* Function: hdiff_list_vg
*
* Purpose: locate all lone Vgroups in the file
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int hdiff_list_vg(const char* fname,
int32 file_id,
int32 sd_id, /* SD interface identifier */
int32 gr_id, /* GR interface identifier */
dtable_t *table)
{
int32 vgroup_id, /* vgroup identifier */
nlones = 0, /* number of lone vgroups */
ntagrefs, /* number of tag/ref pairs in a vgroup */
*ref_array=NULL,/* buffer to hold the ref numbers of lone vgroups */
*tags, /* buffer to hold the tag numbers of vgroups */
*refs, /* buffer to hold the ref numbers of vgroups */
tag_vg,
ref_vg;
char vgroup_name[VGNAMELENMAX], vgroup_class[VGNAMELENMAX];
int i;
/* initialize the V interface */
if (Vstart (file_id)==FAIL) {
printf("Error: Could not start group interface in <%s>\n", fname);
return FAIL;
}
/*
* get the names and class names of all the lone vgroups.
* first, call Vlone with nlones set to 0 to get the number of
* lone vgroups in the file, but not to get their reference numbers.
*/
nlones = Vlone (file_id, NULL, nlones );
if (nlones > 0)
{
/*
* use the nlones returned to allocate sufficient space for the
* buffer ref_array to hold the reference numbers of all lone vgroups,
*/
ref_array = (int32 *) malloc(sizeof(int32) * nlones);
/*
* and call Vlone again to retrieve the reference numbers into
* the buffer ref_array.
*/
nlones = Vlone (file_id, ref_array, nlones);
/*
* iterate tru each lone vgroup.
*/
for (i = 0; i < nlones; i++)
{
/*
* attach to the current vgroup then get its
* name and class. note: the current vgroup must be detached before
* moving to the next.
*/
if ((vgroup_id = Vattach (file_id, ref_array[i], "r"))==FAIL){
printf("Error: Could not attach group with ref <%d>\n", ref_array[i]);
}
if (Vgetname (vgroup_id, vgroup_name)==FAIL){
printf("Error: Could not get name for group with ref <%d>\n", ref_array[i]);
}
if (Vgetclass (vgroup_id, vgroup_class)==FAIL){
printf("Error: Could not get class for group with ref <%d>\n", ref_array[i]);
}
/* ignore reserved HDF groups/vdatas */
if( is_reserved(vgroup_class)){
if (Vdetach (vgroup_id)==FAIL){
printf("Error: Could not detach group <%s>\n", vgroup_class);
}
continue;
}
if(vgroup_name != NULL)
if(strcmp(vgroup_name,GR_NAME)==0) {
if (Vdetach (vgroup_id)==FAIL){
printf("Error: Could not detach group <%s>\n", vgroup_class);
}
continue;
}
if ((ref_vg = VQueryref(vgroup_id))==FAIL){
printf( "Failed to get ref for <%s>\n", vgroup_name);
}
if ((tag_vg = VQuerytag(vgroup_id))==FAIL){
printf( "Failed to get tag for <%s>\n", vgroup_name);
}
/* add object to table */
dtable_add(table,tag_vg,ref_vg,vgroup_name);
#if defined (HDIFF_DEBUG)
printf("%s\n",vgroup_name);
#endif
insert_vg_attrs(vgroup_id,vgroup_name);
insert_vg_an(file_id,vgroup_id,vgroup_name);
/* insert objects for this group */
ntagrefs = Vntagrefs(vgroup_id);
if ( ntagrefs > 0 )
{
tags = (int32 *) malloc(sizeof(int32) * ntagrefs);
refs = (int32 *) malloc(sizeof(int32) * ntagrefs);
Vgettagrefs(vgroup_id, tags, refs, ntagrefs);
insert_vg(fname,file_id,sd_id,gr_id,vgroup_name,tags,refs,ntagrefs,table);
if (tags ) free (tags);
if (refs) free (refs);
}
if(Vdetach (vgroup_id)==FAIL){
printf("Error: Could not detach group <%s>\n", vgroup_name);
}
} /* for */
/* free the space allocated */
if (ref_array)
free (ref_array);
} /* if */
/* terminate access to the V interface */
if (Vend (file_id)==FAIL) {
printf("Error: Could not end group interface in <%s>\n", vgroup_name);
}
return 0;
}
/*-------------------------------------------------------------------------
* Function: insert_vg
*
* Purpose: recursive function to locate objects in lone Vgroups
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int insert_vg(const char* fname,
int32 file_id,
int32 sd_id, /* SD interface identifier */
int32 gr_id, /* GR interface identifier */
char*path_name, /* absolute path for input group name */
int32* in_tags, /* tag list for parent group */
int32* in_refs, /* ref list for parent group */
int npairs, /* number tag/ref pairs for parent group */
dtable_t *table)
{
int32 vgroup_id, /* vgroup identifier */
ntagrefs, /* number of tag/ref pairs in a vgroup */
tag, /* temporary tag */
ref, /* temporary ref */
*tags, /* buffer to hold the tag numbers of vgroups */
*refs; /* buffer to hold the ref numbers of vgroups */
char vgroup_name[VGNAMELENMAX], vgroup_class[VGNAMELENMAX];
char *path=NULL;
int i;
for ( i = 0; i < npairs; i++ )
{
tag = in_tags[i];
ref = in_refs[i];
switch(tag)
{
/*-------------------------------------------------------------------------
* VG
*-------------------------------------------------------------------------
*/
case DFTAG_VG:
vgroup_id = Vattach (file_id, ref, "r");
Vgetname (vgroup_id, vgroup_name);
Vgetclass (vgroup_id, vgroup_class);
/* ignore reserved HDF groups/vdatas */
if( is_reserved(vgroup_class)){
Vdetach (vgroup_id);
break;
}
if(vgroup_name != NULL)
if(strcmp(vgroup_name,GR_NAME)==0) {
Vdetach (vgroup_id);
break;
}
/* initialize path */
path=get_path(path_name,vgroup_name);
/* add object to table */
dtable_add(table,tag,ref,path);
#if defined (HDIFF_DEBUG)
printf("%s\n",path);
#endif
insert_vg_attrs(vgroup_id,path);
insert_vg_an(file_id,vgroup_id,path);
/* get objects for this group */
ntagrefs = Vntagrefs(vgroup_id);
if ( ntagrefs > 0 )
{
tags = (int32 *) malloc(sizeof(int32) * ntagrefs);
refs = (int32 *) malloc(sizeof(int32) * ntagrefs);
Vgettagrefs(vgroup_id, tags, refs, ntagrefs);
/* recurse */
insert_vg(fname,file_id,sd_id,gr_id,path,tags,refs,ntagrefs,table);
free (tags);
free (refs);
}
if(Vdetach (vgroup_id)==FAIL){
printf("Error: Could not detach group <%s>\n", vgroup_name);
}
if (path)
free(path);
break;
/*-------------------------------------------------------------------------
* SDS
*-------------------------------------------------------------------------
*/
case DFTAG_SD: /* Scientific Data */
case DFTAG_SDG: /* Scientific Data Group */
case DFTAG_NDG: /* Numeric Data Group */
insert_sds(file_id,sd_id,tag,ref,path_name,table);
break;
/*-------------------------------------------------------------------------
* Image
*-------------------------------------------------------------------------
*/
case DFTAG_RI: /* Raster Image */
case DFTAG_CI: /* Compressed Image */
case DFTAG_RIG: /* Raster Image Group */
case DFTAG_RI8: /* Raster-8 image */
case DFTAG_CI8: /* RLE compressed 8-bit image */
case DFTAG_II8: /* IMCOMP compressed 8-bit image */
insert_gr(file_id,gr_id,tag,ref,path_name,table);
break;
/*-------------------------------------------------------------------------
* Vdata
*-------------------------------------------------------------------------
*/
case DFTAG_VH: /* Vdata Header */
insert_vs(file_id,tag,ref,path_name,table,0);
break;
}
}
return 0;
}
/*-------------------------------------------------------------------------
* Function: hdiff_list_gr
*
* Purpose: get top level GR images
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int hdiff_list_gr(const char* fname,
int32 file_id,
int32 gr_id, /* GR interface identifier */
dtable_t *table)
{
int32 ri_id, /* raster image identifier */
n_rimages, /* number of raster images in the file */
n_file_attrs, /* number of file attributes */
ri_index, /* index of a image */
gr_ref, /* reference number of the GR image */
dim_sizes[2], /* dimensions of an image */
n_comps, /* number of components an image contains */
interlace_mode, /* interlace mode of an image */
data_type, /* number type of an image */
n_attrs; /* number of attributes belong to an image */
char name[MAX_GR_NAME]; /* name of an image */
/* determine the contents of the file */
if (GRfileinfo (gr_id, &n_rimages, &n_file_attrs)<0)
{
return -1;
}
for (ri_index = 0; ri_index < n_rimages; ri_index++)
{
ri_id = GRselect (gr_id, ri_index);
GRgetiminfo (ri_id, name, &n_comps, &data_type, &interlace_mode,
dim_sizes, &n_attrs);
gr_ref = GRidtoref(ri_id);
/* check if already inserted in Vgroup; search all image tags */
if ( dtable_search(table,DFTAG_RI,gr_ref)>=0 ||
dtable_search(table,DFTAG_CI,gr_ref)>=0 ||
dtable_search(table,DFTAG_RIG,gr_ref)>=0 ||
dtable_search(table,DFTAG_RI8,gr_ref)>=0 ||
dtable_search(table,DFTAG_CI8,gr_ref)>=0 ||
dtable_search(table,DFTAG_II8,gr_ref)>=0 )
{
GRendaccess (ri_id);
continue;
}
/* insert GR */
insert_gr(file_id,gr_id,DFTAG_RI,gr_ref,0,table);
/* terminate access to the current raster image */
GRendaccess (ri_id);
}
return 0;
}
/*-------------------------------------------------------------------------
* Function: hdiff_list_sds
*
* Purpose: get top level SDS
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int hdiff_list_sds(const char* fname,
int32 file_id,
int32 sd_id, /* SD interface identifier */
dtable_t *table)
{
int32 sds_id, /* dataset identifier */
n_datasets, /* number of datasets in the file */
n_file_attrs, /* number of file attributes */
index, /* index of a dataset */
sds_ref, /* reference number */
dim_sizes[MAX_VAR_DIMS],/* dimensions of an image */
data_type, /* number type */
rank, /* rank */
n_attrs; /* number of attributes */
char name[MAX_GR_NAME]; /* name of dataset */
/* determine the number of data sets in the file and the number of file attributes */
if (SDfileinfo (sd_id, &n_datasets, &n_file_attrs)<0)
{
return -1;
}
for (index = 0; index < n_datasets; index++)
{
sds_id = SDselect (sd_id, index);
SDgetinfo(sds_id, name, &rank, dim_sizes, &data_type, &n_attrs);
sds_ref = SDidtoref(sds_id);
/* check if already inserted in Vgroup; search all SDS tags */
if ( dtable_search(table,DFTAG_SD,sds_ref)>=0 ||
dtable_search(table,DFTAG_SDG,sds_ref)>=0 ||
dtable_search(table,DFTAG_NDG,sds_ref)>=0 )
{
SDendaccess (sds_id);
continue;
}
/* insert SDS */
insert_sds(file_id,sd_id,DFTAG_NDG,sds_ref,0,table);
/* terminate access to the current dataset */
SDendaccess (sds_id);
}
return 0;
}
/*-------------------------------------------------------------------------
* Function: hdiff_list_vs
*
* Purpose: get top level VS
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int hdiff_list_vs(const char* fname,
int32 file_id,
dtable_t *table)
{
int32 nlones = 0, /* number of lone vdatas */
*ref_array, /* buffer to hold the ref numbers of lone vdatas */
ref; /* temporary ref number */
int i;
/* initialize the VS interface */
Vstart (file_id);
/*
* get and print the names and class names of all the lone vdatas.
* first, call Vlone with nlones set to 0 to get the number of
* lone vdatas in the file, but not to get their reference numbers.
*/
nlones = VSlone (file_id, NULL, nlones );
if (nlones > 0)
{
/*
* use the nlones returned to allocate sufficient space for the
* buffer ref_array to hold the reference numbers of all lone vgroups,
*/
ref_array = (int32 *) malloc(sizeof(int32) * nlones);
/*
* and call VSlone again to retrieve the reference numbers into
* the buffer ref_array.
*/
nlones = VSlone (file_id, ref_array, nlones);
/*
* iterate tru each lone vdata.
*/
for (i = 0; i < nlones; i++)
{
/*
* attach to the current vdata then get its
* name and class. note: the current vdata must be detached before
* moving to the next.
*/
ref = ref_array[i];
/* check if already inserted in Vgroup*/
if ( dtable_search(table,DFTAG_VH,ref)>=0 ) {
continue;
}
/* insert VS */
insert_vs(file_id,DFTAG_VH,ref,0,table,1);
} /* for */
/* free the space allocated */
if (ref_array) free (ref_array);
} /* if */
/* terminate access to the VS interface */
Vend (file_id);
return 0;
}
/*-------------------------------------------------------------------------
* Function: insert_vg_attrs
*
* Purpose: insert VG attributes
*
* Return: 1
*
*-------------------------------------------------------------------------
*/
int insert_vg_attrs(int32 vg_in,char *path)
{
int n_attrs;
int32 data_type, size, n_values;
char attr_name[MAX_NC_NAME];
int i;
/* Get the number of attributes attached to this vgroup. */
if((n_attrs = Vnattrs (vg_in))==FAIL) {
printf( "Failed to get attributes for <%s>\n", path);
return-1;
}
for (i = 0; i < n_attrs; i++)
{
if((Vattrinfo (vg_in, i, attr_name, &data_type, &n_values, &size))==FAIL) {
printf( "Failed to get attribute %d of <%s>\n", i, path);
continue;
}
}
return 1;
}
/*-------------------------------------------------------------------------
* Function: hdiff_list_glb
*
* Purpose: list/insert global SDS attributes, global GR atrributes
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int hdiff_list_glb(const char* fname,
int32 file_id,
int32 sd_id, /* SD interface identifier */
int32 gr_id, /* GR interface identifier */
dtable_t *table)
{
int32 n_datasets, /* number of datasets in the file */
n_file_attrs; /* number of file attributes */
/*-------------------------------------------------------------------------
* insert SDS global attributes
*-------------------------------------------------------------------------
*/
/* determine the number of data sets in the file and the number of file attributes */
SDfileinfo (sd_id, &n_datasets, &n_file_attrs);
insert_sds_attrs(sd_id,n_file_attrs);
/*-------------------------------------------------------------------------
* insert GR global attributes
*-------------------------------------------------------------------------
*/
/* determine the number of data sets in the file and the number of file attributes */
GRfileinfo (gr_id, &n_datasets, &n_file_attrs);
insert_gr_attrs(gr_id,n_file_attrs);
return 0;
}
/*-------------------------------------------------------------------------
* Function: hdiff_list_an
*
* Purpose: list/insert AN FILE objects
*
* Return: void
*
*-------------------------------------------------------------------------
*/
int hdiff_list_an(const char* fname,
int32 file_id,
dtable_t *table)
{
int32 an_id, /* AN interface identifier */
ann_id, /* an annotation identifier */
i, /* position of an annotation in all of the same type*/
n_file_labels, n_file_descs, n_data_labels, n_data_descs;
/* Initialize the AN interface */
an_id = ANstart (file_id);
/*
* Get the annotation information, e.g., the numbers of file labels, file
* descriptions, data labels, and data descriptions.
*/
ANfileinfo (an_id, &n_file_labels, &n_file_descs, &n_data_labels,
&n_data_descs);
/*-------------------------------------------------------------------------
* AN_FILE_LABEL
*-------------------------------------------------------------------------
*/
for (i = 0; i < n_file_labels; i++)
{
/* Get the identifier of the current data label */
ann_id = ANselect (an_id, i, AN_FILE_LABEL);
/* Terminate access to the current data label */
ANendaccess (ann_id);
}
/*-------------------------------------------------------------------------
* AN_FILE_DESC
*-------------------------------------------------------------------------
*/
for (i = 0; i < n_file_descs; i++)
{
/* Get the identifier of the current data label */
ann_id = ANselect (an_id, i, AN_FILE_DESC);
/* Terminate access to the current data label */
ANendaccess (ann_id);
}
/* Terminate access to the AN interface */
ANend (an_id);
return 0;
}
/*-------------------------------------------------------------------------
* Function: insert_vg_an
*
* Purpose: insert Vgroup ANs
*
* Return: ok, 1, -1 not ok
*
*-------------------------------------------------------------------------
*/
int insert_vg_an(int32 file_id,
int32 vgroup_id,
char *path)
{
int32 ref_in,
tag_in;
if ((ref_in = VQueryref(vgroup_id))==FAIL){
printf( "Failed to get ref for <%s>\n", path);
return-1;
}
if ((tag_in = VQuerytag(vgroup_id))==FAIL){
printf( "Failed to get tag for <%s>\n", path);
return-1;
}
insert_an(file_id,ref_in,tag_in,path);
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_vs_an
*
* Purpose: insert Vdata ANs
*
* Return: ok, 1, -1 not ok
*
*-------------------------------------------------------------------------
*/
int insert_vs_an(int32 file_id,
int32 vdata_id,
char *path)
{
int32 ref_in,
tag_in;
if ((ref_in = VSQueryref(vdata_id))==FAIL){
printf( "Failed to get ref for <%s>\n", path);
return-1;
}
if ((tag_in = VSQuerytag(vdata_id))==FAIL){
printf( "Failed to get tag for <%s>\n", path);
return-1;
}
insert_an(file_id,ref_in,tag_in,path);
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_an_data
*
* Purpose: insert DATA ANs
*
* Return: ok, 1, -1 not ok
*
*-------------------------------------------------------------------------
*/
static
int insert_an_data(int32 file_id,
int32 ref_in,
int32 tag_in,
ann_type type,
char *path)
{
int32 an_id, /* AN interface identifier */
ann_id, /* an annotation identifier */
i, /* position of an annotation */
n_anno;
/* Initialize the AN interface */
an_id = ANstart (file_id);
/* Get the number of ANs in this object */
if((n_anno = ANnumann(an_id,type,(uint16)tag_in,(uint16)ref_in))==FAIL) {
printf( "Failed to get annotations for <%s>\n", path);
return-1;
}
for (i = 0; i < n_anno; i++)
{
if((ann_id = ANselect(an_id,i,type))==FAIL) {
printf( "Failed to select AN %d of <%s>\n", i, path);
continue;
}
if(ANendaccess(ann_id)==FAIL){
printf( "Failed to end AN %d of <%s>\n", i, path);
continue;
}
}
/* Terminate access to the AN interface */
ANend (an_id);
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_an
*
* Purpose: insert DATA ANs (AN_DATA_LABEL and AN_DATA_DESC)
*
* Return: ok, 1, -1 not ok
*
*-------------------------------------------------------------------------
*/
int insert_an(int32 file_id,
int32 ref_in,
int32 tag_in,
char *path)
{
insert_an_data(file_id,ref_in,tag_in,
AN_DATA_LABEL,path);
insert_an_data(file_id,ref_in,tag_in,
AN_DATA_DESC,path);
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_sds
*
* Purpose: insert an SDS into file object list
*
* Return: 0, -1 for error
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
int insert_sds(int32 file_id,
int32 sd_id,
int32 tag, /* tag of input SDS */
int32 ref, /* ref of input SDS */
char *path_name, /* absolute path for input group name */
dtable_t *table)
{
int32 sds_id, /* data set identifier */
sds_index, /* index number of the data set */
dtype, /* SDS data type */
dimsizes[MAX_VAR_DIMS],/* dimensional size of SDS */
nattrs, /* number of SDS attributes */
rank, /* rank of SDS */
dim_size, /* dimension size */
dim_id; /* dimension ID */
char sds_name[MAX_NC_NAME];
char dim_name[MAX_NC_NAME];
char *path=NULL;
int i;
sds_index = SDreftoindex(sd_id,ref);
sds_id = SDselect(sd_id,sds_index);
/*obtain name,rank,dimsizes,datatype and num of attributes of sds */
SDgetinfo(sds_id,sds_name,&rank,dimsizes,&dtype,&nattrs);
/* check if the given SDS is a dimension scale, return 0 for no table add */
if ( SDiscoordvar(sds_id) ) {
SDendaccess(sds_id);
return 0;
}
/* initialize path */
path=get_path(path_name,sds_name);
/* add object to table */
dtable_add(table,tag,ref,path);
#if defined (HDIFF_DEBUG)
printf("%s\n",path);
#endif
/*-------------------------------------------------------------------------
* insert attributes
*-------------------------------------------------------------------------
*/
insert_sds_attrs(sds_id,nattrs);
/*-------------------------------------------------------------------------
* dimension scales
*-------------------------------------------------------------------------
*/
/* loop through each dimension up to rank of SDS */
for (i = 0; i < rank; i++)
{
/* get dimension handle for input dimension */
if ((dim_id = SDgetdimid(sds_id, i)) == FAIL) {
printf( "Failed to get dimension %d of SDS <%s>\n", i, path);
continue;
}
/* get dimension information for input dimension */
if (SDdiminfo(dim_id, dim_name, &dim_size, &dtype, &nattrs) == FAIL) {
printf( "Failed to get info for dimension %d of SDS <%s>\n", i, path);
continue;
}
/* attributes */
if (nattrs && insert_sds_attrs(dim_id, nattrs) == FAIL) {
printf( "Failed to copy attributes for dimension %d of of SDS <%s>\n", i, path);
continue;
}
}
/*-------------------------------------------------------------------------
* insert ANs
*-------------------------------------------------------------------------
*/
insert_an(file_id,ref,tag,path);
/*-------------------------------------------------------------------------
* terminate access to the SDSs
*-------------------------------------------------------------------------
*/
SDendaccess(sds_id);
if (path)
free(path);
return 0;
}
/*-------------------------------------------------------------------------
* Function: insert_sds_attrs
*
* Purpose: insert SDS attributes
* used for global, dataset and dimension attributes
*
* Return: 1, for success
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
int insert_sds_attrs(int32 id_in,int32 nattrs)
{
int32 dtype, /* SDS data type */
nelms; /* number of elements */
char attr_name[MAX_NC_NAME];
int i;
/* loop through attributes in input SDS */
for (i = 0; i < nattrs; i++)
{
if (SDattrinfo (id_in, i, attr_name, &dtype, &nelms) == FAIL) {
printf( "Cannot get info for attribute number %d\n", i);
continue;
}
}
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_gr_attrs
*
* Purpose: insert GR attributes
*
* Return: 1, for success
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
int insert_gr_attrs(int32 ri_id,int32 nattrs)
{
int32 dtype, /* SDS data type */
nelms; /* number of elements */
char attr_name[MAX_NC_NAME];
int i;
/* loop through attributes in input GR */
for (i = 0; i < nattrs; i++)
{
if (GRattrinfo (ri_id, i, attr_name, &dtype, &nelms) == FAIL) {
printf( "Cannot get info for attribute number %d\n", i);
continue;
}
}
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_vs_attrs
*
* Purpose: insert VS attributes
*
* Return: 1, for success, -1 for error
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
int insert_vs_attrs(int32 in, int32 findex, intn attrindex)
{
char attr_name[MAX_NC_NAME];
int32 n_values, attr_size, attr_type;
/* Get attribute information */
VSattrinfo(in, findex, attrindex, attr_name, &attr_type, &n_values, &attr_size);
return 1;
}
/*-------------------------------------------------------------------------
* Function: insert_gr
*
* Purpose: insert a GR
*
* Return: 1
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
int insert_gr(int32 file_id,
int32 gr_in,
int32 tag, /* tag of input GR */
int32 ref, /* ref of input GR */
char*path_name, /* absolute path for input group name */
dtable_t *table)
{
int32 ri_id, /* raster image identifier */
ri_index, /* index of a image */
dimsizes[2], /* dimensions of an image */
n_comps, /* number of components an image contains */
interlace_mode,/* interlace mode of an image */
dtype, /* number type of an image */
n_attrs; /* number of attributes belong to an image */
int32 pal_id, /* palette identifier */
r_num_entries,
r_data_type,
r_ncomp,
r_interlace_mode;
char gr_name[MAX_GR_NAME];
char *path=NULL;
int has_pal = 0;
ri_index = GRreftoindex(gr_in,(uint16)ref);
ri_id = GRselect(gr_in,ri_index);
GRgetiminfo(ri_id,gr_name,&n_comps,&dtype,&interlace_mode,dimsizes,&n_attrs);
/* initialize path */
path=get_path(path_name,gr_name);
/* add object to table */
dtable_add(table,tag,ref,path);
#if defined (HDIFF_DEBUG)
printf("%s\n",path);
#endif
/*-------------------------------------------------------------------------
* insert attributes
*-------------------------------------------------------------------------
*/
insert_gr_attrs(ri_id,n_attrs);
/*-------------------------------------------------------------------------
* check for palette
*-------------------------------------------------------------------------
*/
pal_id = GRgetlutid(ri_id, 0);
GRgetlutinfo(pal_id,&r_ncomp,&r_data_type,&r_interlace_mode,&r_num_entries);
/*check if there is palette data */
has_pal=((r_ncomp == 0) || (r_interlace_mode < 0) || (r_num_entries == 0))?0:1;
if ( has_pal==1 )
{
} /* has_pal==1 */
/*-------------------------------------------------------------------------
* insert ANs
*-------------------------------------------------------------------------
*/
insert_an(file_id,ref,DFTAG_RIG,path);
insert_an(file_id,ref,DFTAG_RI,path);
/*-------------------------------------------------------------------------
* terminate access to the GR
*-------------------------------------------------------------------------
*/
/* terminate access to the GRs */
GRendaccess(ri_id);
if (path)
free(path);
return 0;
}
/*-------------------------------------------------------------------------
* Function: insert_vs
*
* Purpose: insert a VS
*
* Return: 0, -1 for error
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
int insert_vs( int32 file_id,
int32 tag,
int32 ref, /* ref of input VS */
char*path_name, /* absolute path for input group name */
dtable_t *table,
int is_lone)
{
int32 vdata_id, /* vdata identifier */
tag_vs,
ref_vs;
int n_fields, n_attrs;
char vdata_name [VSNAMELENMAX], vdata_class[VSNAMELENMAX];
char *path=NULL;
int i, j, ret=1;
/*-------------------------------------------------------------------------
* attach the vdata, gets its name and class
*-------------------------------------------------------------------------
*/
if ((vdata_id = VSattach (file_id, ref, "r")) == FAIL ){
printf( "Failed to attach vdata ref %d\n", ref);
return-1;
}
if (VSgetname (vdata_id, vdata_name) == FAIL ){
printf( "Failed to name for vdata ref %d\n", ref);
return-1;
}
if (VSgetclass (vdata_id, vdata_class) == FAIL ){
printf( "Failed to name for vdata ref %d\n", ref);
return-1;
}
/* ignore reserved HDF groups/vdatas; they are lone ones */
if( is_lone==1 && vdata_class != NULL) {
if( is_reserved(vdata_class)){
if (VSdetach (vdata_id) == FAIL )
printf( "Failed to detach vdata <%s>\n", path_name);
return 0;
}
}
if ((ref_vs = VSQueryref(vdata_id))==FAIL){
printf( "Failed to get ref for <%s>\n", vdata_name);
}
if ((tag_vs = VSQuerytag(vdata_id))==FAIL){
printf( "Failed to get tag for <%s>\n", vdata_name);
}
/* initialize path */
path=get_path(path_name,vdata_name);
/* add object to table */
dtable_add(table,tag_vs,ref_vs,path);
#if defined (HDIFF_DEBUG)
printf("%s\n",path);
assert(tag==tag_vs);
assert(ref==ref_vs);
#endif
/*-------------------------------------------------------------------------
* fields
*-------------------------------------------------------------------------
*/
if ((n_fields = VFnfields(vdata_id)) == FAIL ){
printf( "Failed getting fields for VS <%s>\n", path);
ret=-1;
goto out;
}
/*-------------------------------------------------------------------------
* insert attributes
*-------------------------------------------------------------------------
*/
if ((n_attrs = VSfnattrs( vdata_id, -1 )) == FAIL ){
printf( "Failed getting attributes for VS <%s>\n", path);
ret=-1;
goto out;
}
for (i = 0; i < n_attrs; i++) {
insert_vs_attrs(vdata_id, -1, i);
}
/*-------------------------------------------------------------------------
* insert field attributes
*-------------------------------------------------------------------------
*/
for (i = 0; i < n_fields; i++) {
if ((n_attrs = VSfnattrs(vdata_id, i)) == FAIL ){
printf( "Failed getting fields for VS <%s>\n", path);
ret=-1;
goto out;
}
for (j = 0; j < n_attrs; j++) {
insert_vs_attrs(vdata_id, i, j);
}
}
/*-------------------------------------------------------------------------
* insert ANs
*-------------------------------------------------------------------------
*/
insert_vs_an(file_id,vdata_id,path);
/*-------------------------------------------------------------------------
* terminate access to the VSs
*-------------------------------------------------------------------------
*/
out:
VSdetach (vdata_id);
if (path)
free(path);
return ret;
}
/*-------------------------------------------------------------------------
* Function: is_reserved
*
* Purpose: check for reserved Vgroup/Vdata class/names
*
* Return: 1 if reserved, 0 if not
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: August 22, 2003
*
*-------------------------------------------------------------------------
*/
static
int is_reserved(char*vgroup_class)
{
int ret=0;
/* ignore reserved HDF groups/vdatas */
if(vgroup_class != NULL) {
if( (strcmp(vgroup_class,_HDF_ATTRIBUTE)==0) ||
(strcmp(vgroup_class,_HDF_VARIABLE) ==0) ||
(strcmp(vgroup_class,_HDF_DIMENSION)==0) ||
(strcmp(vgroup_class,_HDF_UDIMENSION)==0) ||
(strcmp(vgroup_class,DIM_VALS)==0) ||
(strcmp(vgroup_class,DIM_VALS01)==0) ||
(strcmp(vgroup_class,_HDF_CDF)==0) ||
(strcmp(vgroup_class,GR_NAME)==0) ||
(strcmp(vgroup_class,RI_NAME)==0) ||
(strcmp(vgroup_class,RIGATTRNAME)==0) ||
(strcmp(vgroup_class,RIGATTRCLASS)==0) ){
ret=1;
}
/* class and name(partial) for chunk table i.e. Vdata */
if( (strncmp(vgroup_class,"_HDF_CHK_TBL_",13)==0)){
ret=1;
}
}
return ret;
}
/*-------------------------------------------------------------------------
* Function: get_path
*
* Purpose: return absolute path for an object
*
* Return: path
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: July 11, 2003
*
*-------------------------------------------------------------------------
*/
static
char *get_path(char*path_name, char*obj_name)
{
char *path=NULL;
/* initialize path */
if (path_name!=NULL)
{
path = (char*) malloc(strlen(path_name) + strlen(obj_name) + 2);
strcpy( path, path_name );
strcat( path, "/" );
strcat( path, obj_name );
}
else
{
path = (char*) malloc(strlen(obj_name) + 1);
strcpy( path, obj_name );
}
return path;
}
syntax highlighted by Code2HTML, v. 0.9.1