/***************************************************************************** * * NCSA HDF version 3.10 * July 1, 1990 * * NCSA HDF Version 3.10 source code and documentation are in the public * domain. Specifically, we give to the public domain all rights for future * licensing of the source code, all resale rights, and all publishing rights. * * We ask, but do not require, that the following message be included in all * derived works: * * Portions developed at the National Center for Supercomputing Applications at * the University of Illinois at Urbana-Champaign. * * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION, * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE * *****************************************************************************/ #ifdef RCSID static char RcsId??(??) = "@(#)$Revision: 3.10 $" #endif /* $Header: /pita/work/HDF/dev/RCS/src/dfsd.c,v 3.10 90/07/11 09:48:25 clow beta $ $Log: dfsd.c,v $ * Revision 3.10 90/07/11 09:48:25 clow * Modified so that we could do inquiry after doing a getdata. * * Revision 3.9 90/07/05 14:06:03 clow * Fix bug where transposition is used in getslice * * Revision 3.8 90/06/29 17:35:52 clow * Fixed bug in DFSDIgetdata and DFSDreadref where the new sdg info is * not read. * * Revision 3.7 90/06/29 16:49:12 clow * Added some spaces before the #pragma line so that the SGI's c compiler * will not complain. Sigh. * * Revision 3.6 90/06/28 13:49:12 clow * fix bug on DFSDIgetslice and DFSDputslice when the dimensions are collapse * * Revision 3.5 90/06/21 10:39:45 clow * Fixed bug in Iputslice which calculates the pointer to the data wrongly * * Revision 3.4 90/06/13 16:17:38 clow * added DFSDreadref that will set the ref of the next SD read in. * * Revision 3.3 90/06/07 17:40:02 clow * new, faster put/getslice routines done by john walder * fixed bug in the getslice routine where the slice is from the * wrong coordinates * */ /*----------------------------------------------------------------------------- File: dfsd.c Purpose: Routines for input and output of scientific data Invokes: df.c dfgroup.c dfkit.c dfi.h df.h dfsd.h Public functions: DFSDgetdims - get rank and dim sizes DFSDgetdatastrs - get label, unit, format and coord system of data DFSDgetdimstrs - get label, unit and format for a dimension DFSDgetdimscale - get scale for a dimension DFSDgetmaxmin - get max and min of data DFSDgetdata - get data values DFSDsetlengths - set lengths of label, unit, format strings on gets DFSDsetdims - set rank and dim sizes DFSDsetdatastrs - set data label, unit, format and coord system DFSDsetdimstrs - set dim labels, units and formats DFSDsetdimscale - set scale for a dimension DFSDsetmaxmin - get max and min of data DFSDputdata - output data, data info, and display info DFSDrestart - forget info about last file accessed - restart from beginning DFSDnumber - return number of SDGs in file DFSDclear - forget all info set DFSDlastref - get reference number of last SDG read or written DFSDsettype - set output data type, m/c format, number type and array order DFSDgetslice - get part of the data, specified as a slice DFSDstartslice - set up to write SD DFSDputslice - write specified number of data items to file DFSDendslice - end of series of writes, write out SDG Lower level functions: DFSDgetsdg - read SDG into struct DFSDputsdg - read SDG into struct Private functions: DFSDIopen - open or reopen file DFSDIsdginfo - find next sdg in file DFSDIclear - clear sdg data structure of all info DFSDIgetdata - read data from file DFSDIputdata - write data to file DFSDIgetslice - get slice Fortran stub functions: dsisdas_ - set data label, unit, format and coord system dsisdis_ - set dim labels, units and formats Remarks: An SDG stores actual data from scietific computations, which are subsequently to be converted to images. This version assumes that all the values are floating point. *---------------------------------------------------------------------------*/ #include "dfsd.h" #include "dfconvert.h" #ifdef DF_CAPFNAMES # define dsisdas_ DSISDAS # define dsisdis_ DSISDIS #endif /* DF_CAPFNAMES */ #define LABEL 0 #define UNIT 1 #define FORMAT 2 #define COORDSYS 3 static DFSsdg Readsdg = /* struct for reading */ { {0, 0}, 0, NULL, NULL, { NULL, NULL, NULL }, { NULL, NULL, NULL }, NULL, 0.0, 0.0 }, Writesdg = /* struct for writing */ { {0, 0}, 0, NULL, NULL, { NULL, NULL, NULL }, { NULL, NULL, NULL }, NULL, 0.0, 0.0 }; static uint16 Writeref=0; /* ref of next SDG to write to file */ static int Newdata=(-1); /* Values in Readsdg fresh? */ /* -1 : no descriptor read */ /* 1 : descriptor read */ static int Nextsdg = 1; /* Signal if DFSDgetdata should get the */ /* next sdg */ static DF *Sdfile=NULL; /* pointer to file for slice writes */ static int32 *Sddims; /*dims written so far in slice write */ static struct { /* Indicators of status (s) of info: */ int dims; /* s = -1: there is no info in this category */ int nt; /* s = 0: info was set, but not yet written */ int coordsys; /* s>0:info was set and written with ref no.s*/ int luf??(3??); int scales; int maxmin; int transpose; } Ref = { -1, -1, -1, { -1, -1, -1 }, -1, -1 , -1}; static int Maxstrlen??(4??) = { DFS_MAXLEN, DFS_MAXLEN, DFS_MAXLEN, DFS_MAXLEN }; static int Ismaxmin = 0; /* is there a max/min value on read? */ static int FileTranspose = 0; /* is the data in column major order? */ static int Fortorder = 0; /* should data be written col major? */ static int fileNT=DFNTF_IEEE, /* default: all IEEE */ fileNTsize=4, /* size of IEEE in bytes */ outNT=DFNTF_IEEE, /* default output: IEEE */ outNTsize=4, /* size of IEEE in bytes */ userNT=DFNTF_IEEE; /* default */ static int Readref = 0; static char Lastfile??(DF_MAXFNLEN??) = ""; /* last file opened */ static uint16 Lastref = 0; /*----------------------------------------------------------------------------- * Name: DFSDgetdims * Purpose: Get dimensions of data in next SDG * Inputs: filename: name of HDF file to use * prank: pointer to integer for returning rank (no of dimensions) * sizes: array of integers for returning size of each dimension * maxrank: size of array for returning dimensions * Returns: 0 on success, -1 on failure with DFerror set * Outputs: rank in prank, size of each dimension in sizes * If rank > maxrank, rank is set, and -1 is returned * Users: HDF users, utilities, other routines * Invokes: DFSDIopen, DFIerr, DFclose, DFSDIsdginfo * Method: Opens file, calls DFSDIsdginfo to get SDG, copies rank etc, closes * file, returns * Remarks: Always sequences to next SDG in file * User specifies maxrank, and allocates sizes as an array of integers * with dimension maxrank *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgdims(filename, prank, sizes, maxrank) /* JES 90 */ #else /* JES 90 */ int DFSDgetdims(filename, prank, sizes, maxrank) #endif /* JES 90 */ char *filename; int *prank; int32 sizes??(??); int maxrank; { int i; DF *dfile; DFerror = DFE_NOERROR; if (!prank) { /* check if ptr is valid */ DFerror = DFE_BADPTR; return(-1); } #ifdef IBM /* JES 90 */ dfile = dsIopen(filename, DFACC_READ); /* JES 90 */ #else /* JES 90 */ dfile = DFSDIopen(filename, DFACC_READ); /* open/reopen file */ #endif /* JES 90 */ if (dfile == NULL) return(-1); #ifdef IBM /* JES 90 */ if (dsIsdginfo(dfile)<0) /* JES 90 */ #else /* JES 90 */ if (DFSDIsdginfo(dfile)<0) /* reads next SDG from file */ #endif /* JES 90 */ return(DFIerr(dfile)); /* on error, close file and return -1 */ *prank = Readsdg.rank; /* copy rank, dimensions */ if (maxrank<*prank) { /* if not all dimensions copied */ DFerror = DFE_NOTENOUGH; return(DFIerr(dfile)); } for (i=0; i<*prank; i++) sizes??(i??) = Readsdg.dimsizes??(i??); Nextsdg = 0; return(DFclose(dfile)); } /*----------------------------------------------------------------------------- * Name: DFSDgetdatastrs * Purpose: Get information about data: label, units, format * Inputs: label: string to return label in, length Maxstrlen??(LABEL??) * unit: string to return unit in, length Maxstrlen??(UNIT??) * format: string to return format in, length Maxstrlen??(FORMAT??) * coordsys: string to return coord system, length Maxstrlen??(COORDSYS??) * Returns: 0 on success, -1 on failure with DFerror set * Outputs: label, unit, format, coord system in the appropriate arguments * Users: HDF users, utilities, other routines * Invokes: none * Method: get values from struct Readsdg * Remarks: none *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgdast(label, unit, format, coordsys) /* JES 90 */ #else /* JES 90 */ int DFSDgetdatastrs(label, unit, format, coordsys) #endif /* JES 90 */ char *label, *unit, *format, *coordsys; { int32 luf; char *lufp; DFerror = DFE_NOERROR; if (Newdata<0) { DFerror = DFE_BADCALL; return(-1); } /* copy label, unit, format */ for (luf=LABEL; luf<=FORMAT; luf++) { lufp = (luf==LABEL) ? label : (luf==UNIT) ? unit : format; if (lufp) if (Readsdg.dataluf??(luf??)) DFIstrncpy(lufp, Readsdg.dataluf??(luf??), Maxstrlen??(luf??)); } /* copy coordsys */ if (coordsys) if (Readsdg.coordsys) DFIstrncpy(coordsys, Readsdg.coordsys, Maxstrlen??(COORDSYS??)); else coordsys??(0??) = '\0'; return(0); } /*----------------------------------------------------------------------------- * Name: DFSDgetdimstrs * Purpose: Get information about a dimension: label, units, format * Inputs: dim: no of dimension to get information about * label: string to return label in, max length Maxstrlen??(LABEL??) * unit: string to return unit in, max length Maxstrlen??(UNIT??) * format: string to return format in, max length Maxstrlen??(FORMAT??) * Returns: 0 on success, -1 on failure with DFerror set * Outputs: label, unit, format in the appropriate arguments * NULL string if no value for the arguments * Users: HDF users, utilities, other routines * Invokes: none * Method: get values from struct Readsdg * Remarks: none *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgdist(dim, label, unit, format) /* JES 90 */ #else /* JES 90 */ int DFSDgetdimstrs(dim, label, unit, format) #endif /* JES 90 */ int dim; char *label, *unit, *format; { int luf, rdim; char *lufp; DFerror = DFE_NOERROR; if (Newdata<0) { DFerror = DFE_BADCALL; return(-1); } rdim = dim-1; /* translate dim to zero origin */ if ((rdim>=Readsdg.rank) || (rdim<0)) { DFerror = DFE_BADDIM; return(-1); } /* copy labels etc */ for (luf=LABEL; luf<=FORMAT; luf++) { lufp = (luf==LABEL) ? label : (luf==UNIT) ? unit : format; if (lufp) { /****************** JES 90 ***************************** if (!Readsdg.dimluf) { *lufp = '\0'; continue; } **** IBM's C compiler complains thea the above is a pointer to a **** pointer and that it can only negate a scalar ***************/ if (Readsdg.dimluf??(luf??)) DFIstrncpy(lufp, Readsdg.dimluf??(luf??)??(rdim??), Maxstrlen??(luf??)); } } return(0); } /*----------------------------------------------------------------------------- * Name: DFSDgetdatalen() * Purpose: Get actual length of label, unit, format, coordsys strings * Called from FORTRAN * Inputs: llabel, lunit, lformat, lcoordsys - for returning lengths * Globals: Readsdg * Returns: 0 on success, -1 on error with DFerror set * Users: HDF users, utilities, other routines * Invokes: none * Method: get lengths from Readsdg *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgdaln(llabel, lunit, lformat, lcoordsys) /* JES 90 */ #else /* JES 90 */ int DFSDgetdatalen(llabel, lunit, lformat, lcoordsys) #endif /* JES 90 */ int *llabel, *lunit, *lformat, *lcoordsys; { DFerror = DFE_NOERROR; if (Newdata<0) { DFerror = DFE_BADCALL; return(-1); } *llabel = Readsdg.dataluf??(LABEL??) ? strlen(Readsdg.dataluf??(LABEL??)) : 0; *lunit = Readsdg.dataluf??(UNIT??) ? strlen(Readsdg.dataluf??(UNIT??)) : 0; *lformat = Readsdg.dataluf??(FORMAT??) ? strlen(Readsdg.dataluf??(FORMAT??)) : 0; *lcoordsys = Readsdg.coordsys ? strlen(Readsdg.coordsys) : 0; return(0); } /*----------------------------------------------------------------------------- * Name: DFSDgetdimlen() * Purpose: Get actual length of label, unit, format strings * Called from FORTRAN * Inputs: dim. llabel, lunit, lformat - for returning lengths * Globals: Readsdg * Returns: 0 on success, -1 on error with DFerror set * Users: HDF users, utilities, other routines * Invokes: none * Method: get lengths from Readsdg *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgdiln(dim, llabel, lunit, lformat) /* JES 90 */ #else /* JES 90 */ int DFSDgetdimlen(dim, llabel, lunit, lformat) #endif /* JES 90 */ int dim; int *llabel, *lunit, *lformat; { DFerror = DFE_NOERROR; if (Newdata<0) { DFerror = DFE_BADCALL; return(-1); } if (dim>Readsdg.rank) { DFerror = DFE_BADDIM; return(-1); } *llabel = Readsdg.dimluf??(dim-1??)??(LABEL??) ? strlen(Readsdg.dimluf??(dim-1??)??(LABEL??)) : 0; *lunit = Readsdg.dimluf??(dim-1??)??(UNIT??) ? strlen(Readsdg.dimluf??(dim-1??)??(UNIT??)) : 0; *lformat = Readsdg.dimluf??(dim-1??)??(FORMAT??) ? strlen(Readsdg.dimluf??(dim-1??)??(FORMAT??)) : 0; return(0); } /*----------------------------------------------------------------------------- * Name: DFSDgetdimscale * Purpose: Get dimension scale * Inputs: dim: no of dimension to get scale for * size: size of scale array * scale: array to return scale in * Returns: 0 on success, -1 on failure with DFerror set * Outputs: scale if present, else -1 * Users: HDF users, utilities, other routines * Invokes: none * Method: get values from struct Readsdg * Remarks: none *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgdisc(dim, maxsize, scale) /* JES 90 */ #else /* JES 90 */ int DFSDgetdimscale(dim, maxsize, scale) #endif /* JES 90 */ int dim; int32 maxsize; float32 scale??(??); { int32 i; int rdim; DFerror = DFE_NOERROR; if (Newdata<0) { DFerror = DFE_BADCALL; return(-1); } rdim = dim-1; /* translate dim to zero origin */ if ((rdim>=Readsdg.rank) || (rdim<0)) { DFerror = DFE_BADDIM; return(-1); } if (maxsize < Readsdg.dimsizes??(rdim??)) { DFerror = DFE_NOSPACE; return(-1); } if (!scale) { DFerror = DFE_BADPTR; return(-1); } if (!Readsdg.dimscales || !Readsdg.dimscales??(rdim??)) { /* no scale */ DFerror = DFE_NOVALS; return(-1); } for (i=0; i0) Maxstrlen??(LABEL??) = maxlen_label; if (maxlen_unit>0) Maxstrlen??(UNIT??) = maxlen_unit; if (maxlen_format>0) Maxstrlen??(FORMAT??) = maxlen_format; if (maxlen_coordsys>0) Maxstrlen??(COORDSYS??) = maxlen_coordsys; return(0); } /*----------------------------------------------------------------------------- * Name: DFSDsetdims() * Purpose: Set rank and sizes for subsequent SDGs * Inputs: rank: rank of array that holds the raw data * dimsizes: sizes of all of the dimensions * Globals: Writesdg, Ref * Returns: 0 on success, -1 on error with DFerror set * Users: HDF users, utilities, other routines * Invokes: DFSDclear * Method: Stores values in global structure Writesdg * Remarks: If dimensions change, all previous "set"s are cleared * This routine must be called before DFSDsetdimstrs and * DFSDsetdimscales. It need not be called if these routines are * not called, and the correct dimensions are supplied to DFSDputdata * or DFSDadddata *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dssdims(rank, dimsizes) /* JES 90 */ #else /* JES 90 */ int DFSDsetdims(rank, dimsizes) #endif /* JES 90 */ int16 rank; int32 dimsizes??(??); { int i; DFerror = DFE_NOERROR; if (Sdfile!=NULL) { DFerror = DFE_BADCALL; return(-1); } if (Writesdg.rank == rank) /* check if dimensions same */ if (Writesdg.dimsizes) { for (i=0; i=Writesdg.rank) || (rdim<0)) { DFerror = DFE_BADDIM; return(-1); } for (luf=LABEL; luf<=FORMAT; luf++) { /* set lufp to point to label etc. as apppropriate */ lufp = (luf==LABEL) ? label : (luf==UNIT) ? unit : format; /* allocate space if necessary */ if (!Writesdg.dimluf??(luf??)) { Writesdg.dimluf??(luf??) = (char **) DFIgetspace((unsigned) Writesdg.rank * sizeof(char *)); if (Writesdg.dimluf??(luf??)==NULL) return(-1); for (i=0; i=Writesdg.rank) || (rdim<0) /* check dimensions */ || (dimsize!=Writesdg.dimsizes??(rdim??))) { DFerror = DFE_BADDIM; return(-1); } if (!scale) { /* No scale for this dimension */ if (Writesdg.dimscales) Writesdg.dimscales??(rdim??) = (float32 *) DFIfreespace((char*) Writesdg.dimscales??(rdim??)); Ref.scales = 0; return(0); } /* allocate space for dimscales if necessary */ if (!Writesdg.dimscales) { Writesdg.dimscales = (float32 **) DFIgetspace((unsigned)Writesdg.rank * sizeof(float32 *)); if (Writesdg.dimscales==NULL) return(-1); for (i=0; i0) && (!Fortorder || i>8) & 0x0f; if ((machinetype!=DF_MT) && (outNT!=DFNTF_IEEE)) { DFerror = DFE_BADMCTYPE; return(-1); } } if (numbertype) outNT = numbertype; if (outNT == ((DF_MT>>8) & 0x0f)) outNTsize = sizeof(float32); else if (outNT == DFNTF_IEEE) outNTsize = 4; /* sizeof IEEE in bytes */ else { DFerror = DFE_BADNUMTYPE; return(-1); } if (arrayorder==DFO_FORTRAN) { Fortorder = 1; if (Ref.transpose<0) Ref.transpose = 0; } else if (arrayorder==DFO_C) { Fortorder = 0; if (Ref.transpose>=0) Ref.transpose = -1; } else if (arrayorder) { DFerror = DFE_BADORDER; return(-1); } return(0); } /*************************************************************************/ /*--------------------- Lower level routines --------------------------------*/ /*************************************************************************/ /*----------------------------------------------------------------------------- * Name: DFSDgetsdg * Purpose: Reads in SDG * Inputs: dfile: pointer to HDF file containing SDG * ref: ref of SDG to read * sdg: pointer to DFSsdg struct to read SDG into * Returns: 0 on success, -1 on failure with DFerror set * Users: HDF programmers, DFSDgetdims, DFSDgetdata * Invokes: DFgetelement, DFdiread, DFdiget, DFaccess, DFread * Method: Reads in SDG using DFdiread. Gets each tag/ref using DFdiget. * Reads in dimensions, labels, units, formats, scales, coordinate * system using DFgetelement. Mallocs space for these, freeing * previously allocated space. * Remarks: This is specific to floating point data *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsgsdg(dfile, ref, sdg) /* JES 90 */ #else /* JES 90 */ int DFSDgetsdg(dfile, ref, sdg) #endif /* JES 90 */ DF *dfile; uint16 ref; DFSsdg *sdg; { int i, j, luf, cdd; int error; /* used by DFconvert macro */ int charlen; /* JES 90 */ uint16 userCT, fileCT; /* JES 90 */ DFdle *dlep; struct DFdi elmt, nt; char *isscales; char *buf, *p; char ntstring??(4??); DFerror = DFE_NOERROR; if (DFIcheck(dfile)) return( -1); if (!ref) { DFerror = DFE_BADREF; return(-1); } if (DFdiread(dfile, DFTAG_SDG, ref)<0) /* read RIG into memory */ return(-1); userNT = (DF_MT>>8) & 0x0f; /* get third nibble from right */ userCT = DF_MT & 0x000f; /* get machine character type */ /* JES 90 */ fileCT = DFNTC_ASCII; /* file character type is always ASCII */ /* JES 90 */ #ifdef IBM /* JES 90 */ dsIclear(sdg); /* JES 90 */ #else /* JES 90 */ DFSDIclear(sdg); #endif /* JES 90 */ Ismaxmin = 0; while (!DFdiget(&elmt)) { /* get next tag/ref from RIG */ luf = -1; /* flag value for label/unit format gets */ switch (elmt.tag) { /* process tag/ref */ case DFTAG_SD: /* data tag/ref */ sdg->data.tag = elmt.tag; /* put tag/ref in struct */ sdg->data.ref = elmt.ref; break; case DFTAG_SDD: /* dimension */ if (DFaccess(dfile, elmt.tag, elmt.ref, "r")<0) return(-1); /* read rank */ #ifdef DF_STRUCTOK if (DFread(dfile, &sdg->rank, (int32) 2)<0) return(-1); #else /*DF_STRUCTOK*/ if (DFread(dfile, DFtbuf, (int32) 2)<0) return(-1); { register char *p; p = DFtbuf; INT16READ(p, sdg->rank); } #endif /*DF_STRUCTOK*/ /* get space for dimensions */ sdg->dimsizes = (int32 *) DFIgetspace((unsigned) sdg->rank * sizeof(int32)); if (sdg->dimsizes==NULL) return(-1); /* read dimension record */ #ifdef DF_STRUCTOK if (DFread(dfile, sdg->dimsizes, (int32) 4*sdg->rank)<0) return(-1); /* read NT */ if (DFread(dfile, &nt, (int32) 4)<0) return(-1); #else /*DF_STRUCTOK*/ if (DFread(dfile, DFtbuf, (int32) 4*sdg->rank)<0) return(-1); { register char *p; p = DFtbuf; for (i=0; irank; i++) INT32READ(p, sdg->dimsizes??(i??)); /* read NT */ if (DFread(dfile, DFtbuf, (int32) 4)<0) return(-1); p = DFtbuf; UINT16READ(p, nt.tag); UINT16READ(p, nt.ref); } #endif /*DF_STRUCTOK*/ /* read NT */ if (DFgetelement(dfile, nt.tag, nt.ref, ntstring)<0) return(-1); /* check float data */ if (ntstring??(1??) != DFNT_FLOAT) { DFerror = DFE_BADCALL; return(-1); } /* set NT info */ fileNT = ntstring??(3??); fileNTsize = ntstring??(2??) / 8; /* read and check all scale NTs */ for (i=0; irank; i++) { #ifdef DF_STRUCTOK /* read NT tag/ref */ if (DFread(dfile, &nt, (int32) 4)<0) return(-1); #else /*DF_STRUCTOK*/ if (DFread(dfile, DFtbuf, (int32) 4)<0) return(-1); { register char *p; p = DFtbuf; UINT16READ(p, nt.tag); UINT16READ(p, nt.ref); } #endif /*DF_STRUCTOK*/ /* read NT itself */ if (DFgetelement(dfile, nt.tag,nt.ref, ntstring)<0) return(-1); /* check float data */ if (ntstring??(1??) != DFNT_FLOAT) { DFerror = DFE_BADCALL; return(-1); } } break; case DFTAG_SDL: /* labels */ if (luf==(-1)) luf = LABEL; case DFTAG_SDU: /* units */ if (luf==(-1)) luf = UNIT; case DFTAG_SDF: /* formats */ if (luf==(-1)) luf = FORMAT; if (!sdg->dimsizes) { /* internal error */ DFerror = DFE_CORRUPT; return(-1); } /* get needed size of buffer, allocate */ if (DFIfind(dfile, elmt.tag, elmt.ref, 1, (uint16) 0, (uint16) 0, &dlep, &cdd)<0) return(-1); buf = DFIgetspace((unsigned) dlep->dd??(cdd??).length); if (buf==NULL) return(-1); /* read in luf */ /* if (DFgetelement(dfile, elmt.tag, elmt.ref, buf)<0) { JES 90 */ charlen = DFgetelement( dfile, elmt.tag, elmt.ref, buf );/* JES 90 */ if( charlen < 0 ) /* JES 90 */ { buf = DFIfreespace(buf); return(-1); } /***********************************************************/ /* do ascii to ebcdic conversion if necessary JES 90 */ /***********************************************************/ if( fileCT == DFNTC_ASCII && userCT == DFNTC_EBCDIC ) /* JES 90 */ DFCVa2eC( buf,charlen ); /* JES 90 */ else if( fileCT == DFNTC_EBCDIC && /* JES 90 */ userCT == DFNTC_ASCII ) /* JES 90 */ DFCVe2aC( buf,charlen ); /* JES 90 */ p = buf; /* allocate data luf space */ sdg->dataluf??(luf??) = DFIgetspace((unsigned) strlen(p)+1); if (sdg->dataluf??(luf??)==NULL) { buf = DFIfreespace(buf); return(-1); } /* extract data luf */ strcpy(sdg->dataluf??(luf??), p); p += strlen(sdg->dataluf??(luf??))+1; /* get space for dimluf array */ sdg->dimluf??(luf??) = (char **) DFIgetspace((unsigned) sdg->rank * sizeof(char *)); if (sdg->dimluf??(luf??)==NULL) { buf = DFIfreespace(buf); return(-1); } /* extract dimension lufs */ for (i=0; irank; i++) { sdg->dimluf??(luf??)??(i??) = DFIgetspace((unsigned) strlen(p)+1); if (sdg->dimluf??(luf??)??(i??)==NULL) { buf = DFIfreespace(buf); return(-1); } strcpy(sdg->dimluf??(luf??)??(i??), p); p += strlen(sdg->dimluf??(luf??)??(i??))+1; } buf = DFIfreespace(buf); break; case DFTAG_SDS: /* scales */ if (!sdg->dimsizes) { /* internal error */ DFerror = DFE_CORRUPT; return(-1); } /* set up to read scale */ if (DFaccess(dfile, elmt.tag, elmt.ref, "r")<0) return(-1); /* read isscales */ isscales = DFIgetspace((unsigned) sdg->rank); if (isscales==NULL) return(-1); if (DFread(dfile, isscales, (int32) sdg->rank)<0) return(-1); /* allocate scale pointers */ sdg->dimscales = (float32 **) DFIgetspace((unsigned) sdg->rank * sizeof(float32 *)); if (sdg->dimscales==NULL) { isscales = DFIfreespace(isscales); return(-1); } /* read scales */ for (i=0; irank; i++) { sdg->dimscales??(i??) = NULL; /* default */ if (!isscales??(i??)) continue; /* space for scale */ sdg->dimscales??(i??) = (float32 *) DFIgetspace((unsigned) sdg->dimsizes??(i??) * sizeof(float32)); if (sdg->dimscales??(i??)==NULL) { isscales = DFIfreespace(isscales); return(-1); } if (userNT == fileNT) { /* no conversion needed */ if (DFread(dfile, (char*) sdg->dimscales??(i??), (int32) (sdg->dimsizes??(i??)*fileNTsize))<0) { isscales = DFIfreespace(isscales); return(-1); } } else { /* conversion necessary */ register char *p; /* allocate conversion buffer */ buf = DFIgetspace((unsigned) sdg->dimsizes??(i??) * fileNTsize); if (buf==NULL) { isscales = DFIfreespace(isscales); return(-1); } /* read scale from file */ if (DFread(dfile, buf, (int32) (sdg->dimsizes??(i??)*fileNTsize))<0) { buf = DFIfreespace(buf); isscales = DFIfreespace(isscales); return(-1); } p = buf; /* convert, all at once */ DFconvert(p, (char*) sdg->dimscales??(i??), DFNT_FLOAT, fileNT, userNT, sdg->dimsizes??(i??), error); buf = DFIfreespace(buf); } } isscales = DFIfreespace(isscales); break; case DFTAG_SDC: /* coordsys */ /* find and allocate necessary space */ if (DFIfind(dfile, elmt.tag, elmt.ref, 1, 0, 0, &dlep, &cdd)<0) return(-1); sdg->coordsys = DFIgetspace((unsigned) dlep->dd??(cdd??).length); if (sdg->coordsys==NULL) return(-1); /* read coordsys */ /* if (DFgetelement(dfile, elmt.tag, elmt.ref, JES 90 */ /* sdg->coordsys ) < 0) JES 90 */ charlen = DFgetelement(dfile, elmt.tag, elmt.ref, /* JES 90 */ sdg->coordsys ); /* JES 90 */ if( charlen < 0 ) /* JES 90 */ return(-1); /***********************************************************/ /* do ascii to ebcdic conversion if necessary JES 90 */ /***********************************************************/ if( fileCT == DFNTC_ASCII && userCT == DFNTC_EBCDIC ) /* JES 90 */ DFCVa2eC( sdg->coordsys,charlen ); /* JES 90 */ else if( fileCT == DFNTC_EBCDIC && /* JES 90 */ userCT == DFNTC_ASCII ) /* JES 90 */ DFCVe2aC( sdg->coordsys,charlen ); /* JES 90 */ break; case DFTAG_SDM: /* max/min */ if (fileNT==userNT) { /* no conversion */ if (DFgetelement(dfile, elmt.tag, elmt.ref, (char*) &sdg->max_data)<0) return(-1); } else { /* allocate buffer */ #ifndef CVT_BUG float32 mm??(2??); #endif buf = DFIgetspace((unsigned) 2 * fileNTsize); if (buf==NULL) return(-1); /* read and convert max/min */ if (DFgetelement(dfile, elmt.tag, elmt.ref, buf)<0) return(-1); #ifdef CVT_BUG DFconvert(buf, (char*) &sdg->max_data, DFNT_FLOAT, fileNT, userNT, 1, error); DFconvert(buf+fileNTsize, (char*) &sdg->min_data, DFNT_FLOAT, fileNT, userNT, 1, error); #else DFconvert(buf, (char*)mm, DFNT_FLOAT, fileNT, userNT, 2, error); sdg->max_data = mm??(0??); sdg->min_data = mm??(1??); #endif buf = DFIfreespace(buf); } Ismaxmin = 1; break; case DFTAG_SDT: FileTranspose = 1; break; default: /* ignore unknown tags */ break; } } return(0); } /*----------------------------------------------------------------------------- * Name: DFSDputsdg * Purpose: Write SDG out to HDF file * Inputs: dfile: HDF file pointer * ref: ref to put SDG with * sdg: struct containing SDG info to put * Returns: 0 on success, -1 on failure with DFerror set * Users: HDF programmers, utilities, DFSDputdata, other routines * Invokes: DFIcheck, DFdistart, DFdiadd, DFdiend, DFputelement, DFaccess, * DFwrite * Remarks: Writes out NTs *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dspsdg(dfile, ref, sdg) /* JES 90 */ #else /* JES 90 */ int DFSDputsdg(dfile, ref, sdg) #endif /* JES 90 */ DF *dfile; uint16 ref; DFSsdg *sdg; { int i,j, localNT, luf; int error; /* used by DFConvert macro */ int charlen; /* JES 90 */ uint16 userCT, fileCT; /* JES 90 */ uint16 luftag; char ntstring??(4??); char *buf, *Isscales=NULL; DFdi nt; DFerror = DFE_NOERROR; if (DFIcheck(dfile)) return( -1); if (!ref) { DFerror = DFE_BADREF; return(-1); } localNT = (DF_MT>>8) & 0x0f; /* get third nibble from right */ userCT = DF_MT & 0x000f; /* get machine character type */ /* JES 90 */ fileCT = DFNTC_ASCII; /* file character type is always ASCII */ /* JES 90 */ /* prepare to start writing sdg */ if (DFdisetup(10)<0) return(-1); /* max 10 tag/refs in set */ if (DFdiput(sdg->data.tag, sdg->data.ref) < 0) return(-1); /******************************/ /* construct and write out NT */ /******************************/ if (Ref.nt<=0) { ntstring??(0??) = DFNT_VERSION; /* version */ ntstring??(1??) = DFNT_FLOAT; /* type */ ntstring??(2??) = outNTsize*8; /* width of float class in bits */ ntstring??(3??) = outNT; /* class: IEEE floating point */ if (DFputelement(dfile, DFTAG_NT, ref, ntstring, (int32) 4) <0) return(-1); Ref.nt = ref; } /******************************/ /* write rank, dimensions */ /******************************/ if (Ref.dims<=0) { if (DFaccess(dfile, DFTAG_SDD, ref, "w")<0) return(-1); #ifdef DF_STRUCTOK if (DFwrite(dfile, &sdg->rank, 2)<0) return(-1); if (DFwrite(dfile, sdg->dimsizes, 4 * sdg->rank)<0) return(-1); #else /*DF_STRUCTOK*/ { register char *p; p = DFtbuf; UINT16WRITE(p, sdg->rank); for (i=0; irank; i++) INT32WRITE(p, sdg->dimsizes??(i??)); if (DFwrite(dfile, DFtbuf, (int32) (p-DFtbuf))<0) return(-1); } #endif /*DF_STRUCTOK*/ /* write data NT and scale NTs */ nt.tag = DFTAG_NT; nt.ref = Ref.nt; /* same NT for scales too */ /* <= used to write 1 data NT + rank scale NTs */ for (i=0; i<=sdg->rank; i++) /* scale NTs written even if no scale!*/ #ifdef DF_STRUCTOK if (DFwrite(dfile, &nt, (int32) 4)<0) return(-1); #else /*DF_STRUCTOK*/ { register char *p; p = DFtbuf; UINT16WRITE(p, nt.tag); UINT16WRITE(p, nt.ref); if (DFwrite(dfile, DFtbuf, (int32) (p-DFtbuf))<0) return(-1); } #endif /*DF_STRUCTOK*/ Ref.dims = ref; } /* write dimension tag/ref */ if( DFdiput( DFTAG_SDD,(uint16) Ref.dims ) < 0 ) return(-1); /*******************************************************/ /* write out label/unit/format */ /*******************************************************/ for (luf=LABEL; luf<=FORMAT; luf++) { luftag = (luf==LABEL) ? DFTAG_SDL : (luf==UNIT) ? DFTAG_SDU : DFTAG_SDF; /************************************************************/ /* this block of code checks if luf is NULL, else writes it */ /************************************************************/ if (!Ref.luf??(luf??)) { /* if luf was set */ Ref.luf??(luf??) = -1; /* assume it is NULL */ /********************************************************/ /* do this once for each rank */ /********************************************************/ for (i=0; irank; i++) { /****************************************************/ /* if luf is non-NULL set up to write */ /****************************************************/ if( ( sdg->dataluf??(luf??) && sdg->dataluf??(luf??)??(0??) ) || ( sdg->dimluf??(luf??) && sdg->dimluf??(luf??)??(i??) && sdg->dimluf??(luf??)??(i??)??(0??) ) ) { if (DFaccess(dfile, luftag, ref, "w")<0) return(-1); /*******************************************/ /* write data luf */ /*******************************************/ /* JES 90 */ /*******************************************/ /* JES 90 */ /* if the data is in EBCDIC, convert it */ /* JES 90 */ /* to ASCII before writing it out */ /* JES 90 */ /*******************************************/ /* JES 90 */ if( userCT == DFNTC_EBCDIC && /* JES 90 */ fileCT == DFNTC_ASCII ) /* JES 90 */ { /* JES 90 */ /*********************************************/ /* JES 90 */ /* allocate buf, copy the ebcdic string to it*/ /* JES 90 */ /* and convert to ascii */ /* JES 90 */ /*********************************************/ /* JES 90 */ if( sdg->dataluf??( luf ??) ) /* JES 90 */ { /* JES 90 */ charlen = strlen( sdg -> dataluf??( luf ??) ); /* JES 90 */ buf = DFIgetspace( ( unsigned )( charlen+1 ) ); /* JES 90 */ if( buf==NULL ) /* JES 90 */ return(-1); /* JES 90 */ strcpy( buf, sdg -> dataluf??( luf ??) ); /* JES 90 */ DFCVe2aC( buf, charlen ); /* JES 90 */ } /* JES 90 */ else /* JES 90 */ { /* JES 90 */ charlen = 0; /* JES 90 */ buf = DFIgetspace( ( unsigned )( charlen+1 ) ); /* JES 90 */ if( buf==NULL ) /* JES 90 */ return(-1); /* JES 90 */ buf??( 0 ??) = '\0'; /* JES 90 */ } /* JES 90 */ /*********************************************/ /* JES 90 */ /* now write it out */ /* JES 90 */ /*********************************************/ /* JES 90 */ if( DFwrite( dfile, buf, charlen+1 ) < 0 ) /* JES 90 */ return( -1 ); /* JES 90 */ buf = DFIfreespace( buf ); /* JES 90 */ } /* JES 90 */ /*******************************************/ /* JES 90 */ /* if the data is already in ASCII, */ /* JES 90 */ /* just write it out */ /* JES 90 */ /*******************************************/ /* JES 90 */ else /* JES 90 */ { if (sdg->dataluf??(luf??)) { if( DFwrite( dfile, sdg->dataluf??(luf??), ( int32 )strlen( sdg->dataluf??(luf??))+1 ) < 0 ) return(-1); } else { /* write NULL */ if (DFwrite(dfile, "", (int32) 1)<0) return(-1); } /* JES 90 */ } /*******************************************/ /* write dim lufs */ /*******************************************/ for( j=0; jrank; j++ ) /* JES 90 */ { /* JES 90 */ /*******************************************/ /* JES 90 */ /* if the data is in EBCDIC, convert it */ /* JES 90 */ /* to ASCII before writing it out */ /* JES 90 */ /*******************************************/ /* JES 90 */ if( userCT == DFNTC_EBCDIC && /* JES 90 */ fileCT == DFNTC_ASCII ) /* JES 90 */ { /* JES 90 */ /*****************************************/ /* JES 90 */ /* allocate buf, copy the ebcdic string */ /* JES 90 */ /* to it and convert to ascii */ /* JES 90 */ /*****************************************/ /* JES 90 */ if( sdg->dimluf??(luf??) && /* JES 90 */ sdg->dimluf??(luf??)??(j??) ) /* JES 90 */ { /* JES 90 */ charlen = /* JES 90 */ strlen( sdg -> dimluf??(luf??)??(j??) ); /* JES 90 */ buf = DFIgetspace( (unsigned)(charlen+1) ); /* JES 90 */ if( buf==NULL ) /* JES 90 */ return(-1); /* JES 90 */ strcpy( buf, sdg -> dimluf??(luf??)??(j??) ); /* JES 90 */ DFCVe2aC( buf, charlen ); /* JES 90 */ } /* JES 90 */ else /* JES 90 */ { /* JES 90 */ charlen = 0; /* JES 90 */ buf = /* JES 90 */ DFIgetspace( ( unsigned )( charlen+1 ) ); /* JES 90 */ if( buf==NULL ) /* JES 90 */ return(-1); /* JES 90 */ buf??( 0 ??) = '\0'; /* JES 90 */ } /* JES 90 */ /*****************************************/ /* JES 90 */ /* now write it out */ /* JES 90 */ /*****************************************/ /* JES 90 */ if( DFwrite( dfile, buf, charlen+1 ) < 0 ) /* JES 90 */ return( -1 ); /* JES 90 */ buf = DFIfreespace( buf ); /* JES 90 */ } /* JES 90 */ /*******************************************/ /* JES 90 */ /* if the data is already in ASCII, */ /* JES 90 */ /* just write it out */ /* JES 90 */ /*******************************************/ /* JES 90 */ else /* JES 90 */ { if( sdg->dimluf??(luf??) && sdg->dimluf??(luf??)??(j??) ) { if (DFwrite(dfile, sdg->dimluf??(luf??)??(j??), (int32) strlen( sdg->dimluf??(luf??)??(j??))+1) < 0 ) return(-1); } else { /* write NULL */ if (DFwrite(dfile, "", (int32) 1)<0) return(-1); } /* JES 90 */ } /* JES 90 */ } Ref.luf??(luf??) = ref; /* remember ref */ break; } } } /************************************************************/ /* write luf tag/ref */ /************************************************************/ if (Ref.luf??(luf??)>0) if (DFdiput(luftag, (uint16)Ref.luf??(luf??)) < 0) return(-1); } /* check if there is a scale and write it out */ if (!Ref.scales) { /* if scale set */ Isscales = DFIgetspace((unsigned) sdg->rank); if (Isscales==NULL) return(-1); Ref.scales = (-1); /* assume there is no scale */ /* set up Isscales array */ for (i=0; irank; i++) { if (sdg->dimscales && sdg->dimscales??(i??)) { /* a scale exists */ Isscales??(i??) = 1; Ref.scales = 0; /* flag: write out scales */ } else Isscales??(i??) = 0; } } if (!Ref.scales) { /* write out scale */ if (DFaccess(dfile, DFTAG_SDS, ref, "w")<0) { Isscales = DFIfreespace(Isscales); return(-1); } /* write Isscales */ if (DFwrite(dfile, Isscales, (int32) sdg->rank)<0) { Isscales = DFIfreespace(Isscales); return(-1); } /* Write scales */ for (j=0; jrank; j++) { if (!Isscales??(j??)) continue; if (localNT==outNT) { /* no conversion needed */ if (DFwrite(dfile, (char*) sdg->dimscales??(j??), (int32) (sizeof(float32) * sdg->dimsizes??(j??)))<0) { Isscales = DFIfreespace(Isscales); return(-1); } } else { /* convert and write */ /* allocate buffer */ buf = DFIgetspace((unsigned) (outNTsize * sdg->dimsizes??(j??))); if (buf==NULL) { Isscales = DFIfreespace(Isscales); return(-1); } /* convert, all at once */ DFconvert((char*) sdg->dimscales??(j??), buf, DFNT_FLOAT, localNT, outNT, sdg->dimsizes??(j??), error); /* write it all out */ if (DFwrite(dfile, buf, (int32) (outNTsize * sdg->dimsizes??(j??)))<0) { Isscales = DFIfreespace(Isscales); buf = DFIfreespace(buf); return(-1); } buf = DFIfreespace(buf); } } Ref.scales = ref; } Isscales = DFIfreespace(Isscales); if (Ref.scales>0) if (DFdiput(DFTAG_SDS, (uint16) Ref.scales) < 0) return(-1); /*******************************************************/ /* write out coordsys */ /*******************************************************/ if( !sdg->coordsys || !sdg->coordsys??(0??) ) Ref.coordsys = (-1); if (!Ref.coordsys) { /*******************************************/ /* JES 90 */ /* if the data is in EBCDIC, convert it */ /* JES 90 */ /* to ASCII before writing it out */ /* JES 90 */ /*******************************************/ /* JES 90 */ if( userCT == DFNTC_EBCDIC && /* JES 90 */ fileCT == DFNTC_ASCII ) /* JES 90 */ { /* JES 90 */ /*********************************************/ /* JES 90 */ /* allocate buf, copy the ebcdic string to it*/ /* JES 90 */ /* and convert to ascii */ /* JES 90 */ /*********************************************/ /* JES 90 */ charlen = strlen( sdg -> coordsys ); /* JES 90 */ buf = DFIgetspace( ( unsigned )( charlen+1 ) ); /* JES 90 */ if( buf==NULL ) /* JES 90 */ return(-1); /* JES 90 */ strcpy( buf, sdg -> coordsys ); /* JES 90 */ DFCVe2aC( buf, charlen ); /* JES 90 */ /*********************************************/ /* JES 90 */ /* now write it out */ /* JES 90 */ /*********************************************/ /* JES 90 */ if( DFputelement( dfile, DFTAG_SDC, ref, buf, /* JES 90 */ ( int32 )(charlen+1) ) < 0 ) /* JES 90 */ return( -1 ); /* JES 90 */ buf = DFIfreespace( buf ); /* JES 90 */ } /* JES 90 */ /*******************************************/ /* JES 90 */ /* if the data is already in ASCII, */ /* JES 90 */ /* just write it out */ /* JES 90 */ /*******************************************/ /* JES 90 */ else /* JES 90 */ { /* JES 90 */ if( DFputelement( dfile, DFTAG_SDC, ref, sdg->coordsys, (int32) (strlen(sdg->coordsys)+1 ) ) < 0 ) return(-1); } /* JES 90 */ Ref.coordsys = ref; } if( Ref.coordsys>0 ) if( DFdiput( DFTAG_SDC, (uint16) Ref.coordsys ) < 0 ) return(-1); /***************************/ /* write max/min */ /***************************/ if (!Ref.maxmin) { if (localNT == outNT) { /* no conversion */ if( DFputelement( dfile, DFTAG_SDM, ref, (char*) &sdg->max_data, (int32) (2 * sizeof(float32)) ) < 0 ) return(-1); Ref.maxmin = ref; } else { /* allocate buffer */ #ifndef CVT_BUG float32 mm??(2??); mm??(0??) = sdg->max_data; mm??(1??) = sdg->min_data; #endif buf = DFIgetspace((unsigned) 2*outNTsize); /* max/min is 8 bytes */ if (buf==NULL) return(-1); /* convert */ #ifndef CVT_BUG DFconvert( (char*) mm, buf, DFNT_FLOAT, localNT, outNT,2, error ); #else DFconvert( (char*) &sdg->max_data, buf, DFNT_FLOAT, localNT, outNT, 1, error ); DFconvert( (char*) &sdg->min_data, buf+outNTsize, DFNT_FLOAT, localNT, outNT, 1, error ); #endif /* write */ if( DFputelement( dfile, DFTAG_SDM, ref, buf, (int32) (2*outNTsize) ) < 0 ) { buf = DFIfreespace(buf); return(-1); } Ref.maxmin = ref; buf = DFIfreespace(buf); } } if( Ref.maxmin > 0 ) if( DFdiput(DFTAG_SDM, (uint16) Ref.maxmin) < 0 ) return(-1); Ref.maxmin = (-1); /* max/min should be reset for each data set */ if (!Ref.transpose) { if (DFaccess(dfile, DFTAG_SDT, ref, "w")<0) return(-1); Ref.transpose = ref; } if (Ref.transpose>0) if (DFdiput(DFTAG_SDT, (uint16) Ref.transpose) < 0) return(-1); /* write out SDG */ return(DFdiwrite(dfile, DFTAG_SDG, ref)); } /*************************************************************************/ /*----------------------- Internal routines ---------------------------------*/ /*************************************************************************/ /*----------------------------------------------------------------------------- * Name: DFSDIopen * Purpose: open or reopen a file * Inputs: filename: name of file to open * access : access mode * Returns: file pointer on success, NULL on failure with DFerror set * Users: HDF systems programmers, many SD routines * Invokes: DFopen * Remarks: This is a hook for someday providing more efficient ways to * reopen a file, to avoid re-reading all the headers *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ DF *dsIopen(filename, access) /* JES 90 */ #else /* JES 90 */ DF *DFSDIopen(filename, access) #endif /* JES 90 */ char *filename; int access; { DF *dfile; if (Sdfile!=NULL) { /* in the middle of a partial write */ DFerror = DFE_ALROPEN; return(NULL); } /* use reopen if same file as last time - more efficient */ if (strncmp(Lastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) { /* treat create as different file */ if (!(dfile = DFopen(filename, access, -1))) return(NULL); Newdata = (-1); /* data in Readsdg is not fresh */ Readsdg.data.ref = 0; /* No SDG read yet */ /* remember no info written to file */ Ref.scales = (Ref.scales >= 0) ? 0 : Ref.scales; Ref.luf??(LABEL??) = (Ref.luf??(LABEL??) >= 0) ? 0 : Ref.luf??(LABEL??); Ref.luf??(UNIT??) = (Ref.luf??(UNIT??) >= 0) ? 0 : Ref.luf??(UNIT??); Ref.luf??(FORMAT??) = (Ref.luf??(FORMAT??) >= 0) ? 0 : Ref.luf??(FORMAT??); Ref.dims = (Ref.dims >= 0) ? 0 : Ref.dims; Ref.coordsys = (Ref.coordsys >= 0) ? 0 : Ref.coordsys; Ref.maxmin = (Ref.maxmin >= 0) ? 0 : Ref.maxmin; Ref.nt = (Ref.nt >= 0) ? 0 : Ref.nt; } else if (!(dfile = DFopen(filename, access, -1))) return(NULL); strncpy(Lastfile, filename, DF_MAXFNLEN); /* remember filename, so reopen may be used next time if same file*/ return(dfile); } /*----------------------------------------------------------------------------- * Name: DFSDIsdginfo * Purpose: Locates next sdg in file * Inputs: dfile: pointer to DF file * Returns: 0 on success, -1 on failure with DFerror set * Users: HDF systems programmers, DFSDgetdims, DFSDgetdata * Invokes: DFIfind, DFSDgetsdg * Method: Call DFIfind to find SDG, then DFSDgetsdg to read it in to Readsdg * Remarks: none *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsIsdginfo(dfile) /* JES 90 */ #else /* JES 90 */ DFSDIsdginfo(dfile) #endif /* JES 90 */ DF *dfile; { DFdle *dlep; int cdd; if (DFIcheck(dfile)) { DFerror = DFE_BADCALL; return(-1); } /* find next sdg */ if ((!Readref && DFIfind(dfile, DFTAG_SDG, DFREF_WILDCARD, !Readsdg.data.ref, DFTAG_SDG, Readsdg.data.ref, &dlep, &cdd) <0) || (Readref && DFIfind(dfile, DFTAG_SDG, Readref, 1, 0, 0, &dlep, &cdd) < 0)) { Newdata = (-1); DFerror = DFE_NOMATCH; return(-1); } #ifdef IBM /* JES 90 */ if (dsgsdg(dfile, dlep->dd??(cdd??).ref, &Readsdg)<0) return(-1);/*JES 90 */ #else /* JES 90 */ if (DFSDgetsdg(dfile, dlep->dd??(cdd??).ref, &Readsdg)<0) return(-1); #endif /* JES 90 */ Lastref = dlep->dd??(cdd??).ref; /* remember ref read */ /* now Readsdg is fresh */ Newdata=1; Readref = 0; return(0); } /*----------------------------------------------------------------------------- * Name: DFSDIclear * Purpose: Reset all "set" values, free allocated space * Inputs: sdg: pointer to sdg struct to clear * Globals: Ref * Returns: 0 on success, -1 on error with DFerror set * Users: HDF users, utilities, other routines * Invokes: none * Method: Release space in sdg * Remarks: none *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsIclear(sdg) /* JES 90 */ #else /* JES 90 */ int DFSDIclear(sdg) #endif /* JES 90 */ DFSsdg *sdg; { int luf, i; DFerror = DFE_NOERROR; if (Sdfile !=NULL) { /* cannot clear during slice writes */ DFerror = DFE_BADCALL; return(-1); } sdg->dimsizes = (int32 *) DFIfreespace((char*) sdg->dimsizes); sdg->coordsys = DFIfreespace(sdg->coordsys); /* free label/unit/format pointers */ for (luf=LABEL; luf<=FORMAT; luf++) { if (sdg->dimluf??(luf??)) /* free strings */ for (i=0; irank; i++) sdg->dimluf??(luf??)??(i??) = DFIfreespace(sdg->dimluf??(luf??)??(i??)); /* free string pointers */ sdg->dimluf??(luf??) = (char **) DFIfreespace((char*) sdg->dimluf??(luf??)); /* free data string */ sdg->dataluf??(luf??) = DFIfreespace(sdg->dataluf??(luf??)); } /* free scale pointers */ if (sdg->dimscales) for (i=0; irank; i++) sdg->dimscales??(i??) = (float32 *) DFIfreespace((char*) sdg->dimscales??(i??)); /* free array of scale pointers */ sdg->dimscales = (float32 **) DFIfreespace((char*)sdg->dimscales); sdg->rank = 0; Ref.dims = -1; Ref.scales = Ref.luf??(LABEL??) = Ref.luf??(UNIT??) = Ref.luf??(FORMAT??) = (-1); Ref.coordsys = Ref.maxmin = (-1); return(0); } /*----------------------------------------------------------------------------- * Name: DFSDIgetdata * Purpose: Get data from SDG. Will sequence to next SDG if DFSDgetdims not * called. * Inputs: filename: name of HDF file to use * rank: no of dimensions of array "data" * maxsizes: actual dimensions of array "data" * data: data for returning scientific data * isfortran : 0 if called from C, 1 when called from FORTRAN * Returns: 0 on success, -1 on failure with DFerror set * Outputs: actual scientific data in array * Users: DFSDgetdata * Invokes: DFSDIgetslice, DFIgetspace, DFIfreespace, DFSDIopen, DFclose, * DFIerr, DFSDIsdginfo * Method: Open file, call DFSDIsdginfo to read sdg if necessary, set up * window start and end arrays, call DFSDIgetslice. * Remarks: maxsizes may be larger than actual size. In that event, the actual * data may not be contiguous in the array "data" * User sets maxsizes before call. *---------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsIgetdata(filename, rank, maxsizes, data, isfortran) /* JES 90 */ #else /* JES 90 */ int DFSDIgetdata(filename, rank, maxsizes, data, isfortran) #endif /* JES 90 */ char *filename; int rank; int32 maxsizes??(??); float32 data??(??); int isfortran; { int32 *winst, *windims; int ret, i; DF *dfile; DFerror = DFE_NOERROR; if (Newdata!=1 || Nextsdg) { /* if Readsdg not fresh */ #ifdef IBM /* JES 90 */ dfile = dsIopen(filename, DFACC_READ); /* JES 90 */ #else /* JES 90 */ dfile = DFSDIopen(filename, DFACC_READ); #endif /* JES 90 */ if (dfile == NULL) return(-1); #ifdef IBM /* JES 90 */ if (dsIsdginfo(dfile)<0) /* reads next SDG from file */ /* JES 90 */ return(DFIerr(dfile)); /* JES 90 */ #else /* JES 90 */ if (DFSDIsdginfo(dfile)<0) /* reads next SDG from file */ return(DFIerr(dfile)); #endif /* JES 90 */ if (DFclose(dfile)<0) return(-1); } winst = (int32 *) DFIgetspace((unsigned) Readsdg.rank * sizeof(int32)); if (winst==NULL) return(-1); windims = (int32 *) DFIgetspace((unsigned) Readsdg.rank * sizeof(int32)); if (windims==NULL) { DFIfreespace((char*) winst); return(-1); } for (i=0; i Readsdg.dimsizes??(i??))) { DFerror = DFE_BADDIM; return(DFIerr(dfile)); } /* check if space allocated is sufficient */ if (dims??(i??)>8) & 0x0f; /* get third nibble from right*/ convert = (fileNT != userNT); /* is conversion necessary */ transposed = isfortran ^ FileTranspose; /* is transposition needed */ /* * Note that if the data is transposed we must work on a row by row * basis and cannot collapse dimensions. */ if (!transposed) { /* collapse dimensions if contiguous both in the file and in memory */ for (i=rank-1; i>0; i--) { /* stop before most sig dim */ if (adims??(i??) > wdims??(i??) /* not all of data??(??) will be filled */ || wstart??(i??) != 0 /* reading only part of the dataset */ || wdims??(i??) < fdims??(i??)) break; wdims??(i-1??) *= wdims??(i??); adims??(i-1??) = fdims??(i-1??) = wdims??(i-1??); rank--; } } leastsig = rank-1; /* which is least sig dim */ /* position at start of image */ if (DFaccess(dfile, Readsdg.data.tag, Readsdg.data.ref, "r") < 0) { DFIfreespace((char *)wstart); return(DFIerr(dfile)); } error = 0; if (rank==1 && !convert) { /* all data is contiguous with no conversions */ readsize = adims??(0??) * sizeof(float32); if (readsize != DFread(dfile, (char *)data, readsize)) error=1; } else { /* * The data must be further manipulated. * It may be transposed, may need conversion, may not be contiguous, or * any combination of these. */ numfloats = fdims??(leastsig??); readsize = numfloats * fileNTsize; /* allocate 1 row buffers */ if (convert) { if ((buf = DFIgetspace((unsigned) readsize)) == NULL) { DFIfreespace((char *)wstart); DFerror = DFE_NOSPACE; return(DFIerr(dfile)); } } else buf = NULL; if (transposed) { scatterbuf = (float32 *)DFIgetspace((unsigned) numfloats *sizeof(float32)); if (scatterbuf == NULL) { DFIfreespace((char *)wstart); DFIfreespace(buf); DFerror = DFE_NOSPACE; return(DFIerr(dfile)); } } else scatterbuf = NULL; offset = (int32 *) DFIgetspace((unsigned)3 * rank * sizeof(int32)); if (offset==NULL) { DFIfreespace((char *)wstart); DFIfreespace(buf); DFIfreespace((char *)scatterbuf); DFerror = DFE_NOSPACE; return(DFIerr(dfile)); } foffset = offset + rank; dimsleft = foffset + rank; /* compute initial position in the data */ for (i=leastsig; i>=0; i--) dimsleft??(i??) = wdims??(i??); /* compute offsets in the source array */ for (i=leastsig, offset??(i??)=1; i>0; i--) offset??(i-1??) = offset??(i??) * adims??(i??); if (transposed) for (i=0; i<=(leastsig-1)/2; i++) { int t; t = offset??(i??); offset??(i??) = offset??(leastsig-i??); offset??(leastsig-i??) = t; t = dimsleft??(i??); dimsleft??(i??) = dimsleft??(leastsig-i??); dimsleft??(leastsig-i??) = t; } stride = offset??(leastsig??); /* compute offsets in the file */ for (i=leastsig, foffset??(i??)=1*fileNTsize; i>0; i--) foffset??(i-1??) = foffset??(i??) * fdims??(i??); /* * Compute starting position in file * All file reads are done relative to this starting offset. * Cumulative offset is from most sig to next to least sig dim. */ for (i=0, fileoffset=0; i=0; i--) { if (--dimsleft??(i??) > 0) { /* move to next element in the current dimension */ datap += offset??(i??); fileoffset += foffset??(i??); break; } else { dimsleft??(i??) = wdims??(i??); /* * Note that we are still positioned at the beginning of * the last element in the current dimension */ /* move back to the beginning of dimension i */ datap -= offset??(i??) * (wdims??(i??)-1); /* move back to beginning read position of dimension i */ fileoffset -= foffset??(i??) * (wdims??(i??)-1); if (i==0) done = 1; } } } while (!done && leastsig > 0); DFIfreespace(buf); DFIfreespace((char *)scatterbuf); DFIfreespace((char *)offset); } DFIfreespace((char *)wstart); return( error ? DFIerr(dfile) : DFclose(dfile) ); } /*---------------------------------------------------------------------------- * Name: DFSDIputslice * Purpose: Put slice of data to SDG. * Inputs: windims: array of size rank, containing size of slice * data: array containing slice * dims: dimensions of array data * isfortran: 0 for C, 1 for Fortran * Returns: 0 on success, -1 on failure with DFerror set * Users: DFSDputslice * Invokes: DFwrite, DFIgetspace, DFIfreespace * Method: check dimensions for contiguity, convert types if necessary * write to file * Remarks: dims may be larger than size of slice. In that event, the actual * data may not be contiguous in the array "data". * DFSDstartslice must have been called first * Note, writes must be contiguous - successive calls to putslice * must write out array consecutively, according to the setting * of the Fortorder variable - row major if 0, column major if 1 *--------------------------------------------------------------------------*/ #ifdef IBM /* JES 90 */ int dsIputslice(windims, data, dims, isfortran) /* JES 90 */ #else /* JES 90 */ int DFSDIputslice(windims, data, dims, isfortran) #endif /* JES 90 */ int32 windims??(??); /* array containing dimensions of the slice */ int32 dims??(??); /* array containing the dimensions of data??(??) */ float32 data??(??); /* array of the floating point data to write */ int isfortran; /* true if called from Fortran */ { int rank, /* number of dimensions in data??(??) */ ret, /* return code from DFwrite */ leastsig; /* fastest varying subscript in the array */ int convert, /* true if machine NT = NT to be written */ done, /* true if we are at end of the slice */ transposed, /* true if we must transpose */ /* the data before writing */ contiguous; /* true if there are no gaps */ /* in the data to be written */ int error; /* used by DFconvert macro */ int32 i, j, /* temporaries */ numfloats, /* number of floats to write out per row */ writesize, /* number of bytes to write out per row */ stride, /* number of bytes in one row of data??(??) */ *dimsleft, /* array for tracking the */ /* current position in data??(??) */ *offset; /* array for accessing the */ /* next element in data??(??) */ float32 *datap, /* pointer into data??(??) at */ /* the start of the current row */ *dp, /* pointer into data??(??) to an element */ /* of the current row */ *gatherbuf; /* buffer to hold the current row */ /* contiguously */ char *buf, /* buffer containing the */ /* converted current row */ *outbufp; /* pointer to the buffer containing */ /* the data to write */ DFerror = DFE_NOERROR; if (!data) { DFerror = DFE_BADPTR; return(-1); } if (!Sdfile) { DFerror = DFE_BADCALL; return(-1); } rank = Writesdg.rank; for (i=0; iWritesdg.dimsizes??(i??))) { DFerror = DFE_BADDIM; return(-1); } /* check if space allocated is sufficient */ if (dims??(i??) < windims??(i??)) { DFerror = DFE_NOTENOUGH; return(-1); } } /* check to see if the slices fit together */ if (Fortorder) { /* find the first significant dimension */ for (i=rank-1; windims??(i??) == 1 && i>0; i--) ; /* check that all 'lesser' dims match */ for (j=i-1; j>=0; j--) if (dims??(j??) != windims??(j??)) { DFerror = DFE_BADDIM; return (-1); } /* update Sddims to reflect new write */ Sddims??(i??) += windims??(i??); for (; i= dims??(i??); i++) { Sddims??(i+1??) += Sddims??(i??) / dims??(i??); /* promote the unit */ Sddims??(i??) %= dims??(i??); } } else { /* find the first significant dimension */ for (i=0; windims??(i??) == 1 && i0 && Sddims??(i??) >= dims??(i??); i--) { Sddims??(i-1??) += Sddims??(i??) / dims??(i??); /* promote the unit */ Sddims??(i??) %= dims??(i??); } } leastsig = Fortorder ? 0 : rank-1; /* which is least sig dim */ userNT = (DF_MT>>8) & 0x0f; /* get third nibble from right */ convert = (outNT != userNT); /* is conversion necessary */ transposed = isfortran ^ Fortorder; /* is data transposition needed */ contiguous = !transposed; for (i=0; contiguous && i Writesdg.dimsizes??(i??)) contiguous = 0; } /* * 3 Factors that determine how we write (in order of importance) * transposed, conversion, contiguous */ if (!transposed) { if (!convert && contiguous) { /* compute total number of floats to write */ for (i=0, numfloats=1; i0; i--) j *= windims??(i??); else for (i=0, j=1; i 0; i--) offset??(i-1??) = offset??(i??)*dims??(i??); stride = offset??(leastsig??); /* step thru the data on a row by row basis */ do { /* gather the elements of one row together */ #ifdef UNICOS #pragma ivdep #endif for (dp=datap, i=0; i 0) { /* move to next element in the current dimension */ datap += offset??(i??); break; } else { /* move back to the beginning of dimension i */ datap -= offset??(i??)*(dimsleft??(i??) = windims??(i??)); datap += offset??(i??); if (i == rank-1) done = 1; } } } else { /* !Fortorder */ for (i=rank-2; i>=0; i--) { if (--dimsleft??(i??) > 0) { /* move to next element in the current dimension */ datap += offset??(i??); break; } else { /* move back to the beginning of dimension i */ datap -= offset??(i??)*(dimsleft??(i??) = windims??(i??)); datap += offset??(i??); if (i == 0) done = 1; } } } } while (!done && ret >= 0 && rank > 1); DFIfreespace(buf); DFIfreespace((char *)gatherbuf); DFIfreespace((char *)offset); } return(ret>=0 ? 0 : -1); } /*************************************************************************/ /*----------------------- Internal routines ---------------------------------*/ /*************************************************************************/ /*----------------------------------------------------------------------------- * Name: dsisdas_ * Purpose: Set label, unit and format for displaying subsequent SDGs * Inputs: label: label to be used to describe data * unit: unit corresponding to data values * format: format to be used in displaying data values * coordsys: type of coordinate system * isfortran: 1 if called from Fortran, 0 if called from C * llabel, lunit, lformat, lcoordsys: lengths of correspoding strings * Globals: Writesdg, Ref * Returns: 0 on success, -1 on failure with DFerror set * Users: HDF users, utilities, other routines * Invokes: none * Method: Stores values in global structure Writesdg * Remarks: none *---------------------------------------------------------------------------*/ FCALLKEYW int dsisdas_(label, unit, format, coordsys, isfortran, llabel, lunit, lformat, lcoordsys) char *label, *unit, *format, *coordsys; int *isfortran; int *llabel, *lunit, *lformat, *lcoordsys; { int luf; /* takes values LABEL, UNIT, FORMAT in succession */ char *lufp; /* points to label, unit, format in succession */ int luflen; /* length of luf */ DFerror = DFE_NOERROR; for (luf=LABEL; luf<=FORMAT; luf++) { /* set lufp to point to label etc. as apppropriate */ lufp = (luf==LABEL) ? label : (luf==UNIT) ? unit : format; if (*isfortran) luflen = (luf==LABEL) ? *llabel : (luf==UNIT) ? *lunit : *lformat; else luflen = strlen(lufp); /* free space if allocated */ Writesdg.dataluf??(luf??) = DFIfreespace(Writesdg.dataluf??(luf??)); /* copy string */ if (lufp) { Writesdg.dataluf??(luf??) = DFIgetspace((unsigned) luflen+1); if (Writesdg.dataluf??(luf??)==NULL) return(-1); strncpy(Writesdg.dataluf??(luf??), lufp, luflen); Writesdg.dataluf??(luf??)??(luflen??) = '\0'; } } Writesdg.coordsys = DFIfreespace(Writesdg.coordsys); luflen = *isfortran ? *lcoordsys : strlen(coordsys); if (coordsys) { Writesdg.coordsys = DFIgetspace((unsigned) luflen+1); if (Writesdg.coordsys==NULL) return(-1); strncpy(Writesdg.coordsys, coordsys, luflen); Writesdg.coordsys??(luflen??) = '\0'; } /* indicate that label, unit, format and coordsys info modified */ Ref.luf??(LABEL??) = Ref.luf??(UNIT??) = Ref.luf??(FORMAT??) = Ref.coordsys = 0; return(0); } /*----------------------------------------------------------------------------- * Name: dsisdis_ * Purpose: For the given dimension, set label, unit, format * This routine needs to be called once for each dimension whose * values the user wants to set. * Inputs: dim: the dimension that this info applies to * label: label to be used to describe this dimension * unit: units for dimension * format: format to be used in displaying * isfortran: 1 if called from Fortran, 0 otherwise * llabel, lunit, lformat: lengths of corresponding strings * Globals: Writesdg, Ref * Returns: 0 on success, -1 on failure with DFerror set * Users: HDF users, utilities, other routines * Invokes: none * Method: Stores values in global structure Writesdg *---------------------------------------------------------------------------*/ FCALLKEYW int dsisdis_(dim, label, unit, format, isfortran, llabel, lunit, lformat) int *dim; char *label, *unit, *format; int *isfortran; int *llabel, *lunit, *lformat; { int i, rdim; int luf; /* takes values LABEL, UNIT, FORMAT in succession */ char *lufp; /* points to label, unit, format in succession */ int luflen; /* length of lufp */ DFerror = DFE_NOERROR; rdim = *dim-1; /* translate from 1 to 0 origin */ if ((rdim>=Writesdg.rank) || (rdim<0)) { DFerror = DFE_BADDIM; return(-1); } for (luf=LABEL; luf<=FORMAT; luf++) { /* set lufp to point to label etc. as apppropriate */ lufp = (luf==LABEL) ? label : (luf==UNIT) ? unit : format; if (*isfortran) luflen = (luf==LABEL) ? *llabel : (luf==UNIT) ? *lunit : *lformat; else luflen = strlen(lufp); /* allocate space if necessary */ if (!Writesdg.dimluf??(luf??)) { Writesdg.dimluf??(luf??) = (char **) DFIgetspace((unsigned)Writesdg.rank * sizeof(char *)); if (Writesdg.dimluf??(luf??)==NULL) return(-1); for (i=0; i