#include <string.h>
#include "hdf.h"
#include "read_hdf.h"
intn get_hdf_objects(int32 Hid, int32 SDid, int32 GRid, struct Objects **o)
{
intn status; /* Return status flag */
int32 i, n_objs; /* Number of objects in file */
uint16 tag; /* Object tag number */
uint16 ref; /* Object tag reference number */
uint16 lastref; /* Last read reference number */
int32 offset; /* Object byte offset within file */
int32 length; /* Object length in bytes */
int32 ANid; /* Annotation interface ID */
int32 n_fid, fid=0; /* Number of file identifier labels */
int32 n_fd, fd=0; /* Number of file descriptions */
int32 n_dil; /* Number of data identifier labels */
int32 n_dia; /* Number of data identifier annotations */
intn n_pals, pal=0; /* Number of palettes */
int32 n_r8ims, r8im=0; /* Number of 8-bit raster images */
int32 n_r24ims, r24im=0; /* Number of 24-bit raster images */
int32 n_grims; /* Number of general raster images */
int32 n_grattrs; /* Number of GR file attributes */
int32 RIid; /* Raster image ID number */
int32 ilace; /* Raster image interlace type */
int32 SDSid; /* SDS ID number */
int32 index; /* index number */
int32 n_dsets; /* Number of NDG data sets */
int32 rank; /* array rank */
int32 dims[MAX_VAR_DIMS]; /* dimension sizes */
int32 ntype; /* number type */
int32 nattrs; /* number of attributes */
int32 n_sdattr; /* Number of SD global attributes */
int32 Vid; /* Vgroup interface ID */
int32 ntagrefs; /* number of tag/ref pairs in a Vgroup */
int32 objtag; /* tag number in a Vgroup */
int32 objref; /* reference number in a Vgroup */
int32 VSid; /* Vdata interface ID */
char *filename;
char name[VGNAMELENMAX+1];
char object_name[VGNAMELENMAX+1];
char object_class[VGNAMELENMAX+1];
struct Objects *obj;
/* Get names of objects in the HDF(-EOS) file (File Label Annotation, File
* Description Annotation, Numeric Data Groups, Palettes, Raster 8 Images,
* 24-bit Images, General Raster Images, lone Vgroups including any EOS
* POINT, SWATH or GRID objects, and lone Vdata Tables). */
/*
* Get the number of all HDF objects in the file
*/
n_objs = Hnumber(Hid, DFTAG_WILDCARD);
if (n_objs == 0) {
*o = NULL;
return n_objs;
}
obj = calloc(n_objs, sizeof(struct Objects));
/*
* Start the annotation interface, and get the number of all annotations.
*/
ANid = ANstart(Hid);
status = ANfileinfo(ANid, &n_fid, &n_fd, &n_dil, &n_dia);
/*
* Get the number of raster 8, raster 24, and palettes in the file.
*/
filename = (char *)HDfidtoname(Hid);
n_r8ims = DFR8nimages(filename);
n_r24ims = DF24nimages(filename);
n_pals = DFPnpals(filename);
/*
* Get the number of general raster images (includes 8 and 24 rasters).
*/
status = GRfileinfo(GRid, &n_grims, &n_grattrs);
/*
* Get the number of scientific data sets in the file.
*/
status = SDfileinfo(SDid, &n_dsets, &n_sdattr);
/*
* Loop through entire file to get basic tag, ref, offset, length, index
* and name for each HDF object.
*/
for (i=0, tag=0, ref=0; i<n_objs; i++)
{
status = Hfind(Hid, DFTAG_WILDCARD, DFREF_WILDCARD,
&tag, &ref, &offset, &length, DF_FORWARD);
if (status == FAIL) break;
obj[i].tag = tag;
obj[i].ref = ref;
obj[i].offset = offset;
obj[i].length = length;
obj[i].index = -1;
strcpy(object_name, "");
strcpy(object_class, "");
nattrs = 0;
if (tag == DFTAG_FID)
{
if (n_fid == 1) strcpy(object_name, HDgettagsname(tag));
else sprintf(object_name, "%s #%d", HDgettagsname(tag), fid+1);
obj[i].index = fid;
fid++;
}
else if (tag == DFTAG_FD)
{
if (n_fd == 1) strcpy(object_name, HDgettagsname(tag));
else sprintf(object_name, "%s #%d", HDgettagsname(tag), fd+1);
obj[i].index = fd;
fd++;
}
else if (tag == DFTAG_RI8 || tag == DFTAG_CI8 || tag == DFTAG_II8)
{
/*
* Obsolete Raster-8 Image Set format, newer versions of HDF (>2.x)
* use Raster Image Groups (RIG) instead. Check to see if there is
* a corresponding DFTAG_ID for the Raster-8 tags.
*/
if (Hexist(Hid, DFTAG_ID, ref) == FAIL)
{
if (n_r8ims == 1) strcpy(object_name, "8-Bit Raster Image");
else sprintf(object_name, "8-Bit Raster Image #%d", r8im+1);
for (index=(n_grims-n_r8ims-n_r24ims); index<n_grims; index++)
{
RIid = GRselect(GRid, index);
lastref = GRidtoref(RIid);
status = GRendaccess(RIid);
if (obj[i].ref == lastref)
{
obj[i].index = index;
break;
}
}
r8im++;
}
}
else if (tag == DFTAG_IP8 || tag == DFTAG_LUT)
{
/*
* Check to see if this is a lone 8-bit Palette, i.e. one that is
* not attached to an 8-bit Raster Image.
*/
if (tag == DFTAG_IP8 && Hexist(Hid, DFTAG_LUT, ref) == SUCCEED)
continue;
if (tag == DFTAG_LUT && Hexist(Hid, DFTAG_IP8, ref) == FAIL)
continue;
if (Hexist(Hid, DFTAG_ID8, ref) == FAIL ||
Hexist(Hid, DFTAG_ID, ref) == FAIL) {
if (n_pals == 1) strcpy(object_name, "Palette");
else sprintf(object_name, "Palette #%d", pal+1);
obj[i].index = pal;
pal++;
}
}
else if (tag == DFTAG_RIG)
{
for (index=(n_grims-n_r8ims-n_r24ims); index<n_grims; index++)
{
RIid = GRselect(GRid, index);
status = GRgetiminfo(RIid, name, &rank, &ntype, &ilace,
dims, &nattrs);
lastref = GRidtoref(RIid);
status = GRendaccess(RIid);
if (obj[i].ref == lastref)
{
/*
* Check if RIG was created with either the DFR8 or the
* DF24 interfaces (they are created using DFNT_UCHAR8).
*/
if (ntype == DFNT_UCHAR8)
{
if (rank == 1) { /* 8-bit Raster Image */
if (n_r8ims == 1)
strcpy(name,"8-Bit Raster Image");
else
sprintf(name,"8-Bit Raster Image #%d",r8im+1);
r8im++;
}
else if (rank == 3) { /* 24-bit Raster Image */
if (n_r24ims == 1)
strcpy(name,"24-Bit Raster Image");
else
sprintf(name,"24-Bit Raster Image #%d",r24im+1);
r24im++;
}
strcpy(object_name, name);
obj[i].index = index;
}
break;
}
}
}
else if (tag == DFTAG_SDG)
{
/*
* Obsolete Scientific Data Group (SDG) tag, newer versions of HDF
* use Numeric Data Group (NDG) instead.
*/
if (Hexist(Hid, DFTAG_NDG, ref) == SUCCEED) continue;
index = SDreftoindex(SDid, ref);
SDSid = SDselect(SDid, index);
status = SDgetinfo(SDSid, object_name, &rank, dims, &ntype,&nattrs);
status = SDendaccess(SDSid);
}
else if (tag == DFTAG_NDG)
{
index = SDreftoindex(SDid, ref);
SDSid = SDselect(SDid, index);
status = SDgetinfo(SDSid, object_name, &rank, dims, &ntype,&nattrs);
status = SDendaccess(SDSid);
}
else if (tag == DFTAG_VH)
{
VSid = VSattach(Hid, ref, "r");
status = VSgetname(VSid, object_name);
status = VSgetclass(VSid, object_class);
nattrs = VSnattrs(VSid);
status = VSdetach(VSid);
}
else if (tag == DFTAG_VG)
{
Vid = Vattach(Hid, ref, "r");
status = Vgetname(Vid, object_name);
status = Vgetclass(Vid, object_class);
nattrs = Vnattrs(Vid);
if (strcmp(object_class, "RI0.0") == 0)
{
/*
* This is a General Raster Image, and we should record it
* as such and not as a Vgroup.
*/
index = GRnametoindex(GRid, object_name);
if (index == FAIL) {
/*
* There is a bug in HDF versions prior to 4.1r4
* that would not locate compressed GR images.
* Get reference number this way instead!
*/
ntagrefs = Vntagrefs(Vid);
for (index=0; index<ntagrefs; index++) {
Vgettagref(Vid, index, &objtag, &ob