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

Generated by: LCOV version 1.14