LCOV - code coverage report
Current view: top level - frmts/hdf4/hdf-eos - GDapi.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 421 732 57.5 %
Date: 2026-09-18 08:43:21 Functions: 19 24 79.2 %

          Line data    Source code
       1             : /*****************************************************************************
       2             :  *
       3             :  * This module has a number of additions and improvements over the original
       4             :  * implementation to be suitable for usage in GDAL HDF driver.
       5             :  *
       6             :  * Andrey Kiselev <dron@ak4719.spb.edu> is responsible for all the changes.
       7             :  ****************************************************************************/
       8             : 
       9             : /*
      10             : Copyright (C) 1996 Hughes and Applied Research Corporation
      11             : 
      12             : Permission to use, modify, and distribute this software and its documentation
      13             : for any purpose without fee is hereby granted, provided that the above
      14             : copyright notice appear in all copies and that both that copyright notice and
      15             : this permission notice appear in supporting documentation.
      16             : */
      17             : /*****************************************************************************
      18             : REVISIONS:
      19             : 
      20             : Aug 31, 1999  Abe Taaheri    Changed memory allocation for utility strings to
      21             :                              the size of UTLSTR_MAX_SIZE.
      22             :            Added error check for memory unavailability in
      23             :            several functions.
      24             :            Added check for NULL metabuf returned from
      25             :            EHmeta... functions. NULL pointer returned from
      26             :            EHmeta... functions indicate that memory could not
      27             :            be allocated for metabuf.
      28             : Jun  27, 2000  Abe Taaheri   Added support for EASE grid that uses
      29             :                              Behrmann Cylinderical Equal Area (BCEA) projection
      30             : Oct  23, 2000  Abe Taaheri   Updated for ISINUS projection, so that both codes
      31             :                              31 and 99 can be used for this projection.
      32             : Jan  15, 2003   Abe Taaheri  Modified for generalization of EASE Grid.
      33             : 
      34             : Jun  05, 2003 Bruce Beaumont / Abe Taaheri
      35             : 
      36             :                              Fixed SQUARE definition.
      37             :                              Added static projection number/name translation
      38             :                              Added projection table lookup in GDdefproj.
      39             :                              Removed projection table from GDdefproj
      40             :                              Added projection table lookup in GDprojinfo
      41             :                              Removed projection table from GDprojinfo
      42             :                              Added cast for compcode in call to SDsetcompress
      43             :                                 in GDdeffield to avoid compiler errors
      44             :                              Removed declaration for unused variable endptr
      45             :                                 in GDSDfldsrch
      46             :                              Removed initialization code for unused variables
      47             :                                 in GDSDfldsrch
      48             :                              Removed declarations for unused variables
      49             :                                 BCEA_scale, r0, s0, xMtr0, xMtr1, yMtr0,
      50             :                                 and yMtr1 in GDll2ij
      51             :                              Removed initialization code for unused variables
      52             :                                 in GDll2ij
      53             :                              Added code in GEO projection handling to allow
      54             :                                 map to span dateline in GDll2ij
      55             :                              Changed "for each point" loop in GDll2ij to
      56             :                                 return -2147483648.0 for xVal and yVal if
      57             :                                 for_trans returned an error instead of
      58             :                                 returning an error to the caller
      59             :                                 (Note: MAXLONG is defined as 2147483647.0 in
      60             :                                  function cproj.c of GCTP)
      61             :                              Added code in GDij2ll to use for_trans to
      62             :                                 translate the BCEA corner points from packed
      63             :                                 degrees to meters
      64             :                              Removed declarations for unused variables
      65             :                                 BCEA_scale, r0, s0, xMtr, yMtr, epsilon,
      66             :                                 beta, qp_cea, kz_cea, eccen, eccen_sq,
      67             :                                 phi1, sinphi1, cosphi1, lon, lat, xcor,
      68             :                                 ycor, and nlatlon from GDij2ll
      69             :                              Removed initialization code for unused variables
      70             :                                 in GDij2ll
      71             :                              Added declarations for xMtr0, yMtr0, xMtr1, and
      72             :                                 yMtr1 in GDij2ll
      73             :                              Added special-case code for BCEA
      74             :                              Changed "for each point" loop in GDij2ll to
      75             :                                 return PGSd_GCT_IN_ERROR (1.0e51) for
      76             :                                 longitude and latitude values if inv_trans
      77             :                                 returned an error instead of return an error
      78             :                                 to the caller
      79             :                              Removed declaration for unused variable ii in
      80             :                                 GDgetpixvalues
      81             :                              Removed declaration for unused variable
      82             :                                 numTileDims in GDtileinfo
      83             :                              Added error message and error return at the
      84             :                                 end of GDll2mm_cea
      85             :                              Added return statement to GDll2mm_cea
      86             : ******************************************************************************/
      87             : #include "cpl_string.h"
      88             : #include "stdio.h"
      89             : #include "mfhdf.h"
      90             : #include "hcomp.h"
      91             : #include <math.h>
      92             : #include "HdfEosDef.h"
      93             : #include "hfile.h"
      94             : 
      95             : #include "hdf4compat.h"
      96             : 
      97             : #define GDIDOFFSET 4194304
      98             : #define SQUARE(x)       ((x) * (x))   /* x**2 */
      99             : 
     100             : 
     101             : #define NGRID 200
     102             : /* Grid Structure External Arrays */
     103             : struct gridStructure
     104             : {
     105             :     int32 active;
     106             :     int32 IDTable;
     107             :     int32 VIDTable[2];
     108             :     int32 fid;
     109             :     int32 nSDS;
     110             :     int32 *sdsID;
     111             :     int32 compcode;
     112             :     intn  compparm[5];
     113             :     int32 tilecode;
     114             :     int32 tilerank;
     115             :     int32 tiledims[8];
     116             : };
     117             : static struct gridStructure GDXGrid[NGRID];
     118             : 
     119             : 
     120             : 
     121             : #define NGRIDREGN 256
     122             : struct gridRegion
     123             : {
     124             :     int32 fid;
     125             :     int32 gridID;
     126             :     int32 xStart;
     127             :     int32 xCount;
     128             :     int32 yStart;
     129             :     int32 yCount;
     130             :     int32 somStart;
     131             :     int32 somCount;
     132             :     float64 upleftpt[2];
     133             :     float64 lowrightpt[2];
     134             :     int32 StartVertical[8];
     135             :     int32 StopVertical[8];
     136             :     char *DimNamePtr[8];
     137             : };
     138             : static struct gridRegion *GDXRegion[NGRIDREGN];
     139             : 
     140             : /* define a macro for the string size of the utility strings and some dimension
     141             :    list strings. The value of 80 in the previous version of this code
     142             :    may not be enough in some cases. The length now is 512 which seems to
     143             :    be more than enough to hold larger strings. */
     144             : 
     145             : #define UTLSTR_MAX_SIZE 512
     146             : 
     147             : /* Static projection table */
     148             : static const struct {
     149             :     int32 projcode;
     150             :     const char *projname;
     151             : } Projections[] = {
     152             :     {GCTP_GEO,     "GCTP_GEO"},
     153             :     {GCTP_UTM,     "GCTP_UTM"},
     154             :     {GCTP_SPCS,    "GCTP_SPCS"},
     155             :     {GCTP_ALBERS,  "GCTP_ALBERS"},
     156             :     {GCTP_LAMCC,   "GCTP_LAMCC"},
     157             :     {GCTP_MERCAT,  "GCTP_MERCAT"},
     158             :     {GCTP_PS,    "GCTP_PS"},
     159             :     {GCTP_POLYC,   "GCTP_POLYC"},
     160             :     {GCTP_EQUIDC,  "GCTP_EQUIDC"},
     161             :     {GCTP_TM,    "GCTP_TM"},
     162             :     {GCTP_STEREO,  "GCTP_STEREO"},
     163             :     {GCTP_LAMAZ,   "GCTP_LAMAZ"},
     164             :     {GCTP_AZMEQD,  "GCTP_AZMEQD"},
     165             :     {GCTP_GNOMON,  "GCTP_GNOMON"},
     166             :     {GCTP_ORTHO,   "GCTP_ORTHO"},
     167             :     {GCTP_GVNSP,   "GCTP_GVNSP"},
     168             :     {GCTP_SNSOID,  "GCTP_SNSOID"},
     169             :     {GCTP_EQRECT,  "GCTP_EQRECT"},
     170             :     {GCTP_MILLER,  "GCTP_MILLER"},
     171             :     {GCTP_VGRINT,  "GCTP_VGRINT"},
     172             :     {GCTP_HOM,     "GCTP_HOM"},
     173             :     {GCTP_ROBIN,   "GCTP_ROBIN"},
     174             :     {GCTP_SOM,     "GCTP_SOM"},
     175             :     {GCTP_ALASKA,  "GCTP_ALASKA"},
     176             :     {GCTP_GOOD,    "GCTP_GOOD"},
     177             :     {GCTP_MOLL,    "GCTP_MOLL"},
     178             :     {GCTP_IMOLL,   "GCTP_IMOLL"},
     179             :     {GCTP_HAMMER,  "GCTP_HAMMER"},
     180             :     {GCTP_WAGIV,   "GCTP_WAGIV"},
     181             :     {GCTP_WAGVII,  "GCTP_WAGVII"},
     182             :     {GCTP_OBLEQA,  "GCTP_OBLEQA"},
     183             :     {GCTP_ISINUS1, "GCTP_ISINUS1"},
     184             :     {GCTP_CEA,     "GCTP_CEA"},
     185             :     {GCTP_BCEA,    "GCTP_BCEA"},
     186             :     {GCTP_ISINUS,  "GCTP_ISINUS"},
     187             :     {-1,     NULL}
     188             : };
     189             : 
     190             : /* Grid Function Prototypes (internal routines) */
     191             : static intn GDchkgdid(int32, const char *, int32 *, int32 *, int32 *);
     192             : static intn GDSDfldsrch(int32, int32, const char *, int32 *, int32 *,
     193             :                         int32 *, int32 *, int32 [], int32 *);
     194             : static intn GDwrrdfield(int32, const char *, const char *,
     195             :                         int32 [], int32 [], int32 [], VOIDP datbuf);
     196             : static intn GDwrrdattr(int32, const char *, int32, int32, const char *, VOIDP);
     197             : static intn GDwrrdtile(int32, const char *, const char *, int32 [], VOIDP);
     198             : 
     199             : /*----------------------------------------------------------------------------|
     200             : |  BEGIN_PROLOG                                                               |
     201             : |                                                                             |
     202             : |  FUNCTION: GDopen                                                           |
     203             : |                                                                             |
     204             : |  DESCRIPTION: Opens or creates HDF file in order to create, read, or write  |
     205             : |                a grid.                                                      |
     206             : |                                                                             |
     207             : |                                                                             |
     208             : |  Return Value    Type     Units     Description                             |
     209             : |  ============   ======  =========   =====================================   |
     210             : |  fid            int32               HDF-EOS file ID                         |
     211             : |                                                                             |
     212             : |  INPUTS:                                                                    |
     213             : |  filename       char                Filename                                |
     214             : |  l_access         intn                HDF l_access code                         |
     215             : |                                                                             |
     216             : |                                                                             |
     217             : |  OUTPUTS:                                                                   |
     218             : |             None                                                            |
     219             : |                                                                             |
     220             : |  NOTES:                                                                     |
     221             : |                                                                             |
     222             : |                                                                             |
     223             : |   Date     Programmer   Description                                         |
     224             : |  ======   ============  =================================================   |
     225             : |  Jun 96   Joel Gales    Original Programmer                                 |
     226             : |                                                                             |
     227             : |  END_PROLOG                                                                 |
     228             : -----------------------------------------------------------------------------*/
     229             : int32
     230          26 : GDopen(const char *filename, intn l_access)
     231             : 
     232             : {
     233             :     int32           fid /* HDF-EOS file ID */ ;
     234             : 
     235             :     /* Call EHopen to perform file l_access */
     236             :     /* ---------------------------------- */
     237          26 :     fid = EHopen(filename, l_access);
     238             : 
     239          26 :     return (fid);
     240             : 
     241             : }
     242             : 
     243             : 
     244             : /*----------------------------------------------------------------------------|
     245             : |  BEGIN_PROLOG                                                               |
     246             : |                                                                             |
     247             : |  FUNCTION: GDattach                                                         |
     248             : |                                                                             |
     249             : |  DESCRIPTION: Attaches to an existing grid within the file.                 |
     250             : |                                                                             |
     251             : |                                                                             |
     252             : |  Return Value    Type     Units     Description                             |
     253             : |  ============   ======  =========   =====================================   |
     254             : |  gridID         int32               grid structure ID                       |
     255             : |                                                                             |
     256             : |  INPUTS:                                                                    |
     257             : |  fid            int32               HDF-EOS file id                         |
     258             : |  gridname       char                grid structure name                     |
     259             : |                                                                             |
     260             : |                                                                             |
     261             : |  OUTPUTS:                                                                   |
     262             : |             None                                                            |
     263             : |                                                                             |
     264             : |  NOTES:                                                                     |
     265             : |                                                                             |
     266             : |                                                                             |
     267             : |   Date     Programmer   Description                                         |
     268             : |  ======   ============  =================================================   |
     269             : |  Jun 96   Joel Gales    Original Programmer                                 |
     270             : |  Sep 99   Abe Taaheri   Modified test for memory allocation check when no   |
     271             : |                         SDSs are in the grid, NCR24147                    |
     272             : |                                                                             |
     273             : |  END_PROLOG                                                                 |
     274             : -----------------------------------------------------------------------------*/
     275             : int32
     276          13 : GDattach(int32 fid, const char *gridname)
     277             : 
     278             : {
     279             :     intn            i;    /* Loop index */
     280             :     intn            j;    /* Loop index */
     281          13 :     intn            ngridopen = 0;  /* # of grid structures open */
     282             :     intn            status; /* routine return status variable */
     283             : 
     284             :     uint8           acs;  /* Read/Write file l_access code */
     285             : 
     286             :     int32           HDFfid; /* HDF file id */
     287             :     int32           vgRef;  /* Vgroup reference number */
     288             :     int32           vgid[3];  /* Vgroup ID array */
     289          13 :     int32           gridID = -1;/* HDF-EOS grid ID */
     290             :     int32          *tags; /* Pnt to Vgroup object tags array */
     291             :     int32          *refs; /* Pnt to Vgroup object refs array */
     292             :     int32           dum;  /* dummy variable */
     293             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
     294             :     int32           nObjects; /* # of objects in Vgroup */
     295             :     int32           nSDS; /* SDS counter */
     296             :     int32           l_index;  /* SDS l_index */
     297             :     int32           sdid; /* SDS object ID */
     298          13 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
     299             : 
     300             :     char            name[80]; /* Vgroup name */
     301             :     char            class[80];  /* Vgroup class */
     302             :     char            errbuf[256];/* Buffer for error message */
     303             :     char            acsCode[1]; /* Read/Write l_access char: "r/w" */
     304             : 
     305             : 
     306             :     /* Check HDF-EOS file ID, get back HDF file ID and l_access code */
     307             :     /* ----------------------------------------------------------- */
     308          13 :     status = EHchkfid(fid, gridname, &HDFfid, &dum, &acs);
     309             : 
     310             : 
     311          13 :     if (status == 0)
     312             :     {
     313             :   /* Convert numeric l_access code to character */
     314             :   /* ---------------------------------------- */
     315             : 
     316          13 :   acsCode[0] = (acs == 1) ? 'w' : 'r';
     317             : 
     318             :   /* Determine number of grids currently opened */
     319             :   /* ------------------------------------------- */
     320        2613 :   for (i = 0; i < NGRID; i++)
     321             :   {
     322        2600 :       ngridopen += GDXGrid[i].active;
     323             :   }
     324             : 
     325             : 
     326             :   /* If room for more ... */
     327             :   /* -------------------- */
     328          13 :   if (ngridopen < NGRID)
     329             :   {
     330             : 
     331             :       /* Search Vgroups for Grid */
     332             :       /* ------------------------ */
     333          13 :       vgRef = -1;
     334             : 
     335             :       while (1)
     336             :       {
     337          67 :     vgRef = Vgetid(HDFfid, vgRef);
     338             : 
     339             :     /* If no more Vgroups then exist while loop */
     340             :     /* ---------------------------------------- */
     341          67 :     if (vgRef == -1)
     342             :     {
     343           0 :         break;
     344             :     }
     345             : 
     346             :     /* Get name and class of Vgroup */
     347             :     /* ---------------------------- */
     348          67 :     vgid[0] = Vattach(HDFfid, vgRef, "r");
     349          67 :     VgetnameSafe(vgid[0], name, sizeof(name));
     350             : #if LIBVER_MAJOR == 4 && LIBVER_MINOR >= 4
     351             :         size_t sz = sizeof(class);
     352             :         Vgetclass(vgid[0], class, &sz);
     353             : #else
     354          67 :     Vgetclass(vgid[0], class);
     355             : #endif
     356             : 
     357             :     /*
     358             :      * If Vgroup with gridname and class GRID found, load tables
     359             :      */
     360             : 
     361          67 :     if (strcmp(name, gridname) == 0 &&
     362          13 :         strcmp(class, "GRID") == 0)
     363             :     {
     364             :         /* Attach to "Data Fields" and "Grid Attributes" Vgroups */
     365             :         /* ----------------------------------------------------- */
     366          13 :         tags = (int32 *) malloc(sizeof(int32) * 2);
     367          13 :         if(tags == NULL)
     368             :         {
     369           0 :       HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
     370           0 :       return(-1);
     371             :         }
     372          13 :         refs = (int32 *) malloc(sizeof(int32) * 2);
     373          13 :         if(refs == NULL)
     374             :         {
     375           0 :       HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
     376           0 :       free(tags);
     377           0 :       return(-1);
     378             :         }
     379          13 :         Vgettagrefs(vgid[0], tags, refs, 2);
     380          13 :         vgid[1] = Vattach(HDFfid, refs[0], acsCode);
     381          13 :         vgid[2] = Vattach(HDFfid, refs[1], acsCode);
     382          13 :         free(tags);
     383          13 :         free(refs);
     384             : 
     385             : 
     386             :         /* Setup External Arrays */
     387             :         /* --------------------- */
     388          19 :         for (i = 0; i < NGRID; i++)
     389             :         {
     390             :       /* Find empty entry in array */
     391             :       /* ------------------------- */
     392          19 :       if (GDXGrid[i].active == 0)
     393             :       {
     394             :           /*
     395             :            * Set gridID, Set grid entry active, Store root
     396             :            * Vgroup ID, Store sub Vgroup IDs, Store HDF-EOS
     397             :            * file ID
     398             :            */
     399          13 :           gridID = i + idOffset;
     400          13 :           GDXGrid[i].active = 1;
     401          13 :           GDXGrid[i].IDTable = vgid[0];
     402          13 :           GDXGrid[i].VIDTable[0] = vgid[1];
     403          13 :           GDXGrid[i].VIDTable[1] = vgid[2];
     404          13 :           GDXGrid[i].fid = fid;
     405          13 :           break;
     406             :       }
     407             :         }
     408             : 
     409             :         /* Get SDS interface ID */
     410             :         /* -------------------- */
     411          13 :         status = GDchkgdid(gridID, "GDattach", &dum,
     412             :                &sdInterfaceID, &dum);
     413          13 :             if( status < 0)
     414           0 :                 return -1;
     415             : 
     416             :         /* Get # of entries within Data Vgroup & search for SDS */
     417             :         /* ---------------------------------------------------- */
     418          13 :         nObjects = Vntagrefs(vgid[1]);
     419             : 
     420          13 :         if (nObjects > 0)
     421             :         {
     422             :       /* Get tag and ref # for Data Vgroup objects */
     423             :       /* ----------------------------------------- */
     424           5 :       tags = (int32 *) malloc(sizeof(int32) * nObjects);
     425           5 :       if(tags == NULL)
     426             :       {
     427           0 :           HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
     428           0 :           return(-1);
     429             :       }
     430           5 :       refs = (int32 *) malloc(sizeof(int32) * nObjects);
     431           5 :       if(refs == NULL)
     432             :       {
     433           0 :           HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
     434           0 :           free(tags);
     435           0 :           return(-1);
     436             :       }
     437           5 :       Vgettagrefs(vgid[1], tags, refs, nObjects);
     438             : 
     439             :       /* Count number of SDS & allocate SDS ID array */
     440             :       /* ------------------------------------------- */
     441           5 :       nSDS = 0;
     442          10 :       for (j = 0; j < nObjects; j++)
     443             :       {
     444           5 :           if (tags[j] == DFTAG_NDG)
     445             :           {
     446           5 :         nSDS++;
     447             :           }
     448             :       }
     449           5 :       GDXGrid[i].sdsID = (int32 *) calloc(nSDS, 4);
     450           5 :       if(GDXGrid[i].sdsID == NULL && nSDS != 0)
     451             :       {
     452           0 :           HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
     453           0 :           free(tags);
     454           0 :           free(refs);
     455           0 :           return(-1);
     456             :       }
     457           5 :       nSDS = 0;
     458             : 
     459             : 
     460             : 
     461             :       /* Fill SDS ID array */
     462             :       /* ----------------- */
     463          10 :       for (j = 0; j < nObjects; j++)
     464             :       {
     465             :           /* If object is SDS then get id */
     466             :           /* ---------------------------- */
     467           5 :           if (tags[j] == DFTAG_NDG)
     468             :           {
     469           5 :         l_index = SDreftoindex(sdInterfaceID, refs[j]);
     470           5 :         sdid = SDselect(sdInterfaceID, l_index);
     471           5 :         GDXGrid[i].sdsID[nSDS] = sdid;
     472           5 :         nSDS++;
     473           5 :         GDXGrid[i].nSDS++;
     474             :           }
     475             :       }
     476           5 :       free(tags);
     477           5 :       free(refs);
     478             :         }
     479          13 :         break;
     480             :     }
     481             : 
     482             :     /* Detach Vgroup if not desired Grid */
     483             :     /* --------------------------------- */
     484          54 :     Vdetach(vgid[0]);
     485             :       }
     486             : 
     487             :       /* If Grid not found then set up error message */
     488             :       /* ------------------------------------------- */
     489          13 :       if (gridID == -1)
     490             :       {
     491           0 :     HEpush(DFE_RANGE, "GDattach", __FILE__, __LINE__);
     492           0 :     HEreport("Grid: \"%s\" does not exist within HDF file.\n",
     493             :        gridname);
     494             :       }
     495             :   }
     496             :   else
     497             :   {
     498             :       /* Too many files opened */
     499             :       /* --------------------- */
     500           0 :       gridID = -1;
     501           0 :       strcpy(errbuf,
     502             :        "No more than %d grids may be open simultaneously");
     503           0 :       strcat(errbuf, " (%s)");
     504           0 :       HEpush(DFE_DENIED, "GDattach", __FILE__, __LINE__);
     505           0 :       HEreport(errbuf, NGRID, gridname);
     506             :   }
     507             : 
     508             :     }
     509          13 :     return (gridID);
     510             : }
     511             : 
     512             : 
     513             : /*----------------------------------------------------------------------------|
     514             : |  BEGIN_PROLOG                                                               |
     515             : |                                                                             |
     516             : |  FUNCTION: GDchkgdid                                                        |
     517             : |                                                                             |
     518             : |  DESCRIPTION:                                                               |
     519             : |                                                                             |
     520             : |                                                                             |
     521             : |  Return Value    Type     Units     Description                             |
     522             : |  ============   ======  =========   =====================================   |
     523             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
     524             : |                                                                             |
     525             : |  INPUTS:                                                                    |
     526             : |  gridID         int32               grid structure ID                       |
     527             : |  routname       char                Name of routine calling GDchkgdid       |
     528             : |                                                                             |
     529             : |  OUTPUTS:                                                                   |
     530             : |  fid            int32               File ID                                 |
     531             : |  sdInterfaceID  int32               SDS interface ID                        |
     532             : |  gdVgrpID       int32               grid Vgroup ID                          |
     533             : |                                                                             |
     534             : |                                                                             |
     535             : |  OUTPUTS:                                                                   |
     536             : |             None                                                            |
     537             : |                                                                             |
     538             : |  NOTES:                                                                     |
     539             : |                                                                             |
     540             : |                                                                             |
     541             : |   Date     Programmer   Description                                         |
     542             : |  ======   ============  =================================================   |
     543             : |  Jun 96   Joel Gales    Original Programmer                                 |
     544             : |                                                                             |
     545             : |  END_PROLOG                                                                 |
     546             : -----------------------------------------------------------------------------*/
     547             : static intn
     548         179 : GDchkgdid(int32 gridID, const char *routname,
     549             :     int32 * fid, int32 * sdInterfaceID, int32 * gdVgrpID)
     550             : {
     551         179 :     intn            status = 0; /* routine return status variable */
     552             :     uint8           l_access; /* Read/Write l_access code */
     553             :     int32           gID;  /* Grid ID - offset */
     554             : 
     555         179 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
     556             : 
     557             :     static const char message1[] =
     558             :         "Invalid grid id: %d in routine \"%s\".  ID must be >= %d and < %d.\n";
     559             :     static const char message2[] =
     560             :         "Grid id %d in routine \"%s\" not active.\n";
     561             : 
     562             : 
     563             : 
     564             :     /* Check for valid grid id */
     565             : 
     566         179 :     if (gridID < idOffset || gridID >= NGRID + idOffset)
     567             :     {
     568           0 :   status = -1;
     569           0 :   HEpush(DFE_RANGE, "GDchkgdid", __FILE__, __LINE__);
     570           0 :   HEreport(message1, gridID, routname, idOffset, NGRID + idOffset);
     571             :     }
     572             :     else
     573             :     {
     574             : 
     575             :   /* Compute "reduced" ID */
     576             :   /* -------------------- */
     577         179 :   gID = gridID % idOffset;
     578             : 
     579             :   /* Check for active grid ID */
     580             :   /* ------------------------ */
     581         179 :   if (GDXGrid[gID].active == 0)
     582             :   {
     583           1 :       status = -1;
     584           1 :       HEpush(DFE_GENAPP, "GDchkgdid", __FILE__, __LINE__);
     585           1 :       HEreport(message2, gridID, routname);
     586             :   }
     587             :   else
     588             :   {
     589             : 
     590             :       /* Get file & SDS ids and Grid key */
     591             :       /* -------------------------------- */
     592         178 :       status = EHchkfid(GDXGrid[gID].fid, " ",
     593             :             fid, sdInterfaceID, &l_access);
     594         178 :       *gdVgrpID = GDXGrid[gID].IDTable;
     595             :   }
     596             :     }
     597         179 :     return (status);
     598             : 
     599             : }
     600             : 
     601             : 
     602             : /*----------------------------------------------------------------------------|
     603             : |  BEGIN_PROLOG                                                               |
     604             : |                                                                             |
     605             : |  FUNCTION: GDdiminfo                                                        |
     606             : |                                                                             |
     607             : |  DESCRIPTION: Retrieve size of specified dimension.                         |
     608             : |                                                                             |
     609             : |                                                                             |
     610             : |  Return Value    Type     Units     Description                             |
     611             : |  ============   ======  =========   =====================================   |
     612             : |  size           int32               Size of dimension                       |
     613             : |                                                                             |
     614             : |  INPUTS:                                                                    |
     615             : |  gridID         int32               grid structure id                       |
     616             : |  dimname        char                Dimension name                          |
     617             : |                                                                             |
     618             : |                                                                             |
     619             : |  OUTPUTS:                                                                   |
     620             : |             None                                                            |
     621             : |                                                                             |
     622             : |  NOTES:                                                                     |
     623             : |                                                                             |
     624             : |                                                                             |
     625             : |   Date     Programmer   Description                                         |
     626             : |  ======   ============  =================================================   |
     627             : |  Jun 96   Joel Gales    Original Programmer                                 |
     628             : |  Aug 96   Joel Gales    Make metadata ODL compliant                         |
     629             : |  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
     630             : |                                                                             |
     631             : |  END_PROLOG                                                                 |
     632             : -----------------------------------------------------------------------------*/
     633             : int32
     634           4 : GDdiminfo(int32 gridID, const char *dimname)
     635             : 
     636             : {
     637             :     intn            status; /* routine return status variable */
     638             : 
     639             :     int32           fid;  /* HDF-EOS file ID */
     640             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
     641             :     int32           gdVgrpID; /* Grid root Vgroup ID */
     642             :     int32           size; /* Dimension size */
     643           4 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
     644             : 
     645             : 
     646             :     char           *metabuf;  /* Pointer to structural metadata (SM) */
     647             :     char           *metaptrs[2];/* Pointers to begin and end of SM section */
     648             :     char            gridname[80]; /* Grid Name */
     649             :     char           *utlstr; /* Utility string */
     650             : 
     651             :     /* Allocate space for utility string */
     652             :     /* --------------------------------- */
     653           4 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
     654           4 :     if(utlstr == NULL)
     655             :     {
     656           0 :   HEpush(DFE_NOSPACE,"GDdiminfo", __FILE__, __LINE__);
     657           0 :   return(-1);
     658             :     }
     659             :     /* Initialize return value */
     660             :     /* ----------------------- */
     661           4 :     size = -1;
     662             : 
     663             : 
     664             :     /* Check Grid ID */
     665             :     /* ------------- */
     666           4 :     status = GDchkgdid(gridID, "GDdiminfo", &fid, &sdInterfaceID, &gdVgrpID);
     667             : 
     668             : 
     669           4 :     if (status == 0)
     670             :     {
     671             :   /* Get grid name */
     672             :   /* ------------- */
     673           4 :   int gID = gridID % idOffset;
     674           4 :   if (gID >= NGRID)
     675             :   {
     676           0 :      free(utlstr);
     677           0 :      return -1;
     678             :   }
     679           4 :   VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
     680             : 
     681             : 
     682             :   /* Get pointers to "Dimension" section within SM */
     683             :   /* --------------------------------------------- */
     684           4 :   metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
     685             :                "Dimension", metaptrs);
     686             : 
     687           4 :   if(metabuf == NULL)
     688             :   {
     689           0 :       free(utlstr);
     690           0 :       return(-1);
     691             :   }
     692             : 
     693             :   /* Search for dimension name (surrounded by quotes) */
     694             :   /* ------------------------------------------------ */
     695           4 :   snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", dimname, "\"\n");
     696           4 :   metaptrs[0] = strstr(metaptrs[0], utlstr);
     697             : 
     698             :   /*
     699             :    * If dimension found within grid structure then get dimension value
     700             :    */
     701           4 :   if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
     702             :   {
     703             :       /* Set endptr at end of dimension definition entry */
     704             :       /* ----------------------------------------------- */
     705           4 :       metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
     706             : 
     707           4 :       status = EHgetmetavalue(metaptrs, "Size", utlstr);
     708             : 
     709           4 :       if (status == 0)
     710             :       {
     711           4 :     size = atoi(utlstr);
     712             :       }
     713             :       else
     714             :       {
     715           0 :     HEpush(DFE_GENAPP, "GDdiminfo", __FILE__, __LINE__);
     716           0 :     HEreport("\"Size\" string not found in metadata.\n");
     717             :       }
     718             :   }
     719             :   else
     720             :   {
     721           0 :       HEpush(DFE_GENAPP, "GDdiminfo", __FILE__, __LINE__);
     722           0 :       HEreport("Dimension \"%s\" not found.\n", dimname);
     723             :   }
     724             : 
     725           4 :   free(metabuf);
     726             :     }
     727           4 :     free(utlstr);
     728           4 :     return (size);
     729             : }
     730             : 
     731             : 
     732             : 
     733             : 
     734             : 
     735             : /*----------------------------------------------------------------------------|
     736             : |  BEGIN_PROLOG                                                               |
     737             : |                                                                             |
     738             : |  FUNCTION: GDgridinfo                                                       |
     739             : |                                                                             |
     740             : |  DESCRIPTION: Returns xdim, ydim and location of upper left and lower       |
     741             : |                right corners, in meters.                                    |
     742             : |                                                                             |
     743             : |                                                                             |
     744             : |  Return Value    Type     Units     Description                             |
     745             : |  ============   ======  =========   =====================================   |
     746             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
     747             : |                                                                             |
     748             : |  INPUTS:                                                                    |
     749             : |  fid            int32               File ID                                 |
     750             : |  gridname       char                Grid structure name                     |
     751             : |                                                                             |
     752             : |  OUTPUTS:                                                                   |
     753             : |  xdimsize       int32               Number of columns in grid               |
     754             : |  ydimsize       int32               Number of rows in grid                  |
     755             : |  upleftpt       float64             Location (m/deg) of upper left corner   |
     756             : |  lowrightpt     float64             Location (m/deg) of lower right corner  |
     757             : |                                                                             |
     758             : |  NOTES:                                                                     |
     759             : |                                                                             |
     760             : |                                                                             |
     761             : |   Date     Programmer   Description                                         |
     762             : |  ======   ============  =================================================   |
     763             : |  Jun 96   Joel Gales    Original Programmer                                 |
     764             : |  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
     765             : |                                                                             |
     766             : |  END_PROLOG                                                                 |
     767             : -----------------------------------------------------------------------------*/
     768             : intn
     769          11 : GDgridinfo(int32 gridID, int32 * xdimsize, int32 * ydimsize,
     770             :      float64 upleftpt[], float64 lowrightpt[])
     771             : 
     772             : {
     773          11 :     intn            status = 0; /* routine return status variable */
     774          11 :     intn            statmeta = 0; /* EHgetmetavalue return status */
     775             : 
     776             :     int32           fid;  /* HDF-EOS file ID */
     777             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
     778             :     int32           gdVgrpID; /* Grid root Vgroup ID */
     779          11 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
     780             : 
     781             : 
     782             :     char           *metabuf;  /* Pointer to structural metadata (SM) */
     783             :     char           *metaptrs[2];/* Pointers to begin and end of SM section */
     784             :     char            gridname[80]; /* Grid Name */
     785             :     char           *utlstr; /* Utility string */
     786             : 
     787             :     /* Allocate space for utility string */
     788             :     /* --------------------------------- */
     789          11 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
     790          11 :     if(utlstr == NULL)
     791             :     {
     792           0 :   HEpush(DFE_NOSPACE,"GDgridinfo", __FILE__, __LINE__);
     793           0 :   return(-1);
     794             :     }
     795             :     /* Check Grid ID */
     796             :     /* ------------- */
     797          11 :     status = GDchkgdid(gridID, "GDgridinfo", &fid, &sdInterfaceID, &gdVgrpID);
     798             : 
     799          11 :     if (status == 0)
     800             :     {
     801             :   /* Get grid name */
     802             :   /* ------------- */
     803          11 :   int gID = gridID % idOffset;
     804          11 :   if (gID >= NGRID)
     805             :   {
     806           0 :      free(utlstr);
     807           0 :      return -1;
     808             :   }
     809          11 :   VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
     810             : 
     811             : 
     812             :   /* Get pointers to grid structure section within SM */
     813             :   /* ------------------------------------------------ */
     814          11 :   metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
     815             :                NULL, metaptrs);
     816             : 
     817          11 :   if(metabuf == NULL)
     818             :   {
     819           0 :       free(utlstr);
     820           0 :       return(-1);
     821             :   }
     822             : 
     823             : 
     824             :   /* Get xdimsize if requested */
     825             :   /* ------------------------- */
     826          11 :   if (xdimsize != NULL)
     827             :   {
     828          11 :       statmeta = EHgetmetavalue(metaptrs, "XDim", utlstr);
     829          11 :       if (statmeta == 0)
     830             :       {
     831          11 :     *xdimsize = atoi(utlstr);
     832             :       }
     833             :       else
     834             :       {
     835           0 :     status = -1;
     836           0 :     HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
     837           0 :     HEreport("\"XDim\" string not found in metadata.\n");
     838             :       }
     839             :   }
     840             : 
     841             : 
     842             :   /* Get ydimsize if requested */
     843             :   /* ------------------------- */
     844          11 :   if (ydimsize != NULL)
     845             :   {
     846          11 :       statmeta = EHgetmetavalue(metaptrs, "YDim", utlstr);
     847          11 :       if (statmeta == 0)
     848             :       {
     849          11 :     *ydimsize = atoi(utlstr);
     850             :       }
     851             :       else
     852             :       {
     853           0 :     status = -1;
     854           0 :     HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
     855           0 :     HEreport("\"YDim\" string not found in metadata.\n");
     856             :       }
     857             :   }
     858             : 
     859             : 
     860             :   /* Get upleftpt if requested */
     861             :   /* ------------------------- */
     862          11 :   if (upleftpt != NULL)
     863             :   {
     864           4 :       statmeta = EHgetmetavalue(metaptrs, "UpperLeftPointMtrs", utlstr);
     865           4 :       if (statmeta == 0)
     866             :       {
     867             :     /* If value is "DEFAULT" then return zeros */
     868             :     /* --------------------------------------- */
     869           4 :     if (strcmp(utlstr, "DEFAULT") == 0)
     870             :     {
     871           0 :         upleftpt[0] = 0;
     872           0 :         upleftpt[1] = 0;
     873             :     }
     874             :     else
     875             :     {
     876           4 :         sscanf(utlstr, "(%lf,%lf)",
     877             :          &upleftpt[0], &upleftpt[1]);
     878             :     }
     879             :       }
     880             :       else
     881             :       {
     882           0 :     status = -1;
     883           0 :     HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
     884           0 :     HEreport(
     885             :       "\"UpperLeftPointMtrs\" string not found in metadata.\n");
     886             :       }
     887             : 
     888             :   }
     889             : 
     890             :   /* Get lowrightpt if requested */
     891             :   /* --------------------------- */
     892          11 :   if (lowrightpt != NULL)
     893             :   {
     894           4 :       statmeta = EHgetmetavalue(metaptrs, "LowerRightMtrs", utlstr);
     895           4 :       if (statmeta == 0)
     896             :       {
     897             :     /* If value is "DEFAULT" then return zeros */
     898           4 :     if (strcmp(utlstr, "DEFAULT") == 0)
     899             :     {
     900           0 :         lowrightpt[0] = 0;
     901           0 :         lowrightpt[1] = 0;
     902             :     }
     903             :     else
     904             :     {
     905           4 :         sscanf(utlstr, "(%lf,%lf)",
     906             :          &lowrightpt[0], &lowrightpt[1]);
     907             :     }
     908             :       }
     909             :       else
     910             :       {
     911           0 :     status = -1;
     912           0 :     HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
     913           0 :     HEreport(
     914             :           "\"LowerRightMtrs\" string not found in metadata.\n");
     915             :       }
     916             :   }
     917             : 
     918          11 :   free(metabuf);
     919             :     }
     920          11 :     free(utlstr);
     921          11 :     return (status);
     922             : }
     923             : 
     924             : 
     925             : 
     926             : 
     927             : 
     928             : 
     929             : 
     930             : /*----------------------------------------------------------------------------|
     931             : |  BEGIN_PROLOG                                                               |
     932             : |                                                                             |
     933             : |  FUNCTION: GDprojinfo                                                       |
     934             : |                                                                             |
     935             : |  DESCRIPTION: Returns GCTP projection code, zone code, spheroid code        |
     936             : |                and projection parameters.                                   |
     937             : |                                                                             |
     938             : |                                                                             |
     939             : |  Return Value    Type     Units     Description                             |
     940             : |  ============   ======  =========   =====================================   |
     941             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
     942             : |                                                                             |
     943             : |  INPUTS:                                                                    |
     944             : |  gridID         int32               Grid structure ID                       |
     945             : |                                                                             |
     946             : |  OUTPUTS:                                                                   |
     947             : |  projcode       int32               GCTP projection code                    |
     948             : |  zonecode       int32               UTM zone code                           |
     949             : |  spherecode     int32               GCTP spheroid code                      |
     950             : |  projparm       float64             Projection parameters                   |
     951             : |                                                                             |
     952             : |  NOTES:                                                                     |
     953             : |                                                                             |
     954             : |                                                                             |
     955             : |   Date     Programmer   Description                                         |
     956             : |  ======   ============  =================================================   |
     957             : |  Jun 96   Joel Gales    Original Programmer                                 |
     958             : |  Oct 96   Joel Gales    Add check for no projection code                    |
     959             : |  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
     960             : |  Jun 00   Abe Taaheri   Added support for EASE grid                         |
     961             : |                                                                             |
     962             : |  END_PROLOG                                                                 |
     963             : -----------------------------------------------------------------------------*/
     964             : intn
     965           5 : GDprojinfo(int32 gridID, int32 * projcode, int32 * zonecode,
     966             :      int32 * spherecode, float64 projparm[])
     967             : 
     968             : {
     969             :     intn            i;    /* Loop index */
     970             :     intn            projx;    /* Loop index */
     971           5 :     intn            status = 0; /* routine return status variable */
     972           5 :     intn            statmeta = 0; /* EHgetmetavalue return status */
     973             : 
     974             :     int32           fid;  /* HDF-EOS file ID */
     975             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
     976             :     int32           gdVgrpID; /* Grid root Vgroup ID */
     977           5 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
     978             : 
     979             : 
     980             :     char           *metabuf;  /* Pointer to structural metadata (SM) */
     981             :     char           *metaptrs[2];/* Pointers to begin and end of SM section */
     982             :     char            gridname[80]; /* Grid Name */
     983             :     char           *utlstr; /* Utility string */
     984             :     char            fmt[96];  /* Format String */
     985             : 
     986             :     /* Allocate space for utility string */
     987             :     /* --------------------------------- */
     988           5 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
     989           5 :     if(utlstr == NULL)
     990             :     {
     991           0 :   HEpush(DFE_NOSPACE,"GDprojinfo", __FILE__, __LINE__);
     992           0 :   return(-1);
     993             :     }
     994             : 
     995             :     /* Check Grid ID */
     996             :     /* ------------- */
     997           5 :     status = GDchkgdid(gridID, "GDprojinfo", &fid, &sdInterfaceID, &gdVgrpID);
     998             : 
     999           5 :     if (status == 0)
    1000             :     {
    1001             :   /* Get grid name */
    1002             :   /* ------------- */
    1003           5 :   int gID = gridID % idOffset;
    1004           5 :   if (gID >= NGRID)
    1005             :   {
    1006           0 :      free(utlstr);
    1007           0 :      return -1;
    1008             :   }
    1009             : 
    1010           5 :   VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
    1011             : 
    1012             : 
    1013             :   /* Get pointers to grid structure section within SM */
    1014             :   /* ------------------------------------------------ */
    1015           5 :   metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
    1016             :                NULL, metaptrs);
    1017             : 
    1018           5 :   if(metabuf == NULL)
    1019             :   {
    1020           0 :       free(utlstr);
    1021           0 :       return(-1);
    1022             :   }
    1023             : 
    1024             : 
    1025             :   /* Get projcode if requested */
    1026             :   /* ------------------------- */
    1027           5 :   if (projcode != NULL)
    1028             :   {
    1029           5 :       *projcode = -1;
    1030             : 
    1031           5 :       statmeta = EHgetmetavalue(metaptrs, "Projection", utlstr);
    1032           5 :       if (statmeta == 0)
    1033             :       {
    1034             :     /* Loop through projection codes until found */
    1035             :     /* ----------------------------------------- */
    1036           5 :     for (projx = 0; Projections[projx].projcode != -1; projx++)
    1037           5 :         if (strcmp(utlstr, Projections[projx].projname) == 0)
    1038           5 :       break;
    1039           5 :     if (Projections[projx].projname != NULL)
    1040           5 :         *projcode = Projections[projx].projcode;
    1041             :       }
    1042             :       else
    1043             :       {
    1044           0 :     status = -1;
    1045           0 :     HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
    1046           0 :     HEreport("Projection Code not defined for \"%s\".\n",
    1047             :        gridname);
    1048             : 
    1049           0 :     if (projparm != NULL)
    1050             :     {
    1051           0 :         for (i = 0; i < 13; i++)
    1052             :         {
    1053           0 :       projparm[i] = -1;
    1054             :         }
    1055             :     }
    1056             :       }
    1057             :   }
    1058             : 
    1059             : 
    1060             :   /* Get zonecode if requested */
    1061             :   /* ------------------------- */
    1062           5 :   if (projcode && zonecode != NULL)
    1063             :   {
    1064           5 :       *zonecode = -1;
    1065             : 
    1066             : 
    1067             :       /* Zone code only relevant for UTM and State Code projections */
    1068             :       /* ---------------------------------------------------------- */
    1069           5 :       if (*projcode == GCTP_UTM || *projcode == GCTP_SPCS)
    1070             :       {
    1071           0 :     statmeta = EHgetmetavalue(metaptrs, "ZoneCode", utlstr);
    1072           0 :     if (statmeta == 0)
    1073             :     {
    1074           0 :         *zonecode = atoi(utlstr);
    1075             :     }
    1076             :     else
    1077             :     {
    1078           0 :         status = -1;
    1079           0 :         HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
    1080           0 :         HEreport("Zone Code not defined for \"%s\".\n",
    1081             :            gridname);
    1082             :     }
    1083             :       }
    1084             :   }
    1085             : 
    1086             : 
    1087             :   /* Get projection parameters if requested */
    1088             :   /* -------------------------------------- */
    1089           5 :   if (projcode && projparm != NULL)
    1090             :   {
    1091             : 
    1092             :       /*
    1093             :        * Note: No projection parameters for GEO, UTM, and State Code
    1094             :        * projections
    1095             :        */
    1096           5 :       if (*projcode == GCTP_GEO || *projcode == GCTP_UTM ||
    1097           0 :     *projcode == GCTP_SPCS)
    1098             :       {
    1099          70 :     for (i = 0; i < 13; i++)
    1100             :     {
    1101          65 :         projparm[i] = 0.0;
    1102             :     }
    1103             : 
    1104             :       }
    1105             :       else
    1106             :       {
    1107           0 :     statmeta = EHgetmetavalue(metaptrs, "ProjParams", utlstr);
    1108             : 
    1109           0 :     if (statmeta == 0)
    1110             :     {
    1111             : 
    1112             :         /* Build format string to read projection parameters */
    1113             :         /* ------------------------------------------------- */
    1114           0 :         strcpy(fmt, "%lf,");
    1115           0 :         for (i = 1; i <= 11; i++)
    1116           0 :       strcat(fmt, "%lf,");
    1117           0 :         strcat(fmt, "%lf");
    1118             : 
    1119             : 
    1120             :         /* Read parameters from numeric list */
    1121             :         /* --------------------------------- */
    1122           0 :         sscanf(&utlstr[1], fmt,
    1123             :          &projparm[0], &projparm[1],
    1124             :          &projparm[2], &projparm[3],
    1125             :          &projparm[4], &projparm[5],
    1126             :          &projparm[6], &projparm[7],
    1127             :          &projparm[8], &projparm[9],
    1128             :          &projparm[10], &projparm[11],
    1129             :          &projparm[12]);
    1130             :     }
    1131             :     else
    1132             :     {
    1133           0 :         status = -1;
    1134           0 :         HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
    1135           0 :         HEreport("Projection parameters not defined for \"%s\".\n",
    1136             :            gridname);
    1137             : 
    1138             :     }
    1139             :       }
    1140             :   }
    1141             : 
    1142             : 
    1143             :   /* Get spherecode if requested */
    1144             :   /* --------------------------- */
    1145           5 :   if (projcode && spherecode != NULL)
    1146             :   {
    1147           5 :       *spherecode = 0;
    1148             : 
    1149             :       /* Note: Spherecode not defined for GEO projection */
    1150             :       /* ----------------------------------------------- */
    1151           5 :       if ((*projcode != GCTP_GEO))
    1152             :       {
    1153           0 :     EHgetmetavalue(metaptrs, "SphereCode", utlstr);
    1154           0 :     if (statmeta == 0)
    1155             :     {
    1156           0 :         *spherecode = atoi(utlstr);
    1157             :     }
    1158             :       }
    1159             :   }
    1160           5 :   free(metabuf);
    1161             : 
    1162             :     }
    1163           5 :     free(utlstr);
    1164           5 :     return (status);
    1165             : }
    1166             : 
    1167             : 
    1168             : /*----------------------------------------------------------------------------|
    1169             : |  BEGIN_PROLOG                                                               |
    1170             : |                                                                             |
    1171             : |  FUNCTION: GDfieldinfo                                                      |
    1172             : |                                                                             |
    1173             : |  DESCRIPTION: Retrieve information about a specific geolocation or data     |
    1174             : |                field in the grid.                                           |
    1175             : |                                                                             |
    1176             : |                                                                             |
    1177             : |  Return Value    Type     Units     Description                             |
    1178             : |  ============   ======  =========   =====================================   |
    1179             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    1180             : |                                                                             |
    1181             : |  INPUTS:                                                                    |
    1182             : |  gridID         int32               grid structure id                       |
    1183             : |  fieldname      char                name of field                           |
    1184             : |                                                                             |
    1185             : |                                                                             |
    1186             : |  OUTPUTS:                                                                   |
    1187             : |  rank           int32               rank of field (# of dims)               |
    1188             : |  dims           int32               field dimensions                        |
    1189             : |  numbertype     int32               field number type                       |
    1190             : |  dimlist        char                field dimension list                    |
    1191             : |                                                                             |
    1192             : |                                                                             |
    1193             : |  OUTPUTS:                                                                   |
    1194             : |             None                                                            |
    1195             : |                                                                             |
    1196             : |  NOTES:                                                                     |
    1197             : |                                                                             |
    1198             : |                                                                             |
    1199             : |   Date     Programmer   Description                                         |
    1200             : |  ======   ============  =================================================   |
    1201             : |  Jun 96   Joel Gales    Original Programmer                                 |
    1202             : |  Aug 96   Joel Gales    Make metadata ODL compliant                         |
    1203             : |  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
    1204             : |  Feb 99   Abe Taaheri   Changed memcpy to memmove to avoid overlapping      |
    1205             : |                         problem when copying strings                        |
    1206             : |                                                                             |
    1207             : |  END_PROLOG                                                                 |
    1208             : -----------------------------------------------------------------------------*/
    1209             : intn
    1210         107 : GDfieldinfo(int32 gridID, const char *fieldname, int32 * rank, int32 dims[],
    1211             :       int32 * numbertype, char dimlist[HDFE_DIMBUFSIZE+1])
    1212             : 
    1213             : {
    1214             :     intn            i;        /* Loop index */
    1215             :     intn            status;     /* routine return status variable */
    1216         107 :     intn            statmeta = 0;   /* EHgetmetavalue return status */
    1217             : 
    1218             :     int32           fid;      /* HDF-EOS file ID */
    1219             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
    1220         107 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    1221         107 :     int32           ndims = 0;      /* Number of dimensions */
    1222             :     int32           slen[8];      /* Length of each entry in parsed string */
    1223             :     int32           dum;      /* Dummy variable */
    1224         107 :     int32           xdim = 0;     /* X dim size */
    1225         107 :     int32           ydim = 0;     /* Y dim size */
    1226             :     int32           sdid;     /* SDS id */
    1227             : 
    1228             :     char           *metabuf;      /* Pointer to structural metadata (SM) */
    1229             :     char           *metaptrs[2];    /* Pointers to begin and end of SM section */
    1230             :     char            gridname[80];   /* Grid Name */
    1231             :     char           *utlstr;     /* Utility string */
    1232             :     char           *ptr[8];     /* String pointers for parsed string */
    1233             :     char            dimstr[64];     /* Individual dimension entry string */
    1234             : 
    1235             : 
    1236             :     /* Allocate space for utility string */
    1237             :     /* --------------------------------- */
    1238         107 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    1239         107 :     if(utlstr == NULL)
    1240             :     {
    1241           0 :   HEpush(DFE_NOSPACE,"GDfieldinfo", __FILE__, __LINE__);
    1242           0 :   return(-1);
    1243             :     }
    1244         107 :     *rank = -1;
    1245         107 :     *numbertype = -1;
    1246             : 
    1247         107 :     status = GDchkgdid(gridID, "GDfieldinfo", &fid, &sdInterfaceID, &dum);
    1248             : 
    1249         107 :     if (status == 0)
    1250             :     {
    1251         107 :   int gID = gridID % idOffset;
    1252         107 :   if (gID >= NGRID)
    1253             :   {
    1254           0 :       free(utlstr);
    1255           0 :       return -1;
    1256             :     }
    1257         107 :   VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
    1258             : 
    1259         107 :   metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
    1260             :                "DataField", metaptrs);
    1261         107 :   if(metabuf == NULL)
    1262             :   {
    1263           0 :       free(utlstr);
    1264           0 :       return(-1);
    1265             :   }
    1266             : 
    1267         107 :     if (!metaptrs[0])
    1268             :     {
    1269           0 :         free(utlstr);
    1270           0 :         free(metabuf);
    1271           0 :         return -1;
    1272             :     }
    1273             : 
    1274             :   /* Search for field */
    1275         107 :   snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"\n");
    1276         107 :   metaptrs[0] = strstr(metaptrs[0], utlstr);
    1277             : 
    1278             :   /* If field found ... */
    1279         107 :   if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    1280             :   {
    1281             : 
    1282             :       /* Set endptr at end of dimension definition entry */
    1283           7 :       metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
    1284             : 
    1285             :       /* Get DataType string */
    1286           7 :       statmeta = EHgetmetavalue(metaptrs, "DataType", utlstr);
    1287             : 
    1288             :       /* Convert to numbertype code */
    1289           7 :       if (statmeta == 0)
    1290           7 :     *numbertype = EHnumstr(utlstr);
    1291             :       else
    1292             :       {
    1293           0 :     status = -1;
    1294           0 :     HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
    1295           0 :     HEreport("\"DataType\" string not found in metadata.\n");
    1296             :       }
    1297             : 
    1298             :       /*
    1299             :        * Get DimList string and trim off leading and trailing parens
    1300             :        * "()"
    1301             :        */
    1302           7 :       statmeta = EHgetmetavalue(metaptrs, "DimList", utlstr);
    1303             : 
    1304           7 :       if (statmeta == 0)
    1305             :       {
    1306           7 :     const size_t len = strlen(utlstr);
    1307           7 :     if (len >= 2 && utlstr[0] == '(' && utlstr[len-1] == ')')
    1308             :     {
    1309           4 :         memmove(utlstr, utlstr + 1, len - 2);
    1310           4 :         utlstr[len - 2] = '\0';
    1311             :     }
    1312             : 
    1313             :     /* Parse trimmed DimList string and get rank */
    1314           7 :     ndims = EHparsestr(utlstr, ',', ptr, CPL_ARRAYSIZE(ptr), slen, CPL_ARRAYSIZE(slen));
    1315           7 :         if (ndims < 0)
    1316             :         {
    1317           0 :             status = -1;
    1318           0 :             HEpush(DFE_NOSPACE, "GDfieldinfo", __FILE__, __LINE__);
    1319             :         }
    1320           7 :     *rank = ndims;
    1321             :       }
    1322             :       else
    1323             :       {
    1324           0 :     status = -1;
    1325           0 :     HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
    1326           0 :     HEreport("\"DimList\" string not found in metadata.\n");
    1327             :       }
    1328             : 
    1329             : 
    1330           7 :       if (status == 0)
    1331             :       {
    1332           7 :     status = GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
    1333             : 
    1334           7 :         dims[0] = -1;
    1335          15 :     for (i = 0; i < ndims; i++)
    1336             :     {
    1337           8 :         memcpy(dimstr, ptr[i] + 1, slen[i] - 2);
    1338           8 :         dimstr[slen[i] - 2] = 0;
    1339             : 
    1340           8 :         if (strcmp(dimstr, "XDim") == 0)
    1341             :         {
    1342           0 :       dims[i] = xdim;
    1343             :         }
    1344           8 :         else if (strcmp(dimstr, "YDim") == 0)
    1345             :         {
    1346           4 :       dims[i] = ydim;
    1347             :         }
    1348             :         else
    1349             :         {
    1350           4 :       dims[i] = GDdiminfo(gridID, dimstr);
    1351             :         }
    1352             : 
    1353             : 
    1354           8 :         if (dimlist != NULL)
    1355             :         {
    1356           4 :       if (i == 0)
    1357             :       {
    1358           2 :           dimlist[0] = 0;
    1359             :       }
    1360             : 
    1361           4 :       if (i > 0)
    1362             :       {
    1363           2 :           if( strlen(dimlist) + 1 > HDFE_DIMBUFSIZE )
    1364             :           {
    1365           0 :               free(metabuf);
    1366           0 :               free(utlstr);
    1367           0 :               return -1;
    1368             :           }
    1369           2 :           strcat(dimlist, ",");
    1370             :       }
    1371           4 :       if( strlen(dimlist) + strlen(dimstr) > HDFE_DIMBUFSIZE )
    1372             :       {
    1373           0 :           free(metabuf);
    1374           0 :           free(utlstr);
    1375           0 :           return -1;
    1376             :       }
    1377           4 :       strcat(dimlist, dimstr);
    1378             :         }
    1379             :     }
    1380             : 
    1381             : 
    1382           7 :     if (dims[0] == 0)
    1383             :     {
    1384           4 :         status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
    1385             :            &sdid, &dum, &dum, &dum, dims,
    1386             :            &dum);
    1387             :     }
    1388             :       }
    1389             :   }
    1390             : 
    1391         107 :   free(metabuf);
    1392             :     }
    1393             : 
    1394         107 :     if (*rank == -1)
    1395             :     {
    1396         100 :   status = -1;
    1397             : 
    1398         100 :   HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
    1399         100 :   HEreport("Fieldname \"%s\" not found.\n", fieldname);
    1400             :     }
    1401         107 :     free(utlstr);
    1402         107 :     return (status);
    1403             : }
    1404             : 
    1405             : 
    1406             : 
    1407             : /*----------------------------------------------------------------------------|
    1408             : |  BEGIN_PROLOG                                                               |
    1409             : |                                                                             |
    1410             : |  FUNCTION: GDSDfldsrch                                                      |
    1411             : |                                                                             |
    1412             : |  DESCRIPTION: Retrieves information from SDS fields                         |
    1413             : |                                                                             |
    1414             : |                                                                             |
    1415             : |  Return Value    Type     Units     Description                             |
    1416             : |  ============   ======  =========   =====================================   |
    1417             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    1418             : |                                                                             |
    1419             : |  INPUTS:                                                                    |
    1420             : |  gridID         int32               grid structure ID                       |
    1421             : |  sdInterfaceID  int32               SD interface ID                         |
    1422             : |  fieldname      char                field name                              |
    1423             : |                                                                             |
    1424             : |                                                                             |
    1425             : |  OUTPUTS:                                                                   |
    1426             : |  sdid           int32               SD element ID                           |
    1427             : |  rankSDS        int32               Rank of SDS                             |
    1428             : |  rankFld        int32               True rank of field (merging)            |
    1429             : |  offset         int32               Offset of field within merged field     |
    1430             : |  dims           int32               Dimensions of field                     |
    1431             : |  solo           int32               Solo field flag                         |
    1432             : |                                                                             |
    1433             : |  NOTES:                                                                     |
    1434             : |                                                                             |
    1435             : |                                                                             |
    1436             : |   Date     Programmer   Description                                         |
    1437             : |  ======   ============  =================================================   |
    1438             : |  Jun 96   Joel Gales    Original Programmer                                 |
    1439             : |  Aug 96   Joel Gales    Make metadata ODL compliant                         |
    1440             : |                                                                             |
    1441             : |  END_PROLOG                                                                 |
    1442             : -----------------------------------------------------------------------------*/
    1443             : static intn
    1444          10 : GDSDfldsrch(int32 gridID, int32 sdInterfaceID, const char *fieldname,
    1445             :             int32 * sdid, int32 * rankSDS, int32 * rankFld, int32 * offset,
    1446             :             int32 dims[], int32 * solo)
    1447             : {
    1448             :     intn            i;    /* Loop index */
    1449          10 :     intn            status = -1;/* routine return status variable */
    1450             : 
    1451             :     int32           gID;  /* GridID - offset */
    1452          10 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    1453             :     int32           dum;  /* Dummy variable */
    1454             :     int32           dums[128];  /* Dummy array */
    1455             :     int32           attrIndex;  /* Attribute l_index */
    1456             : 
    1457             :     char            name[2048]; /* Merged-Field Names */
    1458             :     char            gridname[80]; /* Grid Name */
    1459             :     char           *utlstr;/* Utility string */
    1460             :     char           *metabuf;  /* Pointer to structural metadata (SM) */
    1461             :     char           *metaptrs[2];/* Pointers to begin and end of SM section */
    1462             : #ifdef broken_logic
    1463             :     char           *oldmetaptr; /* Pointer within SM section */
    1464             :     char           *metaptr;  /* Pointer within SM section */
    1465             : #endif
    1466             : 
    1467             :     /* Allocate space for utility string */
    1468             :     /* --------------------------------- */
    1469          10 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    1470          10 :     if(utlstr == NULL)
    1471             :     {
    1472           0 :   HEpush(DFE_NOSPACE,"GDSDfldsrch", __FILE__, __LINE__);
    1473           0 :   return(-1);
    1474             :     }
    1475             :     /* Set solo flag to 0 (no) */
    1476             :     /* ----------------------- */
    1477          10 :     *solo = 0;
    1478             : 
    1479             : 
    1480             :     /* Compute "reduced" grid ID */
    1481             :     /* ------------------------- */
    1482          10 :     gID = gridID % idOffset;
    1483          10 :     if (gID >= NGRID)
    1484             :     {
    1485           0 :         free(utlstr);
    1486           0 :         return -1;
    1487             :     }
    1488             : 
    1489             :     /* Loop through all SDSs in grid */
    1490             :     /* ----------------------------- */
    1491          15 :     for (i = 0; i < GDXGrid[gID].nSDS; i++)
    1492             :     {
    1493             :   /* If active SDS ... */
    1494             :   /* ----------------- */
    1495           5 :   if (GDXGrid[gID].sdsID[i] != 0)
    1496             :   {
    1497             :       /* Get SDS ID, name, rankSDS, and dimensions */
    1498             :       /* ----------------------------------------- */
    1499           5 :       *sdid = GDXGrid[gID].sdsID[i];
    1500           5 :       SDgetinfo(*sdid, name, rankSDS, dims, &dum, &dum);
    1501           5 :       *rankFld = *rankSDS;
    1502             : 
    1503             : 
    1504             :       /* If merged field ... */
    1505             :       /* ------------------- */
    1506           5 :       if (strstr(name, "MRGFLD_") == &name[0])
    1507             :       {
    1508             :     /* Get grid name */
    1509             :     /* ------------- */
    1510           5 :     VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
    1511             : 
    1512             : 
    1513             :     /* Get pointers to "MergedFields" section within SM */
    1514             :     /* ------------------------------------------------ */
    1515           5 :     metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
    1516             :                  "MergedFields", metaptrs);
    1517           5 :     if(metabuf == NULL)
    1518             :     {
    1519           0 :         free(utlstr);
    1520           0 :         return(-1);
    1521             :     }
    1522             : 
    1523             : #ifdef broken_logic
    1524             :     /* Initialize metaptr to beg. of section */
    1525             :     /* ------------------------------------- */
    1526             :     metaptr = metaptrs[0];
    1527             : 
    1528             : 
    1529             :     /* Store metaptr in order to recover */
    1530             :     /* --------------------------------- */
    1531             :     oldmetaptr = metaptr;
    1532             : 
    1533             : 
    1534             :     /* Search for Merged field name */
    1535             :     /* ---------------------------- */
    1536             :     snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "MergedFieldName=\"",
    1537             :       name, "\"\n");
    1538             :     metaptr = strstr(metaptr, utlstr);
    1539             : 
    1540             : 
    1541             :     /* If not found check for old metadata */
    1542             :     /* ----------------------------------- */
    1543             :     if (metaptr == NULL)
    1544             :     {
    1545             :         snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "OBJECT=\"", name, "\"\n");
    1546             :         metaptr = strstr(oldmetaptr, utlstr);
    1547             :     }
    1548             : #endif
    1549             : 
    1550             :         /* Get field list and strip off leading and trailing quotes */
    1551             :         /* -------------------------------------------------------- */
    1552           5 :         if (EHgetmetavalue(metaptrs, "FieldList", name) == 0)
    1553             :         {
    1554           5 :             const size_t len = strlen(name);
    1555           5 :             if (len >= 2 && name[0] == '"' && name[len-1] == '"')
    1556             :             {
    1557           0 :                 memmove(name, name + 1, strlen(name) - 2);
    1558           0 :                 name[strlen(name) - 2] = 0;
    1559             :             }
    1560             :         }
    1561             :         else
    1562             :         {
    1563           0 :             name[0] = '\0';
    1564             :         }
    1565             : 
    1566             :     /* Search for desired field within merged field list */
    1567             :     /* ------------------------------------------------- */
    1568           5 :     snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"");
    1569           5 :     dum = EHstrwithin(utlstr, name, ',');
    1570             : 
    1571           5 :     free(metabuf);
    1572             :       }
    1573             :       else
    1574             :       {
    1575             :     /* If solo (unmerged) check if SDS name matches fieldname */
    1576             :     /* ------------------------------------------------------ */
    1577           0 :     dum = EHstrwithin(fieldname, name, ',');
    1578           0 :     if (dum != -1)
    1579             :     {
    1580           0 :         *solo = 1;
    1581           0 :         *offset = 0;
    1582             :     }
    1583             :       }
    1584             : 
    1585             : 
    1586             : 
    1587             :       /* If field found ... */
    1588             :       /* ------------------ */
    1589           5 :       if (dum != -1)
    1590             :       {
    1591           0 :     status = 0;
    1592             : 
    1593             :     /* If merged field ... */
    1594             :     /* ------------------- */
    1595           0 :     if (*solo == 0)
    1596             :     {
    1597             :         /* Get "Field Offsets" SDS attribute l_index */
    1598             :         /* --------------------------------------- */
    1599           0 :         attrIndex = SDfindattr(*sdid, "Field Offsets");
    1600             : 
    1601             :         /*
    1602             :          * If attribute exists then get offset of desired field
    1603             :          * within merged field
    1604             :          */
    1605           0 :         if (attrIndex != -1)
    1606             :         {
    1607           0 :       SDreadattr(*sdid, attrIndex, (VOIDP) dums);
    1608           0 :       *offset = dums[dum];
    1609             :         }
    1610             : 
    1611             : 
    1612             :         /* Get "Field Dims" SDS attribute l_index */
    1613             :         /* ------------------------------------ */
    1614           0 :         attrIndex = SDfindattr(*sdid, "Field Dims");
    1615             : 
    1616             :         /*
    1617             :          * If attribute exists then get 0th dimension of desired
    1618             :          * field within merged field
    1619             :          */
    1620           0 :         if (attrIndex != -1)
    1621             :         {
    1622           0 :       SDreadattr(*sdid, attrIndex, (VOIDP) dums);
    1623           0 :       dims[0] = dums[dum];
    1624             : 
    1625             :       /* If this dimension = 1 then field is really 2 dim */
    1626             :       /* ------------------------------------------------ */
    1627           0 :       if (dums[dum] == 1)
    1628             :       {
    1629           0 :           *rankFld = 2;
    1630             :       }
    1631             :         }
    1632             :     }
    1633             : 
    1634             : 
    1635             :     /* Break out of SDS loop */
    1636             :     /* --------------------- */
    1637           0 :     break;
    1638             :       }     /* End of found field section */
    1639             :   }
    1640             :   else
    1641             :   {
    1642             :       /* First non-active SDS signifies no more, break out of SDS loop */
    1643             :       /* ------------------------------------------------------------- */
    1644           0 :       break;
    1645             :   }
    1646             :     }
    1647          10 :     free(utlstr);
    1648          10 :     return (status);
    1649             : }
    1650             : 
    1651             : 
    1652             : 
    1653             : 
    1654             : /*----------------------------------------------------------------------------|
    1655             : |  BEGIN_PROLOG                                                               |
    1656             : |                                                                             |
    1657             : |  FUNCTION: GDwrrdfield                                                      |
    1658             : |                                                                             |
    1659             : |  DESCRIPTION: Writes/Reads fields                                           |
    1660             : |                                                                             |
    1661             : |                                                                             |
    1662             : |  Return Value    Type     Units     Description                             |
    1663             : |  ============   ======  =========   =====================================   |
    1664             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    1665             : |                                                                             |
    1666             : |  INPUTS:                                                                    |
    1667             : |  gridID         int32               grid structure ID                       |
    1668             : |  fieldname      char                fieldname                               |
    1669             : |  code           char                Write/Read code (w/r)                   |
    1670             : |  start          int32               start array                             |
    1671             : |  stride         int32               stride array                            |
    1672             : |  edge           int32               edge array                              |
    1673             : |  datbuf         void                data buffer for read                    |
    1674             : |                                                                             |
    1675             : |                                                                             |
    1676             : |  OUTPUTS:                                                                   |
    1677             : |  datbuf         void                data buffer for write                   |
    1678             : |                                                                             |
    1679             : |                                                                             |
    1680             : |  NOTES:                                                                     |
    1681             : |                                                                             |
    1682             : |                                                                             |
    1683             : |   Date     Programmer   Description                                         |
    1684             : |  ======   ============  =================================================   |
    1685             : |  Jun 96   Joel Gales    Original Programmer                                 |
    1686             : |  Feb 97   Joel Gales    Stride = 1 HDF compression workaround               |
    1687             : |                                                                             |
    1688             : |  END_PROLOG                                                                 |
    1689             : -----------------------------------------------------------------------------*/
    1690             : static intn
    1691           0 : GDwrrdfield(int32 gridID, const char *fieldname, const char *code,
    1692             :       int32 start[], int32 stride[], int32 edge[], VOIDP datbuf)
    1693             : 
    1694             : {
    1695             :     intn            i;    /* Loop index */
    1696           0 :     intn            status = 0; /* routine return status variable */
    1697             : 
    1698             :     int32           fid;  /* HDF-EOS file ID */
    1699             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
    1700             :     int32           sdid; /* SDS ID */
    1701             :     int32           dum;  /* Dummy variable */
    1702             :     int32           rankSDS;  /* Rank of SDS */
    1703             :     int32           rankFld;  /* Rank of field */
    1704             : 
    1705           0 :     int32           offset[8] = {0};  /* I/O offset (start) */
    1706             :     int32           incr[8];  /* I/O increment (stride) */
    1707             :     int32           count[8]; /* I/O count (edge) */
    1708             :     int32           dims[8];  /* Field/SDS dimensions */
    1709           0 :     int32           mrgOffset = 0;  /* Merged field offset */
    1710             :     int32           strideOne;  /* Strides = 1 flag */
    1711             : 
    1712           0 :     for (i = 0; i < 8; ++i)
    1713           0 :         incr[i] = 1;
    1714             : 
    1715             :     /* Check for valid grid ID */
    1716             :     /* ----------------------- */
    1717           0 :     status = GDchkgdid(gridID, "GDwrrdfield", &fid, &sdInterfaceID, &dum);
    1718           0 :     if (status < 0)
    1719           0 :         return -1;
    1720             : 
    1721             :     /* Check that field exists */
    1722             :     /* ----------------------- */
    1723           0 :     status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
    1724             : 
    1725             : 
    1726           0 :   if (status != 0)
    1727             :   {
    1728           0 :       HEpush(DFE_GENAPP, "GDwrrdfield", __FILE__, __LINE__);
    1729           0 :       HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
    1730           0 :       status = -1;
    1731             : 
    1732             :   }
    1733             : 
    1734             : 
    1735           0 :     if (status == 0)
    1736             :     {
    1737           0 :         status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
    1738             :                              &rankSDS, &rankFld, &mrgOffset, dims, &dum);
    1739           0 :         if (status < 0)
    1740           0 :             return -1;
    1741             : 
    1742             : 
    1743             :         /* Set I/O offset Section */
    1744             :         /* ---------------------- */
    1745             : 
    1746             :         /*
    1747             :          * If start == NULL (default) set I/O offset of 0th field to
    1748             :          * offset within merged field (if any) and the rest to 0
    1749             :          */
    1750           0 :         if (start == NULL)
    1751             :         {
    1752           0 :             for (i = 0; i < rankSDS; i++)
    1753             :             {
    1754           0 :                 offset[i] = 0;
    1755             :             }
    1756           0 :             offset[0] = mrgOffset;
    1757             :         }
    1758             :         else
    1759             :         {
    1760             :             /*
    1761             :              * ... otherwise set I/O offset to user values, adjusting the
    1762             :              * 0th field with the merged field offset (if any)
    1763             :              */
    1764           0 :             if (rankFld == rankSDS)
    1765             :             {
    1766           0 :                 for (i = 0; i < rankSDS; i++)
    1767             :                 {
    1768           0 :                 offset[i] = start[i];
    1769             :                 }
    1770           0 :                 offset[0] += mrgOffset;
    1771             :             }
    1772             :             else
    1773             :             {
    1774             :                 /*
    1775             :                  * If field really 2-dim merged in 3-dim field then set
    1776             :                  * 0th field offset to merge offset and then next two to
    1777             :                  * the user values
    1778             :                  */
    1779           0 :                 for (i = 0; i < rankFld; i++)
    1780             :                 {
    1781           0 :                     offset[i + 1] = start[i];
    1782             :                 }
    1783           0 :                 offset[0] = mrgOffset;
    1784             :             }
    1785             :             }
    1786             : 
    1787             : 
    1788             : 
    1789             :             /* Set I/O stride Section */
    1790             :             /* ---------------------- */
    1791             : 
    1792             :             /*
    1793             :              * If stride == NULL (default) set I/O stride to 1
    1794             :              */
    1795           0 :             if (stride == NULL)
    1796             :             {
    1797           0 :             for (i = 0; i < rankSDS; i++)
    1798             :             {
    1799           0 :                 incr[i] = 1;
    1800             :             }
    1801             :             }
    1802             :             else
    1803             :             {
    1804             :             /*
    1805             :              * ... otherwise set I/O stride to user values
    1806             :              */
    1807           0 :             if (rankFld == rankSDS)
    1808             :             {
    1809           0 :                 for (i = 0; i < rankSDS; i++)
    1810             :                 {
    1811           0 :                 incr[i] = stride[i];
    1812             :                 }
    1813             :             }
    1814             :             else
    1815             :             {
    1816             :                 /*
    1817             :                  * If field really 2-dim merged in 3-dim field then set
    1818             :                  * 0th field stride to 1 and then next two to the user
    1819             :                  * values.
    1820             :                  */
    1821           0 :                 for (i = 0; i < rankFld; i++)
    1822             :                 {
    1823           0 :                 incr[i + 1] = stride[i];
    1824             :                 }
    1825           0 :                 incr[0] = 1;
    1826             :             }
    1827             :             }
    1828             : 
    1829             : 
    1830             : 
    1831             :             /* Set I/O count Section */
    1832             :             /* --------------------- */
    1833             : 
    1834             :             /*
    1835             :              * If edge == NULL (default) set I/O count to number of remaining
    1836             :              * entries (dims - start) / increment.  Note that 0th field
    1837             :              * offset corrected for merged field offset (if any).
    1838             :              */
    1839           0 :             if (edge == NULL)
    1840             :             {
    1841           0 :             for (i = 1; i < rankSDS; i++)
    1842             :             {
    1843           0 :                 count[i] = (dims[i] - offset[i]) / incr[i];
    1844             :             }
    1845           0 :             count[0] = (dims[0] - (offset[0] - mrgOffset)) / incr[0];
    1846             :             }
    1847             :             else
    1848             :             {
    1849             :             /*
    1850             :              * ... otherwise set I/O count to user values
    1851             :              */
    1852           0 :             if (rankFld == rankSDS)
    1853             :             {
    1854           0 :                 for (i = 0; i < rankSDS; i++)
    1855             :                 {
    1856           0 :                 count[i] = edge[i];
    1857             :                 }
    1858             :             }
    1859             :             else
    1860             :             {
    1861             :                 /*
    1862             :                  * If field really 2-dim merged in 3-dim field then set
    1863             :                  * 0th field count to 1 and then next two to the user
    1864             :                  * values.
    1865             :                  */
    1866           0 :                 for (i = 0; i < rankFld; i++)
    1867             :                 {
    1868           0 :                 count[i + 1] = edge[i];
    1869             :                 }
    1870           0 :                 count[0] = 1;
    1871             :             }
    1872             :             }
    1873             : 
    1874             : 
    1875             :             /* Perform I/O with relevant HDF I/O routine */
    1876             :             /* ----------------------------------------- */
    1877           0 :             if (strcmp(code, "w") == 0)
    1878             :             {
    1879             :             /* Set strideOne to true (1) */
    1880             :             /* ------------------------- */
    1881           0 :             strideOne = 1;
    1882             : 
    1883             : 
    1884             :             /* If incr[i] != 1 set strideOne to false (0) */
    1885             :             /* ------------------------------------------ */
    1886           0 :             for (i = 0; i < rankSDS; i++)
    1887             :             {
    1888           0 :                 if (incr[i] != 1)
    1889             :                 {
    1890           0 :                 strideOne = 0;
    1891           0 :                 break;
    1892             :                 }
    1893             :             }
    1894             : 
    1895             : 
    1896             :             /*
    1897             :              * If strideOne is true use NULL parameter for stride. This
    1898             :              * is a work-around to HDF compression problem
    1899             :              */
    1900           0 :             if (strideOne == 1)
    1901             :             {
    1902           0 :                 status = SDwritedata(sdid, offset, NULL, count,
    1903             :                          (VOIDP) datbuf);
    1904             :             }
    1905             :             else
    1906             :             {
    1907           0 :                 status = SDwritedata(sdid, offset, incr, count,
    1908             :                          (VOIDP) datbuf);
    1909             :             }
    1910             :             }
    1911             :             else
    1912             :             {
    1913           0 :             status = SDreaddata(sdid, offset, incr, count,
    1914             :                         (VOIDP) datbuf);
    1915             :             }
    1916             :         }
    1917             : 
    1918           0 :     return (status);
    1919             : }
    1920             : 
    1921             : 
    1922             : /*----------------------------------------------------------------------------|
    1923             : |  BEGIN_PROLOG                                                               |
    1924             : |                                                                             |
    1925             : |  FUNCTION: GDreadfield                                                      |
    1926             : |                                                                             |
    1927             : |  DESCRIPTION: Reads data from a grid field.                                 |
    1928             : |                                                                             |
    1929             : |                                                                             |
    1930             : |  Return Value    Type     Units     Description                             |
    1931             : |  ============   ======  =========   =====================================   |
    1932             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    1933             : |                                                                             |
    1934             : |  INPUTS:                                                                    |
    1935             : |  gridID         int32               grid structure ID                       |
    1936             : |  fieldname      char                fieldname                               |
    1937             : |  start          int32               start array                             |
    1938             : |  stride         int32               stride array                            |
    1939             : |  edge           int32               edge array                              |
    1940             : |  buffer         void                data buffer for read                    |
    1941             : |                                                                             |
    1942             : |                                                                             |
    1943             : |  OUTPUTS:                                                                   |
    1944             : |     None                                                                    |
    1945             : |                                                                             |
    1946             : |  NOTES:                                                                     |
    1947             : |                                                                             |
    1948             : |                                                                             |
    1949             : |   Date     Programmer   Description                                         |
    1950             : |  ======   ============  =================================================   |
    1951             : |  Jun 96   Joel Gales    Original Programmer                                 |
    1952             : |                                                                             |
    1953             : |  END_PROLOG                                                                 |
    1954             : -----------------------------------------------------------------------------*/
    1955             : intn
    1956           0 : GDreadfield(int32 gridID, const char *fieldname,
    1957             :       int32 start[], int32 stride[], int32 edge[], VOIDP buffer)
    1958             : 
    1959             : {
    1960           0 :     intn            status = 0; /* routine return status variable */
    1961             : 
    1962           0 :     status = GDwrrdfield(gridID, fieldname, "r", start, stride, edge,
    1963             :        buffer);
    1964           0 :     return (status);
    1965             : }
    1966             : 
    1967             : 
    1968             : 
    1969             : 
    1970             : /*----------------------------------------------------------------------------|
    1971             : |  BEGIN_PROLOG                                                               |
    1972             : |                                                                             |
    1973             : |  FUNCTION: GDwrrdattr                                                       |
    1974             : |                                                                             |
    1975             : |  DESCRIPTION:                                                               |
    1976             : |                                                                             |
    1977             : |                                                                             |
    1978             : |  Return Value    Type     Units     Description                             |
    1979             : |  ============   ======  =========   =====================================   |
    1980             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    1981             : |                                                                             |
    1982             : |  INPUTS:                                                                    |
    1983             : |  gridID         int32               grid structure ID                       |
    1984             : |  attrname       char                attribute name                          |
    1985             : |  numbertype     int32               attribute HDF numbertype                |
    1986             : |  count          int32               Number of attribute elements            |
    1987             : |  wrcode         char                Read/Write Code "w/r"                   |
    1988             : |  datbuf         void                I/O buffer                              |
    1989             : |                                                                             |
    1990             : |  OUTPUTS:                                                                   |
    1991             : |  datbuf                                                                     |
    1992             : |                                                                             |
    1993             : |  NOTES:                                                                     |
    1994             : |                                                                             |
    1995             : |                                                                             |
    1996             : |   Date     Programmer   Description                                         |
    1997             : |  ======   ============  =================================================   |
    1998             : |  Jun 96   Joel Gales    Original Programmer                                 |
    1999             : |  Oct 96   Joel Gales    Get Attribute Vgroup ID from external array         |
    2000             : |                                                                             |
    2001             : |  END_PROLOG                                                                 |
    2002             : -----------------------------------------------------------------------------*/
    2003             : static intn
    2004           1 : GDwrrdattr(int32 gridID, const char *attrname, int32 numbertype, int32 count,
    2005             :      const char *wrcode, VOIDP datbuf)
    2006             : 
    2007             : {
    2008             :     intn            status; /* routine return status variable */
    2009             : 
    2010             :     int32           fid;  /* HDF-EOS file ID */
    2011             :     int32           attrVgrpID; /* Grid attribute ID */
    2012             :     int32           dum;  /* dummy variable */
    2013           1 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    2014             : 
    2015             : 
    2016             :     /* Check Grid id */
    2017           1 :     status = GDchkgdid(gridID, "GDwrrdattr", &fid, &dum, &dum);
    2018             : 
    2019           1 :     if (status == 0)
    2020             :     {
    2021             :   /* Perform Attribute I/O */
    2022             :   /* --------------------- */
    2023           1 :   int gID = gridID % idOffset;
    2024           1 :   if (gID >= NGRID)
    2025             :   {
    2026           0 :     return -1;
    2027             :   }
    2028           1 :   attrVgrpID = GDXGrid[gID].VIDTable[1];
    2029           1 :   status = EHattr(fid, attrVgrpID, attrname, numbertype, count,
    2030             :       wrcode, datbuf);
    2031             :     }
    2032           1 :     return (status);
    2033             : }
    2034             : 
    2035             : /*----------------------------------------------------------------------------|
    2036             : |  BEGIN_PROLOG                                                               |
    2037             : |                                                                             |
    2038             : |  FUNCTION: GDreadattr                                                       |
    2039             : |                                                                             |
    2040             : |  DESCRIPTION: Reads attribute from a grid.                                  |
    2041             : |                                                                             |
    2042             : |                                                                             |
    2043             : |  Return Value    Type     Units     Description                             |
    2044             : |  ============   ======  =========   =====================================   |
    2045             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    2046             : |                                                                             |
    2047             : |  INPUTS:                                                                    |
    2048             : |  gridID         int32               grid structure ID                       |
    2049             : |  attrname       char                attribute name                          |
    2050             : |                                                                             |
    2051             : |  OUTPUTS:                                                                   |
    2052             : |  datbuf         void                I/O buffer                              |
    2053             : |                                                                             |
    2054             : |  NOTES:                                                                     |
    2055             : |                                                                             |
    2056             : |                                                                             |
    2057             : |   Date     Programmer   Description                                         |
    2058             : |  ======   ============  =================================================   |
    2059             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2060             : |                                                                             |
    2061             : |  END_PROLOG                                                                 |
    2062             : -----------------------------------------------------------------------------*/
    2063             : intn
    2064           1 : GDreadattr(int32 gridID, const char *attrname, VOIDP datbuf)
    2065             : {
    2066           1 :     intn            status = 0; /* routine return status variable */
    2067           1 :     int32           dum = 0;  /* dummy variable */
    2068             : 
    2069             :     /* Call GDwrrdattr routine to read attribute */
    2070             :     /* ----------------------------------------- */
    2071           1 :     status = GDwrrdattr(gridID, attrname, dum, dum, "r", datbuf);
    2072             : 
    2073           1 :     return (status);
    2074             : }
    2075             : 
    2076             : 
    2077             : 
    2078             : 
    2079             : 
    2080             : /*----------------------------------------------------------------------------|
    2081             : |  BEGIN_PROLOG                                                               |
    2082             : |                                                                             |
    2083             : |  FUNCTION: GDattrinfo                                                       |
    2084             : |                                                                             |
    2085             : |  DESCRIPTION:                                                               |
    2086             : |                                                                             |
    2087             : |                                                                             |
    2088             : |  Return Value    Type     Units     Description                             |
    2089             : |  ============   ======  =========   =====================================   |
    2090             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    2091             : |                                                                             |
    2092             : |  INPUTS:                                                                    |
    2093             : |  gridID         int32               grid structure ID                       |
    2094             : |  attrname       char                attribute name                          |
    2095             : |                                                                             |
    2096             : |  OUTPUTS:                                                                   |
    2097             : |  numbertype     int32               attribute HDF numbertype                |
    2098             : |  count          int32               Number of attribute elements            |
    2099             : |                                                                             |
    2100             : |                                                                             |
    2101             : |  OUTPUTS:                                                                   |
    2102             : |             None                                                            |
    2103             : |                                                                             |
    2104             : |  NOTES:                                                                     |
    2105             : |                                                                             |
    2106             : |                                                                             |
    2107             : |   Date     Programmer   Description                                         |
    2108             : |  ======   ============  =================================================   |
    2109             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2110             : |  Oct 96   Joel Gales    Get Attribute Vgroup ID from external array         |
    2111             : |                                                                             |
    2112             : |  END_PROLOG                                                                 |
    2113             : -----------------------------------------------------------------------------*/
    2114             : intn
    2115           0 : GDattrinfo(int32 gridID, const char *attrname, int32 * numbertype, int32 * count)
    2116             : {
    2117           0 :     intn            status = 0; /* routine return status variable */
    2118             : 
    2119           0 :     int32           fid = 0;  /* HDF-EOS file ID */
    2120             :     int32           attrVgrpID; /* Grid attribute ID */
    2121             :     int32           dum;  /* dummy variable */
    2122           0 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    2123             : 
    2124           0 :     status = GDchkgdid(gridID, "GDattrinfo", &fid, &dum, &dum);
    2125           0 :     if (status < 0)
    2126           0 :         return -1;
    2127             : 
    2128           0 :     int gID = gridID % idOffset;
    2129           0 :     if (gID >= NGRID)
    2130             :     {
    2131           0 :         return -1;
    2132             :     }
    2133           0 :     attrVgrpID = GDXGrid[gID].VIDTable[1];
    2134             : 
    2135           0 :     status = EHattrinfo(fid, attrVgrpID, attrname, numbertype,
    2136             :       count);
    2137             : 
    2138           0 :     return (status);
    2139             : }
    2140             : 
    2141             : 
    2142             : 
    2143             : 
    2144             : 
    2145             : 
    2146             : /*----------------------------------------------------------------------------|
    2147             : |  BEGIN_PROLOG                                                               |
    2148             : |                                                                             |
    2149             : |  FUNCTION: GDinqattrs                                                       |
    2150             : |                                                                             |
    2151             : |  DESCRIPTION:                                                               |
    2152             : |                                                                             |
    2153             : |                                                                             |
    2154             : |  Return Value    Type     Units     Description                             |
    2155             : |  ============   ======  =========   =====================================   |
    2156             : |  nattr          int32               Number of attributes in swath struct    |
    2157             : |                                                                             |
    2158             : |  INPUTS:                                                                    |
    2159             : |  grid ID        int32               grid structure ID                       |
    2160             : |                                                                             |
    2161             : |  OUTPUTS:                                                                   |
    2162             : |  attrnames      char                Attribute names in swath struct         |
    2163             : |                                     (Comma-separated list)                  |
    2164             : |  strbufsize     int32               Attributes name list string length      |
    2165             : |                                                                             |
    2166             : |  OUTPUTS:                                                                   |
    2167             : |             None                                                            |
    2168             : |                                                                             |
    2169             : |  NOTES:                                                                     |
    2170             : |                                                                             |
    2171             : |                                                                             |
    2172             : |   Date     Programmer   Description                                         |
    2173             : |  ======   ============  =================================================   |
    2174             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2175             : |  Oct 96   Joel Gales    Initialize nattr                                    |
    2176             : |  Oct 96   Joel Gales    Get Attribute Vgroup ID from external array         |
    2177             : |                                                                             |
    2178             : |  END_PROLOG                                                                 |
    2179             : -----------------------------------------------------------------------------*/
    2180             : int32
    2181           4 : GDinqattrs(int32 gridID, char *attrnames, int32 * strbufsize)
    2182             : {
    2183             :     intn            status; /* routine return status variable */
    2184             : 
    2185             :     int32           fid;  /* HDF-EOS file ID */
    2186             :     int32           attrVgrpID; /* Grid attribute ID */
    2187             :     int32           dum;  /* dummy variable */
    2188           4 :     int32           nattr = 0;  /* Number of attributes */
    2189           4 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    2190             : 
    2191             : 
    2192             :     /* Check Grid id */
    2193           4 :     status = GDchkgdid(gridID, "GDinqattrs", &fid, &dum, &dum);
    2194             : 
    2195           4 :     if (status == 0)
    2196             :     {
    2197           4 :   int gID = gridID % idOffset;
    2198           4 :   if (gID >= NGRID)
    2199             :   {
    2200           0 :       return -1;
    2201             :     }
    2202           4 :   attrVgrpID = GDXGrid[gID].VIDTable[1];
    2203           4 :   nattr = EHattrcat(fid, attrVgrpID, attrnames, strbufsize);
    2204             :     }
    2205             : 
    2206           4 :     return (nattr);
    2207             : }
    2208             : 
    2209             : 
    2210             : 
    2211             : 
    2212             : 
    2213             : 
    2214             : #define REMQUOTE(x) do { \
    2215             :     char* l_x = x; \
    2216             :     const size_t l_x_len = strlen(l_x); \
    2217             :     if (l_x_len >= 2 && l_x[0] == '"' && l_x[l_x_len - 1] == '"') {\
    2218             :         memmove(l_x, l_x + 1, l_x_len - 2); \
    2219             :         l_x[l_x_len - 2] = 0; \
    2220             :     } \
    2221             :   } while(0)
    2222             : 
    2223             : 
    2224             : /*----------------------------------------------------------------------------|
    2225             : |  BEGIN_PROLOG                                                               |
    2226             : |                                                                             |
    2227             : |  FUNCTION: GDinqfields                                                      |
    2228             : |                                                                             |
    2229             : |  DESCRIPTION: Retrieve information about all data fields defined in a grid. |
    2230             : |                                                                             |
    2231             : |                                                                             |
    2232             : |  Return Value    Type     Units     Description                             |
    2233             : |  ============   ======  =========   =====================================   |
    2234             : |  nFld           int32               Number of fields in swath               |
    2235             : |                                                                             |
    2236             : |  INPUTS:                                                                    |
    2237             : |  gridID         int32               grid structure ID                       |
    2238             : |                                                                             |
    2239             : |                                                                             |
    2240             : |  OUTPUTS:                                                                   |
    2241             : |  fieldlist      char                Field names (comma-separated)           |
    2242             : |  rank           int32               Array of ranks                          |
    2243             : |  numbertype     int32               Array of HDF number types               |
    2244             : |                                                                             |
    2245             : |  NOTES:                                                                     |
    2246             : |                                                                             |
    2247             : |                                                                             |
    2248             : |   Date     Programmer   Description                                         |
    2249             : |  ======   ============  =================================================   |
    2250             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2251             : |  Aug 96   Joel Gales    Make metadata ODL compliant                         |
    2252             : |  Feb 97   Joel Gales    Set nFld to -1 if status = -1                       |
    2253             : |                                                                             |
    2254             : |  END_PROLOG                                                                 |
    2255             : -----------------------------------------------------------------------------*/
    2256             : int32
    2257           6 : GDinqfields(int32 gridID, char *fieldlist, int32 rank[],
    2258             :       int32 numbertype[])
    2259             : {
    2260             :     intn            status; /* routine return status variable */
    2261             : 
    2262             :     int32           fid;  /* HDF-EOS file ID */
    2263             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
    2264             :     int32           gdVgrpID; /* Grid root Vgroup ID */
    2265           6 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    2266           6 :     int32           nFld = 0; /* Number of mappings */
    2267             :     int32           slen[8];  /* String length array */
    2268             : 
    2269             :     char           *metabuf;  /* Pointer to structural metadata (SM) */
    2270             :     char           *metaptrs[2];/* Pointers to begin and end of SM section */
    2271             :     char            gridname[80]; /* Grid Name */
    2272             :     char           *utlstr;/* Utility string */
    2273             :     char           *ptr[8]; /* String pointer array */
    2274             : 
    2275             :     /* Allocate space for utility string */
    2276             :     /* --------------------------------- */
    2277           6 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    2278           6 :     if(utlstr == NULL)
    2279             :     {
    2280           0 :   HEpush(DFE_NOSPACE,"GDinqfields", __FILE__, __LINE__);
    2281           0 :   return(-1);
    2282             :     }
    2283             :     /* Check for valid grid id */
    2284             :     /* ----------------------- */
    2285           6 :     status = GDchkgdid(gridID, "GDinqfields", &fid, &sdInterfaceID, &gdVgrpID);
    2286           6 :     if (status == 0)
    2287             :     {
    2288             : 
    2289             :   /* If field names, ranks,  or number types desired ... */
    2290             :   /* --------------------------------------------------- */
    2291           6 :   if (fieldlist != NULL || rank != NULL || numbertype != NULL)
    2292             :   {
    2293             :       /* Get grid name */
    2294             :       /* ------------- */
    2295           6 :       int gID = gridID % idOffset;
    2296           6 :       if (gID >= NGRID)
    2297             :       {
    2298           0 :          free(utlstr);
    2299           0 :          return -1;
    2300             :       }
    2301           6 :       VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
    2302             : 
    2303             : 
    2304             :       /* Get pointers to "DataField" section within SM */
    2305             :       /* --------------------------------------------- */
    2306           6 :       metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
    2307             :              "DataField", metaptrs);
    2308           6 :       if(metabuf == NULL)
    2309             :       {
    2310           0 :     free(utlstr);
    2311           0 :     return(-1);
    2312             :       }
    2313             : 
    2314             : 
    2315             :       /* If field names are desired then "clear" name buffer */
    2316             :       /* --------------------------------------------------- */
    2317           6 :       if (fieldlist != NULL)
    2318             :       {
    2319           6 :     fieldlist[0] = 0;
    2320             :       }
    2321             : 
    2322             : 
    2323             :       /* Begin loop through mapping entries in metadata */
    2324             :       /* ---------------------------------------------- */
    2325             :       while (1)
    2326             :       {
    2327             :     /* Search for OBJECT string */
    2328             :     /* ------------------------ */
    2329         110 :     metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");
    2330             : 
    2331             : 
    2332             :     /* If found within "Data" Field metadata section .. */
    2333             :     /* ------------------------------------------------ */
    2334         110 :     if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    2335             :     {
    2336             :         /* Get Fieldnames (if desired) */
    2337             :         /* --------------------------- */
    2338         104 :         if (fieldlist != NULL)
    2339             :         {
    2340             :       /* Check 1st for old meta data then new */
    2341             :       /* ------------------------------------ */
    2342         104 :       EHgetmetavalue(metaptrs, "OBJECT", utlstr);
    2343             : 
    2344             :       /*
    2345             :        * If OBJECT value begins with double quote then old
    2346             :        * metadata, field name is OBJECT value. Otherwise
    2347             :        * search for "DataFieldName" string
    2348             :        */
    2349             : 
    2350         104 :       if (utlstr[0] != '"')
    2351             :       {
    2352         104 :           strcpy(utlstr, "\t\t\t\t");
    2353         104 :           strcat(utlstr, "DataFieldName");
    2354         104 :           strcat(utlstr, "=");
    2355         104 :           metaptrs[0] = strstr(metaptrs[0], utlstr);
    2356         104 :           EHgetmetavalue(metaptrs, "DataFieldName", utlstr);
    2357             :       }
    2358             : 
    2359             :       /* Strip off double quotes */
    2360             :       /* ----------------------- */
    2361         104 :       REMQUOTE(utlstr);
    2362             : 
    2363             : 
    2364             :       /* Add to fieldlist */
    2365             :       /* ---------------- */
    2366         104 :           if (nFld > 0)
    2367             :       {
    2368          98 :           strcat(fieldlist, ",");
    2369             :       }
    2370         104 :       strcat(fieldlist, utlstr);
    2371             : 
    2372             :         }
    2373             :         /* Get Numbertype */
    2374         104 :         if (numbertype != NULL)
    2375             :         {
    2376         104 :       EHgetmetavalue(metaptrs, "DataType", utlstr);
    2377         104 :       numbertype[nFld] = EHnumstr(utlstr);
    2378             :         }
    2379             :         /*
    2380             :          * Get Rank (if desired) by counting # of dimensions in
    2381             :          * "DimList" string
    2382             :          */
    2383         104 :         if (rank != NULL)
    2384             :         {
    2385         104 :       EHgetmetavalue(metaptrs, "DimList", utlstr);
    2386         104 :       rank[nFld] = EHparsestr(utlstr, ',', ptr, CPL_ARRAYSIZE(ptr), slen, CPL_ARRAYSIZE(slen));
    2387         104 :             if (rank[nFld] < 0)
    2388             :             {
    2389           0 :                 status = -1;
    2390           0 :                 break;
    2391             :             }
    2392             :         }
    2393             :         /* Increment number of fields */
    2394         104 :         nFld++;
    2395             :     }
    2396             :     else
    2397             :         /* No more fields found */
    2398             :     {
    2399             :         break;
    2400             :     }
    2401             :       }
    2402           6 :       free(metabuf);
    2403             :   }
    2404             :     }
    2405             : 
    2406             :     /* Set nFld to -1 if error status exists */
    2407             :     /* ------------------------------------- */
    2408           6 :     if (status == -1)
    2409             :     {
    2410           0 :   nFld = -1;
    2411             :     }
    2412           6 :     free(utlstr);
    2413           6 :     return (nFld);
    2414             : }
    2415             : 
    2416             : 
    2417             : 
    2418             : 
    2419             : 
    2420             : /*----------------------------------------------------------------------------|
    2421             : |  BEGIN_PROLOG                                                               |
    2422             : |                                                                             |
    2423             : |  FUNCTION: GDnentries                                                       |
    2424             : |                                                                             |
    2425             : |  DESCRIPTION: Returns number of entries and descriptive string buffer       |
    2426             : |                size for a specified entity.                                 |
    2427             : |                                                                             |
    2428             : |                                                                             |
    2429             : |  Return Value    Type     Units     Description                             |
    2430             : |  ============   ======  =========   =====================================   |
    2431             : |  nEntries       int32               Number of entries                       |
    2432             : |                                                                             |
    2433             : |  INPUTS:                                                                    |
    2434             : |  gridID         int32               grid structure ID                       |
    2435             : |  entrycode      int32               Entry code                              |
    2436             : |                               HDFE_NENTDIM  (0)                       |
    2437             : |                               HDFE_NENTDFLD (4)                       |
    2438             : |                                                                             |
    2439             : |                                                                             |
    2440             : |  OUTPUTS:                                                                   |
    2441             : |  strbufsize     int32               Length of comma-separated list          |
    2442             : |                                     (Does not include null-terminator       |
    2443             : |                                                                             |
    2444             : |  NOTES:                                                                     |
    2445             : |                                                                             |
    2446             : |                                                                             |
    2447             : |   Date     Programmer   Description                                         |
    2448             : |  ======   ============  =================================================   |
    2449             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2450             : |  Aug 96   Joel Gales    Make metadata ODL compliant                         |
    2451             : |  Feb 97   Joel Gales    Set nEntries to -1 if status = -1                   |
    2452             : |                                                                             |
    2453             : |  END_PROLOG                                                                 |
    2454             : -----------------------------------------------------------------------------*/
    2455             : int32
    2456           6 : GDnentries(int32 gridID, int32 entrycode, int32 * strbufsize)
    2457             : 
    2458             : {
    2459             :     intn            status; /* routine return status variable */
    2460             :     intn            i;    /* Loop index */
    2461             : 
    2462             :     int32           fid;  /* HDF-EOS file ID */
    2463             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
    2464             :     int32           gdVgrpID; /* Grid root Vgroup ID */
    2465           6 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    2466           6 :     int32           nEntries = 0; /* Number of entries */
    2467             :     int32           metaflag; /* Old (0), New (1) metadata flag) */
    2468           6 :     int32           nVal = 0; /* Number of strings to search for */
    2469             : 
    2470           6 :     char           *metabuf = NULL; /* Pointer to structural metadata (SM) */
    2471           6 :     char           *metaptrs[2] = {NULL, NULL};/* Pointers to begin and end of SM section */
    2472             :     char            gridname[80]; /* Grid Name */
    2473             :     char           *utlstr;/* Utility string */
    2474             :     char            valName[2][32]; /* Strings to search for */
    2475             : 
    2476           6 :     memset(valName, 0, sizeof(valName));
    2477             : 
    2478             :     /* Allocate space for utility string */
    2479             :     /* --------------------------------- */
    2480           6 :     utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    2481           6 :     if(utlstr == NULL)
    2482             :     {
    2483           0 :   HEpush(DFE_NOSPACE,"GDnentries", __FILE__, __LINE__);
    2484           0 :   return(-1);
    2485             :     }
    2486           6 :     status = GDchkgdid(gridID, "GDnentries", &fid, &sdInterfaceID, &gdVgrpID);
    2487             : 
    2488           6 :     if (status == 0)
    2489             :     {
    2490             :   /* Get grid name */
    2491           6 :   int gID = gridID % idOffset;
    2492           6 :   if (gID >= NGRID)
    2493             :   {
    2494           0 :      free(utlstr);
    2495           0 :      return -1;
    2496             :   }
    2497             : 
    2498           6 :   VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
    2499             : 
    2500             :   /* Zero out string buffer size */
    2501           6 :   *strbufsize = 0;
    2502             : 
    2503             : 
    2504             :   /*
    2505             :    * Get pointer to  relevant section within SM and Get names of
    2506             :    * metadata strings to inquire about
    2507             :    */
    2508           6 :   switch (entrycode)
    2509             :   {
    2510           0 :   case HDFE_NENTDIM:
    2511             :       {
    2512           0 :     metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
    2513             :                  "Dimension", metaptrs);
    2514           0 :     if(metabuf == NULL)
    2515             :     {
    2516           0 :         free(utlstr);
    2517           0 :         return(-1);
    2518             :     }
    2519             : 
    2520           0 :     nVal = 1;
    2521           0 :     strcpy(&valName[0][0], "DimensionName");
    2522             :       }
    2523           0 :       break;
    2524             : 
    2525           6 :   case HDFE_NENTDFLD:
    2526             :       {
    2527           6 :     metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
    2528             :                  "DataField", metaptrs);
    2529           6 :     if(metabuf == NULL)
    2530             :     {
    2531           0 :         free(utlstr);
    2532           0 :         return(-1);
    2533             :     }
    2534             : 
    2535           6 :     nVal = 1;
    2536           6 :     strcpy(&valName[0][0], "DataFieldName");
    2537             :       }
    2538           6 :       break;
    2539             :   }
    2540             : 
    2541           6 :   if (!metabuf || metaptrs[0] == NULL)
    2542             :     {
    2543           0 :         free(metabuf);
    2544           0 :         free(utlstr);
    2545           0 :         return -1;
    2546             :     }
    2547             : 
    2548             :   /*
    2549             :    * Check for presence of 'GROUP="' string If found then old metadata,
    2550             :    * search on OBJECT string
    2551             :    */
    2552           6 :   metaflag = (strstr(metabuf, "GROUP=\"") == NULL) ? 1 : 0;
    2553           6 :   if (metaflag == 0)
    2554             :   {
    2555           0 :       nVal = 1;
    2556           0 :       strcpy(&valName[0][0], "\t\tOBJECT");
    2557             :   }
    2558             : 
    2559             : 
    2560             :   /* Begin loop through entries in metadata */
    2561             :   /* -------------------------------------- */
    2562             :   while (1)
    2563             :   {
    2564             :       /* Search for first string */
    2565         110 :       strcpy(utlstr, &valName[0][0]);
    2566         110 :       strcat(utlstr, "=");
    2567         110 :       metaptrs[0] = strstr(metaptrs[0], utlstr);
    2568             : 
    2569             :       /* If found within relevant metadata section ... */
    2570         110 :       if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    2571             :       {
    2572         208 :     for (i = 0; i < nVal; i++)
    2573             :     {
    2574             :         /*
    2575             :          * Get all string values Don't count quotes
    2576             :          */
    2577         104 :         EHgetmetavalue(metaptrs, &valName[i][0], utlstr);
    2578         104 :         if( utlstr[0] == '"' && utlstr[strlen(utlstr)-1] == '"' )
    2579           4 :             *strbufsize += (int32)strlen(utlstr) - 2;
    2580             :         else
    2581         100 :             *strbufsize += (int32)strlen(utlstr);
    2582             :     }
    2583             :     /* Increment number of entries */
    2584         104 :     nEntries++;
    2585             : 
    2586             :     /* Go to end of OBJECT */
    2587         104 :     metaptrs[0] = strstr(metaptrs[0], "END_OBJECT");
    2588             :       }
    2589             :       else
    2590             :     /* No more entries found */
    2591             :       {
    2592             :     break;
    2593             :       }
    2594             :   }
    2595           6 :   free(metabuf);
    2596             : 
    2597             : 
    2598             :   /* Count comma separators & slashes (if mappings) */
    2599             :   /* ---------------------------------------------- */
    2600           6 :   if (nEntries > 0)
    2601             :   {
    2602           6 :       *strbufsize += nEntries - 1;
    2603           6 :       *strbufsize += (nVal - 1) * nEntries;
    2604             :   }
    2605             :     }
    2606             : 
    2607             : 
    2608             :     /* Set nEntries to -1 if error status exists */
    2609             :     /* ----------------------------------------- */
    2610           6 :     if (status == -1)
    2611             :     {
    2612           0 :   nEntries = -1;
    2613             :     }
    2614             : 
    2615           6 :     free(utlstr);
    2616           6 :     return (nEntries);
    2617             : }
    2618             : 
    2619             : 
    2620             : 
    2621             : 
    2622             : 
    2623             : /*----------------------------------------------------------------------------|
    2624             : |  BEGIN_PROLOG                                                               |
    2625             : |                                                                             |
    2626             : |  FUNCTION: GDinqgrid                                                        |
    2627             : |                                                                             |
    2628             : |  DESCRIPTION: Returns number and names of grid structures in file           |
    2629             : |                                                                             |
    2630             : |                                                                             |
    2631             : |  Return Value    Type     Units     Description                             |
    2632             : |  ============   ======  =========   =====================================   |
    2633             : |  nGrid          int32               Number of grid structures in file       |
    2634             : |                                                                             |
    2635             : |  INPUTS:                                                                    |
    2636             : |  filename       char                HDF-EOS filename                        |
    2637             : |                                                                             |
    2638             : |  OUTPUTS:                                                                   |
    2639             : |  gridlist       char                List of grid names (comma-separated)    |
    2640             : |  strbufsize     int32               Length of gridlist                      |
    2641             : |                                                                             |
    2642             : |  NOTES:                                                                     |
    2643             : |                                                                             |
    2644             : |                                                                             |
    2645             : |   Date     Programmer   Description                                         |
    2646             : |  ======   ============  =================================================   |
    2647             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2648             : |                                                                             |
    2649             : |  END_PROLOG                                                                 |
    2650             : -----------------------------------------------------------------------------*/
    2651             : int32
    2652          25 : GDinqgrid(const char *filename, char *gridlist, int32 * strbufsize)
    2653             : {
    2654             :     int32           nGrid;  /* Number of grid structures in file */
    2655             : 
    2656             :     /* Call "EHinquire" routine */
    2657             :     /* ------------------------ */
    2658          25 :     nGrid = EHinquire(filename, "GRID", gridlist, strbufsize);
    2659             : 
    2660          25 :     return (nGrid);
    2661             : }
    2662             : 
    2663             : 
    2664             : 
    2665             : /*----------------------------------------------------------------------------|
    2666             : |  BEGIN_PROLOG                                                               |
    2667             : |                                                                             |
    2668             : |  FUNCTION: GDgetfillvalue                                                   |
    2669             : |                                                                             |
    2670             : |  DESCRIPTION: Retrieves fill value for a specified field.                   |
    2671             : |                                                                             |
    2672             : |                                                                             |
    2673             : |  Return Value    Type     Units     Description                             |
    2674             : |  ============   ======  =========   =====================================   |
    2675             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    2676             : |                                                                             |
    2677             : |  INPUTS:                                                                    |
    2678             : |  gridID         int32               grid structure ID                       |
    2679             : |  fieldname      char                field name                              |
    2680             : |                                                                             |
    2681             : |  OUTPUTS:                                                                   |
    2682             : |  fillval        void                fill value                              |
    2683             : |                                                                             |
    2684             : |  NOTES:                                                                     |
    2685             : |                                                                             |
    2686             : |                                                                             |
    2687             : |   Date     Programmer   Description                                         |
    2688             : |  ======   ============  =================================================   |
    2689             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2690             : |                                                                             |
    2691             : |  END_PROLOG                                                                 |
    2692             : -----------------------------------------------------------------------------*/
    2693             : intn
    2694           2 : GDgetfillvalue(int32 gridID, const char *fieldname, VOIDP fillval)
    2695             : {
    2696             :     intn            status; /* routine return status variable */
    2697             : 
    2698             :     int32           nt;   /* Number type */
    2699             :     int32           dims[8];  /* Dimensions array */
    2700             :     int32           dum;  /* Dummy variable */
    2701             : 
    2702             :     char            name[80]; /* Fill value "attribute" name */
    2703             : 
    2704           2 :     status = GDchkgdid(gridID, "GDgetfillvalue", &dum, &dum, &dum);
    2705             : 
    2706             :     /* Check for valid grid ID */
    2707           2 :     if (status == 0)
    2708             :     {
    2709             :   /* Get field info */
    2710           1 :   status = GDfieldinfo(gridID, fieldname, &dum, dims, &nt, NULL);
    2711             : 
    2712           1 :   if (status == 0)
    2713             :   {
    2714             :       /* Read fill value attribute */
    2715           1 :       strcpy(name, "_FV_");
    2716           1 :       strcat(name, fieldname);
    2717           1 :       status = GDreadattr(gridID, name, fillval);
    2718             :   }
    2719             :   else
    2720             :   {
    2721           0 :       HEpush(DFE_GENAPP, "GDgetfillvalue", __FILE__, __LINE__);
    2722           0 :       HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
    2723             :   }
    2724             : 
    2725             :     }
    2726           2 :     return (status);
    2727             : }
    2728             : 
    2729             : 
    2730             : 
    2731             : 
    2732             : 
    2733             : /*----------------------------------------------------------------------------|
    2734             : |  BEGIN_PROLOG                                                               |
    2735             : |                                                                             |
    2736             : |  FUNCTION: GDdetach                                                         |
    2737             : |                                                                             |
    2738             : |  DESCRIPTION: Detaches from grid interface and performs file housekeeping.  |
    2739             : |                                                                             |
    2740             : |                                                                             |
    2741             : |  Return Value    Type     Units     Description                             |
    2742             : |  ============   ======  =========   =====================================   |
    2743             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    2744             : |                                                                             |
    2745             : |  INPUTS:                                                                    |
    2746             : |  gridID         int32               grid structure ID                       |
    2747             : |                                                                             |
    2748             : |                                                                             |
    2749             : |  OUTPUTS:                                                                   |
    2750             : |             None                                                            |
    2751             : |                                                                             |
    2752             : |  NOTES:                                                                     |
    2753             : |                                                                             |
    2754             : |                                                                             |
    2755             : |   Date     Programmer   Description                                         |
    2756             : |  ======   ============  =================================================   |
    2757             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2758             : |  Sep 96   Joel Gales    Setup dim names for SDsetdimname in dimbuf1 rather  |
    2759             : |                         that utlstr                                         |
    2760             : |  Oct 96   Joel Gales    Detach Grid Vgroups                                 |
    2761             : |  Oct 96   Joel Gales    "Detach" from SDS                                   |
    2762             : |  Nov 96   Joel Gales    Call GDchkgdid to check for proper grid ID          |
    2763             : |  Dec 96   Joel Gales    Add multiple vertical subsetting garbage collection |
    2764             : |  Oct 98   Abe Taaheri   Added GDXRegion[k]->DimNamePtr[i] =0; after freeing |
    2765             : |                         memory                                              |
    2766             : |  Sep 99   Abe Taaheri   Changed memcpy to memmove because of overlapping    |
    2767             : |                         source and destination for GDXSDcomb, nameptr, and  |
    2768             : |                         dimptr. memcpy may cause unexpected results.        |
    2769             : |                                                                             |
    2770             : |  END_PROLOG                                                                 |
    2771             : -----------------------------------------------------------------------------*/
    2772             : intn
    2773          13 : GDdetach(int32 gridID)
    2774             : 
    2775             : {
    2776             :     intn            i;    /* Loop index */
    2777             :     intn            k;    /* Loop index */
    2778          13 :     intn            status = 0; /* routine return status variable */
    2779             : 
    2780             :     int32           sdInterfaceID;  /* SDS interface ID */
    2781             :     int32           gID;  /* Grid ID - offset */
    2782          13 :     int32           idOffset = GDIDOFFSET;  /* Grid ID offset */
    2783             :     int32           dum;  /* Dummy variable */
    2784             : 
    2785             :     char            gridname[VGNAMELENMAX + 1]; /* Grid name */
    2786             : 
    2787             : 
    2788          13 :     status = GDchkgdid(gridID, "GDdetach", &dum, &sdInterfaceID, &dum);
    2789             : 
    2790          13 :     if (status == 0)
    2791             :     {
    2792          13 :   gID = gridID % idOffset;
    2793          13 :   if (gID >= NGRID)
    2794             :   {
    2795           0 :      return -1;
    2796             :   }
    2797          13 :   VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
    2798             : 
    2799             : 
    2800             :   /* "Detach" from previously attached SDSs */
    2801             :   /* -------------------------------------- */
    2802          18 :   for (k = 0; k < GDXGrid[gID].nSDS; k++)
    2803             :   {
    2804           5 :       SDendaccess(GDXGrid[gID].sdsID[k]);
    2805             :   }
    2806          13 :   free(GDXGrid[gID].sdsID);
    2807          13 :   GDXGrid[gID].sdsID = 0;
    2808          13 :   GDXGrid[gID].nSDS = 0;
    2809             : 
    2810             : 
    2811             : 
    2812             :   /* Detach Grid Vgroups */
    2813             :   /* ------------------- */
    2814          13 :   Vdetach(GDXGrid[gID].VIDTable[0]);
    2815          13 :   Vdetach(GDXGrid[gID].VIDTable[1]);
    2816          13 :   Vdetach(GDXGrid[gID].IDTable);
    2817             : 
    2818          13 :   GDXGrid[gID].active = 0;
    2819          13 :   GDXGrid[gID].VIDTable[0] = 0;
    2820          13 :   GDXGrid[gID].VIDTable[1] = 0;
    2821          13 :   GDXGrid[gID].IDTable = 0;
    2822          13 :   GDXGrid[gID].fid = 0;
    2823             : 
    2824             : 
    2825             : 
    2826             : 
    2827             :   /* Free Region Pointers */
    2828             :   /* -------------------- */
    2829        3341 :   for (k = 0; k < NGRIDREGN; k++)
    2830             :   {
    2831        3328 :       if (GDXRegion[k] != 0 &&
    2832           0 :     GDXRegion[k]->gridID == gridID)
    2833             :       {
    2834           0 :     for (i = 0; i < 8; i++)
    2835             :     {
    2836           0 :         if (GDXRegion[k]->DimNamePtr[i] != 0)
    2837             :         {
    2838           0 :       free(GDXRegion[k]->DimNamePtr[i]);
    2839           0 :       GDXRegion[k]->DimNamePtr[i] = 0;
    2840             :         }
    2841             :     }
    2842             : 
    2843           0 :     free(GDXRegion[k]);
    2844           0 :     GDXRegion[k] = 0;
    2845             :       }
    2846             :   }
    2847             :     }
    2848          13 :     return (status);
    2849             : }
    2850             : 
    2851             : 
    2852             : /*----------------------------------------------------------------------------|
    2853             : |  BEGIN_PROLOG                                                               |
    2854             : |                                                                             |
    2855             : |  FUNCTION: GDclose                                                          |
    2856             : |                                                                             |
    2857             : |  DESCRIPTION: Closes file.                                                  |
    2858             : |                                                                             |
    2859             : |                                                                             |
    2860             : |  Return Value    Type     Units     Description                             |
    2861             : |  ============   ======  =========   =====================================   |
    2862             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    2863             : |                                                                             |
    2864             : |  INPUTS:                                                                    |
    2865             : |  fid            int32               File ID                                 |
    2866             : |                                                                             |
    2867             : |                                                                             |
    2868             : |  OUTPUTS:                                                                   |
    2869             : |             None                                                            |
    2870             : |                                                                             |
    2871             : |  NOTES:                                                                     |
    2872             : |                                                                             |
    2873             : |                                                                             |
    2874             : |   Date     Programmer   Description                                         |
    2875             : |  ======   ============  =================================================   |
    2876             : |  Jun 96   Joel Gales    Original Programmer                                 |
    2877             : |                                                                             |
    2878             : |  END_PROLOG                                                                 |
    2879             : -----------------------------------------------------------------------------*/
    2880             : intn
    2881          26 : GDclose(int32 fid)
    2882             : 
    2883             : {
    2884          26 :     intn            status = 0; /* routine return status variable */
    2885             : 
    2886             :     /* Call EHclose to perform file close */
    2887             :     /* ---------------------------------- */
    2888          26 :     status = EHclose(fid);
    2889             : 
    2890          26 :     return (status);
    2891             : }
    2892             : 
    2893             : /***********************************************
    2894             : GDwrrdtile --
    2895             :      This function is the underlying function below GDwritetile and
    2896             :      GDreadtile.
    2897             : 
    2898             : 
    2899             : Author--
    2900             : Alexis Zubrow
    2901             : 
    2902             : ********************************************************/
    2903             : 
    2904             : static intn
    2905           0 : GDwrrdtile(int32 gridID, const char *fieldname, const char *code, int32 start[],
    2906             :      VOIDP datbuf)
    2907             : {
    2908             :     intn            i;    /* Loop index */
    2909           0 :     intn            status = 0; /* routine return status variable */
    2910             : 
    2911             :     int32           fid;  /* HDF-EOS file ID */
    2912             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
    2913             :     int32           sdid; /* SDS ID */
    2914             : 
    2915             :     int32           dum;  /* Dummy variable */
    2916             :     int32           rankSDS;  /* Rank of SDS/Field */
    2917             : 
    2918             :     int32           dims[8];  /* Field/SDS dimensions */
    2919             :     int32           tileFlags;  /* flag to determine if field is tiled */
    2920             :     int32           numTileDims;/* number of tiles spanning a dimension */
    2921             :     HDF_CHUNK_DEF   tileDef;  /* union holding tiling info. */
    2922             : 
    2923             : 
    2924             :     /* Get gridID */
    2925           0 :     status = GDchkgdid(gridID, "GDwrrdtile", &fid, &sdInterfaceID, &dum);
    2926           0 :     if (status == 0)
    2927             :     {
    2928             : 
    2929             :   /* Get field info */
    2930           0 :   status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
    2931             : 
    2932           0 :   if (status == 0)
    2933             :   {
    2934             : 
    2935             :         /* Check whether fieldname is in SDS (multi-dim field) */
    2936             :         /* --------------------------------------------------- */
    2937           0 :         status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
    2938             :                  &rankSDS, &dum, &dum, dims, &dum);
    2939           0 :         if (status < 0)
    2940           0 :             return -1;
    2941             : 
    2942             : 
    2943             :         /*
    2944             :          * Check for errors in parameters passed to GDwritetile or
    2945             :          * GDreadtile
    2946             :          */
    2947             : 
    2948             :         /* Check if untiled field */
    2949           0 :         status = SDgetchunkinfo(sdid, &tileDef, &tileFlags);
    2950           0 :         if (tileFlags == HDF_NONE)
    2951             :         {
    2952           0 :             HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
    2953           0 :             HEreport("Field \"%s\" is not tiled.\n", fieldname);
    2954           0 :             status = -1;
    2955           0 :             return (status);
    2956             : 
    2957             :         }
    2958             : 
    2959             :       /*
    2960             :        * Check if rd/wr tilecoords are within the extent of the field
    2961             :        */
    2962           0 :       for (i = 0; i < rankSDS; i++)
    2963             :       {
    2964             :     /*
    2965             :      * Calculate the number of tiles which span a dimension of
    2966             :      * the field
    2967             :      */
    2968           0 :     numTileDims = dims[i] / tileDef.chunk_lengths[i];
    2969           0 :     if ((start[i] >= numTileDims) || (start[i] < 0))
    2970             :     {
    2971             :         /*
    2972             :          * ERROR INDICATING BEYOND EXTENT OF THAT DIMENSION OR
    2973             :          * NEGATIVE TILECOORDS
    2974             :          */
    2975           0 :         HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
    2976           0 :         HEreport("Tilecoords for dimension \"%d\" ...\n", i);
    2977           0 :         HEreport("is beyond the extent of dimension length\n");
    2978           0 :         status = -1;
    2979             : 
    2980             :     }
    2981             :       }
    2982             : 
    2983           0 :       if (status == -1)
    2984             :       {
    2985           0 :     return (status);
    2986             :       }
    2987             : 
    2988             : 
    2989             :       /* Actually write/read to the field */
    2990             : 
    2991           0 :       if (strcmp(code, "w") == 0) /* write tile */
    2992             :       {
    2993           0 :     status = SDwritechunk(sdid, start, (VOIDP) datbuf);
    2994             :       }
    2995           0 :       else if (strcmp(code, "r") == 0)  /* read tile */
    2996             :       {
    2997           0 :     status = SDreadchunk(sdid, start, (VOIDP) datbuf);
    2998             :       }
    2999             : 
    3000             : 
    3001             :   }
    3002             : 
    3003             :   /* Non-existent fieldname */
    3004             :   else
    3005             :   {
    3006           0 :       HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
    3007           0 :       HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
    3008           0 :       status = -1;
    3009             :   }
    3010             : 
    3011             :     }
    3012             : 
    3013           0 :     return (status);
    3014             : }
    3015             : 
    3016             : /***********************************************
    3017             : GDtileinfo --
    3018             :      This function queries the field to determine if it is tiled.  If it is
    3019             :      tile, one can retrieve some of the characteristics of the tiles.
    3020             : 
    3021             : Author--  Alexis Zubrow
    3022             : 
    3023             : ********************************************************/
    3024             : 
    3025             : 
    3026             : intn
    3027           1 : GDtileinfo(int32 gridID, const char *fieldname, int32 * tilecode, int32 * tilerank,
    3028             :      int32 tiledims[])
    3029             : 
    3030             : {
    3031             :     intn            i;    /* Loop index */
    3032           1 :     intn            status = 0; /* routine return status variable */
    3033             : 
    3034             :     int32           fid;  /* HDF-EOS file ID */
    3035             :     int32           sdInterfaceID;  /* HDF SDS interface ID */
    3036             :     int32           sdid; /* SDS ID */
    3037             : 
    3038             :     int32           dum;  /* Dummy variable */
    3039             :     int32           rankSDS;  /* Rank of SDS/Field/tile */
    3040             : 
    3041             :     int32           dims[8];  /* Field/SDS dimensions */
    3042             :     int32           tileFlags;  /* flag to determine if field is tiled */
    3043             :     HDF_CHUNK_DEF   tileDef;  /* union holding tiling info. */
    3044             : 
    3045             : 
    3046             :     /* Check if improper gridID */
    3047           1 :     status = GDchkgdid(gridID, "GDtileinfo", &fid, &sdInterfaceID, &dum);
    3048           1 :     if (status == 0)
    3049             :     {
    3050             : 
    3051             :   /* Get field info */
    3052           1 :   status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
    3053             : 
    3054           1 :   if (status == 0)
    3055             :   {
    3056             : 
    3057             :         /* Check whether fieldname is in SDS (multi-dim field) */
    3058             :         /* --------------------------------------------------- */
    3059           0 :         status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
    3060             :                  &rankSDS, &dum, &dum, dims, &dum);
    3061           0 :         if (status < 0)
    3062           0 :             return -1;
    3063             : 
    3064             :         /* Query field for tiling information */
    3065           0 :         status = SDgetchunkinfo(sdid, &tileDef, &tileFlags);
    3066             : 
    3067             :       /* If field is untiled, return untiled flag */
    3068           0 :       if (tileFlags == HDF_NONE)
    3069             :       {
    3070           0 :     *tilecode = HDFE_NOTILE;
    3071           0 :     return (status);
    3072             :       }
    3073             : 
    3074             :       /* IF field is tiled or tiled with compression */
    3075           0 :       else if ((tileFlags == HDF_CHUNK) ||
    3076           0 :          (tileFlags == (HDF_CHUNK | HDF_COMP)))
    3077             :       {
    3078           0 :     if (tilecode != NULL)
    3079             :     {
    3080           0 :         *tilecode = HDFE_TILE;
    3081             :     }
    3082           0 :     if (tilerank != NULL)
    3083             :     {
    3084           0 :         *tilerank = rankSDS;
    3085             :     }
    3086           0 :     if (tiledims != NULL)
    3087             :     {
    3088             :         /* Assign size of tile dimensions */
    3089           0 :         for (i = 0; i < rankSDS; i++)
    3090             :         {
    3091           0 :       tiledims[i] = tileDef.chunk_lengths[i];
    3092             :         }
    3093             :     }
    3094             :       }
    3095             :   }
    3096             : 
    3097             :   /* Non-existent fieldname */
    3098             :   else
    3099             :   {
    3100           1 :       HEpush(DFE_GENAPP, "GDtileinfo", __FILE__, __LINE__);
    3101           1 :       HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
    3102           1 :       status = -1;
    3103             :   }
    3104             : 
    3105             :     }
    3106           1 :     return (status);
    3107             : }
    3108             : 
    3109             : /***********************************************
    3110             : GDreadtile --
    3111             :      This function reads one tile from a particular field.
    3112             : 
    3113             : 
    3114             : Author--
    3115             : Alexis Zubrow
    3116             : 
    3117             : ********************************************************/
    3118             : 
    3119             : intn
    3120           0 : GDreadtile(int32 gridID, const char *fieldname, int32 tilecoords[],
    3121             :      VOIDP tileData)
    3122             : {
    3123           0 :     char            code[] = "r"; /* read tile code */
    3124           0 :     intn            status = 0; /* routine return status variable */
    3125             : 
    3126           0 :     status = GDwrrdtile(gridID, fieldname, code, tilecoords, tileData);
    3127             : 
    3128           0 :     return (status);
    3129             : }
    3130             : 
    3131             : /*----------------------------------------------------------------------------|
    3132             : |  BEGIN_PROLOG                                                               |
    3133             : |                                                                             |
    3134             : |  FUNCTION: GDsdid                                                           |
    3135             : |                                                                             |
    3136             : |  DESCRIPTION: Returns SD element ID for grid field                          |
    3137             : |                                                                             |
    3138             : |                                                                             |
    3139             : |  Return Value    Type     Units     Description                             |
    3140             : |  ============   ======  =========   =====================================   |
    3141             : |  status         intn                return status (0) SUCCEED, (-1) FAIL    |
    3142             : |                                                                             |
    3143             : |  INPUTS:                                                                    |
    3144             : |  gridID         int32               grid structure ID                       |
    3145             : |  fieldname      const char          field name                              |
    3146             : |                                                                             |
    3147             : |                                                                             |
    3148             : |  OUTPUTS:                                                                   |
    3149             : |  sdid           int32               SD element ID                           |
    3150             : |                                                                             |
    3151             : |  NOTES:                                                                     |
    3152             : |                                                                             |
    3153             : |                                                                             |
    3154             : |   Date     Programmer   Description                                         |
    3155             : |  ======   ============  =================================================   |
    3156             : |  Oct 07   Andrey Kiselev  Original Programmer                               |
    3157             : |                                                                             |
    3158             : |  END_PROLOG                                                                 |
    3159             : -----------------------------------------------------------------------------*/
    3160             : intn
    3161           6 : GDsdid(int32 gridID, const char *fieldname, int32 *sdid)
    3162             : {
    3163             :     intn            status;         /* routine return status variable */
    3164             :     int32           fid;          /* HDF-EOS file ID */
    3165             :     int32           sdInterfaceID;      /* HDF SDS interface ID */
    3166             :     int32           dum;          /* Dummy variable */
    3167             :     int32           dims[H4_MAX_VAR_DIMS]; /* Field/SDS dimensions */
    3168             : 
    3169           6 :     status = GDchkgdid(gridID, "GDsdid", &fid, &sdInterfaceID, &dum);
    3170           6 :     if (status != -1)
    3171             :     {
    3172           6 :         status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
    3173             :                              sdid, &dum, &dum, &dum, dims, &dum);
    3174             :     }
    3175             : 
    3176           6 :     return (status);
    3177             : }

Generated by: LCOV version 1.14