/*
Copyright (C) 1996 Hughes and Applied Research Corporation

Permission to use, modify, and distribute this software and its documentation
for any purpose without fee is hereby granted, provided that the above
copyright notice appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation.
*/
/*****************************************************************************
REVISIONS:

Aug 31, 1999  Abe Taaheri    Changed memory allocation for utility strings to
                             the size of UTLSTR_MAX_SIZE.
			     Added error check for memory unavailability in
			     several functions.
			     Added check for NULL metabuf returned from
			     EHmeta... functions. NULL pointer returned from
			     EHmeta... functions indicate that memory could not
			     be allocated for metabuf.

June 05, 2003 Abe Taaheri / Bruce Beaumont

                            Changed MAXNREGIONS to 1024 to support MOPITT data
			    Supplied cast for compcode in call to
			      SDsetcompress to avoid compiler error
			    Removed declaration for unused variable rstatus
			      in SWwrrdfield
			    Removed initialization code for unused variables
			      in SWwrrdfield
			    Removed declaration for unused variable tmpVal
			      in SWdefboxregion
			    Added code in SWdefboxregion to check for index k
			      exceeding NSWATHREGN to avoid overwriting
			      memory
			    Removed declaration for unused variable retchar
			      in SWregionindex
			    Removed initialization code for unused variables
			      in SWregionindex
			    Removed declarations for unused variables tstatus,
			      nfields, nflgs, and swathname in SWextractregion
			    Removed initialization code for unused variables
			      in SWextractregion
			    Removed declaration for unused variable
			      land_status in SWscan2longlat
			    Removed initialization code for unused variables
			      in SWscan2longlat
			    Added clear (0) of timeflag in SWextractperiod if
			      return status from SWextractregion is non-zero
			    Removed declarations for unused variables tstatus,
			      scandim, ndfields, ndflds, and swathname in
			      SWregioninfo
			    Removed initialization code for unused variables
			      in SWregioninfo
			    Added clear (0) of timeflag in SWperiodinfo if
			      return status from SWregioninfo is non-zero
			    Removed declarations for unused variables size,
			      nfields, nflds, nswath, idxsz, cornerlon, and
			      cornerlat in SWdefscanregion
			    Removed initialization code for unused variables
			      in SWdefscanregion
			    Removed declarations for unused variables dims2,
			      rank, nt, swathname, dimlist, and buffer in
			      SWupdateidxmap
			    Removed declaration for unused variable statmeta
			      in SWgeomapinfo

Sept. 14, 2004 Melissa Porricelli
                            NCR 39839 Added SWindexinfo function to obtain
                              indices of subsetted swath
Nov 15, 2005   Tom Roegner  NCR 44092 - Added CYGWIN capability
Jun 22, 2007   Abe Taaheri  Added SZIP compression capability.
May 15, 2010   Abe Taaheri  Added Dimension Scale set & get functions
Jul  09, 2020   Peter Smith  Updated szlib code exclusions
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "mfhdf.h"
#include "hcomp.h"
#include "HdfEosDef.h"
#include <math.h>

/* if HDF4 is configured with SZIP */
#ifdef HAVE_SZLIB_H
#include "szlib.h"
#endif

#ifdef FORTRAN_API
#include "fortran_api.h"
#endif // FORTRAN_API

#define SWIDOFFSET 1048576


int32 SWX1dcomb[512*3];
int32 SWXSDcomb[512*5];
char  SWXSDname[HDFE_NAMBUFSIZE];
char  SWXSDdims[HDFE_DIMBUFSIZE];

/* This flag was added to allow the Time field to have different Dimensions
** than Longitude and Latitude and still be used for subsetting
** 23 June,1997  DaW
*/
intn  timeflag = 0;


/* Added for routine that converts scanline to Lat/long
** for floating scene subsetting
** Jul 1999 DaW
*/
#ifndef M_PI
#define M_PI      3.141592653589793238
#endif
#define RADOE	6371.0		/* Radius of Earth in Km */

#define NSWATH 400
/* Swath Structure External Arrays */
struct swathStructure
{
    int32 active;
    int32 IDTable;
    int32 VIDTable[3];
    int32 fid;
    int32 nSDS;
    int32 *sdsID;
    int32 compcode;
    intn  compparm[5];
    int32 tilecode;
    int32 tilerank;
    int32 tiledims[8];
};
struct swathStructure SWXSwath[NSWATH];



#define NSWATHREGN 512
#define MAXNREGIONS 2048
struct swathRegion
{
    int32 fid;
    int32 swathID;
    int32 nRegions;
    int32 StartRegion[MAXNREGIONS];
    int32 StopRegion[MAXNREGIONS];
    int32 StartVertical[8];
    int32 StopVertical[8];
    int32 StartScan[8];
    int32 StopScan[8];
    char *DimNamePtr[8];
    intn band8flag;
    intn  scanflag;
};
struct swathRegion *SWXRegion[NSWATHREGN];

/* define a macro for the string size of the utility strings. The value
   of 80 in previous version of this code was resulting in core dump (Array
   Bounds Write and Array Bounds Read problem in SWfinfo function and the
   functions called from there) for 7-8 dimensional fields where the
   string length for "DimList" can exceed 80 characters, including " and
   commas in the string. The length now is 512 which seems to be more
   than enough to avoid the problem mentioned above. */

#define UTLSTR_MAX_SIZE 512

/* Swath Prototypes (internal routines) */
intn SWchkswid(int32, const char *, int32 *, int32 *, int32 *);
int32 SWimapinfo(int32, char *, char *, int32 []);
int32 SWfinfo(int32, const char *, const char *, int32 *, int32 [], int32 *, char *);
intn SWfldinfo(int32, const char *, int32 *, int32 [], int32 *, char *);
intn SWdefimap(int32, char *, char *, int32 []);
intn SWdefinefield(int32, const char *, const char *, const char *, int32, int32);
intn SWdefgfld(int32, const char *, const char *, int32, int32);
intn SWdefdfld(int32, const char *, const char *, int32, int32);
intn SWwrgmeta(int32, const char *, const char *, int32);
intn SWwrdmeta(int32, const char *, const char *, int32);
intn SWwrrdattr(int32, const char *, int32, int32, const char *, VOIDP);
intn SW1dfldsrch(int32, int32, const char *, const char *, int32 *, int32 *, int32 *);
intn SWSDfldsrch(int32, int32, const char *, int32 *, int32 *,
                 int32 *, int32 *, int32 [], int32 *);
intn SWwrrdfield(int32, const char *, const char *, int32 [], int32 [], int32 [], VOIDP);
intn SWwrfld(int32, const char *, int32 [], int32 [], int32 [], VOIDP);
intn SWrdfld(int32, const char *, int32 [], int32 [], int32 [], VOIDP);
intn SWreginfo(int32, int32, const char *, int32 *, int32 *, int32 [], int32 *);
intn SWperinfo(int32, int32, const char *, int32 *, int32 *, int32 [], int32 *);
int32 SWinqfields(int32, const char *, char *, int32 [], int32 []);
int32 SWdefvrtreg(int32, int32, const char *, float64 []);
intn SWscan2longlat(int32, const char *, VOIDP, int32 [], int32 [], int32 *,
                    int32, int32);
int32 SWidxinfo(int32, const char *, int32, char *, int32 *);
int32 SWllmapedidxinfo(int32 swathID, const char *object, int32 *index0, int32 *index1);
intn SWtileinfo(int32, char *, int32 *, int32 *,
		int32 []);
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWopen                                                           |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  fid            int32               HDF-EOS file ID                         |
|                                                                             |
|  INPUTS:                                                                    |
|  filename       char                Filename                                |
|  l_access         intn              HDF access code                         |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWopen(const char *filename, intn l_access)

{
    int32           fid /* HDF-EOS file ID */ ;

    /* Call EHopen to perform file access */
    /* ---------------------------------- */
    fid = EHopen(filename, l_access);

    return (fid);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWcreate                                                         |
|                                                                             |
|  DESCRIPTION: Creates a new swath structure and returns swath ID            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  swathID        int32               Swath structure ID                      |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            int32               File ID                                 |
|  swathname      char                Swath structure name                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Sep 96   Joel Gales    Check swath name for length                         |
|  Mar 97   Joel Gales    Enlarge utlbuf to 512                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWcreate(int32 fid, const char *swathname)
{
    intn            i;		/* Loop index */
    intn            nswathopen = 0;	/* # of swath structures open */
    intn            status = 0;	/* routine return status variable */

    uint8           l_access;	/* Read/Write file access code */

    int32           HDFfid;	/* HDF file id */
    int32           vgRef;	/* Vgroup reference number */
    int32           vgid[4];	/* Vgroup ID array */
    int32           swathID = -1;	/* HDF-EOS swath ID */

    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           nSwath = 0;	/* Swath counter */

    char            name[UTLSTR_MAX_SIZE];	/* Vgroup name */
    char            a_class[UTLSTR_MAX_SIZE];	/* Vgroup class */
    char            errbuf[256];/* Buffer for error message */
    char            utlbuf[UTLSTR_MAX_SIZE];/* Utility buffer */
    char            utlbuf2[32];/* Utility buffer 2 */

    /*
     * Check HDF-EOS file ID, get back HDF file ID, SD interface ID  and
     * access code
     */
    status = EHchkfid(fid, swathname, &HDFfid, &sdInterfaceID, &l_access);

    /* Check file access */
    /* -------------------------- */
    if ( l_access == 0 )
      {
    	status = -1;
	HEpush(DFE_GENAPP, "SWcreate", __FILE__, __LINE__);
	HEreport("Cannot call SWcreate on a file opened read-only.\n");
      }

    /* Check swathname for length */
    /* -------------------------- */
    else if ((intn) strlen(swathname) > VGNAMELENMAX)
    {
	status = -1;
	HEpush(DFE_GENAPP, "SWcreate", __FILE__, __LINE__);
	HEreport("Swathname \"%s\" must be less than %d characters.\n",
		 swathname, VGNAMELENMAX);
    }


    if (status == 0)
    {

	/* Determine number of swaths currently opened */
	/* ------------------------------------------- */
	for (i = 0; i < NSWATH; i++)
	{
	    nswathopen += SWXSwath[i].active;
	}


	/* Setup file interface */
	/* -------------------- */
	if (nswathopen < NSWATH)
	{

	    /* Check that swath has not been previously opened */
	    /* ----------------------------------------------- */
	    vgRef = -1;

	    while (1)
	    {
		vgRef = Vgetid(HDFfid, vgRef);

		/* If no more Vgroups then exist while loop */
		/* ---------------------------------------- */
		if (vgRef == -1)
		{
		    break;
		}

		/* Get name and class of Vgroup */
		/* ---------------------------- */
		vgid[0] = Vattach(HDFfid, vgRef, "r");
		Vgetname(vgid[0], name);
		Vgetclass(vgid[0], a_class);
		Vdetach(vgid[0]);

		/* If SWATH then increment # swath counter */
		/* --------------------------------------- */
		if (strcmp(a_class, "SWATH") == 0)
		{
		    nSwath++;
		}

		/* If swath already exist, return error */
		/* ------------------------------------ */
		if (strcmp(name, swathname) == 0 &&
		    strcmp(a_class, "SWATH") == 0)
		{
		    status = -1;
		    HEpush(DFE_GENAPP, "SWcreate", __FILE__, __LINE__);
		    HEreport("\"%s\" already exists.\n", swathname);
		    break;
		}
	    }


	    if (status == 0)
	    {

		/* Create Root Vgroup for Swath */
		/* ---------------------------- */
		vgid[0] = Vattach(HDFfid, -1, "w");


		/* Set Name and Class (SWATH) */
		/* -------------------------- */
		Vsetname(vgid[0], swathname);
		Vsetclass(vgid[0], "SWATH");



		/* Create Geolocation Fields Vgroup */
		/* -------------------------------- */
		vgid[1] = Vattach(HDFfid, -1, "w");
		Vsetname(vgid[1], "Geolocation Fields");
		Vsetclass(vgid[1], "SWATH Vgroup");
		Vinsert(vgid[0], vgid[1]);



		/* Create Data Fields Vgroup */
		/* ------------------------- */
		vgid[2] = Vattach(HDFfid, -1, "w");
		Vsetname(vgid[2], "Data Fields");
		Vsetclass(vgid[2], "SWATH Vgroup");
		Vinsert(vgid[0], vgid[2]);



		/* Create Attributes Vgroup */
		/* ------------------------ */
		vgid[3] = Vattach(HDFfid, -1, "w");
		Vsetname(vgid[3], "Swath Attributes");
		Vsetclass(vgid[3], "SWATH Vgroup");
		Vinsert(vgid[0], vgid[3]);



		/* Establish Swath in Structural MetaData Block */
		/* -------------------------------------------- */
		snprintf(utlbuf, sizeof(utlbuf), "%s%d%s%s%s",
			"\tGROUP=SWATH_", nSwath + 1,
			"\n\t\tSwathName=\"", swathname, "\"\n");

		strcat(utlbuf, "\t\tGROUP=Dimension\n");
		strcat(utlbuf, "\t\tEND_GROUP=Dimension\n");
		strcat(utlbuf, "\t\tGROUP=DimensionMap\n");
		strcat(utlbuf, "\t\tEND_GROUP=DimensionMap\n");
		strcat(utlbuf, "\t\tGROUP=IndexDimensionMap\n");
		strcat(utlbuf, "\t\tEND_GROUP=IndexDimensionMap\n");
		strcat(utlbuf, "\t\tGROUP=GeoField\n");
		strcat(utlbuf, "\t\tEND_GROUP=GeoField\n");
		strcat(utlbuf, "\t\tGROUP=DataField\n");
		strcat(utlbuf, "\t\tEND_GROUP=DataField\n");
		strcat(utlbuf, "\t\tGROUP=MergedFields\n");
		strcat(utlbuf, "\t\tEND_GROUP=MergedFields\n");
		snprintf(utlbuf2, sizeof(utlbuf2), "%s%d%s",
			"\tEND_GROUP=SWATH_", nSwath + 1, "\n");
		strcat(utlbuf, utlbuf2);


		status = EHinsertmeta(sdInterfaceID, "", "s", 1001L,
				      utlbuf, NULL);
	    }
	}
	else
	{
	    /* Too many files opened */
	    /* --------------------- */
	    status = -1;
	    strcpy(errbuf,
		   "No more than %d swaths may be open simutaneously");
	    strcat(errbuf, " (%s)");
	    HEpush(DFE_DENIED, "SWcreate", __FILE__, __LINE__);
	    HEreport(errbuf, NSWATH, swathname);
	}


	/* Assign swathID # & Load swath and SWXSwath table entries */
	/* -------------------------------------------------------- */
	if (status == 0)
	{

	    for (i = 0; i < NSWATH; i++)
	    {
		if (SWXSwath[i].active == 0)
		{
		    /*
		     * Set swathID, Set swath entry active, Store root Vgroup
		     * ID, Store sub Vgroup IDs, Store HDF-EOS file ID
		     */
		    swathID = i + idOffset;
		    SWXSwath[i].active = 1;
		    SWXSwath[i].IDTable = vgid[0];
		    SWXSwath[i].VIDTable[0] = vgid[1];
		    SWXSwath[i].VIDTable[1] = vgid[2];
		    SWXSwath[i].VIDTable[2] = vgid[3];
		    SWXSwath[i].fid = fid;
		    status = 0;
		    break;
		}
	    }

	}
    }
    return (swathID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWattach                                                         |
|                                                                             |
|  DESCRIPTION:  Attaches to an existing swath within the file.               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            int32               HDF-EOS file ID                         |
|  swathname      char                swath structure name                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Apr 99   David Wynne   Modified test for memory allocation check when no   |
|                         SDSs are in the Swath, NCR22513                     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWattach(int32 fid, const char *swathname)

{
    intn            i;		/* Loop index */
    intn            j;	        /* Loop index */
    intn            nswathopen = 0;	/* # of swath structures open */
    intn            status;	/* routine return status variable */

    uint8           acs;	/* Read/Write file access code */

    int32           HDFfid;	/* HDF file id */
    int32           vgRef;	/* Vgroup reference number */
    int32           vgid[4];	/* Vgroup ID array */
    int32           swathID = -1;	/* HDF-EOS swath ID */
    int32          *tags;	/* Pnt to Vgroup object tags array */
    int32          *refs;	/* Pnt to Vgroup object refs array */
    int32           dum;	/* dummy variable */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           nObjects;	/* # of objects in Vgroup */
    int32           nSDS;	/* SDS counter */
    int32           l_index;	/* SDS index */
    int32           sdid;	/* SDS object ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char            name[UTLSTR_MAX_SIZE];	/* Vgroup name */
    char            a_class[UTLSTR_MAX_SIZE];	/* Vgroup class */
    char            errbuf[256];/* Buffer for error message */
    char            acsCode[1];	/* Read/Write access char: "r/w" */


    /* Check HDF-EOS file ID, get back HDF file ID and access code */
    /* ----------------------------------------------------------- */
    status = EHchkfid(fid, swathname, &HDFfid, &dum, &acs);

    if (status == 0)
    {
	/* Convert numeric access code to character */
	/* ---------------------------------------- */
	acsCode[0] = (acs == 1) ? 'w' : 'r';

	/* Determine number of swaths currently opened */
	/* ------------------------------------------- */
	for (i = 0; i < NSWATH; i++)
	{
	    nswathopen += SWXSwath[i].active;
	}

	/* If room for more ... */
	/* -------------------- */
	if (nswathopen < NSWATH)
	{

	    /* Search Vgroups for Swath */
	    /* ------------------------ */
	    vgRef = -1;

	    while (1)
	    {
		vgRef = Vgetid(HDFfid, vgRef);


		/* If no more Vgroups then exist while loop */
		/* ---------------------------------------- */
		if (vgRef == -1)
		{
		    break;
		}

		/* Get name and class of Vgroup */
		/* ---------------------------- */
		vgid[0] = Vattach(HDFfid, vgRef, "r");
		Vgetname(vgid[0], name);
		Vgetclass(vgid[0], a_class);


		/*
		 * If Vgroup with swathname and class SWATH found, load
		 * tables
		 */

		if (strcmp(name, swathname) == 0 &&
		    strcmp(a_class, "SWATH") == 0)
		{
		    /* Attach to "Fields" and "Swath Attributes" Vgroups */
		    /* ------------------------------------------------- */
		    tags = (int32 *) malloc(sizeof(int32) * 3);
		    if(tags == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			return(-1);
		    }
		    refs = (int32 *) malloc(sizeof(int32) * 3);
		    if(refs == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			free(tags);
			return(-1);
		    }
		    Vgettagrefs(vgid[0], tags, refs, 3);
		    vgid[1] = Vattach(HDFfid, refs[0], acsCode);
		    vgid[2] = Vattach(HDFfid, refs[1], acsCode);
		    vgid[3] = Vattach(HDFfid, refs[2], acsCode);
		    free(tags);
		    free(refs);

		    /* Setup External Arrays */
		    /* --------------------- */
		    for (i = 0; i < NSWATH; i++)
		    {
			/* Find empty entry in array */
			/* ------------------------- */
			if (SWXSwath[i].active == 0)
			{
			    /*
			     * Set swathID, Set swath entry active, Store
			     * root Vgroup ID, Store sub Vgroup IDs, Store
			     * HDF-EOS file ID
			     */
			    swathID = i + idOffset;
			    SWXSwath[i].active = 1;
			    SWXSwath[i].IDTable = vgid[0];
			    SWXSwath[i].VIDTable[0] = vgid[1];
			    SWXSwath[i].VIDTable[1] = vgid[2];
			    SWXSwath[i].VIDTable[2] = vgid[3];
			    SWXSwath[i].fid = fid;
			    break;
			}
		    }

		    /* Get SDS interface ID */
		    /* -------------------- */
		    status = SWchkswid(swathID, "SWattach", &dum,
				       &sdInterfaceID, &dum);

		    /* Access swath "Geolocation" SDS */
		    /* ------------------------------ */

		    /* Get # of entries within this Vgroup & search for SDS */
		    /* ---------------------------------------------------- */
		    nObjects = Vntagrefs(vgid[1]);

		    if (nObjects > 0)
		    {
			/* Get tag and ref # for Geolocation Vgroup objects */
			/* ------------------------------------------------ */
			tags = (int32 *) malloc(sizeof(int32) * nObjects);
			if(tags == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			    return(-1);
			}
			refs = (int32 *) malloc(sizeof(int32) * nObjects);
			if(refs == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			    free(tags);
			    return(-1);
			}
			Vgettagrefs(vgid[1], tags, refs, nObjects);

			/* Count number of SDS & allocate SDS ID array */
			/* ------------------------------------------- */
			nSDS = 0;
			for (j = 0; j < nObjects; j++)
			{
			    if (tags[j] == DFTAG_NDG)
			    {
				nSDS++;
			    }
			}
			SWXSwath[i].sdsID = (int32 *) calloc(nSDS, 4);
			if(SWXSwath[i].sdsID == NULL && nSDS != 0)
			{
			    HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			    free(tags);
			    free(refs);
			    return(-1);
			}
			nSDS = 0;


			/* Fill SDS ID array */
			/* ----------------- */
			for (j = 0; j < nObjects; j++)
			{
			    /* If object is SDS then get id */
			    /* ---------------------------- */
			    if (tags[j] == DFTAG_NDG)
			    {
				l_index = SDreftoindex(sdInterfaceID, refs[j]);
				sdid = SDselect(sdInterfaceID, l_index);
				SWXSwath[i].sdsID[nSDS] = sdid;
				nSDS++;
				SWXSwath[i].nSDS++;
			    }
			}
			free(tags);
			free(refs);
		    }

		    /* Access swath "Data" SDS */
		    /* ----------------------- */

		    /* Get # of entries within this Vgroup & search for SDS */
		    /* ---------------------------------------------------- */
		    nObjects = Vntagrefs(vgid[2]);

		    if (nObjects > 0)
		    {
			/* Get tag and ref # for Data Vgroup objects */
			/* ----------------------------------------- */
			tags = (int32 *) malloc(sizeof(int32) * nObjects);
			if(tags == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			    return(-1);
			}
			refs = (int32 *) malloc(sizeof(int32) * nObjects);
			if(refs == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			    free(tags);
			    return(-1);
			}
			Vgettagrefs(vgid[2], tags, refs, nObjects);


			/* Count number of SDS & allocate SDS ID array */
			/* ------------------------------------------- */
			nSDS = 0;
			for (j = 0; j < nObjects; j++)
			{
			    if (tags[j] == DFTAG_NDG)
			    {
				nSDS++;
			    }
			}
			SWXSwath[i].sdsID = (int32 *)
			    realloc((void *) SWXSwath[i].sdsID,
				    (SWXSwath[i].nSDS + nSDS) * 4);
			if(SWXSwath[i].sdsID == NULL && nSDS != 0)
			{
			    HEpush(DFE_NOSPACE,"SWattach", __FILE__, __LINE__);
			    return(-1);
			}

			/* Fill SDS ID array */
			/* ----------------- */
			for (j = 0; j < nObjects; j++)
			{
			    /* If object is SDS then get id */
			    /* ---------------------------- */
			    if (tags[j] == DFTAG_NDG)
			    {
				l_index = SDreftoindex(sdInterfaceID, refs[j]);
				sdid = SDselect(sdInterfaceID, l_index);
				SWXSwath[i].sdsID[SWXSwath[i].nSDS] = sdid;
				SWXSwath[i].nSDS++;
			    }
			}
			free(tags);
			free(refs);
		    }
		    break;
		}

		/* Detach Vgroup if not desired Swath */
		/* ---------------------------------- */
		Vdetach(vgid[0]);
	    }

	    /* If Swath not found then set up error message */
	    /* -------------------------------------------- */
	    if (swathID == -1)
	    {
		HEpush(DFE_RANGE, "SWattach", __FILE__, __LINE__);
		HEreport("Swath: \"%s\" does not exist within HDF file.\n",
			 swathname);
	    }
	}
	else
	{
	    /* Too many files opened */
	    /* --------------------- */
	    swathID = -1;
	    strcpy(errbuf,
		   "No more than %d swaths may be open simutaneously");
	    strcat(errbuf, " (%s)");
	    HEpush(DFE_DENIED, "SWattach", __FILE__, __LINE__);
	    HEreport(errbuf, NSWATH, swathname);
	}

    }
    return (swathID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWchkswid                                                        |
|                                                                             |
|  DESCRIPTION: Checks for valid swathID and returns file ID, SDS ID, and     |
|               swath Vgroup ID                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  routname       char                Name of routine calling SWchkswid       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fid            int32               File ID                                 |
|  sdInterfaceID  int32               SDS interface ID                        |
|  swVgrpID       int32               swath Vgroup ID                         |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWchkswid(int32 swathID, const char *routname,
	  int32 * fid, int32 * sdInterfaceID, int32 * swVgrpID)

{
    intn            status = 0;	/* routine return status variable */
    uint8           l_access;	/* Read/Write access code */

    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char            message1[] =
    "Invalid swath id: %d in routine \"%s\".  ID must be >= %d and < %d.\n";
    char            message2[] =
    "Swath id %d in routine \"%s\" not active.\n";


    /* Check for valid swath id */
    /* ------------------------ */
    if (swathID < idOffset || swathID >= NSWATH + idOffset)
    {
	status = -1;
	HEpush(DFE_RANGE, "SWchkswid", __FILE__, __LINE__);
	HEreport(message1, swathID, routname, idOffset, NSWATH + idOffset);
    }
    else
    {
	/* Check for active swath ID */
	/* ------------------------- */
	if (SWXSwath[swathID % idOffset].active == 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWchkswid", __FILE__, __LINE__);
	    HEreport(message2, swathID, routname);
	}
	else
	{

	    /* Get file & SDS ids and Swath Vgroup */
	    /* ----------------------------------- */
	    status = EHchkfid(SWXSwath[swathID % idOffset].fid, " ", fid,
			      sdInterfaceID, &l_access);
	    *swVgrpID = SWXSwath[swathID % idOffset].IDTable;
	}
    }
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefdim                                                         |
|                                                                             |
|  DESCRIPTION: Defines numerical value of dimension                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  dimname        char                Dimension name to define                |
|  dim            int32               Dimension value                         |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Dec 96   Joel Gales    Check that dim value >= 0                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefdim(int32 swathID, const char *dimname, int32 dim)

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file id */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char            swathname[80] /* Swath name */ ;
    char           *tmpdimname=NULL;

    /* Check for valid swath id */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWdefdim", &fid, &sdInterfaceID, &swVgrpID);

    /* Make sure dimension >= 0 */
    /* ------------------------ */
    if (dim < 0)
    {
	status = -1;
	HEpush(DFE_GENAPP, "SWdefdim", __FILE__, __LINE__);
	HEreport("Dimension value for \"%s\" less than zero: %d.\n",
		 dimname, dim);
    }


    /* Write Dimension to Structural MetaData */
    /* -------------------------------------- */
    if (status == 0)
    {
	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);
	tmpdimname = (char *)malloc(((int)strlen(dimname)+1)*sizeof(char));
	strcpy(tmpdimname, dimname);
	status = EHinsertmeta(sdInterfaceID, swathname, "s", 0L,
			      tmpdimname, &dim);
	free(tmpdimname);
	tmpdimname = NULL;
    }
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdiminfo                                                        |
|                                                                             |
|  DESCRIPTION: Returns size in bytes of named dimension                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  size           int32               Size of dimension                       |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  dimname        char                Dimension name                          |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWdiminfo(int32 swathID, const char *dimname)

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           size;	/* Dimension size */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */


    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;	/* Utility string */

    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWdiminfo", __FILE__, __LINE__);
	return(-1);
    }
    /* Initialize return value */
    size = -1;

    /* Check Swath ID */
    status = SWchkswid(swathID, "SWdiminfo", &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Get swath name */
	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	/* Get pointers to "Dimension" section within SM */
	metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "Dimension", metaptrs);

	if(metabuf == NULL)
	{
	    free(utlstr);
	    return(-1);
	}

	/* Search for dimension name (surrounded by quotes) */
	snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", dimname, "\"\n");
	metaptrs[0] = strstr(metaptrs[0], utlstr);

	/*
	 * If dimension found within swath structure then get dimension value
	 */
	if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	{
	    /* Set endptr at end of dimension definition entry */
	    metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");

	    status = EHgetmetavalue(metaptrs, "Size", utlstr);

	    if (status == 0)
	    {
	      int32 strlen_utlstr;
	      /* If the value in utlstr has leading and trailing quotes, get rid
		 of them before applying atoi, otherwise atoi will return zero */

	      strlen_utlstr = (int32)strlen(utlstr);
	      if(utlstr[0] == '"' && utlstr[strlen_utlstr-1] == '"')
		{
		  memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
		  utlstr[(int32)strlen(utlstr) - 2] = 0;
		  size = (int32)atoi(utlstr);
		}
	      else
		{
		  size = (int32)atoi(utlstr);
		}
	    }
	    else
	    {
		HEpush(DFE_GENAPP, "SWdiminfo", __FILE__, __LINE__);
		HEreport("\"Size\" string not found in metadata.\n");
	    }
	}
	else
	{
	    HEpush(DFE_GENAPP, "SWdiminfo", __FILE__, __LINE__);
	    HEreport("Dimension \"%s\" not found.\n", dimname);
	}

	free(metabuf);
    }
    free(utlstr);

    return (size);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefdimscale                                                    |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale for all fields dimension of a swath |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  dimname        char                dim name                                |
|  dimsize        int32               Dimension size value                    |
|  numbertype     int32               dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES: This function finds out which field in a swath has the dimension    |
|         and sets dimension scale for that field calling SWsetdimscale()     |
|         User must detach swath after creating fields and attach again before|
|         calling the routine.                                                |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jan 14    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefdimscale(int32 swathID, const char *dimname, int32 dimsize,
	      int32 numbertype, VOIDP data)
{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           sdid;	/* SDS object ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           rank = 0;	/* Field rank */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    int32           gID;	/* SwathID - offset */
    int32           rankSDS=0;	        /* Rank of SDS */
    int32           dum;	        /* Dummy variable */
    char            fieldname[2048];	/* Field Names */
    char            dimlist[HDFE_DIMBUFSIZE];/* Dimension list       */
    int32           Dimindex;
    int32           nt;		        /* Number type */
    int32           foundField=0;

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWdefdimscale",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {

      /* Make certain that dimsize != 0 */
      /* ------------------------------ */
      if ( dimsize == 0 )
	{
	    HEpush(DFE_GENAPP, "SWdefdimscale", __FILE__, __LINE__);
	    HEreport("Invalid (zero) dimension size.\n");
	    status = -1;
	    goto error;
	}

      /* Loop over all fields in the swath and find out if
	 field's dimension list  has the dimension name.
	 If true then set the dimension scale for the dim
	 in that field
      */

      /* Inquire Data Fields first*/
      /* ------------------------ */

      /* Remove offset from swath ID */
      gID = swathID % idOffset;

      /* Loop through all SDSs in swath */
      /* ------------------------------ */
      if(SWXSwath[gID].nSDS > 0)
	{
	  for (i = 0; i < SWXSwath[gID].nSDS; i++)
	    {
	      /* If active SDS ... */
	      /* ----------------- */
	      if (SWXSwath[gID].sdsID[i] != 0)
		{
		  /* Get SDS ID, name, rankSDS, and dimensions */
		  /* ----------------------------------------- */
		  sdid = SWXSwath[gID].sdsID[i];
		  SDgetinfo(sdid, fieldname, &rankSDS, dims, &dum, &dum);

		  /* if field is MERGED field, continue */
		  if (strstr(fieldname, "MRGFLD_") == &fieldname[0]) continue;

		  status = SWfieldinfo(swathID, fieldname, &rank, dims, &nt, dimlist);
		  if (status != 0)
		    {
		      status = -1;
		      HEpush(DFE_GENAPP, "SWdefdimscale", __FILE__, __LINE__);
		      HEreport("Field: \"%s\" not found.\n", fieldname);
		      goto error;
		    }

		  Dimindex = -1;
		  Dimindex = EHstrwithin(dimname, dimlist, ',');
		  if (Dimindex == -1)
		    {
		      continue; /*dimlist does not contain dim name */
		    }
		  else
		    {
		      foundField = 1;
		      status = SWsetdimscale(swathID, fieldname, dimname, dimsize,
					     numbertype, data);
		      if ( status != 0 )
			{
			  status = -1;
			  HEpush(DFE_GENAPP, "SWdefdimscale", __FILE__, __LINE__);
			  HEreport("Cannot set dimension scale %s for the field %s. \n",
				   dimname, fieldname);
			  goto error;
			}
		    }
		}
	    }
	}

      if(i == SWXSwath[gID].nSDS && foundField == 0) /* did not find any fields
							with the dimname       */
	{
	  HEpush(DFE_GENAPP, "SWdefdimscale", __FILE__, __LINE__);
	  HEreport("Did not find any hdfeos field in the swath \n");
	  status = -1;
	  goto error;
	}
      else
	{
	  status = 0;
	}
    }

 error:

    return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWsetdimscale                                                    |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale for a fields dimension of a swath   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|  dimsize        int32               Dimension size value                    |
|  numbertype     int32               dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWsetdimscale(int32 swathID, const char *fieldname, const char *dimname,int32 dimsize,
	      int32 numbertype, VOIDP data)
{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           vgid;	/* Geo/Data field Vgroup ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           sdid;	/* SDS object ID */
    int32           dimid;	/* SDS dimension ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           rank = 0;	/* Field rank */
    int32           slen;	/* String length array */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    int32           gID;	/* SwathID - offset */
    char            utlbuf[UTLSTR_MAX_SIZE];/* Utility buffer */
    char           *ptr[32];	/* String pointer array */
    char            swathname[80];	/* Swath name */
    char            parmbuf[128];	/* Parameter string buffer */
    int32           rankSDS;	        /* Rank of SDS */
    int32           dum;	        /* Dummy variable */
    int32           size;

    void           *data_buff=NULL;
    int32           data_type=0;
    int32           count;
    char            name[2048];	/* Field Names */

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWsetdimscale",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Check that field exists */
	/* ----------------------- */
	status = SWfieldinfo(swathID, fieldname, &rankSDS, dims, &dum, NULL);

	if (status != 0)
	{
	    HEpush(DFE_GENAPP, "SWsetdimscale", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    goto error;
	}

	/* Remove offset from swath ID & get swathname */
	gID = swathID % idOffset;
	Vgetname(SWXSwath[gID].IDTable, swathname);

	data_buff = data;

	/* Loop through all SDSs in swath */
	/* ------------------------------ */
	for (i = 0; i < SWXSwath[gID].nSDS; i++)
	  {
	    /* If active SDS ... */
	    /* ----------------- */
	    if (SWXSwath[gID].sdsID[i] != 0)
	      {
		/* Get SDS ID, name, rankSDS, and dimensions */
		/* ----------------------------------------- */
		sdid = SWXSwath[gID].sdsID[i];
		SDgetinfo(sdid, name, &rankSDS, dims, &dum, &dum);
		if(strcmp(name, fieldname) == 0)
		  {
		    break;
		  }
		else
		  {
		    continue;
		  }
	      }
	  }

	if(i == SWXSwath[gID].nSDS) /* did not find fieldname */
	  {
	    HEpush(DFE_GENAPP, "SWsetdimscale", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    goto error;
	  }

	for (i = 0; i < rankSDS; i++)
	  {
	    /* Dimension name = Swathname:Dimname */
	    /* ---------------------------------- */
	    slen = (int32)strlen(dimname);
	    memcpy(utlbuf, dimname, slen);
	    utlbuf[slen] = 0;
	    strcat(utlbuf, ":");
	    strcat(utlbuf, swathname);

	    dimid = SDgetdimid(sdid, i);
	    SDdiminfo(dimid, name, &count, &data_type, &dum);
	    if(strcmp(name,utlbuf) == 0 )
	      {
		break;
	      }
	    else
	      {
		continue;
	      }
	  }
	if (i == rankSDS) /* did not find appropriate dimname */
	  {
   	    HEpush(DFE_GENAPP, "SWsetdimscale", __FILE__, __LINE__);
	    HEreport("Dimname \"%s\" does not exist for field \"%s\".\n",
		     dimname, fieldname);
	    status = -1;
	    goto error;
	  }

	/* Found the dimname; Use its dimid to set Dimension Scale*/

	/* See if dimscale already set */
	if(data_type == 0)
	  {
	    status = SDsetdimscale(dimid, dimsize, numbertype, data_buff);
	    if (status != 0)
	      {
		HEpush(DFE_GENAPP, "SWsetdimscale", __FILE__, __LINE__);
		HEreport("Failed to set dimscale for \"%s\" in the field \"%s\".\n",
			 dimname, fieldname);
		status = -1;
		goto error;
	      }
	  }
	else
	  {
	    HEpush(DFE_GENAPP, "SWsetdimscale", __FILE__, __LINE__);
	    HEreport("Dimscale for \"%s\" in the field \"%s\" has already been set.\n",
		     dimname, fieldname);
	    status = 0;
	  }
    }

 error:

    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefdimstrs                                                     |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale label, unit and format for          |
|               all fields in a swath                                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  dimname        char                dim name                                |
|  label          char                Lable string for dimension (Gris X Axix)|
|  unit           char                unit for dimension (such as meter)      |
|  format         char                format in which numeric values to be    |
|                                     printed (such as F7.2)                  |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jan 14    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefdimstrs(int32 swathID, const char *dimname, char *label, char *unit, char *format)
{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           sdid;	/* SDS object ID */
    int32           swVgrpID;	/* Grid root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           gID;	        /* SwathID - offset */
    int32           rank = 0;	        /* Field rank */
    int32           rankSDS=0;	        /* Rank of SDS */
    int32           dum;	        /* Dummy variable */
    char            fieldname[2048];	/* Field Names */
    int32           data_type=0;
    int32           foundField=0;
    char            dimlist[HDFE_DIMBUFSIZE];/* Dimension list       */
    int32           Dimindex;
    int32           nt;		       /* Number type */

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWdefdimstrs",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
      /* Loop over all fields in the swath and find out if
	 field's dimension list  has the dimension name.
	 If true then set the dimension scale for the dim
	 in that field
      */

      /* Inquire Data Fields first*/
      /* ------------------------ */

      /* Remove offset from swath ID */
      gID = swathID % idOffset;

      /* Loop through all SDSs in swath */
      /* ------------------------------ */
      if(SWXSwath[gID].nSDS > 0)
	{
	  for (i = 0; i < SWXSwath[gID].nSDS; i++)
	    {
	      /* If active SDS ... */
	      /* ----------------- */
	      if (SWXSwath[gID].sdsID[i] != 0)
		{
		  /* Get SDS ID, name, rankSDS, and dimensions */
		  /* ----------------------------------------- */
		  sdid = SWXSwath[gID].sdsID[i];
		  SDgetinfo(sdid, fieldname, &rankSDS, dims, &dum, &dum);

		  /* if field is MERGED field, continue */
		  if (strstr(fieldname, "MRGFLD_") == &fieldname[0]) continue;

		  status = SWfieldinfo(swathID, fieldname, &rank, dims, &nt, dimlist);
		  if (status != 0)
		    {
		      status = -1;
		      HEpush(DFE_GENAPP, "SWdefdimstrs", __FILE__, __LINE__);
		      HEreport("Field: \"%s\" not found.\n", fieldname);
		      goto error;
		    }

		  Dimindex = -1;
		  Dimindex = EHstrwithin(dimname, dimlist, ',');
		  if (Dimindex == -1)
		    {
		      continue; /* dimlist does not contain dim name */
		    }
		  else
		    {
		      foundField = 1;
		      SWsetdimstrs(swathID, fieldname, dimname, label, unit, format);
		      if ( status != 0 )
			{
			  status = -1;
			  HEpush(DFE_GENAPP, "SWdefdimstrs", __FILE__, __LINE__);
			  HEreport("Failed to set dimstrs for \"%s\" in the field \"%s\".\n",
				   dimname, fieldname);
			  goto error;
			}
		    }
		}
	    }
	}

      if(foundField == 0) /* did not find any fields */
	{
	  HEpush(DFE_GENAPP, "SWdefdimstrs", __FILE__, __LINE__);
	  HEreport("Did not find any hdfeos field in the swath with the dimension specified\n");
	  status = -1;
	  goto error;
	}
      else
	{
	  status = 0;
	}
    }

 error:

    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWsetdimstrs                                                     |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale label, unit and format              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|  label          char                Lable string for dimension (Gris X Axix)|
|  unit           char                unit for dimension (such as meter)      |
|  format         char                format in which numeric values to be    |
|                                     printed (such as F7.2)                  |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWsetdimstrs(int32 swathID, const char *fieldname,
	     const char *dimname, char *label, char *unit, char *format)
{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           sdid;	/* SDS object ID */
    int32           dimid;	/* SDS dimension ID */
    int32           swVgrpID;	/* Grid root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           rank = 0;	/* Field rank */
    int32           slen;	/* String length array */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           gID;	        /* SwathID - offset */

    char            utlbuf[UTLSTR_MAX_SIZE];        /* Utility buffer */
    char            swathname[80];	/* Swath name */
    char            parmbuf[128];	/* Parameter string buffer */
    int32           rankSDS;	        /* Rank of SDS */
    int32           dum;	        /* Dummy variable */

    int32           count;
    char            name[2048];	        /* Field Names */
    int32           data_type=0;

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWsetdimstrs",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Check that field exists */
	/* ----------------------- */
	status = SWfieldinfo(swathID, fieldname, &rankSDS, dims, &dum, NULL);

	if (status != 0)
	{
	    HEpush(DFE_GENAPP, "SWsetdimstrs", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    goto error;
	}

	/* Remove offset from swath ID & get swathname */
	gID = swathID % idOffset;
	Vgetname(SWXSwath[gID].IDTable, swathname);

	/* Loop through all SDSs in swath */
	/* ------------------------------ */
	for (i = 0; i < SWXSwath[gID].nSDS; i++)
	  {
	    /* If active SDS ... */
	    /* ----------------- */
	    if (SWXSwath[gID].sdsID[i] != 0)
	      {
		/* Get SDS ID, name, rankSDS, and dimensions */
		/* ----------------------------------------- */
		sdid = SWXSwath[gID].sdsID[i];
		SDgetinfo(sdid, name, &rankSDS, dims, &dum, &dum);
		if(strcmp(name, fieldname) == 0)
		  {
		    break;
		  }
		else
		  {
		    continue;
		  }
	      }
	  }

	if(i == SWXSwath[gID].nSDS) /* did not find fieldname */
	  {
	    HEpush(DFE_GENAPP, "SWsetdimstrs", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    goto error;
	  }

	for (i = 0; i < rankSDS; i++)
	  {
	    /* Dimension name = Swathname:Dimname */
	    /* ---------------------------------- */
	    slen = (int32)strlen(dimname);
	    memcpy(utlbuf, dimname, slen);
	    utlbuf[slen] = 0;
	    strcat(utlbuf, ":");
	    strcat(utlbuf, swathname);

	    dimid = SDgetdimid(sdid, i);
	    SDdiminfo(dimid, name, &count, &data_type, &dum);
	    if(strcmp(name,utlbuf) == 0 )
	      {
		break;
	      }
	    else
	      {
		continue;
	      }
	  }

	if (i == rankSDS) /* did not find appropriate dimname */
	  {
   	    HEpush(DFE_GENAPP, "SWsetdimstrs", __FILE__, __LINE__);
	    HEreport("Dimname \"%s\" does not exist for field \"%s\".\n",
		     dimname, fieldname);
	    status = -1;
	    goto error;
	  }

	/* Found the dimname; Use its dimid to set Dimension Scale*/

	/* See if dimscale already set */
	if(data_type != 0)
	  {
	    status = SDsetdimstrs(dimid, label, unit, format);
	    if (status != 0)
	      {
		HEpush(DFE_GENAPP, "SWsetdimstrs", __FILE__, __LINE__);
		HEreport("Failed to set dimstrs for \"%s\" in the field \"%s\".\n",
			 dimname, fieldname);
		status = -1;
		goto error;
	      }
	  }
	else
	  {
	    HEpush(DFE_GENAPP, "SWsetdimstrs", __FILE__, __LINE__);
	    HEreport("Dimscale for \"%s\" in the field \"%s\" has not been been set yet.\n",
		     dimname, fieldname);
	    status = -1;
	    goto error;
	  }
    }

 error:

    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWgetdimscale                                                    |
|                                                                             |
|  DESCRIPTION: Get dimension scale for a dimension of a field in a swath     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return databuffsize  SUCCEED, (-1) FAIL |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimsize        int32               Dimension size value                    |
|  data_type      int32               dtata type of dimension scale           |
|  data           void                data buffer for read                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWgetdimscale(int32 swathID, const char *fieldname, const char *dimname, int32 *dimsize,
	      int32 *data_type, VOIDP data)
{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           vgid;	/* Geo/Data field Vgroup ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           count;
    int32           sdid;	/* SDS object ID */
    int32           dimid;	/* SDS dimension ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           slen;	/* String length array */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    int32           gID;	/* SwathID - offset */
    char            utlbuf[UTLSTR_MAX_SIZE];/* Utility buffer */
    char           *ptr[32];	/* String pointer array */
    char            swathname[80];	/* Swath name */
    char            parmbuf[128];	/* Parameter string buffer */
    int32           rankSDS;	        /* Rank of SDS */
    int32           dum;	        /* Dummy variable */
    int32           size;
    char            name[2048];	/* Field Names */

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWgetdimscale",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Check that field exists */
	/* ----------------------- */
	status = SWfieldinfo(swathID, fieldname, &rankSDS, dims, &dum, NULL);

	if (status != 0)
	{
	    HEpush(DFE_GENAPP, "SWgetdimscale", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    return ( status );
	}

	/* Remove offset from swath ID & get swathname */
	gID = swathID % idOffset;
	Vgetname(SWXSwath[gID].IDTable, swathname);

	/* Loop through all SDSs in swath */
	/* ------------------------------ */
	for (i = 0; i < SWXSwath[gID].nSDS; i++)
	  {
	    /* If active SDS ... */
	    /* ----------------- */
	    if (SWXSwath[gID].sdsID[i] != 0)
	      {
		/* Get SDS ID, name, rankSDS, and dimensions */
		/* ----------------------------------------- */
		sdid = SWXSwath[gID].sdsID[i];
		SDgetinfo(sdid, name, &rankSDS, dims, &dum, &dum);
		if(strcmp(name, fieldname) == 0)
		  {
		    break;
		  }
		else
		  {
		    continue;
		  }
	      }
	  }

	if(i == SWXSwath[gID].nSDS) /* did not find fieldname */
	  {
	    HEpush(DFE_GENAPP, "SWgetdimscale", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    return ( status );
	  }

	for (i = 0; i < rankSDS; i++)
	  {
	    /* Dimension name = Swathname:Dimname */
	    /* ---------------------------------- */
	    slen = (int32)strlen(dimname);
	    memcpy(utlbuf, dimname, slen);
	    utlbuf[slen] = 0;
	    strcat(utlbuf, ":");
	    strcat(utlbuf, swathname);

	    dimid = SDgetdimid(sdid, i);
	    SDdiminfo(dimid, name, &count, data_type, &dum);
	    if(strcmp(name,utlbuf) == 0 )
	      {
		break;
	      }
	    else
	      {
		continue;
	      }
	  }
	if (i == rankSDS) /* did not find appropriate dimname */
	  {
   	    HEpush(DFE_GENAPP, "SWgetdimscale", __FILE__, __LINE__);
	    HEreport("Dimname \"%s\" does not exist for field \"%s\".\n",
		     dimname, fieldname);
	    status = -1;
	    return ( status );
	  }

	/* Found the dimname; Use its dimid to get Dimension Scale*/
	/* if data == NULLjust return size of dimension and type for
	   appropriate data buffer setting */
	if( data == NULL)
	  {
	    if(*data_type != 0)	/* See if dimscale is set */
	      {
		*dimsize = count;
		return ( count * DFKNTsize(*data_type));
	      }
	    else
	      {
		HEpush(DFE_GENAPP, "SWgetdimscale", __FILE__, __LINE__);
		HEreport("Dimscale for \"%s\" in the field \"%s\" has not been set.\n",
			 dimname, fieldname);
		status = -1;
		return ( status );
	      }
	  }
	else
	  {
	    /* See if dimscale is set */
	    if(*data_type != 0)
	      {
		status = SDgetdimscale(dimid, data);
		if (status != 0)
		  {
		    HEpush(DFE_GENAPP, "SWgetdimscale", __FILE__, __LINE__);
		    HEreport("Failed to get dimscale for \"%s\" in the field \"%s\".\n",
			     dimname, fieldname);
		    status = -1;
		    return ( status );
		  }
	      }
	    else
	      {
		HEpush(DFE_GENAPP, "SWgetdimscale", __FILE__, __LINE__);
		HEreport("Dimscale for \"%s\" in the field \"%s\" has not been set.\n",
			 dimname, fieldname);
		status = -1;
		return ( status );
	      }
	  }

	*dimsize = count;
	return (count * DFKNTsize(*data_type));
    }
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWgetdimstrs                                                     |
|                                                                             |
|  DESCRIPTION: Get dimension strs for a dimension of a field in a swath      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return 0  SUCCEED, (-1) FAIL            |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|  len            intn                Maximum string length it is safe to     |
|                                     return                                  |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  label          char                Lable string for dimension (Gris X Axix)|
|  unit           char                unit for dimension (such as meter)      |
|  format         char                format in which numeric values to be    |
|                                     printed (such as F7.2)                  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWgetdimstrs(int32 swathID, const char *fieldname,
	     const char *dimname, char *label, char *unit, char *format, intn len)
{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           count;
    int32           sdid;	/* SDS object ID */
    int32           dimid;	/* SDS dimension ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           slen;	/* String length array */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    int32           gID;	        /* SwathID - offset */
    char            utlbuf[UTLSTR_MAX_SIZE];        /* Utility buffer */
    char            swathname[80];	/* Swath name */
    char            parmbuf[128];	/* Parameter string buffer */
    int32           rankSDS;	        /* Rank of SDS */
    int32           dum;	        /* Dummy variable */
    int32           size;
    char            name[2048];	        /* Field Names */
    int32           data_type=0;

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWgetdimstrs",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Check that field exists */
	/* ----------------------- */
	status = SWfieldinfo(swathID, fieldname, &rankSDS, dims, &dum, NULL);

	if (status != 0)
	{
	    HEpush(DFE_GENAPP, "SWgetdimstrs", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    return ( status );
	}

	/* Remove offset from swath ID & get swathname */
	gID = swathID % idOffset;
	Vgetname(SWXSwath[gID].IDTable, swathname);

	/* Loop through all SDSs in swath */
	/* ------------------------------ */
	for (i = 0; i < SWXSwath[gID].nSDS; i++)
	  {
	    /* If active SDS ... */
	    /* ----------------- */
	    if (SWXSwath[gID].sdsID[i] != 0)
	      {
		/* Get SDS ID, name, rankSDS, and dimensions */
		/* ----------------------------------------- */
		sdid = SWXSwath[gID].sdsID[i];
		SDgetinfo(sdid, name, &rankSDS, dims, &dum, &dum);
		if(strcmp(name, fieldname) == 0)
		  {
		    break;
		  }
		else
		  {
		    continue;
		  }
	      }
	  }

	if(i == SWXSwath[gID].nSDS) /* did not find fieldname */
	  {
	    HEpush(DFE_GENAPP, "SWgetdimsctrs", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	    return ( status );
	  }

	for (i = 0; i < rankSDS; i++)
	  {
	    /* Dimension name = Swathname:Dimname */
	    /* ---------------------------------- */
	    slen = (int32)strlen(dimname);
	    memcpy(utlbuf, dimname, slen);
	    utlbuf[slen] = 0;
	    strcat(utlbuf, ":");
	    strcat(utlbuf, swathname);

	    dimid = SDgetdimid(sdid, i);
	    SDdiminfo(dimid, name, &count, &data_type, &dum);
	    if(strcmp(name,utlbuf) == 0 )
	      {
		break;
	      }
	    else
	      {
		continue;
	      }
	  }
	if (i == rankSDS) /* did not find appropriate dimname */
	  {
   	    HEpush(DFE_GENAPP, "SWgetdimstrs", __FILE__, __LINE__);
	    HEreport("Dimname \"%s\" does not exist for field \"%s\".\n",
		     dimname, fieldname);
	    status = -1;
	    return ( status );
	  }

	/* See if dimscale is set */
	if(data_type != 0)
	  {
	    status = SDgetdimstrs(dimid, label, unit, format, len);
	    if (status != 0)
	      {
		HEpush(DFE_GENAPP, "SWgetdimstrs", __FILE__, __LINE__);
		HEreport("Failed to get dimscale strs for \"%s\" in the field \"%s\".\n",
			 dimname, fieldname);
		status = -1;
		return ( status );
	      }
	  }
	else
	  {
	    HEpush(DFE_GENAPP, "SWgetdimstrs", __FILE__, __LINE__);
	    HEreport("Dimscale for \"%s\" in the field \"%s\" has not been set.\n",
		     dimname, fieldname);
	    status = -1;
	    return ( status );
	  }
    }

    return ( status );
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWmapinfo                                                        |
|                                                                             |
|  DESCRIPTION: Returns dimension mapping information                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  geodim         char                geolocation dimension name              |
|  datadim        char                data dimension name                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  offset         int32               mapping offset                          |
|  increment      int32               mapping increment                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWmapinfo(int32 swathID, const char *geodim, const char *datadim, int32 * offset,
	  int32 * increment)

{
    intn            status;	/* routine return status variable */
    intn            statmeta = 0;	/* EHgetmetavalue return status */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;	/* Utility string */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWmapinfo", __FILE__, __LINE__);
	return(-1);
    }
    /* Initialize return values */
    *offset = -1;
    *increment = -1;

    /* Check Swath ID */
    status = SWchkswid(swathID, "SWmapinfo", &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Get swath name */
	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	/* Get pointers to "DimensionMap" section within SM */
	metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "DimensionMap", metaptrs);
	if(metabuf == NULL)
	{
	    free(utlstr);
	    return(-1);
	}

	/* Search for mapping - GeoDim/DataDim (surrounded by quotes) */
	snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s%s%s", "\t\t\t\tGeoDimension=\"", geodim,
		"\"\n\t\t\t\tDataDimension=\"", datadim, "\"\n");
	metaptrs[0] = strstr(metaptrs[0], utlstr);

	/*
	 * If mapping found within swath structure then get offset and
	 * increment value
	 */
	if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	{
	    /* Get Offset */
	    statmeta = EHgetmetavalue(metaptrs, "Offset", utlstr);
	    if (statmeta == 0)
	    {
		*offset = atoi(utlstr);
	    }
	    else
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWmapinfo", __FILE__, __LINE__);
		HEreport("\"Offset\" string not found in metadata.\n");
	    }


	    /* Get Increment */
	    statmeta = EHgetmetavalue(metaptrs, "Increment", utlstr);
	    if (statmeta == 0)
	    {
		*increment = atoi(utlstr);
	    }
	    else
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWmapinfo", __FILE__, __LINE__);
		HEreport("\"Increment\" string not found in metadata.\n");
	    }
	}
	else
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWmapinfo", __FILE__, __LINE__);
	    HEreport("Mapping \"%s/%s\" not found.\n", geodim, datadim);
	}

	free(metabuf);
    }
    free(utlstr);
    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWidxmapinfo                                                     |
|                                                                             |
|  DESCRIPTION: Returns indexed mapping information                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  gsize          int32               Number of index values (sz of geo dim)  |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  geodim         char                geolocation dimension name              |
|  datadim        char                data dimension name                     |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  l_index          int32             array of index values                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWidxmapinfo(int32 swathID, const char *geodim, const char *datadim, int32 l_index[])
{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           vgid;	/* Swath Attributes Vgroup ID */
    int32           vdataID;	/* Index Mapping Vdata ID */
    int32           gsize = -1;	/* Size of geo dim */

    char            utlbuf[256];/* Utility buffer */


    /* Check Swath ID */
    status = SWchkswid(swathID, "SWidxmapinfo",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Find Index Mapping Vdata with Swath Attributes Vgroup */
	snprintf(utlbuf, sizeof(utlbuf), "%s%s%s%s", "INDXMAP:", geodim, "/", datadim);
	vgid = SWXSwath[swathID % idOffset].VIDTable[2];
	vdataID = EHgetid(fid, vgid, utlbuf, 1, "r");

	/* If found then get geodim size & read index mapping values */
	if (vdataID != -1)
	{
	    gsize = SWdiminfo(swathID, geodim);

	    VSsetfields(vdataID, "Index");
	    VSread(vdataID, (uint8 *) l_index, 1, FULL_INTERLACE);
	    VSdetach(vdataID);
	}
	else
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWidxmapinfo", __FILE__, __LINE__);
	    HEreport("Index Mapping \"%s\" not found.\n", utlbuf);
	}
    }
    return (gsize);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWcompinfo                                                       |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                                                        |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32                                                       |
|  compcode       int32                                                       |
|  compparm       intn                                                        |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 96   Joel Gales    Original Programmer                                 |
|  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
|  Jul 08   Abe Taaheri   Added code to detect compression from SDS if it     |
|                         to find it from structure metadata.                 |
|  Apr 10   AbeTaaheri    Replaced problmatic SDgetcompress with SDgetcompinfo|
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWcompinfo(int32 swathID, const char *fieldname, int32 * compcode, intn compparm[])
{
    intn            i;		/* Loop Index */
    intn            status;	/* routine return status variable */
    intn            statmeta = 0;	/* EHgetmetavalue return status */
    intn            statusSD;	/* SDgetcompinfo return status */
    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;     /* Utility string */
    int32           sID;	/* Swath ID - offset */
    comp_info       c_info;	/* Compression parameter structure */
    int32           sdid;	/* SDS object ID */
    int32           rankSDS;
    int32           dum;	/* Dummy variable */
    int32           dims[8];
    char            name[2048];	/* Field Names */
    int32           got_compparm;
    /* Compression Codes */
    const char     *HDFcomp[6] = {"HDFE_COMP_NONE", "HDFE_COMP_RLE",
				  "HDFE_COMP_NBIT", "HDFE_COMP_SKPHUFF",
				  "HDFE_COMP_DEFLATE","HDFE_COMP_SZIP"};

    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWcompinfo", __FILE__, __LINE__);
	return(-1);
    }

    /* Check Swath ID */
    status = SWchkswid(swathID, "SWcompinfo",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Get swath name */
	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	/* Get pointers to "DataField" section within SM */
	metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "DataField", metaptrs);
	if(metabuf == NULL)
	{
	    free(utlstr);
	    return(-1);
	}
	/* Search for field */
	snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"\n");
	metaptrs[0] = strstr(metaptrs[0], utlstr);

	/* If not found then search in "GeoField" section */
	if (metaptrs[0] > metaptrs[1] || metaptrs[0] == NULL)
	{
	    free(metabuf);

	    /* Get pointers to "GeoField" section within SM */
	    metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					   "GeoField", metaptrs);
	    if(metabuf == NULL)
	    {
		free(utlstr);
		return(-1);
	    }
	    /* Search for field */
	    snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"\n");
	    metaptrs[0] = strstr(metaptrs[0], utlstr);
	}


	/* If field found and user wants compression code ... */
	if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	{
	    if (compcode != NULL)
	    {
	      /* Set endptr at end of field's definition entry */
	      metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");

	      /* Get compression type */
	      statmeta = EHgetmetavalue(metaptrs, "CompressionType", utlstr);

	      /*
	       * Default is no compression if "CompressionType" string not
	       * in metadata
	       */
	      *compcode = HDFE_COMP_NONE;

	      /* If compression code is found ... */
	      if (statmeta == 0)
		{
		  /* Loop through compression types until match */
		  for (i = 0; i < 6; i++)
		    {
		      if (strcmp(utlstr, HDFcomp[i]) == 0)
			{
			  *compcode = i;
			  break;
			}
		    }
		}

	      /* Compression is not listed in the structure metadata.
		 Lets see if the field is compressed by other means such
		 as herepack where the compression is done but does not
		 show up in the structure metadata.
	      */
	      got_compparm = 0;
	      if(*compcode == HDFE_COMP_NONE)
		{
		  /* Compute "reduced" swath ID */
		  /* -------------------------- */
		  sID = swathID % idOffset;
		  /* Loop through all SDSs in swath */
		  /* ------------------------------ */
		  for (i = 0; i < SWXSwath[sID].nSDS; i++)
		    {
		      /* If active SDS ... */
		      /* ----------------- */
		      if (SWXSwath[sID].sdsID[i] != 0)
			{
			  /* Get SDS ID, name, rankSDS, and dimensions */
			  /* ----------------------------------------- */
			  sdid = SWXSwath[sID].sdsID[i];
			  SDgetinfo(sdid, name, &rankSDS, dims, &dum, &dum);
			  if(strcmp(name, fieldname) == 0)
			    {
			      statusSD = SDgetcompinfo(sdid, (comp_coder_t *) (compcode), &c_info);
			      /* Note: Per HDF4 users guide this will
				 return success and compcode as
				 HDFE_COMP_NONE if SDS is not compressed
				 or no data has been written to SDS */

			      if(statusSD == 0 ) /* Sucess. compcode is
						    HDFE_COMP_NONE,
						    HDFE_COMP_NBIT,
						    HDFE_COMP_DEFLATE,
						    HDFE_COMP_SKIPHUFF,
						    HDFE_COMP_RLE,
						    or HDFE_COMP_SZIP */
				{
				  status = 0;
				  switch (*compcode)
				    {
				      /* Set NBIT compression parameters
					 in compression external array */
				    case HDFE_COMP_NBIT:

				      compparm[0] = c_info.nbit.sign_ext;
				      compparm[1] = c_info.nbit.fill_one;
				      compparm[2] = c_info.nbit.start_bit;
				      compparm[3] = c_info.nbit.bit_len;
				      got_compparm = 1;
				      break;

				      /* Set GZIP compression parameter
					 in compression external array */
				    case HDFE_COMP_DEFLATE:

				      compparm[0] = c_info.deflate.level;
				      got_compparm = 1;
				      break;

				      /* Set SZIP compression parameter
					 in compression external array */
				    case HDFE_COMP_SZIP:
#if defined(HAVE_HDF4_SZIP_DECODER)
				      compparm[0] = c_info.szip.pixels_per_block;
				      if(c_info.szip.options_mask ==
					 (SZ_EC_OPTION_MASK | SZ_RAW_OPTION_MASK))
					{
					  compparm[1] = SZ_EC;
					  got_compparm = 1;
					}
				      else if(c_info.szip.options_mask ==
					      (SZ_NN_OPTION_MASK | SZ_RAW_OPTION_MASK))
					{
					  compparm[1] = SZ_NN;
					  got_compparm = 1;
					}
				      else if(c_info.szip.options_mask ==
					      (SZ_RAW_OPTION_MASK))
					{
					  status = -1;
					  HEpush(DFE_GENAPP, "SWcompinfo", __FILE__, __LINE__);
					  HEreport("Could not get valid types SZ_NN and SZ_EC for szip compression.\n");
					  got_compparm = 1;
					}
#endif
				      break;
				    case HDFE_COMP_NONE:
				      got_compparm = 1;
				      break;
				    }
				}
			      else /* SDgetcompinfo failed getting a valid compcode */
				{
				  HEpush(DFE_GENAPP, "SWcompinfo", __FILE__, __LINE__);
				  HEreport(
				  "\"SDgetcompinfo\" failed getting compression info.\n");
				  status = -1;
				  got_compparm = 1;
				}
			      break;
			    }
			  else
			    {
			      continue;
			    }
			}
		    }
		}
	    }

	    /* if compression parameters are obtained from field itself when
	       calling SDgetcompinfo, we will skip next if statement */
	    /* If user wants compression parameters ... */
	    if (compparm != NULL && compcode != NULL && got_compparm != 1)
	    {
		/* Initialize to zero */
		for (i = 0; i < 4; i++)
		{
		    compparm[i] = 0;
		}

		/*
		 * Get compression parameters if NBIT, DEFLATE
		 * or SZIP compression
		 */
		if (*compcode == HDFE_COMP_NBIT)
		{
		    statmeta =
			EHgetmetavalue(metaptrs, "CompressionParams", utlstr);
		    if (statmeta == 0)
		    {
			sscanf(utlstr, "(%d,%d,%d,%d)",
			       &compparm[0], &compparm[1],
			       &compparm[2], &compparm[3]);
		    }
		    else
		    {
			status = -1;
			HEpush(DFE_GENAPP, "SWcompinfo", __FILE__, __LINE__);
			HEreport(
				 "\"CompressionParams\" string not found in metadata.\n");
		    }
		}
		else if (*compcode == HDFE_COMP_DEFLATE)
		{
		    statmeta =
			EHgetmetavalue(metaptrs, "DeflateLevel", utlstr);
		    if (statmeta == 0)
		    {
			sscanf(utlstr, "%d", &compparm[0]);
		    }
		    else
		    {
			status = -1;
			HEpush(DFE_GENAPP, "SWcompinfo", __FILE__, __LINE__);
			HEreport(
			"\"DeflateLevel\" string not found in metadata.\n");
		    }
		}
		else if (*compcode == HDFE_COMP_SZIP)
		{
		    statmeta =
			EHgetmetavalue(metaptrs, "CompressionParams", utlstr);
		    if (statmeta == 0)
		    {
			sscanf(utlstr, "(%d,%d)",
			       &compparm[0], &compparm[1]);
		    }
		    else
		    {
			status = -1;
			HEpush(DFE_GENAPP, "SWcompinfo", __FILE__, __LINE__);
			HEreport(
				 "\"CompressionParams\" string not found in metadata.\n");
		    }
		}
	    }
	}
	else
	{
	    HEpush(DFE_GENAPP, "SWcompinfo", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" not found.\n", fieldname);
	}

	free(metabuf);
    }
    free(utlstr);

    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWfinfo                                                          |
|                                                                             |
|  DESCRIPTION: Returns field info                                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  fieldtype      char                fieldtype (geo or data)                 |
|  fieldname      char                name of field                           |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int32               rank of field (# of dims)               |
|  dims           int32               field dimensions                        |
|  numbertype     int32               field number type                       |
|  dimlist        char                field dimension list                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Jan 97   Joel Gales    Check for metadata error status from EHgetmetavalue |
|  May 09   Abe Taaheri   Added code to see if actual dim size is bigger than |
|                         the one in structure metadata                       |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWfinfo(int32 swathID, const char *fieldtype, const char *fieldname, int32 *rank,
	int32 dims[], int32 *numbertype, char *dimlist)

{
    intn            i;		/* Loop index */
    intn            j;		/* Loop index */
    intn            status, status2;	/* routine return status variable */
    intn            statmeta = 0;	/* EHgetmetavalue return status */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           fsize;	/* field size in bytes */
    int32           ndims;	/* Number of dimensions */
    int32           slen[8];	/* Length of each entry in parsed string */
    int32           dum;	/* Dummy variable */
    int32           vdataID;	/* 1d field vdata ID */

    uint8          *buf;	/* One-Dim field buffer */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;	/* Utility string */
    char           *ptr[8];	/* String pointers for parsed string */
    char            dimstr[64];	/* Individual dimension entry string */
    int             rgid;


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWfinfo", __FILE__, __LINE__);
	return(-1);
    }

    /* Initialize rank and numbertype to -1 (error) */
    /* -------------------------------------------- */
    *rank = -1;
    *numbertype = -1;
    status = 0;

    /* Get HDF-EOS file ID and SDS interface ID */
    status = SWchkswid(swathID, "SWfinfo", &fid, &sdInterfaceID, &dum);
    if(status != 0)
      {
	free(utlstr);
	return(status);
      }

    /* Get swath name */
    Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

    /* Get pointers to appropriate "Field" section within SM */
    if (strcmp(fieldtype, "Geolocation Fields") == 0)
    {
	metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "GeoField", metaptrs);

	if(metabuf == NULL)
	{
	    free(utlstr);
	    return(-1);
	}
    }
    else
    {
	metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "DataField", metaptrs);
	if(metabuf == NULL)
	{
	    free(utlstr);
	    return(-1);
	}
    }


    /* Search for field */
    snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"\n");
    metaptrs[0] = strstr(metaptrs[0], utlstr);

    /* If field found ... */
    if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    {
	/* Get DataType string */
	statmeta = EHgetmetavalue(metaptrs, "DataType", utlstr);

	/* Convert to numbertype code */
	if (statmeta == 0)
	{
	    if (strcmp(utlstr, "DFNT_UCHAR8") == 0 ||
		strcmp(utlstr, "DFNT_UCHAR") == 0)
		*numbertype = 3;
	    else if (strcmp(utlstr, "DFNT_CHAR8") == 0 ||
		     strcmp(utlstr, "DFNT_CHAR") == 0)
		*numbertype = 4;
	    else if (strcmp(utlstr, "DFNT_FLOAT32") == 0 ||
		     strcmp(utlstr, "DFNT_FLOAT") == 0)
		*numbertype = 5;
	    else if (strcmp(utlstr, "DFNT_FLOAT64") == 0)
		*numbertype = 6;
	    else if (strcmp(utlstr, "DFNT_INT8") == 0)
		*numbertype = 20;
	    else if (strcmp(utlstr, "DFNT_UINT8") == 0)
		*numbertype = 21;
	    else if (strcmp(utlstr, "DFNT_INT16") == 0)
		*numbertype = 22;
	    else if (strcmp(utlstr, "DFNT_UINT16") == 0)
		*numbertype = 23;
	    else if (strcmp(utlstr, "DFNT_INT32") == 0)
		*numbertype = 24;
	    else if (strcmp(utlstr, "DFNT_UINT32") == 0)
		*numbertype = 25;
	}
	else
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWfieldinfo", __FILE__, __LINE__);
	    HEreport(
		     "\"DataType\" string not found in metadata.\n");
	}


	/*
	 * Get DimList string and trim off leading and trailing parens "()"
	 */
	statmeta = EHgetmetavalue(metaptrs, "DimList", utlstr);

	if (statmeta == 0)
	{
	    memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
	    utlstr[(int32)strlen(utlstr) - 2] = 0;

	    /* Parse trimmed DimList string and get rank */
	    ndims = EHparsestr(utlstr, ',', ptr, slen);
	    *rank = ndims;
	}
	else
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWfieldinfo", __FILE__, __LINE__);
	    HEreport(
		     "\"DimList\" string not found in metadata.\n");
	}

	/* If dimension list is desired by user then initialize length to 0 */
	if (dimlist != NULL)
	{
	    dimlist[0] = 0;
	}

	/*
	 * Copy each entry in DimList and remove leading and trailing quotes,
	 * Get dimension sizes and concatenate dimension names to dimension
	 * list
	 */
	for (i = 0; i < ndims; i++)
	{
	    memcpy(dimstr, ptr[i] + 1, slen[i] - 2);
	    dimstr[slen[i] - 2] = 0;
	    dims[i] = SWdiminfo(swathID, dimstr);
	    if (dimlist != NULL)
	    {
		if (i > 0)
		{
		    strcat(dimlist, ",");
		}
		strcat(dimlist, dimstr);
	    }

	}


	/* Appendable Field Section */
	/* ------------------------ */
	if (dims[0] == 0)
	{
	    /* One-Dimensional Field */
	    if (*rank == 1)
	    {
		/* Get vdata ID */
		status = SW1dfldsrch(fid, swathID, fieldname, "r",
				     &dum, &vdataID, &dum);

		/* Get actual size of field */
		dims[0] = VSelts(vdataID);

		/*
		 * If size=1 then check where actual record of
		 * "initialization" record
		 */
		if (dims[0] == 1)
		{
		  char *tmpfieldname= NULL;
		  tmpfieldname = (char *)malloc(((int)strlen(fieldname) + 1)*sizeof(char));
		  /* Get record size and read 1st record */
		  strcpy(tmpfieldname, fieldname);
		  fsize = VSsizeof(vdataID, tmpfieldname);
		  buf = (uint8 *) calloc(fsize, 1);
		  if(buf == NULL)
		    {
		      HEpush(DFE_NOSPACE,"SWfinfo", __FILE__, __LINE__);
		      free(utlstr);
		      return(-1);
		    }
		  VSsetfields(vdataID, tmpfieldname);
		  VSseek(vdataID, 0);
		  VSread(vdataID, (uint8 *) buf, 1, FULL_INTERLACE);
		  free(tmpfieldname);
		  tmpfieldname = NULL;

		  /* Sum up "bytes" in record */
		  for (i = 0, j = 0; i < fsize; i++)
		    {
		      j += buf[i];
		    }

		  /*
		   * If filled with 255 then "initialization" record,
		   * actual number of records = 0
		   */
		  if (j == 255 * fsize)
		    {
		      dims[0] = 0;
		    }

		  free(buf);
		}
		/* Detach from 1d field */
		VSdetach(vdataID);
	    }
	    else
	    {
		/* Get actual size of Multi-Dimensional Field */
		status = SWSDfldsrch(swathID, sdInterfaceID, fieldname,
				     &dum, &dum, &dum, &dum, dims,
				     &dum);
	    }
	}
	/* Non-appendable Field Section */
	/* ---------------------------- */
	/* some data producesrs may use pure hdf to change
	   the field dims, which will not change dim values found
	   in structure metadata. Since dims[] found above came
	   from structure metadata, lets see if actual dims are
	   larger to replace the output values, to avoid allocating
	   little memory for the field data later using the values
	   obtained from this function.

	   we may choose
		if (dims[0] < actualsize)
		  {
		    dims[0] = actualsize;
		  }

		  or

		if (dims[0] != actualsize)
		{
		    HEpush(DFE_GENAPP,"SWfinfo", __FILE__, __LINE__);
		    free(utlstr);
		    return(-1);
		}

	*/
	else
	{
	  /* Tried to add this section to get correct dim sizes
	     from the field itself.Though it seems to work by itself,
	     but when called in other functions some othetr functions,
	     such as SWwrrdfield() in SWwrfld() for a 1D field causes problem.
	     NCR 8048515 was fixed (grid problem) in GDapi.c .
	     The better treatment of fieldinfo for swath will be fixed later
	     if needed under a separate NCR

	  int swathID_IsSubset = 0;
	  for(rgid=0; rgid < NSWATHREGN; rgid++)
	    {
	      if(SWXRegion[rgid] == 0)
		{
		  continue;
		}
	      else
		{
		  if(SWXRegion[rgid]->swathID == swathID)
		    {
		      swathID_IsSubset = 1;
		      break;
		    }
		}
	    }
	  if (swathID_IsSubset == 0)
	    {
	      if (*rank == 1)
		{

		  int32 actualsize;

		  status2 = SW1dfldsrch(fid, swathID, fieldname, "r",
				       &dum, &vdataID, &dum);

		  actualsize = VSelts(vdataID);
		  if (dims[0] < actualsize)
		    {
		      dims[0] = actualsize;
		    }
		}
	      else
		{
		  int32 actualdims[H4_MAX_VAR_DIMS];

		  status2 = SWSDfldsrch(swathID, sdInterfaceID, fieldname,
				       &dum, &dum, &dum, &dum, actualdims,
				       &dum);
		  if (status2 == 0)
		    {
		      for (i = 0; i < ndims; i++)
			{
			  if (dims[i] < actualdims[i])
			    {
			      dims[i] = actualdims[i];
			    }
			}
		    }
		}
	    }
	  */
	}

    }
    free(metabuf);

    if (*rank == -1)
    {
	status = -1;
    }
    free(utlstr);

    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWfieldinfo                                                      |
|                                                                             |
|  DESCRIPTION: Wrapper around SWfinfo                                        |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  fieldname      char                name of field                           |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int32               rank of field (# of dims)               |
|  dims           int32               field dimensions                        |
|  numbertype     int32               field number type                       |
|  dimlist        char                field dimension list                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWfieldinfo(int32 swathID, const char *fieldname, int32 * rank, int32 dims[],
	    int32 * numbertype, char *dimlist)

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */


    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWfieldinfo", &fid,
		       &sdInterfaceID, &swVgrpID);
    if (status == 0)
    {
	/* Check for field within Geolocatation Fields */
	status = SWfinfo(swathID, "Geolocation Fields", fieldname,
			 rank, dims, numbertype, dimlist);

	/* If not there then check within Data Fields */
	if (status == -1)
	{
	    status = SWfinfo(swathID, "Data Fields", fieldname,
			     rank, dims, numbertype, dimlist);
	}

	/* If not there either then can't be found */
	if (status == -1)
	{
	    HEpush(DFE_GENAPP, "SWfieldinfo", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" not found.\n", fieldname);
	}
    }
    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWfldinfo                                                        |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper around SWfieldinfo                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  fieldname      char                name of field                           |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int32               rank of field (# of dims)               |
|  dims           int32               field dimensions                        |
|  numbertype     int32               field number type                       |
|  fortdimlist    char                field dimension list (FORTRAN order)    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Jul 96   Joel Gales    Perform swap only if SWfieldinfo succesful          |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWfldinfo(int32 swathID, const char *fieldname, int32 * rank, int32 dims[],
	  int32 * numbertype, char *fortdimlist)
{
    intn            j;		/* Loop Index */
    intn            status;	/* routine return status variable */

    int32           swap;	/* Temporary swap entry for dimension sizes */
    char           *dimlist;/* Dimension list in C order */

    /* Allocate space for C order dimension list */
    /* ----------------------------------------- */
    dimlist = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(dimlist == NULL)
    {
	HEpush(DFE_NOSPACE,"SWfldinfo", __FILE__, __LINE__);
	return(-1);
    }

    /* Get field info */
    status = SWfieldinfo(swathID, fieldname, rank, dims,
			 numbertype, dimlist);

    /* If no error then reverse order of dimension sizes */
    if (status == 0)
    {
	for (j = 0; j < *rank / 2; j++)
	{
	    swap = dims[*rank - 1 - j];
	    dims[*rank - 1 - j] = dims[j];
	    dims[j] = swap;
	}

	/* Reverse order of dimensions entries in dimension list */
	EHrevflds(dimlist, fortdimlist);
    }

    free(dimlist);
    return (status);

}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefdimmap                                                      |
|                                                                             |
|  DESCRIPTION: Defines mapping between geolocation and data dimensions       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  geodim         char                Geolocation dimension                   |
|  datadim        char                Data dimension                          |
|  offset         int32               Mapping offset                          |
|  increment      int32               Mapping increment                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefdimmap(int32 swathID, const char *geodim, const char *datadim, int32 offset,
	    int32 increment)

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           size;	/* Size of geo dim */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           dum;	/* Dummy variable */
    int32           metadata[2];/* Offset & Increment (passed to metadata) */

    char            mapname[80];/* Mapping name (geodim/datadim) */
    char            swathname[80];	/* Swath name */

    /* Check Swath ID */
    status = SWchkswid(swathID, "SWdefdimmap", &fid, &sdInterfaceID, &dum);

    if (status == 0)
    {

	/* Search Dimension Vdata for dimension entries */
	/* -------------------------------------------- */
	size = SWdiminfo(swathID, geodim);
	if (size == -1)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWdefdimmap", __FILE__, __LINE__);
	    HEreport("Geolocation dimension name: \"%s\" not found.\n",
		     geodim);
	}
	/* Data Dimension Search */
	/* --------------------- */
	if (status == 0)
	{
	    size = SWdiminfo(swathID, datadim);
	    if (size == -1)
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWdefdimmap", __FILE__, __LINE__);
		HEreport("Data dimension name: \"%s\" not found.\n",
			 datadim);
	    }
	}

	/* Write Dimension Map to Structural MetaData */
	/* ------------------------------------------ */
	if (status == 0)
	{
	  snprintf(mapname, sizeof(mapname), "%s%s%s", geodim, "/", datadim);
	  metadata[0] = offset;
	  metadata[1] = increment;

	  Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);
	  status = EHinsertmeta(sdInterfaceID, swathname, "s", 1L,
				mapname, metadata);
	}
    }
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefidxmap                                                      |
|                                                                             |
|  DESCRIPTION: Defines indexed (non-linear) mapping between geolocation      |
|               and data dimensions                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  geodim         char                Geolocation dimension                   |
|  datadim        char                Data dimension                          |
|  l_index          int32             Index mapping array                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefidxmap(int32 swathID, const char *geodim, const char *datadim, int32 l_index[])

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           attrVgrpID;	/* Swath attribute ID */
    int32           vdataID;	/* Mapping Index Vdata ID */
    int32           gsize;	/* Size of geo dim */
    int32           dsize;	/* Size of data dim */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           dum;	/* Dummy variable */

    uint8          *buf;	/* Vdata field buffer */

    char            mapname[80];/* Mapping name (geodim/datadim) */
    char            swathname[80];	/* Swath name */
    char            utlbuf[256];/* Utility buffer */


    /* Check Swath ID */
    status = SWchkswid(swathID, "SWdefidxmap", &fid, &sdInterfaceID, &dum);
    if (status == 0)
    {
	/* Search Dimension Vdata for dimension entries */
	/* -------------------------------------------- */

	/* Geo Dimension Search */
	/* -------------------- */

	gsize = SWdiminfo(swathID, geodim);

	if (gsize == -1)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWdefidxmap", __FILE__, __LINE__);
	    HEreport("Geolocation dimension name: \"%s\" not found.\n",
		     geodim);
	}
	/* Data Dimension Search */
	/* --------------------- */
	if (status == 0)
	{
	    dsize = SWdiminfo(swathID, datadim);
	    if (dsize == -1)
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWdefidxmap", __FILE__, __LINE__);
		HEreport("Data dimension name: \"%s\" not found.\n",
			 datadim);
	    }
	}
	/* Define Index Vdata and Store Index Array */
	/* ---------------------------------------- */
	if (status == 0)
	{
	    /* Get attribute Vgroup ID and allocate data buffer */
	    /* ------------------------------------------------ */
	    attrVgrpID = SWXSwath[swathID % idOffset].VIDTable[2];
	    buf = (uint8 *) calloc(4 * gsize, 1);
	    if(buf == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdefidxmap", __FILE__, __LINE__);
		return(-1);
	    }

	    /* Name: "INDXMAP:" + geodim + "/" + datadim */
	    snprintf(utlbuf, sizeof(utlbuf), "%s%s%s%s", "INDXMAP:", geodim, "/", datadim);

	    vdataID = VSattach(fid, -1, "w");
	    VSsetname(vdataID, utlbuf);

	    /* Attribute Class */
	    VSsetclass(vdataID, "Attr0.0");

	    /* Fieldname is "Index" */
	    VSfdefine(vdataID, "Index", DFNT_INT32, gsize);
	    VSsetfields(vdataID, "Index");
	    memcpy(buf, l_index, 4 * gsize);

	    /* Write to vdata and free data buffer */
	    VSwrite(vdataID, buf, 1, FULL_INTERLACE);
	    free(buf);

	    /* Insert in Attribute Vgroup and detach Vdata */
	    Vinsert(attrVgrpID, vdataID);
	    VSdetach(vdataID);


	    /* Write to Structural Metadata */
	    snprintf(mapname, sizeof(mapname), "%s%s%s", geodim, "/", datadim);
	    Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);
	    status = EHinsertmeta(sdInterfaceID, swathname, "s", 2L,
				  mapname, &dum);

	}
    }
    return (status);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefcomp                                                        |
|                                                                             |
|  DESCRIPTION: Defines compression type and parameters                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  compcode       int32               compression code                        |
|  compparm       intn                compression parameters                  |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Sep 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefcomp(int32 swathID, int32 compcode, intn compparm[])
{
    intn            status = 0;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file id */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           sID;	/* swathID - offset */
    uint32          can_encode; /* szip encoder presence flag     */

    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWdefcomp", &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	sID = swathID % idOffset;

#if defined(HAVE_HDF4_SZIP_DECODER)
	status = HCget_config_info(COMP_CODE_SZIP, &can_encode);
#endif

	/* Set compression code in compression external array */
	SWXSwath[sID].compcode = compcode;

	switch (compcode)
	{
	    /* Set NBIT compression parameters in compression external array */
	case HDFE_COMP_NBIT:

	    SWXSwath[sID].compparm[0] = compparm[0];
	    SWXSwath[sID].compparm[1] = compparm[1];
	    SWXSwath[sID].compparm[2] = compparm[2];
	    SWXSwath[sID].compparm[3] = compparm[3];

	    break;

	    /* Set GZIP compression parameter in compression external array */
	case HDFE_COMP_DEFLATE:

	    SWXSwath[sID].compparm[0] = compparm[0];

	    break;

	    /* Set SZIP compression parameter in compression external array */
	case HDFE_COMP_SZIP:
#if defined(HAVE_HDF4_SZIP_DECODER)
	  if(can_encode == (COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED))
		{
		  if( compparm[0] != 2 && compparm[0] != 4 &&
		      compparm[0] != 6 && compparm[0] != 8 &&
		      compparm[0] != 10 && compparm[0] != 12 &&
		      compparm[0] != 14 && compparm[0] != 16 &&
		      compparm[0] != 18 && compparm[0] != 20 &&
		      compparm[0] != 22 && compparm[0] != 24 &&
		      compparm[0] != 26 && compparm[0] != 28 &&
		      compparm[0] != 30 && compparm[0] != 32)
		    {
		      status = -1;
		      HEpush(DFE_GENAPP, "SWdefcomp", __FILE__, __LINE__);
		      HEreport("Invalid SZIP compression block size. Valid values are 2 to 32, in multiples of 2.\n");
		      return(status);
		    }
		  if( compparm[1] != SZ_NN &&
		      compparm[1] != SZ_EC )
		    {
		      status = -1;
		      HEpush(DFE_GENAPP, "SWdefcomp", __FILE__, __LINE__);
		      HEreport("Invalid SZIP compression type. Valid types are SZ_NN and SZ_EC.\n");
		      return(status);
		    }
		  SWXSwath[sID].compparm[0] = compparm[0];
		  SWXSwath[sID].compparm[1] = compparm[1];
		}
	      else
		{
		  HEpush(DFE_GENAPP, "SWdefcomp", __FILE__, __LINE__);
		  HEreport("Szip does not have encoder; Szip compression won't apply to datafields.\n");
		}
#endif
	    break;
	}
    }

    return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefinefield                                                    |
|                                                                             |
|  DESCRIPTION: Defines geolocation or data field within swath structure      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldtype      char                geo/data fieldtype                      |
|  fieldname      char                fieldname                               |
|  dimlist        char                Dimension list (comma-separated list)   |
|  numbertype     int32               field type                              |
|  merge          int32               merge code                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Check name for length                               |
|  Sep 96   Joel Gales    Make string array "dimbuf" dynamic                  |
|  Oct 96   Joel Gales    Make sure total length of "merged" Vdata < 64       |
|  Jun 03   Abe Taaheri   Supplied cast comp_coder_t in call to SDsetcompress |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefinefield(int32 swathID, const char *fieldtype, const char *fieldname, const char *dimlist,
	      int32 numbertype, int32 merge)

{
    intn            i;		/* Loop index */
    intn            status;	/* routine return status variable */
    intn            found;	/* utility found flag */
    intn            foundNT = 0;/* found number type flag */
    intn            foundAllDim = 1;	/* found all dimensions flag */
    intn            first = 1;	/* first entry flag */
    intn            fac;	/* Geo (-1), Data (+1) field factor */
    int32           cnt = 0;

    int32           fid;	/* HDF-EOS file ID */
    int32           vdataID = 0;	/* Vdata ID */
    int32           vgid;	/* Geo/Data field Vgroup ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           sdid;	/* SDS object ID */
    int32           dimid;	/* SDS dimension ID */
    int32           recSize;	/* Vdata record size */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           dims[8];	/* Dimension size array */
    int32           dimsize;	/* Dimension size */
    int32           rank = 0;	/* Field rank */
    int32           slen[32];	/* String length array */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           compcode;	/* Compression code */
    int32           sID;	/* SwathID - offset */

    uint8          *oneDbuf;	/* Vdata record buffer */
    char           *dimbuf;	/* Dimension buffer */
    char           *comma;	/* Pointer to comma */
    char           *dimcheck;	/* Dimension check buffer */
    char            utlbuf[UTLSTR_MAX_SIZE];/* Utility buffer */
    char            utlbuf2[UTLSTR_MAX_SIZE];	/* Utility buffer 2 */
    char           *ptr[32];	/* String pointer array */
    char            swathname[80];	/* Swath name */
    char            errbuf1[128];	/* Error message buffer 1 */
    char            errbuf2[128];	/* Error message buffer 2 */
    char            compparmbuf[128];	/* Compression parameter string buffer */
    int32           temp_compcode = HDFE_COMP_NONE; /* temp Compression code */
    uint32          can_encode;         /* szip encoder presence flag     */

    /* Compression code names */
    const char     *HDFcomp[6] = {"HDFE_COMP_NONE", "HDFE_COMP_RLE",
				  "HDFE_COMP_NBIT", "HDFE_COMP_SKPHUFF",
				  "HDFE_COMP_DEFLATE","HDFE_COMP_SZIP"};

    uint16          good_number[10] = {3, 4, 5, 6, 20, 21, 22, 23, 24, 25};
    /* Valid number types */
    comp_info       c_info;	/* Compression parameter structure */

    /* check for illegal characters in fieldname ',', '/', ';', and ':' */
    /* ICHECKNAME(fieldname);*/
    /* for HEG we will ignore this illegal issue.
       Some products has already these characters in them! */
#ifndef MRTlinux
    status = EHchkname(fieldname);
    if (status == -1) return(status);
#endif

    /* Setup error message strings */
    /* --------------------------- */
    strcpy(errbuf1, "SWXSDname array too small.\nPlease increase ");
    strcat(errbuf1, "size of HDFE_NAMBUFSIZE in \"HdfEosDef.h\".\n");
    strcpy(errbuf2, "SWXSDdims array too small.\nPlease increase ");
    strcat(errbuf2, "size of HDFE_DIMBUFSIZE in \"HdfEosDef.h\".\n");

#if defined(HAVE_HDF4_SZIP_DECODER)
    status = HCget_config_info(COMP_CODE_SZIP, &can_encode);
#endif

    /*
     * Check for proper swath ID and return HDF-EOS file ID, SDinterface ID,
     * and swath root Vgroup ID
     */
    status = SWchkswid(swathID, "SWdefinefield",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Remove offset from swath ID & get swathname */
	sID = swathID % idOffset;
	Vgetname(swVgrpID, swathname);

	/* Allocate space for dimbuf, copy dimlist into it, & append comma */
	dimbuf = (char *) calloc(strlen(dimlist) + 64, 1);
	if(dimbuf == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWdefinefield", __FILE__, __LINE__);
	    return(-1);
	}
	strcpy(dimbuf, dimlist);
	strcat(dimbuf, ",");

	/* Find comma */
	comma = strchr(dimbuf, ',');


	/*
	 * Loop through entries in dimension list to make sure they are
	 * defined in swath
	 */
	while (comma != NULL)
	{
	    /* Copy dimension list entry to dimcheck */
	    dimcheck = (char *) calloc(comma - dimbuf + 1, 1);
	    if(dimcheck == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdefinefield", __FILE__, __LINE__);
		free(dimbuf);
		return(-1);
	    }
	    memcpy(dimcheck, dimbuf, comma - dimbuf);

	    /* Get dimension size */
	    dimsize = SWdiminfo(swathID, dimcheck);

	    /* if != -1 then sent found flag, store size and increment rank */
	    if (dimsize != -1)
	    {
		dims[rank] = dimsize;
		rank++;
	    }
	    else
	    {
		/*
		 * If dimension list entry not found - set error return
		 * status, append name to utility buffer for error report
		 */
		status = -1;
		foundAllDim = 0;
		if (first == 1)
		{
		    strcpy(utlbuf, dimcheck);
		}
		else
		{
		    strcat(utlbuf, ",");
		    strcat(utlbuf, dimcheck);
		}
		first = 0;
	    }

	    /*
	     * Go to next dimension entry, find next comma, & free up
	     * dimcheck buffer
	     */
            *comma = '\0';  /* zero out first comma  */
            comma++;
            comma = strchr(comma, ',');
            if (comma != NULL)
            {
               for (i=0; i<(int32)strlen(dimcheck) + 1; i++)
               {
                  dimbuf++;
                  cnt++;
               }
            }
	    free(dimcheck);
	}
        for(i=0; i<cnt; i++)
           dimbuf--;

	free(dimbuf);


	/* Check that UNLIMITED dimension is first dimension if present */
	/* ------------------------------------------------------------ */
	if (status == 0)
	{
	    for (i = 0; i < rank; i++)
	    {
		if (dims[i] == 0 && i != 0)
		{
		    status = -1;
		    HEpush(DFE_GENAPP, "SWdefinefield", __FILE__, __LINE__);
		    HEreport("UNLIMITED dimension must be first dimension.\n");
		}
	    }
	}


	/* Check fieldname length */
	/* ---------------------- */
	if (status == 0)
	{
/* ((intn) strlen(fieldname) > MAX_NC_NAME - 7)
** this was changed because HDF4.1r3 made a change in the
** hlimits.h file.  We have notified NCSA and asked to have
** it made the same as in previous versions of HDF
** see ncr 26314.  DaW  Apr 2000
*/

	    if ((intn) strlen(fieldname) > VSNAMELENMAX && rank == 1 ||
		(intn) strlen(fieldname) > (256 - 7) && rank > 1)
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWdefinefield", __FILE__, __LINE__);
		HEreport("Fieldname \"%s\" too long.\n", fieldname);
	    }
	}

	/* Check for valid numbertype */
	/* -------------------------- */
	if (status == 0)
	{
	    for (i = 0; i < 10; i++)
	    {
		if (numbertype == good_number[i])
		{
		    foundNT = 1;
		}
	    }

	    if (foundNT == 0)
	    {
		HEpush(DFE_BADNUMTYPE, "SWdefinefield", __FILE__, __LINE__);
		HEreport("Invalid number type: %d (%s).\n",
			 numbertype, fieldname);
		status = -1;
	    }
	}


	/* Define Field */
	/* ------------ */
	if (status == 0)
	{
	    /* Set factor & get Field Vgroup id */
	    /* -------------------------------- */
	    if (strcmp(fieldtype, "Geolocation Fields") == 0)
	    {
		fac = -1;
		vgid = SWXSwath[sID].VIDTable[0];
	    }
	    else
	    {
		fac = +1;
		vgid = SWXSwath[sID].VIDTable[1];
	    }
	    /*
	     * Note: "fac" is used to distinguish geo fields from data fields
	     * so that they are not merged together
	     */


	    /* One D Fields */
	    /* ------------ */
	    if (rank == 1)
	    {
		/* No Compression for 1D (Vdata) fields */
		compcode = HDFE_COMP_NONE;


		/* If field non-appendable and merge set to AUTOMERGE ... */
		if (dims[0] != 0 && merge == HDFE_AUTOMERGE)
		{
		    i = 0;
		    found = 0;

		    /* Loop through previous entries in 1d combination array */
		    while (SWX1dcomb[3 * i] != 0)
		    {
			/* Get name of previous 1d combined field */
			vdataID = SWX1dcomb[3 * i + 2];
			VSgetname(vdataID, utlbuf);

			/*
			 * If dimension, field type (geo/data), and swath
			 * structure if current entry match a previous entry
			 * and combined name is less than max allowed then
			 * set "found" flag and exit loop
			 */
			if (SWX1dcomb[3 * i] == fac * dims[0] &&
			    SWX1dcomb[3 * i + 1] == swVgrpID &&
			    (intn) strlen(utlbuf) +
			    (intn) strlen(fieldname) + 1 <=
			    VSNAMELENMAX)
			{
			    found = 1;
			    break;
			}
			/* Increment loop index */
			i++;
		    }


		    if (found == 0)
		    {
			/*
			 * If no matching entry found then start new Vdata
			 * and store dimension size, swath root Vgroup ID,
			 * field Vdata and fieldname in external array
			 * "SWX1dcomb"
			 */
			vdataID = VSattach(fid, -1, "w");
			SWX1dcomb[3 * i] = fac * dims[0];
			SWX1dcomb[3 * i + 1] = swVgrpID;
			SWX1dcomb[3 * i + 2] = vdataID;
			VSsetname(vdataID, fieldname);
		    }
		    else
		    {
			/*
			 * If match then concatenate current fieldname to
			 * previous matching fieldnames.
			 */
			strcat(utlbuf, ",");
			strcat(utlbuf, fieldname);
			VSsetname(vdataID, utlbuf);
		    }

		    /* Define field as field within Vdata */
		    VSfdefine(vdataID, fieldname, numbertype, 1);
		    Vinsert(vgid, vdataID);

		}
		else
		{
		    /* 1d No Merge Section */

		    /* Get new vdata ID and establish field within Vdata */
		    vdataID = VSattach(fid, -1, "w");
		    VSsetname(vdataID, fieldname);
		    VSfdefine(vdataID, fieldname, numbertype, 1);
		    VSsetfields(vdataID, fieldname);

		    recSize = EHsizeof(vdataID, fieldname);

		    if (dims[0] == 0)
		    {
			/*
			 * If appendable field then write single record
			 * filled with 255
			 */
			oneDbuf = (uint8 *) calloc(recSize, 1);
			if(oneDbuf == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWdefinefield", __FILE__, __LINE__);
			    return(-1);
			}
			for (i = 0; i < recSize; i++)
			    oneDbuf[i] = 255;
			VSwrite(vdataID, oneDbuf, 1, FULL_INTERLACE);
		    }
		    else
		    {
			/*
			 * If non-appendable then write entire field with
			 * blank records
			 */
			oneDbuf = (uint8 *) calloc(recSize, dims[0]);
			if(oneDbuf == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWdefinefield", __FILE__, __LINE__);
			    return(-1);
			}
			VSwrite(vdataID, oneDbuf, dims[0], FULL_INTERLACE);
		    }
		    free(oneDbuf);

		    /* Insert Vdata into field Vgroup & detach */
		    Vinsert(vgid, vdataID);
		    VSdetach(vdataID);

		}		/* End No Merge Section */

	    }			/* End 1d field Section */
	    else
	    {
		/* SDS Interface (Multi-dim fields) */
		/* -------------------------------- */

		/* Get current compression code */
		compcode = SWXSwath[sID].compcode;

		/*
		 * If rank is less than or equal to 3 (and greater than 1)
		 * and AUTOMERGE is set and the first dimension is not
		 * appendable and the compression code is set to none then
		 * ...
		 */
		if (rank <= 3 && merge == HDFE_AUTOMERGE && dims[0] != 0
		    && compcode == HDFE_COMP_NONE)
		{
		    /* Find first empty slot in external combination array */
		    /* --------------------------------------------------- */
		    i = 0;
		    while (SWXSDcomb[5 * i] != 0)
		    {
			i++;
		    }

		    /*
		     * Store dimensions (with geo/data factor), swath root
		     * Vgroup ID, and number type in external combination
		     * array "SWXSDcomb"
		     */

		    if (rank == 2)
		    {
			/* If 2-dim field then set lowest dimension to +/- 1 */
			SWXSDcomb[5 * i] = fac;
			SWXSDcomb[5 * i + 1] = fac * dims[0];
			SWXSDcomb[5 * i + 2] = fac * dims[1];
		    }
		    else
		    {
			SWXSDcomb[5 * i] = fac * dims[0];
			SWXSDcomb[5 * i + 1] = fac * dims[1];
			SWXSDcomb[5 * i + 2] = fac * dims[2];
		    }

		    SWXSDcomb[5 * i + 3] = swVgrpID;
		    SWXSDcomb[5 * i + 4] = numbertype;


		    /* Concatenate fieldname with combined name string */
		    /* ----------------------------------------------- */
		    if ((intn) strlen(SWXSDname) +
			(intn) strlen(fieldname) + 2 < HDFE_NAMBUFSIZE)
		    {
			strcat(SWXSDname, fieldname);
			strcat(SWXSDname, ",");
		    }
		    else
		    {
			/* SWXSDname array too small! */
			/* -------------------------- */
			HEpush(DFE_GENAPP, "SWdefinefield",
			       __FILE__, __LINE__);
			HEreport(errbuf1);
			status = -1;
			return (status);
		    }



		    /*
		     * If 2-dim field then set lowest dimension (in 3-dim
		     * array) to "ONE"
		     */
		    if (rank == 2)
		    {
			if ((intn) strlen(SWXSDdims) + 5 < HDFE_DIMBUFSIZE)
			{
			    strcat(SWXSDdims, "ONE,");
			}
			else
			{
			    /* SWXSDdims array too small! */
			    /* -------------------------- */
			    HEpush(DFE_GENAPP, "SWdefinefield",
				   __FILE__, __LINE__);
			    HEreport(errbuf2);
			    status = -1;
			    return (status);
			}

		    }

		    /*
		     * Concatenate field dimlist to merged dimlist and
		     * separate fields with semi-colon.
		     */
		    if ((intn) strlen(SWXSDdims) +
			(intn) strlen(dimlist) + 2 < HDFE_DIMBUFSIZE)
		    {
			strcat(SWXSDdims, dimlist);
			strcat(SWXSDdims, ";");
		    }
		    else
		    {
			/* SWXSDdims array too small! */
			/* -------------------------- */
			HEpush(DFE_GENAPP, "SWdefinefield",
			       __FILE__, __LINE__);
			HEreport(errbuf2);
			status = -1;
			return (status);
		    }

		}		/* End Multi-Dim Merge Section */
		else
		{
		    char *tmpdimlist=NULL;

		    /* Multi-Dim No Merge Section */
		    /* ========================== */

		    /* Create SDS dataset */
		    /* ------------------ */
		    sdid = SDcreate(sdInterfaceID, fieldname,
				    numbertype, rank, dims);


		    /* Store Dimension Names in SDS */
		    /* ---------------------------- */
		    rank = EHparsestr(dimlist, ',', ptr, slen);
		    /*
		    tmpdimlist = (char *)malloc(((int)strlen(dimlist)+1)*sizeof(char));
		    strcpy(tmpdimlist, dimlist);
		    rank = EHparsestr(tmpdimlist, ',', ptr, slen);
		    free(tmpdimlist);
		    tmpdimlist = NULL;
		    */
		    for (i = 0; i < rank; i++)
		    {
			/* Dimension name = Swathname:Dimname */
			memcpy(utlbuf, ptr[i], slen[i]);
			utlbuf[slen[i]] = 0;
			strcat(utlbuf, ":");
			strcat(utlbuf, swathname);

			dimid = SDgetdimid(sdid, i);
			SDsetdimname(dimid, utlbuf);
		    }


		    /* Setup compression parameters */
		    if (compcode == HDFE_COMP_NBIT)
		      {
			temp_compcode = compcode;
			c_info.nbit.nt = numbertype;
			c_info.nbit.sign_ext = SWXSwath[sID].compparm[0];
			c_info.nbit.fill_one = SWXSwath[sID].compparm[1];
			c_info.nbit.start_bit = SWXSwath[sID].compparm[2];
			c_info.nbit.bit_len = SWXSwath[sID].compparm[3];
		      }
		    else if (compcode == HDFE_COMP_SKPHUFF)
		      {
			temp_compcode = compcode;
			c_info.skphuff.skp_size = (intn) DFKNTsize(numbertype);
		      }
		    else if (compcode == HDFE_COMP_DEFLATE)
		      {
			temp_compcode = compcode;
			c_info.deflate.level = SWXSwath[sID].compparm[0];
		      }
#if defined(HAVE_HDF4_SZIP_DECODER)
		    else if (compcode == HDFE_COMP_SZIP )
		      {
			if(can_encode == (COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED))
			  {
			    temp_compcode = compcode;
			    /* pixels_per_block is even number from 2-32 */
			    c_info.szip.pixels_per_block = SWXSwath[sID].compparm[0];
			    if( SWXSwath[sID].compparm[1] == SZ_EC)
			      {
				c_info.szip.options_mask = SZ_EC_OPTION_MASK | SZ_RAW_OPTION_MASK;
			      }
			    else if ( SWXSwath[sID].compparm[1] == SZ_NN)
			      {
				c_info.szip.options_mask = SZ_NN_OPTION_MASK | SZ_RAW_OPTION_MASK;
			      }
			    else
			      {
				c_info.szip.options_mask = SZ_RAW_OPTION_MASK;
			      }
			  }
			else /* encoder is disabled; Would not compress */
			  {
			    temp_compcode =  HDFE_COMP_NONE;
			  }
		      }
#else
		    if(compcode != HDFE_COMP_NONE)
		      {
			temp_compcode =  compcode;
		      }
		    else
		      {
			temp_compcode = HDFE_COMP_NONE;
		      }
#endif
		    /* If field is compressed then call SDsetcompress */
		    /* ---------------------------------------------- */
		    if (temp_compcode != HDFE_COMP_NONE)
		    {
			status = SDsetcompress(sdid, (comp_coder_t) compcode, &c_info);
		    }


		    /* Attach to Vgroup */
		    /* ---------------- */
		    Vaddtagref(vgid, DFTAG_NDG, SDidtoref(sdid));


		    /* Store SDS dataset IDs */
		    /* --------------------- */
		    if (SWXSwath[sID].nSDS > 0)
		    {
			SWXSwath[sID].sdsID = (int32 *)
			    realloc((void *) SWXSwath[sID].sdsID,
				    (SWXSwath[sID].nSDS + 1) * 4);
			if(SWXSwath[sID].sdsID == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWdefinefield", __FILE__, __LINE__);
			    return(-1);
			}

		    }
		    else
		    {
			SWXSwath[sID].sdsID = (int32 *) calloc(1, 4);
			if(SWXSwath[sID].sdsID == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWdefinefield", __FILE__, __LINE__);
			    return(-1);
			}
		    }
		    SWXSwath[sID].sdsID[SWXSwath[sID].nSDS] = sdid;
		    SWXSwath[sID].nSDS++;

		}		/* End Multi-Dim No Merge Section */

	    }			/* End Multi-Dim Section */



	    /* Setup metadata string */
	    /* --------------------- */
	    snprintf(utlbuf, sizeof(utlbuf), "%s%s%s", fieldname, ":", dimlist);


	    /* Setup compression metadata */
	    /* -------------------------- */
	    if (temp_compcode != HDFE_COMP_NONE)
	    {
		snprintf(utlbuf2, sizeof(utlbuf2),
			"%s%s",
			":\n\t\t\t\tCompressionType=", HDFcomp[compcode]);

		switch (compcode)
		{
		case HDFE_COMP_NBIT:

		  snprintf(compparmbuf, sizeof(compparmbuf),
			    "%s%d,%d,%d,%d%s",
			    "\n\t\t\t\tCompressionParams=(",
			    SWXSwath[sID].compparm[0],
			    SWXSwath[sID].compparm[1],
			    SWXSwath[sID].compparm[2],
			    SWXSwath[sID].compparm[3], ")");
		    strcat(utlbuf2, compparmbuf);
		    break;


		case HDFE_COMP_DEFLATE:

		  snprintf(compparmbuf, sizeof(compparmbuf),
			    "%s%d",
			    "\n\t\t\t\tDeflateLevel=",
			    SWXSwath[sID].compparm[0]);
		    strcat(utlbuf2, compparmbuf);
		    break;


		case HDFE_COMP_SZIP:

		    snprintf(compparmbuf, sizeof(compparmbuf),
			    "%s%d,%d%s",
			    "\n\t\t\t\tCompressionParams=(",
			    SWXSwath[sID].compparm[0],
			    SWXSwath[sID].compparm[1], ")");
		    strcat(utlbuf2, compparmbuf);
		    break;

		}

		/* Concatenate compression parameters with compression code */
		strcat(utlbuf, utlbuf2);
	    }


	    /* Insert field metadata within File Structural Metadata */
	    /* ----------------------------------------------------- */
	    if (strcmp(fieldtype, "Geolocation Fields") == 0)
	    {
		status = EHinsertmeta(sdInterfaceID, swathname, "s", 3L,
				      utlbuf, &numbertype);
	    }
	    else
	    {
		status = EHinsertmeta(sdInterfaceID, swathname, "s", 4L,
				      utlbuf, &numbertype);
	    }

	}
    }

    /* If all dimensions not found then report error */
    /* --------------------------------------------- */
    if (foundAllDim == 0)
    {
	HEpush(DFE_GENAPP, "SWdefinefield", __FILE__, __LINE__);
	HEreport("Dimension(s): \"%s\" not found (%s).\n",
		 utlbuf, fieldname);
	status = -1;
    }

    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefgeofield                                                    |
|                                                                             |
|  DESCRIPTION: Defines geolocation field within swath structure (wrapper)    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  dimlist        char                Dimension list (comma-separated list)   |
|  numbertype     int32               field type                              |
|  merge          int32               merge code                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefgeofield(int32 swathID, const char *fieldname, const char *dimlist,
	      int32 numbertype, int32 merge)
{
    intn            status;	/* routine return status variable */

    /* Call SWdefinefield routine */
    /* -------------------------- */
    status = SWdefinefield(swathID, "Geolocation Fields", fieldname, dimlist,
			   numbertype, merge);

    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefdatafield                                                   |
|                                                                             |
|  DESCRIPTION: Defines data field within swath structure (wrapper)           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  dimlist        char                Dimension list (comma-separated list)   |
|  numbertype     int32               field type                              |
|  merge          int32               merge code                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefdatafield(int32 swathID, const char *fieldname, const char *dimlist,
	       int32 numbertype, int32 merge)
{
    intn            status;	/* routine return status variable */

    /* Call SWdefinefield routine */
    /* -------------------------- */
    status = SWdefinefield(swathID, "Data Fields", fieldname, dimlist,
			   numbertype, merge);

    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwritegeometa                                                   |
|                                                                             |
|  DESCRIPTION: Defines structural metadata for pre-existing geolocation      |
|               field within swath structure                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  dimlist        char                Dimension list (comma-separated list)   |
|  numbertype     int32               field type                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwritegeometa(int32 swathID, const char *fieldname, const char *dimlist,
	       int32 numbertype)
{
    intn            status = 0;	/* routine return status variable */

    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           dum;	/* dummy variable */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char            utlbuf[256];/* Utility buffer */
    char            swathname[80];	/* Swath name */

    status = SWchkswid(swathID, "SWwritegeometa", &dum, &sdInterfaceID,
		       &dum);

    if (status == 0)
    {
	/* Setup and write field metadata */
	/* ------------------------------ */
	snprintf(utlbuf, sizeof(utlbuf), "%s%s%s", fieldname, ":", dimlist);

	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);
	status = EHinsertmeta(sdInterfaceID, swathname, "s", 3L,
			      utlbuf, &numbertype);
    }

    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwritedatameta                                                  |
|                                                                             |
|  DESCRIPTION: Defines structural metadata for pre-existing data             |
|               field within swath structure                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  dimlist        char                Dimension list (comma-separated list)   |
|  numbertype     int32               field type                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwritedatameta(int32 swathID, const char *fieldname, const char *dimlist,
		int32 numbertype)
{
    intn            status = 0;	/* routine return status variable */

    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           dum;	/* dummy variable */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char            utlbuf[256];/* Utility buffer */
    char            swathname[80];	/* Swath name */

    status = SWchkswid(swathID, "SWwritedatameta", &dum, &sdInterfaceID,
		       &dum);

    if (status == 0)
    {
	/* Setup and write field metadata */
	/* ------------------------------ */
	snprintf(utlbuf, sizeof(utlbuf), "%s%s%s", fieldname, ":", dimlist);

	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);
	status = EHinsertmeta(sdInterfaceID, swathname, "s", 4L,
			      utlbuf, &numbertype);
    }
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefgfld                                                        |
|                                                                             |
|  DESCRIPTION: Defines geolocation field within swath structure (FORTRAN)    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  fortdimlist    char                Dimension list (comma-separated list)   |
|                                         FORTRAN dimesion order              |
|  numbertype     int32               field type                              |
|  merge          int32               merge code                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefgfld(int32 swathID, const char *fieldname, const char *fortdimlist,
	  int32 numbertype, int32 merge)
{
    intn            status = 0;	/* routine return status variable */
    char           *dimlist;	/* Dimension list (C order) */

    /* Allocate space for C order dimension list */
    /* ----------------------------------------- */
    dimlist = (char *) calloc(strlen(fortdimlist) + 1, 1);
    if(dimlist == NULL)
    {
	HEpush(DFE_NOSPACE,"SWdefgfld", __FILE__, __LINE__);
	return(-1);
    }

    /* Reverse entries in dimension list (FORTRAN -> C) */
    /* ------------------------------------------------ */
    status = EHrevflds(fortdimlist, dimlist);

    /* Call Define Field routine */
    /* ------------------------- */
    status = SWdefinefield(swathID, "Geolocation Fields", fieldname,
			   dimlist, numbertype, merge);

    free(dimlist);
    return (status);

}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefdfld                                                        |
|                                                                             |
|                                                                             |
|  DESCRIPTION: Defines data field within swath structure (FORTRAN)           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  fortdimlist    char                Dimension list (comma-separated list)   |
|                                         FORTRAN dimesion order              |
|  numbertype     int32               field type                              |
|  merge          int32               merge code                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdefdfld(int32 swathID, const char *fieldname, const char *fortdimlist,
	  int32 numbertype, int32 merge)

{
    intn            status = 0;	/* routine return status variable */
    char           *dimlist;	/* Dimension list (C order) */

    /* Allocate space for C order dimension list */
    /* ----------------------------------------- */
    dimlist = (char *) calloc(strlen(fortdimlist) + 1, 1);
    if(dimlist == NULL)
    {
	HEpush(DFE_NOSPACE,"SWdefdfld", __FILE__, __LINE__);
	return(-1);
    }

    /* Reverse entries in dimension list (FORTRAN -> C) */
    /* ------------------------------------------------ */
    status = EHrevflds(fortdimlist, dimlist);

    /* Call Define Field routine */
    /* ------------------------- */
    status = SWdefinefield(swathID, "Data Fields", fieldname,
			   dimlist, numbertype, merge);

    free(dimlist);
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwrgmeta                                                        |
|                                                                             |
|                                                                             |
|  DESCRIPTION: Defines structural metadata for pre-existing geolocation      |
|               field within swath structure (FORTRAN)                        |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  fortdimlist    char                Dimension list (comma-separated list)   |
|                                         FORTRAN dimesion order              |
|  numbertype     int32               field type                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwrgmeta(int32 swathID, const char *fieldname, const char *fortdimlist,
	  int32 numbertype)
{
    intn            status = 0;	/* routine return status variable */
    char           *dimlist;	/* Dimension list (C order) */

    /* Allocate space for C order dimension list */
    /* ----------------------------------------- */
    dimlist = (char *) calloc(strlen(fortdimlist) + 1, 1);
    if(dimlist == NULL)
    {
	HEpush(DFE_NOSPACE,"SWwrgmeta", __FILE__, __LINE__);
	return(-1);
    }

    /* Reverse entries in dimension list (FORTRAN -> C) */
    /* ------------------------------------------------ */
    status = EHrevflds(fortdimlist, dimlist);

    /* Call Write Metadata routine */
    /* --------------------------- */
    status = SWwritegeometa(swathID, fieldname, dimlist, numbertype);

    free(dimlist);
    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwrdmeta                                                        |
|                                                                             |
|  DESCRIPTION: Defines structural metadata for pre-existing data             |
|               field within swath structure (FORTRAN)                        |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  fortdimlist    char                Dimension list (comma-separated list)   |
|                                         FORTRAN dimesion order              |
|  numbertype     int32               field type                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwrdmeta(int32 swathID, const char *fieldname, const char *fortdimlist,
	  int32 numbertype)
{
    intn            status = 0;	/* routine return status variable */
    char           *dimlist;	/* Dimension list (C order) */

    /* Allocate space for C order dimension list */
    /* ----------------------------------------- */
    dimlist = (char *) calloc(strlen(fortdimlist) + 1, 1);
    if(dimlist == NULL)
    {
	HEpush(DFE_NOSPACE,"SWwrdmeta", __FILE__, __LINE__);
	return(-1);
    }

    /* Reverse entries in dimension list (FORTRAN -> C) */
    /* ------------------------------------------------ */
    status = EHrevflds(fortdimlist, dimlist);

    /* Call Write Metadata routine */
    /* --------------------------- */
    status = SWwritedatameta(swathID, fieldname, dimlist, numbertype);

    free(dimlist);
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwrrdattr                                                       |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  attrname       char                attribute name                          |
|  numbertype     int32               attribute HDF numbertype                |
|  count          int32               Number of attribute elements            |
|  wrcode         char                Read/Write Code "w/r"                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf                                                                     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Oct 96   Joel Gales    Get Attribute Vgroup ID from external array         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwrrdattr(int32 swathID, const char *attrname, int32 numbertype, int32 count,
	   const char *wrcode, VOIDP datbuf)

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           attrVgrpID;	/* Swath attribute ID */
    int32           dum;	/* dummy variable */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    /* Check Swath id */
    status = SWchkswid(swathID, "SWwrrdattr", &fid, &dum, &dum);

    if (status == 0)
    {
	/* Get attribute Vgroup ID and call EHattr to perform I/O */
	/* ------------------------------------------------------ */
	attrVgrpID = SWXSwath[swathID % idOffset].VIDTable[2];
	status = EHattr(fid, attrVgrpID, attrname, numbertype, count,
			wrcode, datbuf);
    }
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwriteattr                                                      |
|                                                                             |
|  DESCRIPTION: Writes/updates attribute in a swath.                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  attrname       char                attribute name                          |
|  numbertype     int32               attribute HDF numbertype                |
|  count          int32               Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwriteattr(int32 swathID, const char *attrname, int32 numbertype, int32 count,
	    VOIDP datbuf)
{
    intn            status = 0;	/* routine return status variable */

    /* Call SWwrrdattr routine to write attribute */
    /* ------------------------------------------ */
    status = SWwrrdattr(swathID, attrname, numbertype, count, "w", datbuf);

    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWreadattr                                                       |
|                                                                             |
|  DESCRIPTION: Reads attribute from a swath.                                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWreadattr(int32 swathID, const char *attrname, VOIDP datbuf)
{
    intn            status = 0;	/* routine return status variable */
    int32           dum = 0;	/* dummy variable */

    /* Call SWwrrdattr routine to read attribute */
    /* ----------------------------------------- */
    status = SWwrrdattr(swathID, attrname, dum, dum, "r", datbuf);

    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWattrinfo                                                       |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  numbertype     int32               attribute HDF numbertype                |
|  count          int32               Number of attribute elements            |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Oct 96   Joel Gales    Get Attribute Vgroup ID from external array         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWattrinfo(int32 swathID, const char *attrname, int32 * numbertype, int32 * count)
{
    intn            status = 0;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           attrVgrpID;	/* Swath attribute ID */
    int32           dum;	/* dummy variable */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWattrinfo", &fid, &dum, &dum);

    if (status == 0)
    {
	/* Get attribute Vgroup ID and call EHattrinfo */
	/* ------------------------------------------- */
	attrVgrpID = SWXSwath[swathID % idOffset].VIDTable[2];

	status = EHattrinfo(fid, attrVgrpID, attrname, numbertype,
			    count);
    }
    return (status);
}






/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqattrs                                                       |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          int32               Number of attributes in swath struct    |
|                                                                             |
|  INPUTS:                                                                    |
|  swath ID       int32               swath structure ID                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  attrnames      char                Attribute names in swath struct         |
|                                     (Comma-separated list)                  |
|  strbufsize     int32               Attributes name list string length      |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Oct 96   Joel Gales    Initialize nattr                                    |
|  Oct 96   Joel Gales    Get Attribute Vgroup ID from external array         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqattrs(int32 swathID, char *attrnames, int32 * strbufsize)
{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           attrVgrpID;	/* Swath attribute ID */
    int32           dum;	/* dummy variable */
    int32           nattr = 0;	/* Number of attributes */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */


    /* Check Swath id */
    status = SWchkswid(swathID, "SWinqattrs", &fid, &dum, &dum);

    if (status == 0)
    {
	/* Get attribute Vgroup ID and call EHattrcat */
	/* ------------------------------------------ */
	attrVgrpID = SWXSwath[swathID % idOffset].VIDTable[2];

	nattr = EHattrcat(fid, attrVgrpID, attrnames, strbufsize);
    }

    return (nattr);
}

#define REMQUOTE \
\
memmove(utlstr, utlstr + 1, strlen(utlstr) - 2); \
utlstr[(int32)strlen(utlstr) - 2] = 0;


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqdims                                                        |
|                                                                             |
|  DESCRIPTION: Returns dimension names and values defined in swath structure |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nDim           int32               Number of defined dimensions            |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimnames       char                Dimension names (comma-separated)       |
|  dims           int32               Dimension values                        |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Feb 97   Joel Gales    Set nDim to -1 if status = -1                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqdims(int32 swathID, char *dimnames, int32 dims[])

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           size;	/* Dimension size */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           nDim = 0;	/* Number of dimensions */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;     /* Utility string */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWinqdims", __FILE__, __LINE__);
	return(-1);
    }

    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWinqdims", &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* If dimension names or sizes are desired ... */
	/* ------------------------------------------- */
	if (dimnames != NULL || dims != NULL)
	{
	    /* Get swath name */
	    Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	    /* Get pointers to "Dimension" section within SM */
	    metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					   "Dimension", metaptrs);
	    if(metabuf == NULL)
	    {
		free(utlstr);
		return(-1);
	    }
	    /* If dimension names are desired then "clear" name buffer */
	    if (dimnames != NULL)
	    {
		dimnames[0] = 0;
	    }


	    /* Begin loop through dimension entries in metadata */
	    /* ------------------------------------------------ */
	    while (1)
	    {
		/* Search for OBJECT string */
		metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");

		/* If found within "Dimension" metadata section ... */
		if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
		{
		    /* Get Dimension Name (if desired) */
		    if (dimnames != NULL)
		    {
			/* Check 1st for old meta data then new */
			/* ------------------------------------ */
			EHgetmetavalue(metaptrs, "OBJECT", utlstr);

			/*
			 * If OBJECT value begins with double quote then old
			 * metadata, dimension name is OBJECT value.
			 * Otherwise search for "DimensionName" string
			 */
			if (utlstr[0] != '"')
			{
			    metaptrs[0] =
				strstr(metaptrs[0], "\t\t\t\tDimensionName=");
			    EHgetmetavalue(metaptrs, "DimensionName", utlstr);
			}

			/* Strip off double quotes */
			/* ----------------------- */
			REMQUOTE

			/* If not first name then add comma delimiter */
			    if (nDim > 0)
			{
			    strcat(dimnames, ",");
			}
			/* Add dimension name to dimension list */
			strcat(dimnames, utlstr);
		    }

		    /* Get Dimension Size (if desired) */
		    if (dims != NULL)
		    {
		      int32 strlen_utlstr;
		      EHgetmetavalue(metaptrs, "Size", utlstr);
		      /* If the value in utlstr has leading and trailing quotes, get rid
			 of them before applying atoi, otherwise atoi will return zero */

		      strlen_utlstr = (int32)strlen(utlstr);
		      if(utlstr[0] == '"' && utlstr[strlen_utlstr-1] == '"')
			{
			  memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
			  utlstr[(int32)strlen(utlstr) - 2] = 0;
			  size = (int32)atoi(utlstr);
			}
		      else
			{
			  size = (int32)atoi(utlstr);
			}
		      dims[nDim] = size;
		    }
		    /* Increment number of dimensions */
		    nDim++;
		}
		else
		    /* No more dimensions found */
		{
		    break;
		}
	    }
	    free(metabuf);
	}
    }


    /* Set nDim to -1 if error status exists */
    /* ------------------------------------- */
    if (status == -1)
    {
	nDim = -1;
    }
    free(utlstr);

    return (nDim);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqmaps                                                        |
|                                                                             |
|  DESCRIPTION: Returns dimension mappings and offsets and increments         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nMap           int32               Number of dimension mappings            |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimmaps        char                dimension mappings (comma-separated)    |
|  offset         int32               array of offsets                        |
|  increment      int32               array of increments                     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Feb 97   Joel Gales    Set nMap to -1 if status = -1                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqmaps(int32 swathID, char *dimmaps, int32 offset[], int32 increment[])

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           off;	/* Mapping Offset */
    int32           incr;	/* Mapping Increment */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           nMap = 0;	/* Number of mappings */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;     /* Utility string */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWinqmaps", __FILE__, __LINE__);
	return(-1);
    }

    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWinqmaps", &fid, &sdInterfaceID, &swVgrpID);
    if (status == 0)
    {
	/* If mapping names or offsets or increments desired ... */
	/* ----------------------------------------------------- */
	if (dimmaps != NULL || offset != NULL || increment != NULL)
	{

	    /* Get swath name */
	    Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	    /* Get pointers to "DimensionMap" section within SM */
	    metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					   "DimensionMap", metaptrs);
	    if(metabuf == NULL)
	    {
		free(utlstr);
		return(-1);
	    }
	    /* If mapping names are desired then "clear" name buffer */
	    if (dimmaps != NULL)
	    {
		dimmaps[0] = 0;
	    }

	    /* Begin loop through mapping entries in metadata */
	    /* ---------------------------------------------- */
	    while (1)
	    {
		/* Search for OBJECT string */
		metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");

		/* If found within "DimensionMap" metadata section ... */
		if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
		{
		    /* Get Geo & Data Dimensions (if desired) */
		    if (dimmaps != NULL)
		    {
			/* Get Geo Dim, remove quotes, add "/" */
			EHgetmetavalue(metaptrs, "GeoDimension", utlstr);
			REMQUOTE
			    strcat(utlstr, "/");

			/* if not first map then add comma delimiter */
			if (nMap > 0)
			{
			    strcat(dimmaps, ",");
			}

			/* Add to map list */
			strcat(dimmaps, utlstr);

			/* Get Data Dim, remove quotes */
			EHgetmetavalue(metaptrs, "DataDimension", utlstr);
			REMQUOTE

			/* Add to map list */
			    strcat(dimmaps, utlstr);
		    }

		    /* Get Offset (if desired) */
		    if (offset != NULL)
		    {
			EHgetmetavalue(metaptrs, "Offset", utlstr);
			off = atoi(utlstr);
			offset[nMap] = off;
		    }

		    /* Get Increment (if desired) */
		    if (increment != NULL)
		    {
			EHgetmetavalue(metaptrs, "Increment", utlstr);
			incr = atoi(utlstr);
			increment[nMap] = incr;
		    }

		    /* Increment number of maps */
		    nMap++;
		}
		else
		    /* No more mappings found */
		{
		    break;
		}
	    }
	    free(metabuf);
	}
    }


    /* Set nMap to -1 if error status exists */
    /* ------------------------------------- */
    if (status == -1)
    {
	nMap = -1;
    }
    free(utlstr);

    return (nMap);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqidxmaps                                                     |
|                                                                             |
|  DESCRIPTION: Returns indexed mappings and index sizes                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nMap           int32               Number of indexed dimension mappings    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  idxmaps        char                indexed dimension mappings              |
|                                     (comma-separated)                       |
|  idxsizes       int32               Number of elements in each mapping      |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Feb 97   Joel Gales    Set nMap to -1 if status = -1                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqidxmaps(int32 swathID, char *idxmaps, int32 idxsizes[])

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           nMap = 0;	/* Number of mappings */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;     /* Utility string */
    char           *slash;	/* Pointer to slash */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWinqidxmaps", __FILE__, __LINE__);
	return(-1);
    }
    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWinqidxmaps", &fid,
		       &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* If mapping names or index sizes desired ... */
	/* ------------------------------------------- */
	if (idxmaps != NULL || idxsizes != NULL)
	{
	    /* Get swath name */
	    Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	    /* Get pointers to "IndexDimensionMap" section within SM */
	    metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					   "IndexDimensionMap", metaptrs);
	    if(metabuf == NULL)
	    {
		free(utlstr);
		return(-1);
	    }
	    /* If mapping names are desired then "clear" name buffer */
	    if (idxmaps != NULL)
	    {
		idxmaps[0] = 0;
	    }

	    /* Begin loop through mapping entries in metadata */
	    /* ---------------------------------------------- */
	    while (1)
	    {
		/* Search for OBJECT string */
		metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");

		/* If found within "IndexDimensionMap" metadata section ... */
		if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
		{
		    /* Get Geo & Data Dimensions and # of indices */
		    if (idxmaps != NULL)
		    {
			/* Get Geo Dim, remove quotes, add "/" */
			EHgetmetavalue(metaptrs, "GeoDimension", utlstr);
			REMQUOTE
			    strcat(utlstr, "/");

			/* if not first map then add comma delimiter */
			if (nMap > 0)
			{
			    strcat(idxmaps, ",");
			}

			/* Add to map list */
			strcat(idxmaps, utlstr);


			/* Get Index size (if desired) */
			if (idxsizes != NULL)
			{
			    /* Parse off geo dimension and find its size */
			    slash = strchr(utlstr, '/');
			    *slash = 0;
			    idxsizes[nMap] = SWdiminfo(swathID, utlstr);
			}


			/* Get Data Dim, remove quotes */
			EHgetmetavalue(metaptrs, "DataDimension", utlstr);
			REMQUOTE

			/* Add to map list */
			    strcat(idxmaps, utlstr);
		    }

		    /* Increment number of maps */
		    nMap++;
		}
		else
		    /* No more mappings found */
		{
		    break;
		}
	    }
	    free(metabuf);
	}
    }


    /* Set nMap to -1 if error status exists */
    /* ------------------------------------- */
    if (status == -1)
    {
	nMap = -1;
    }
    free(utlstr);

    return (nMap);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqfields                                                      |
|                                                                             |
|  DESCRIPTION: Returns fieldnames, ranks and numbertypes defined in swath.   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nFld           int32               Number of (geo/data) fields in swath    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldtype      char                field type (geo or data)                |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fieldlist      char                Field names (comma-separated)           |
|  rank           int32               Array of ranks                          |
|  numbertype     int32               Array of HDF number types               |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Feb 97   Joel Gales    Set nFld to -1 if status = -1                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqfields(int32 swathID, const char *fieldtype, char *fieldlist, int32 rank[],
	    int32 numbertype[])

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           nFld = 0;	/* Number of mappings */
    int32           slen[8];	/* String length array */
    int32           ntype;	/* Data Type */

    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;	/* Utility string */
    char           *utlstr2;	/* Utility string 2 */
    char           *ptr[8];	/* String pointer array */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWinqfields", __FILE__, __LINE__);
	return(-1);
    }

    utlstr2 = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr2 == NULL)
    {
	HEpush(DFE_NOSPACE,"SWinqfields", __FILE__, __LINE__);
	free(utlstr);
	return(-1);
    }

    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWinqfields",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* If field names, ranks,  or number types desired ... */
	/* --------------------------------------------------- */
	if (fieldlist != NULL || rank != NULL || numbertype != NULL)
	{
	    /* Get swath name */
	    Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	    /* Get pointers to "GeoField" or "DataField" section within SM */
	    if (strcmp(fieldtype, "Geolocation Fields") == 0)
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "GeoField", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    free(utlstr2);
		    return(-1);
		}
		strcpy(utlstr2, "GeoFieldName");
	    }
	    else
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "DataField", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    free(utlstr2);
		    return(-1);
		}
		strcpy(utlstr2, "DataFieldName");
	    }


	    /* If field names are desired then "clear" name buffer */
	    if (fieldlist != NULL)
	    {
		fieldlist[0] = 0;
	    }


	    /* Begin loop through mapping entries in metadata */
	    /* ---------------------------------------------- */
	    while (1)
	    {
		/* Search for OBJECT string */
		metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");

		/* If found within "Geo" or "Data" Field metadata section .. */
		if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
		{
		    /* Get Fieldnames (if desired) */
		    if (fieldlist != NULL)
		    {
			/* Check 1st for old meta data then new */
			/* ------------------------------------ */
			EHgetmetavalue(metaptrs, "OBJECT", utlstr);

			/*
			 * If OBJECT value begins with double quote then old
			 * metadata, field name is OBJECT value. Otherwise
			 * search for "GeoFieldName" or "DataFieldName"
			 * string
			 */

			if (utlstr[0] != '"')
			{
			    strcpy(utlstr, "\t\t\t\t");
			    strcat(utlstr, utlstr2);
			    strcat(utlstr, "=");
			    metaptrs[0] = strstr(metaptrs[0], utlstr);
			    EHgetmetavalue(metaptrs, utlstr2, utlstr);
			}

			/* Strip off double quotes */
			/* ----------------------- */
			REMQUOTE


			/* Add to fieldlist */
			/* ---------------- */
			    if (nFld > 0)
			{
			    strcat(fieldlist, ",");
			}
			strcat(fieldlist, utlstr);

		    }
		    /* Get Numbertype */
		    if (numbertype != NULL)
		    {
			EHgetmetavalue(metaptrs, "DataType", utlstr);

			if (strcmp(utlstr, "DFNT_UCHAR8") == 0 ||
			    strcmp(utlstr, "DFNT_UCHAR") == 0)
			    ntype = 3;
			else if (strcmp(utlstr, "DFNT_CHAR8") == 0 ||
				 strcmp(utlstr, "DFNT_CHAR") == 0)
			    ntype = 4;
			else if (strcmp(utlstr, "DFNT_FLOAT32") == 0 ||
				 strcmp(utlstr, "DFNT_FLOAT") == 0)
			    ntype = 5;
			else if (strcmp(utlstr, "DFNT_FLOAT64") == 0)
			    ntype = 6;
			else if (strcmp(utlstr, "DFNT_INT8") == 0)
			    ntype = 20;
			else if (strcmp(utlstr, "DFNT_UINT8") == 0)
			    ntype = 21;
			else if (strcmp(utlstr, "DFNT_INT16") == 0)
			    ntype = 22;
			else if (strcmp(utlstr, "DFNT_UINT16") == 0)
			    ntype = 23;
			else if (strcmp(utlstr, "DFNT_INT32") == 0)
			    ntype = 24;
			else if (strcmp(utlstr, "DFNT_UINT32") == 0)
			    ntype = 25;

			numbertype[nFld] = ntype;
		    }
		    /*
		     * Get Rank (if desired) by counting # of dimensions in
		     * "DimList" string
		     */
		    if (rank != NULL)
		    {
			EHgetmetavalue(metaptrs, "DimList", utlstr);
			rank[nFld] = EHparsestr(utlstr, ',', ptr, slen);
		    }
		    /* Increment number of fields */
		    nFld++;
		}
		else
		    /* No more fields found */
		{
		    break;
		}
	    }
	    free(metabuf);
	}
    }

    /* Set nFld to -1 if error status exists */
    /* ------------------------------------- */
    if (status == -1)
    {
	nFld = -1;
    }

    free(utlstr);
    free(utlstr2);

    return (nFld);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqgeofields                                                   |
|                                                                             |
|  DESCRIPTION: Inquires about geo fields in swath                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nflds          int32               Number of geo fields in swath           |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fieldlist      char                Field names (comma-separated)           |
|  rank           int32               Array of ranks                          |
|  numbertype     int32               Array of HDF number types               |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqgeofields(int32 swathID, char *fieldlist, int32 rank[],
	       int32 numbertype[])
{

    int32           nflds;	/* Number of Geolocation fields */

    /* Call "SWinqfields" routine */
    /* -------------------------- */
    nflds = SWinqfields(swathID, "Geolocation Fields", fieldlist, rank,
			numbertype);

    return (nflds);

}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqdatafields                                                  |
|                                                                             |
|  DESCRIPTION: Inquires about data fields in swath                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nflds          int32               Number of data fields in swath          |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fieldlist      char                Field names (comma-separated)           |
|  rank           int32               Array of ranks                          |
|  numbertype     int32               Array of HDF number types               |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqdatafields(int32 swathID, char *fieldlist, int32 rank[],
		int32 numbertype[])
{

    int32           nflds;	/* Number of Data fields */

    /* Call "SWinqfields" routine */
    /* -------------------------- */
    nflds = SWinqfields(swathID, "Data Fields", fieldlist, rank,
			numbertype);

    return (nflds);

}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWnentries                                                       |
|                                                                             |
|  DESCRIPTION: Returns number of entries and string buffer size              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nEntries       int32               Number of entries                       |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  entrycode      int32               Entry code                              |
|	                              HDFE_NENTDIM  (0)                       |
|	                              HDFE_NENTMAP  (1)                       |
|	                              HDFE_NENTIMAP (2)                       |
|	                              HDFE_NENTGFLD (3)                       |
|	                              HDFE_NENTDFLD (4)                       |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     int32               Length of comma-separated list          |
|                                     (Does not include null-terminator       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|  Feb 97   Joel Gales    Set nEntries to -1 if status = -1                   |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWnentries(int32 swathID, int32 entrycode, int32 * strbufsize)

{
    intn            status;	/* routine return status variable */
    intn            i;		/* Loop index */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           nEntries = 0;	/* Number of entries */
    int32           metaflag;	/* Old (0), New (1) metadata flag) */
    int32           nVal = 0;	/* Number of strings to search for */

    char           *metabuf = NULL;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;	/* Utility string */
    char            valName[2][32];	/* Strings to search for */

    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWnemtries", __FILE__, __LINE__);
	return(-1);
    }
    /* Check for valid swath id */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWnentries", &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Get swath name */
	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	/* Zero out string buffer size */
	*strbufsize = 0;


	/*
	 * Get pointer to relevant section within SM and Get names of
	 * metadata strings to inquire about
	 */
	switch (entrycode)
	{
	case HDFE_NENTDIM:
	    /* Dimensions */
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "Dimension", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    return(-1);
		}
		nVal = 1;
		strcpy(&valName[0][0], "DimensionName");
	    }
	    break;

	case HDFE_NENTMAP:
	    /* Dimension Maps */
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "DimensionMap", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    return(-1);
		}
		nVal = 2;
		strcpy(&valName[0][0], "GeoDimension");
		strcpy(&valName[1][0], "DataDimension");
	    }
	    break;

	case HDFE_NENTIMAP:
	    /* Indexed Dimension Maps */
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					     "IndexDimensionMap", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    return(-1);
		}
		nVal = 2;
		strcpy(&valName[0][0], "GeoDimension");
		strcpy(&valName[1][0], "DataDimension");
	    }
	    break;

	case HDFE_NENTGFLD:
	    /* Geolocation Fields */
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "GeoField", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    return(-1);
		}
		nVal = 1;
		strcpy(&valName[0][0], "GeoFieldName");
	    }
	    break;

	case HDFE_NENTDFLD:
	    /* Data Fields */
	    {
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "DataField", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    return(-1);
		}
		nVal = 1;
		strcpy(&valName[0][0], "DataFieldName");
	    }
	    break;
	}


	/*
	 * Check for presence of 'GROUP="' string If found then old metadata,
	 * search on OBJECT string
	 */
	metaflag = (strstr(metabuf, "GROUP=\"") == NULL) ? 1 : 0;
	if (metaflag == 0)
	{
	    nVal = 1;
	    strcpy(&valName[0][0], "\t\tOBJECT");
	}


	/* Begin loop through entries in metadata */
	/* -------------------------------------- */
	while (1)
	{
	    /* Search for first string */
	    strcpy(utlstr, &valName[0][0]);
	    strcat(utlstr, "=");
	    metaptrs[0] = strstr(metaptrs[0], utlstr);

	    /* If found within relevant metadata section ... */
	    if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	    {
		for (i = 0; i < nVal; i++)
		{
		    /*
		     * Get all string values Don't count quotes
		     */
		    EHgetmetavalue(metaptrs, &valName[i][0], utlstr);
		    *strbufsize += (int32)strlen(utlstr) - 2;
		}
		/* Increment number of entries */
		nEntries++;

		/* Go to end of OBJECT */
		metaptrs[0] = strstr(metaptrs[0], "END_OBJECT");
	    }
	    else
		/* No more entries found */
	    {
		break;
	    }
	}
	free(metabuf);


	/* Count comma separators & slashes (if mappings) */
	/* ---------------------------------------------- */
	if (nEntries > 0)
	{
	    *strbufsize += nEntries - 1;
	    *strbufsize += (nVal - 1) * nEntries;
	}
    }


    /* Set nEntries to -1 if error status exists */
    /* ----------------------------------------- */
    if (status == -1)
    {
	nEntries = -1;
    }

    free(utlstr);

    return (nEntries);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWinqswath                                                       |
|                                                                             |
|  DESCRIPTION: Returns number and names of swath structures in file          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nSwath         int32               Number of swath structures in file      |
|                                                                             |
|  INPUTS:                                                                    |
|  filename       char                HDF-EOS filename                        |
|                                                                             |
|  OUTPUTS:                                                                   |
|  swathlist      char                List of swath names (comma-separated)   |
|  strbufsize     int32               Length of swathlist                     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWinqswath(const char *filename, char *swathlist, int32 * strbufsize)
{
    int32           nSwath;	/* Number of swath structures in file */

    /* Call "EHinquire" routine */
    /* ------------------------ */
    nSwath = EHinquire(filename, "SWATH", swathlist, strbufsize);

    return (nSwath);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SW1dfldsrch                                                      |
|                                                                             |
|  DESCRIPTION: Retrieves information about a 1D field                        |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            int32               HDF-EOS file ID                         |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|  l_access         char              Access code (w/r)                       |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  vgidout        int32               Field (geo/data) vgroup ID              |
|  vdataIDout     int32               Field Vdata ID                          |
|  fldtype        int32               Field type                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SW1dfldsrch(int32 fid, int32 swathID, const char *fieldname, const char *l_access,
	    int32 * vgidout, int32 * vdataIDout, int32 * fldtype)

{
    intn            status = 0;	/* routine return status variable */

    int32           sID;	/* SwathID - offset */
    int32           vgid;	/* Swath Geo or Data Vgroup ID */
    int32           vdataID;	/* 1d field vdata */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */


    /* Compute "reduced" swath ID */
    /* -------------------------- */
    sID = swathID % idOffset;


    /* Get Geolocation Vgroup id and 1D field name Vdata id */
    /* ---------------------------------------------------- */
    vgid = SWXSwath[sID].VIDTable[0];
    vdataID = EHgetid(fid, vgid, fieldname, 1, l_access);
    *fldtype = 0;


    /*
     * If name not found in Geolocation Vgroup then detach Geolocation Vgroup
     * and search in Data Vgroup
     */
    if (vdataID == -1)
    {
	vgid = SWXSwath[sID].VIDTable[1];;
	vdataID = EHgetid(fid, vgid, fieldname, 1, l_access);
	*fldtype = 1;

	/* If field also not found in Data Vgroup then set error status */
	/* ------------------------------------------------------------ */
	if (vdataID == -1)
	{
	    status = -1;
	    vgid = -1;
	    vdataID = -1;
	}
    }
    *vgidout = vgid;
    *vdataIDout = vdataID;

    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWSDfldsrch                                                      |
|                                                                             |
|  DESCRIPTION: Retrieves information SDS field                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  sdInterfaceID  int32               SD interface ID                         |
|  fieldname      char                field name                              |
|  l_access         char              Access code (w/r)                       |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  sdid           int32               SD element ID                           |
|  rankSDS        int32               Rank of SDS                             |
|  rankFld        int32               True rank of field (merging)            |
|  offset         int32               Offset of field within merged field     |
|  dims           int32               Dimensions of field                     |
|  solo           int32               Solo field flag                         |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Make metadata ODL compliant                         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWSDfldsrch(int32 swathID, int32 sdInterfaceID, const char *fieldname, int32 * sdid,
	    int32 * rankSDS, int32 * rankFld, int32 * offset, int32 dims[],
	    int32 * solo)
{
    intn            i;		/* Loop index */
    intn            status = -1;/* routine return status variable */

    int32           sID;	/* SwathID - offset */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           dum;	/* Dummy variable */
    int32           dums[128];	/* Dummy array */
    int32           attrIndex;	/* Attribute index */

    char            name[2048];	/* Merged-Field Names */
    char            swathname[80];	/* Swath Name */
    char           *utlstr;	/* Utility string */
    char           *metabuf;	/* Pointer to structural metadata (SM) */
    char           *metaptrs[2];/* Pointers to begin and end of SM section */
    char           *oldmetaptr;	/* Pointer within SM section */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWSDfldsrch", __FILE__, __LINE__);
	return(-1);
    }
    /* Set solo flag to 0 (no) */
    /* ----------------------- */
    *solo = 0;


    /* Compute "reduced" swath ID */
    /* -------------------------- */
    sID = swathID % idOffset;


    /* Loop through all SDSs in swath */
    /* ------------------------------ */
    for (i = 0; i < SWXSwath[sID].nSDS; i++)
    {
	/* If active SDS ... */
	/* ----------------- */
	if (SWXSwath[sID].sdsID[i] != 0)
	{
	    /* Get SDS ID, name, rankSDS, and dimensions */
	    /* ----------------------------------------- */
	    *sdid = SWXSwath[sID].sdsID[i];
	    SDgetinfo(*sdid, name, rankSDS, dims, &dum, &dum);
	    *rankFld = *rankSDS;

	    /* If merged field ... */
	    /* ------------------- */
	    if (strstr(name, "MRGFLD_") == &name[0])
	    {
		/* Get swath name */
		/* -------------- */
		Vgetname(SWXSwath[sID].IDTable, swathname);


		/* Get pointers to "MergedFields" section within SM */
		/* ------------------------------------------------ */
		metabuf = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
					       "MergedFields", metaptrs);
		if(metabuf == NULL)
		{
		    free(utlstr);
		    return(-1);
		}

		/* Store metaptr in order to recover */
		/* --------------------------------- */
		oldmetaptr = metaptrs[0];


		/* Search for Merged field name */
		/* ---------------------------- */
		snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "MergedFieldName=\"",
			name, "\"\n");
		metaptrs[0] = strstr(metaptrs[0], utlstr);


		/* If not found check for old metadata */
		/* ----------------------------------- */
		if (metaptrs[0] == NULL)
		{
		    snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "OBJECT=\"", name, "\"\n");
		    metaptrs[0] = strstr(oldmetaptr, utlstr);
		}


		/* Get field list and strip off leading and trailing quotes */
		EHgetmetavalue(metaptrs, "FieldList", name);  /* not return status --xhua */
		memmove(name, name + 1, strlen(name) - 2);
		name[(int32)strlen(name) - 2] = 0;

		/* Search for desired field within merged field list */
		snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"");
		dum = EHstrwithin(utlstr, name, ',');

		free(metabuf);
	    }
	    else
	    {
		/* If solo (unmerged) check if SDS name matches fieldname */
		/* ------------------------------------------------------ */
		dum = EHstrwithin(fieldname, name, ',');
		if (dum != -1)
		{
		    *solo = 1;
		    *offset = 0;
		}
	    }


	    /* If field found ... */
	    /* ------------------ */
	    if (dum != -1)
	    {
		status = 0;

		/* If merged field ... */
		/* ------------------- */
		if (*solo == 0)
		{
		    /* Get "Field Offsets" SDS attribute index */
		    /* --------------------------------------- */
		    attrIndex = SDfindattr(*sdid, "Field Offsets");

		    /*
		     * If attribute exists then get offset of desired field
		     * within merged field
		     */
		    if (attrIndex != -1)
		    {
			SDreadattr(*sdid, attrIndex, (VOIDP) dums);
			*offset = dums[dum];
		    }


		    /* Get "Field Dims" SDS attribute index */
		    /* ------------------------------------ */
		    attrIndex = SDfindattr(*sdid, "Field Dims");

		    /*
		     * If attribute exists then get 0th dimension of desired
		     * field within merged field
		     */
		    if (attrIndex != -1)
		    {
			SDreadattr(*sdid, attrIndex, (VOIDP) dums);
			dims[0] = dums[dum];

			/* If this dimension = 1 then field is really 2 dim */
			/* ------------------------------------------------ */
			if (dums[dum] == 1)
			{
			    *rankFld = 2;
			}
		    }
		}


		/* Break out of SDS loop */
		/* --------------------- */
		break;
	    }			/* End of found field section */
	}
	else
	{
	    /* First non-active SDS signifies no more, break out of SDS loop */
	    /* ------------------------------------------------------------- */
	    break;
	}
    }

    free(utlstr);

    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwrrdfield                                                      |
|                                                                             |
|  DESCRIPTION: Writes/Reads fields                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  code           char                Write/Read code (w/r)                   |
|  start          int32               start array                             |
|  stride         int32               stride array                            |
|  edge           int32               edge array                              |
|  datbuf         void                data buffer for read                    |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                data buffer for write                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Feb 97   Joel Gales    Stride = 1 HDF compression workaround               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwrrdfield(int32 swathID, const char *fieldname, const char *code,
	    int32 start[], int32 stride[], int32 edge[], VOIDP datbuf)

{
    intn            i;		/* Loop index */
    intn            status = 0;	/* routine return status variable */
    intn            status1 = 0;	/* routine return status variable */
    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           vgid;	/* Swath Geo or Data Vgroup ID */
    int32           sdid;	/* SDS ID */
    int32           dum;	/* Dummy variable */
    int32           rankSDS;	/* Rank of SDS */
    int32           rankFld;	/* Rank of field */

    int32           vdataID;	/* 1d field vdata */
    int32           recsize;	/* Vdata record size */
    int32           fldsize;	/* Field size */
    int32           nrec;	/* Number of records in Vdata */

    int32           offset[8];	/* I/O offset (start) */
    int32           incr[8];	/* I/O increment (stride) */
    int32           count[8];	/* I/O count (edge) */
    int32           dims[8];	/* Field/SDS dimensions */
    int32           mrgOffset;	/* Merged field offset */
    int32           nflds;	/* Number of fields in Vdata */
    int32           strideOne;	/* Strides = 1 flag */

    uint8          *buf;	/* I/O (transfer) buffer */
    uint8          *fillbuf;	/* Fill value buffer */

    char            attrName[80];	/* Name of fill value attribute */
    char           *ptr[64];	/* String pointer array */
    char            fieldlist[256];	/* Vdata field list */
    int32           SZ_unsuppoted_flag = 0;
    int32           compcode;
    int32           attnumbertype, attcount;

    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWwrrdfield", &fid, &sdInterfaceID, &dum);

    if (status == 0)
    {

	/* Check whether fieldname is in SDS (multi-dim field) */
	/* --------------------------------------------------- */
	status = SWSDfldsrch(swathID, sdInterfaceID, fieldname, &sdid,
			     &rankSDS, &rankFld, &mrgOffset, dims, &dum);

	/* Multi-Dimensional Field Section */
	/* ------------------------------- */
	if (status != -1)
	{
	    /* Set I/O offset Section */
	    /* ---------------------- */

	    /*
	     * If start == NULL (default) set I/O offset of 0th field to
	     * offset within merged field (if any) and the rest to 0
	     */
	    if (start == NULL)
	    {
		for (i = 0; i < rankSDS; i++)
		{
		    offset[i] = 0;
		}
		offset[0] = mrgOffset;
	    }
	    else
	    {
		/*
		 * ... otherwise set I/O offset to user values, adjusting the
		 * 0th field with the merged field offset (if any)
		 */
		if (rankFld == rankSDS)
		{
		    for (i = 0; i < rankSDS; i++)
		    {
			offset[i] = start[i];
		    }
		    offset[0] += mrgOffset;
		}
		else
		{
		    /*
		     * If field really 2-dim merged in 3-dim field then set
		     * 0th field offset to merge offset and then next two to
		     * the user values
		     */
		    for (i = 0; i < rankFld; i++)
		    {
			offset[i + 1] = start[i];
		    }
		    offset[0] = mrgOffset;
		}
	    }



	    /* Set I/O stride Section */
	    /* ---------------------- */

	    /*
	     * If stride == NULL (default) set I/O stride to 1
	     */
	    if (stride == NULL)
	    {
		for (i = 0; i < rankSDS; i++)
		{
		    incr[i] = 1;
		}
	    }
	    else
	    {
		/*
		 * ... otherwise set I/O stride to user values
		 */
		if (rankFld == rankSDS)
		{
		    for (i = 0; i < rankSDS; i++)
		    {
			incr[i] = stride[i];
		    }
		}
		else
		{
		    /*
		     * If field really 2-dim merged in 3-dim field then set
		     * 0th field stride to 1 and then next two to the user
		     * values.
		     */
		    for (i = 0; i < rankFld; i++)
		    {
			incr[i + 1] = stride[i];
		    }
		    incr[0] = 1;
		}
	    }



	    /* Set I/O count Section */
	    /* --------------------- */

	    /*
	     * If edge == NULL (default) set I/O count to number of remaining
	     * entries (dims - start) / increment.  Note that 0th field
	     * offset corrected for merged field offset (if any).
	     */
	    if (edge == NULL)
	    {
		for (i = 1; i < rankSDS; i++)
		{
		    count[i] = (dims[i] - offset[i]) / incr[i];
		}
		count[0] = (dims[0] - (offset[0] - mrgOffset)) / incr[0];
	    }
	    else
	    {
		/*
		 * ... otherwise set I/O count to user values
		 */
		if (rankFld == rankSDS)
		{
		    for (i = 0; i < rankSDS; i++)
		    {
			count[i] = edge[i];
		    }
		}
		else
		{
		    /*
		     * If field really 2-dim merged in 3-dim field then set
		     * 0th field count to 1 and then next two to the user
		     * values.
		     */
		    for (i = 0; i < rankFld; i++)
		    {
			count[i + 1] = edge[i];
		    }
		    count[0] = 1;
		}
	    }

	    /* Perform I/O with relevant HDF I/O routine */
	    /* ----------------------------------------- */
	    if (strcmp(code, "w") == 0)
	    {
		/* Set strideOne to true (1) */
		/* ------------------------- */
		strideOne = 1;


		/* If incr[i] != 1 set strideOne to false (0) */
		/* ------------------------------------------ */
		for (i = 0; i < rankSDS; i++)
		{
		    if (incr[i] != 1)
		    {
			strideOne = 0;
			break;
		    }
		}


		/*
		 * If strideOne is true use NULL parameter for stride. This
		 * is a work-around to HDF compression problem
		 */
		if (strideOne == 1)
		{
		    status = SDwritedata(sdid, offset, NULL, count,
					 (VOIDP) datbuf);
		}
		else
		{
		    status = SDwritedata(sdid, offset, incr, count,
					 (VOIDP) datbuf);
		}

		/* For SZIP compression currently one cannot do partial
		   compression. So offset and count cannot be anything
		   other than the min and max of these numbers respectively.
		   So if SDwritedata fails it may be because of this. Lets
		   inform the user if this is the case */
		if ( status != 0 )
		  {
		    status1 = SWcompinfo(swathID, fieldname, &compcode, NULL);
		    if (compcode == HDFE_COMP_SZIP)
		      {
			SZ_unsuppoted_flag = 0;
			if (rankFld == rankSDS)
			  {
			    for (i = 0; i < rankSDS; i++)
			      {
				if(offset[i] != 0 || count[i] != dims[i])
				  {
				    SZ_unsuppoted_flag = 1;
				    break;
				  }
			      }
			  }
			else
			  {
			    /*
			     * If field really 2-dim merged in 3-dim
			     * field then set 0th field count has been
			     * set to 1 and the next two to the user
			     * values.
			     */
			    for (i = 0; i < rankFld; i++)
			      {
				if(offset[i] != 0 || count[i + 1] != dims[i])
				  {
				    SZ_unsuppoted_flag = 1;
				    break;
				  }
			      }
			  }
			if(SZ_unsuppoted_flag == 1)
			  {
			    HEpush(DFE_GENAPP, "SWwrrdfield", __FILE__, __LINE__);
			    HEreport("Possibly unsupported start and/or edge values for SZIP compression.Partial compression OF SDS is not allowed.\n");
			  }
		      }
		  }
	    }
	    else
	    {
		status = SDreaddata(sdid, offset, incr, count,
				    (VOIDP) datbuf);
	    }
	}			/* End of Multi-Dimensional Field Section */
	else
	{
	    /* One-Dimensional Field Section */
	    /* ----------------------------- */

	    /* Check fieldname within 1d field Vgroups */
	    /* --------------------------------------- */
	    status = SW1dfldsrch(fid, swathID, fieldname, code,
				 &vgid, &vdataID, &dum);

	    if (status != -1)
	    {

		/* Get number of records */
		/* --------------------- */
		nrec = VSelts(vdataID);


		/* Set offset, increment, & count */
		/* ------------------------------ */
		offset[0] = (start == NULL) ? 0 : start[0];
		incr[0] = (stride == NULL) ? 1 : stride[0];
		count[0] = (edge == NULL)
		    ? (nrec - offset[0]) / incr[0]
		    : edge[0];


		/* Write Section */
		/* ------------- */
		if (strcmp(code, "w") == 0)
		{
		    /* Get size of field and setup fill buffer */
		    /* --------------------------------------- */

		    fldsize = EHsizeof(vdataID, fieldname);

		    fillbuf = (uint8 *) calloc(fldsize, 1);

		    if(fillbuf == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWwrrdfield", __FILE__, __LINE__);
			return(-1);
		    }

		    /* Get size of record in Vdata and setup I/O buffer */
		    /* ------------------------------------------------ */
		    VSQueryvsize(vdataID, &recsize);

		    buf = (uint8 *) calloc(recsize, count[0] * incr[0]);
		    if(buf == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWwrrdfield", __FILE__, __LINE__);
			return(-1);
		    }

		    /* Get names and number of fields in each record  */
		    /* ---------------------------------------------- */
		    VSgetfields(vdataID, fieldlist);
		    dum = EHstrwithin(fieldname, fieldlist, ',');
		    nflds = EHparsestr(fieldlist, ',', ptr, NULL);

		    /* Get Merged Field Offset (if any) */
		    /* -------------------------------- */
		    if (nflds > 1)
		    {
			if (dum > 0)
			{
			    *(ptr[dum] - 1) = 0;
			    mrgOffset = VSsizeof(vdataID, fieldlist);
			    *(ptr[dum] - 1) = ',';
			}
			else
			{
			    mrgOffset = 0;
			}

			/* Read records to recover previously written data */
			status = VSsetfields(vdataID, fieldlist);
			status = VSseek(vdataID, offset[0]);
			nrec = VSread(vdataID, buf, 1 + (count[0] - 1) * incr[0],
				      FULL_INTERLACE);
		    }
		    else
		    {
			mrgOffset = 0;
		    }



		    /* Fill buffer with "Fill" value (if any) */
		    /* -------------------------------------- */
		    strcpy(attrName, "_FV_");
		    strcat(attrName, fieldname);

		    status = SWattrinfo(swathID, attrName, &attnumbertype, &attcount);
		      if(status == -1)
			{
			  *fillbuf = 0;
			}
		      else
			{
			  status = SWreadattr(swathID, attrName, fillbuf);
			}

		    if (status == 0)
		    {
			for (i = 0; i < count[0] * incr[0]; i++)
			{
			    memcpy(buf + i * recsize + mrgOffset,
				   fillbuf, fldsize);
			}
		    }

		    /* Write new data into buffer */
		    /* -------------------------- */
		    if (incr[0] == 1 && nflds == 1)
		    {
			memcpy(buf, datbuf, count[0] * recsize);
		    }
		    else
		    {
			for (i = 0; i < count[0]; i++)
			{
			    memcpy(buf + i * recsize * incr[0] + mrgOffset,
				   (uint8 *) datbuf + i * fldsize, fldsize);
			}
		    }

		    /* If append read last record */
		    /* -------------------------- */
		    if (offset[0] == nrec)
		    {
			/* abe added "status =" to next line 8/8/97 */

			status = VSseek(vdataID, offset[0] - 1);
			VSread(vdataID, fillbuf, 1, FULL_INTERLACE);
		    }
		    else
		    {
			status = VSseek(vdataID, offset[0]);
		    }


		    /* Write data into Vdata */
		    /* --------------------- */
		    nrec = VSwrite(vdataID, buf, count[0] * incr[0],
				   FULL_INTERLACE);

		    free(fillbuf);
                    if (status > 0)
                       status = 0;

		}		/* End Write Section */
		else
		{
		    /* Read Section */
		    /* ------------ */
		    status = VSsetfields(vdataID, fieldname);

		    fldsize = EHsizeof(vdataID, fieldname);

		    buf = (uint8 *) calloc(fldsize, count[0] * incr[0]);

		    if(buf == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWwrrdfield", __FILE__, __LINE__);
			return(-1);
		    }

		    (void) VSseek(vdataID, offset[0]);
		    (void) VSread(vdataID, buf, 1 + (count[0]- 1) * incr[0],
			   FULL_INTERLACE);


		    /* Copy from input buffer to returned data buffer */
		    /* ---------------------------------------------- */
		    if (incr[0] == 1)
		    {/*
		      memcpy(datbuf, buf, count[0] * fldsize);
		     */
			memmove(datbuf, buf, count[0] * fldsize);
		    }
		    else
		    {
			for (i = 0; i < count[0]; i++)
			{/*
			    memcpy((uint8 *) datbuf + i * fldsize,
				   buf + i * fldsize * incr[0], fldsize);
			 */
			    memmove((uint8 *) datbuf + i * fldsize,
				   buf + i * fldsize * incr[0], fldsize);
			}
		    }

		}		/* End Read Section */

		free(buf);
		VSdetach(vdataID);
	    }
	    else
	    {
		HEpush(DFE_GENAPP, "SWwrrdfield", __FILE__, __LINE__);
		HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    }
	}			/* End One-D Field Section */

    }
    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwritefield                                                     |
|                                                                             |
|  DESCRIPTION: Writes data to field                                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  start          int32               start array                             |
|  stride         int32               stride array                            |
|  edge           int32               edge array                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  data           void                data buffer for write                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwritefield(int32 swathID, const char *fieldname,
	     int32 start[], int32 stride[], int32 edge[], VOIDP data)

{
    intn            status = 0;	/* routine return status variable */

    status = SWwrrdfield(swathID, fieldname, "w", start, stride, edge,
			 data);
    return (status);
}






/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWreadfield                                                      |
|                                                                             |
|  DESCRIPTION: Reads data from field                                         |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  start          int32               start array                             |
|  stride         int32               stride array                            |
|  edge           int32               edge array                              |
|  buffer         void                data buffer for read                    |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|     None                                                                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWreadfield(int32 swathID, const char *fieldname,
	    int32 start[], int32 stride[], int32 edge[], VOIDP buffer)

{
    intn            status = 0;	/* routine return status variable */

    status = SWwrrdfield(swathID, fieldname, "r", start, stride, edge,
			 buffer);
    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWwrfld                                                          |
|                                                                             |
|  DESCRIPTION: Writes data to field (FORTRAN wrapper around SWwritefield)    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  fortstart      int32               start array                             |
|  fortstride     int32               stride array                            |
|  fortedge       int32               edge array                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  data           void                data buffer for write                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWwrfld(int32 swathID, const char *fieldname,
	int32 fortstart[], int32 fortstride[], int32 fortedge[], VOIDP data)

{
    intn            i;		/* Loop index */
    intn            status = 0;	/* routine return status variable */

    int32           rank;	/* Field rank */
    int32           ntype;	/* Field numbertype */
    int32           dims[8];	/* Field dimensions */
    int32          *start;	/* Pointer to start array (C order) */
    int32          *stride;	/* Pointer to stride array (C order) */
    int32          *edge;	/* Pointer to edge array (C order) */


    status = SWfieldinfo(swathID, fieldname, &rank, dims, &ntype, NULL);

    if (status != -1)
    {
	start = (int32 *) malloc(4 * rank);
	if(start == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWwrfld", __FILE__, __LINE__);
	    return(-1);
	}
	stride = (int32 *) malloc(4 * rank);
	if(stride == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWwrfld", __FILE__, __LINE__);
	    free(start);
	    return(-1);
	}
	edge = (int32 *) malloc(4 * rank);
	if(edge == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWwrfld", __FILE__, __LINE__);
	    free(start);
	    free(stride);
	    return(-1);
	}

	/* Reverse order of dimensions (FORTRAN -> C) */
	for (i = 0; i < rank; i++)
	{
	    start[i] = fortstart[rank - 1 - i];
	    stride[i] = fortstride[rank - 1 - i];
	    edge[i] = fortedge[rank - 1 - i];
	}

	status = SWwrrdfield(swathID, fieldname, "w", start, stride, edge,
			     data);

	free(start);
	free(stride);
	free(edge);
    }
    else
    {
	HEpush(DFE_GENAPP, "SWwrfld", __FILE__, __LINE__);
	HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
    }

    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWrdfld                                                          |
|                                                                             |
|  DESCRIPTION: Reads data from field (FORTRAN wrapper around SWreadfield)    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                fieldname                               |
|  fortstart      int32               start array                             |
|  fortstride     int32               stride array                            |
|  fortedge       int32               edge array                              |
|  buffer         void                data buffer for read                    |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|     None                                                                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWrdfld(int32 swathID, const char *fieldname, int32 fortstart[],
	int32 fortstride[], int32 fortedge[], VOIDP buffer)

{
    intn            i;		/* Loop index */
    intn            status = 0;	/* routine return status variable */

    int32           rank;	/* Field rank */
    int32           ntype;	/* Field numbertype */
    int32           dims[8];	/* Field dimensions */
    int32          *start;	/* Pointer to start array (C order) */
    int32          *stride;	/* Pointer to stride array (C order) */
    int32          *edge;	/* Pointer to edge array (C order) */


    status = SWfieldinfo(swathID, fieldname, &rank, dims, &ntype, NULL);

    if (status != -1)
    {
	start = (int32 *) malloc(4 * rank);
	if(start == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWrdfld", __FILE__, __LINE__);
	    return(-1);
	}
	stride = (int32 *) malloc(4 * rank);
	if(stride == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWrdfld", __FILE__, __LINE__);
	    free(start);
	    return(-1);
	}
	edge = (int32 *) malloc(4 * rank);
	if(edge == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWrdfld", __FILE__, __LINE__);
	    free(start);
	    free(stride);
	    return(-1);
	}

	/* Reverse order of dimensions (FORTRAN -> C) */
	for (i = 0; i < rank; i++)
	{
	    start[i] = fortstart[rank - 1 - i];
	    stride[i] = fortstride[rank - 1 - i];
	    edge[i] = fortedge[rank - 1 - i];
	}

	status = SWwrrdfield(swathID, fieldname, "r", start, stride, edge,
			     buffer);

	free(start);
	free(stride);
	free(edge);
    }
    else
    {
	HEpush(DFE_GENAPP, "SWrdfld", __FILE__, __LINE__);
	HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
    }
    return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefboxregion                                                   |
|                                                                             |
|  DESCRIPTION: Finds swath cross tracks within area of interest and returns  |
|               region ID                                                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       int32               Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  cornerlon      float64  dec deg    Longitude of opposite corners of box    |
|  cornerlat      float64  dec deg    Latitude of opposite corners of box     |
|  mode           int32               Search mode                             |
|                                     HDFE_MIDPOINT - Use midpoint of Xtrack  |
|                                     HDFE_ENDPOINT - Use endpoints of Xtrack |
|                                     HDFE_ANYPOINT - Use all points of Xtrack|
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Oct 96   Joel Gales    Add ability to handle regions crossing date line    |
|  Dec 96   Joel Gales    Add multiple vertical subsetting capability         |
|  Jul 98   Abe Taaheri   Fixed core dump in SWregioninfo associated with     |
|                         SWXRegion[k]->nRegions exceeding MAXNREGIONS in     |
|                         this function                                       |
|  Aug 99   Abe Taaheri   Fixed the code so that all cross tracks or all      |
|                         points on the along track that fall inside the box  |
|                         are identified. At the same time added code to      |
|                         function "updatescene" to reject cases where there  |
|                         is single cross track in the box (for LANDSAT)      |
|  Jun 03   Abe Taaheri   Added a few lines to report error and return -1 if  |
|                         regionID exceeded NSWATHREGN                        |
|  Mar 04   Abe Taaheri   Added recognition for GeodeticLatitude              |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWdefboxregion(int32 swathID, float64 cornerlon[], float64 cornerlat[],
	       int32 mode)
{
    intn            i;		/* Loop index */
    intn            j = 0;	/* Loop index */
    intn            k;		/* Loop index */

    intn            status;	/* routine return status variable */
    intn            statLon;	/* Status from SWfieldinfo for longitude */
    intn            statLat;	/* Status from SWfieldinfo for latitude */
    intn            statCoLat = -1;	/* Status from SWfieldinfo for
					 * Colatitude */
    intn            statGeodeticLat = -1; /* Status from SWfieldinfo for
					 * GeodeticLatitude */

    uint8           found = 0;	/* Found flag */
    uint8          *flag;	/* Pointer to track flag array */
    intn            validReg = -1; /* -1 is invalid validReg */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */
    int32           rank;	/* Rank of geolocation fields */
    int32           nt;		/* Number type of geolocation fields */
    int32           dims[8];	/* Dimensions of geolocation fields */
    int32           nElem;	/* Number of elements to read */
    int32           bndflag;	/* +/-180 longitude boundary flag */
    int32           lonTest;	/* Longitude test flag */
    int32           latTest;	/* Latitude test flag */
    int32           start[2];	/* Start array (read) */
    int32           stride[2] = {1, 1};	/* Stride array (read) */
    int32           edge[2];	/* Edge array (read) */
    int32           regionID = -1;	/* Region ID (return) */
    int32           anyStart[2];/* ANYPOINT start array (read) */
    int32           anyEdge[2];	/* ANYPOINT edge array (read) */

    float32         temp32;	/* Temporary float32 variable */

    float64         lonTestVal;	/* Longitude test value */
    float64         latTestVal;	/* Latitude test value */
    float64         temp64;	/* Temporary float64 variable */

    char           *lonArr;	/* Longitude data array */
    char           *latArr;	/* Latitude data array */
    char            dimlist[256];	/* Dimension list (geolocation
					 * fields) */
    char            latName[17];/* Latitude field name */


    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWdefboxregion", &fid, &sdInterfaceID,
		       &swVgrpID);

    /* Inclusion mode must be between 0 and 2 */
    /* -------------------------------------- */
    if (mode < 0 || mode > 2)
    {
	status = -1;
	HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
	HEreport("Improper Inclusion Mode: %d.\n", mode);
    }

    if (status == 0)
    {
	/* Get "Longitude" field info */
	/* -------------------------- */
	statLon = SWfieldinfo(swathID, "Longitude", &rank, dims, &nt, dimlist);
	if (statLon != 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
	    HEreport("\"Longitude\" field not found.\n");
	}

	/* Get "Latitude" field info */
	/* -------------------------- */
	statLat = SWfieldinfo(swathID, "Latitude", &rank, dims, &nt, dimlist);
	if (statLat != 0)
	{
	    /* If not found check for "Colatitude" field info */
	    /* ---------------------------------------------- */
	    statCoLat = SWfieldinfo(swathID, "Colatitude", &rank, dims, &nt,
				    dimlist);
	    if (statCoLat != 0)
	    {
	      /* Check again for Geodeticlatitude */
	      statGeodeticLat = SWfieldinfo(swathID,
					    "GeodeticLatitude", &rank,
					    dims, &nt, dimlist);
	      if (statGeodeticLat != 0)
		{
		  /* Neither "Latitude" nor "Colatitude" nor
		     "GeodeticLatitude" field found */
		  /* ----------------------------------------------- */
		  status = -1;
		  HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
		  HEreport(
			   "Neither \"Latitude\" nor \"Colatitude\" nor \"GeodeticLatitude\" fields found.\n");
		}
	      else
		{
		  /* Latitude field is "GeodeticLatitude" */
		  /* ------------------------------ */
		  strcpy(latName, "GeodeticLatitude");
		}
	    }
	    else
	    {
		/* Latitude field is "Colatitude" */
		/* ------------------------------ */
		strcpy(latName, "Colatitude");
	    }
	}
	else
	{
	    /* Latitude field is "Latitude" */
	    /* ---------------------------- */
	    strcpy(latName, "Latitude");
	}


	if (status == 0)
	{
	    /* Search along entire "Track" dimension from beginning to end */
	    /* ----------------------------------------------------------- */
	    start[0] = 0;
	    edge[0] = dims[0];


	    /* If 1D geolocation fields then set mode to MIDPOINT */
	    /* -------------------------------------------------- */
	    if (rank == 1)
	    {
		mode = HDFE_MIDPOINT;
	    }


	    switch (mode)
	    {
		/* If MIDPOINT search single point in middle of "CrossTrack" */
		/* --------------------------------------------------------- */
	    case HDFE_MIDPOINT:

		start[1] = dims[1] / 2;
		edge[1] = 1;

		break;

		/* If ENDPOINT search 2 points at either end of "CrossTrack" */
		/* --------------------------------------------------------- */
	    case HDFE_ENDPOINT:

		start[1] = 0;
		stride[1] = dims[1] - 1;
		edge[1] = 2;

		break;

		/* If ANYPOINT do initial MIDPOINT search */
		/* -------------------------------------- */
	    case HDFE_ANYPOINT:

		start[1] = dims[1] / 2;
		edge[1] = 1;

		break;
	    }


	    /* Compute number of elements */
	    /* -------------------------- */
	    nElem = edge[0] * edge[1];


	    /* Allocate space for longitude and latitude (float64) */
	    /* --------------------------------------------------- */
	    lonArr = (char *) calloc(nElem, sizeof(float64));
	    if(lonArr == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdefboxregion", __FILE__, __LINE__);
		return(-1);
	    }

	    latArr = (char *) calloc(nElem, sizeof(float64));
	    if(latArr == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdefboxregion", __FILE__, __LINE__);
		free(lonArr);
		return(-1);
	    }


	    /* Allocate space for flag array (uint8) */
	    /* ------------------------------------- */
	    flag = (uint8 *) calloc(edge[0] + 1, 1);
	    if(flag == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdefboxregion", __FILE__, __LINE__);
		free(lonArr);
		free(latArr);
		return(-1);
	    }


	    /* Read Longitude and Latitude fields */
	    /* ---------------------------------- */
	    status = SWreadfield(swathID, "Longitude",
				 start, stride, edge, lonArr);
	    if(status != 0)
	    {
		HEpush(DFE_GENAPP,"SWdefboxregion", __FILE__, __LINE__);
		free(flag);
		free(lonArr);
		free(latArr);
		return(-1);
	    }

	    status = SWreadfield(swathID, latName,
				 start, stride, edge, latArr);
	    if(status != 0)
	    {
		HEpush(DFE_GENAPP,"SWdefboxregion", __FILE__, __LINE__);
		free(flag);
		free(lonArr);
		free(latArr);
		return(-1);
	    }

	    /*
	     * If geolocation fields are FLOAT32 then cast each entry as
	     * FLOAT64
	     */
	    if (nt == DFNT_FLOAT32 || nt == DFNT_FLOAT)
	    {
		for (i = nElem - 1; i >= 0; i--)
		{
		    memcpy(&temp32, lonArr + 4 * i, 4);
		    temp64 = (float64) temp32;
		    memcpy(lonArr + 8 * i, &temp64, 8);

		    memcpy(&temp32, latArr + 4 * i, 4);
		    temp64 = (float64) temp32;
		    memcpy(latArr + 8 * i, &temp64, 8);
		}
	    }


	    /* Set boundary flag */
	    /* ----------------- */

	    /*
	     * This variable is set to 1 if the region of interest crosses
	     * the +/- 180 longitude boundary
	     */
	    bndflag = (cornerlon[0] < cornerlon[1]) ? 0 : 1;


	    /* Main Search Loop */
	    /* ---------------- */

	    /* For each track ... */
	    /* ------------------ */

	    for (i = 0; i < edge[0]; i++)
	    {
		/* For each value from Cross Track ... */
		/* ----------------------------------- */
		for (j = 0; j < edge[1]; j++)
		{
		    /* Read in single lon & lat values from data buffers */
		    /* ------------------------------------------------- */
		    memcpy(&lonTestVal, &lonArr[8 * (i * edge[1] + j)], 8);
		    memcpy(&latTestVal, &latArr[8 * (i * edge[1] + j)], 8);


		    /* If longitude value > 180 convert to -180 to 180 range */
		    /* ----------------------------------------------------- */
		    if (lonTestVal > 180)
		    {
			lonTestVal = lonTestVal - 360;
		    }

		    /* If Colatitude value convert to latitude value */
		    /* --------------------------------------------- */
		    if (statCoLat == 0)
		    {
			latTestVal = 90 - latTestVal;
		    }


		    /* Test if lat value is within range */
		    /* --------------------------------- */
		    latTest = (latTestVal >= cornerlat[0] &&
			       latTestVal <= cornerlat[1]);


		    if (bndflag == 1)
		    {
			/*
			 * If boundary flag set test whether longitude value
			 * is outside region and then flip
			 */
			lonTest = (lonTestVal >= cornerlon[1] &&
				   lonTestVal <= cornerlon[0]);
			lonTest = 1 - lonTest;
		    }
		    else
		    {
			lonTest = (lonTestVal >= cornerlon[0] &&
				   lonTestVal <= cornerlon[1]);
		    }


		    /*
		     * If both longitude and latitude are within region set
		     * flag on for this track
		     */
		    if (lonTest + latTest == 2)
		    {
			flag[i] = 1;
			found = 1;
			break;
		    }
		}
	    }



	    /* ANYPOINT search */
	    /* --------------- */
	    if (mode == HDFE_ANYPOINT && rank > 1)
	    {
		free(lonArr);
		free(latArr);

		/* Allocate space for an entire single cross track */
		/* ----------------------------------------------- */
		lonArr = (char *) calloc(dims[1], sizeof(float64));
		if(lonArr == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdefboxregion", __FILE__, __LINE__);
		    free(flag);
		    return(-1);
		}

		latArr = (char *) calloc(dims[1], sizeof(float64));
		if(latArr == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdefboxregion", __FILE__, __LINE__);
		    free(flag);
		    free(lonArr);
		    return(-1);
		}


		/* Setup start and edge */
		/* -------------------- */
		anyStart[1] = 0;
		anyEdge[0] = 1;
		anyEdge[1] = dims[1];


		/* For each track starting from 0 */
		/* ------------------------------ */
		for (i = 0; i < edge[0]; i++)
		{

		    /* If cross track not in region (with MIDPOINT search ... */
		    /* ------------------------------------------------------ */
		    if (flag[i] == 0)
		    {
			/* Setup track start */
			/* ----------------- */
			anyStart[0] = i;


			/* Read in lon and lat values for cross track */
			/* ------------------------------------------ */
			status = SWreadfield(swathID, "Longitude",
					   anyStart, NULL, anyEdge, lonArr);
			if (status != 0)
			  {
			    HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
			    HEreport("Failed reading longitude field.\n");
			    free(flag);
			    free(lonArr);
			    free(latArr);
			    return (-1);
			  }

			status = SWreadfield(swathID, latName,
					   anyStart, NULL, anyEdge, latArr);
			if (status != 0)
			  {
			    HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
			    HEreport("Failed reading latilude field.\n");
			    free(flag);
			    free(lonArr);
			    free(latArr);
			    return (-1);
			  }


			/*
			 * If geolocation fields are FLOAT32 then cast each
			 * entry as FLOAT64
			 */
			if (nt == DFNT_FLOAT32 || nt == DFNT_FLOAT)
			{
			    for (j = dims[1] - 1; j >= 0; j--)
			    {
				memcpy(&temp32, lonArr + 4 * j, 4);
				temp64 = (float64) temp32;
				memcpy(lonArr + 8 * j, &temp64, 8);

				memcpy(&temp32, latArr + 4 * j, 4);
				temp64 = (float64) temp32;
				memcpy(latArr + 8 * j, &temp64, 8);
			    }
			}


			/* For each value from Cross Track ... */
			/* ----------------------------------- */
			for (j = 0; j < dims[1]; j++)
			{
			    /* Read in single lon & lat values from buffers */
			    /* -------------------------------------------- */
			    memcpy(&lonTestVal, &lonArr[8 * j], 8);
			    memcpy(&latTestVal, &latArr[8 * j], 8);


			    /* If lon value > 180 convert to -180 - 180 range */
			    /* ---------------------------------------------- */
			    if (lonTestVal > 180)
			    {
				lonTestVal = lonTestVal - 360;
			    }

			    /* If Colatitude value convert to latitude value */
			    /* --------------------------------------------- */
			    if (statCoLat == 0)
			    {
				latTestVal = 90 - latTestVal;
			    }


			    /* Test if lat value is within range */
			    /* --------------------------------- */
			    latTest = (latTestVal >= cornerlat[0] &&
				       latTestVal <= cornerlat[1]);


			    if (bndflag == 1)
			    {
				/*
				 * If boundary flag set test whether
				 * longitude value is outside region and then
				 * flip
				 */
				lonTest = (lonTestVal >= cornerlon[1] &&
					   lonTestVal <= cornerlon[0]);
				lonTest = 1 - lonTest;
			    }
			    else
			    {
				lonTest = (lonTestVal >= cornerlon[0] &&
					   lonTestVal <= cornerlon[1]);
			    }


			    /*
			     * If both longitude and latitude are within
			     * region set flag on for this track
			     */
			    if (lonTest + latTest == 2)
			    {
				flag[i] = 1;
				found = 1;
				break;
			    }
			}
		    }
		}
            }

	    /* If within region setup Region Structure */
	    /* --------------------------------------- */
	    if (found == 1)
	    {
		/* For all entries in SWXRegion array ... */
		/* -------------------------------------- */
		for (k = 0; k < NSWATHREGN; k++)
		{
		    /* If empty region ... */
		    /* ------------------- */
		    if (SWXRegion[k] == 0)
		    {
			/* Allocate space for region entry */
			/* ------------------------------- */
			SWXRegion[k] = (struct swathRegion *)
			    calloc(1, sizeof(struct swathRegion));
			if(SWXRegion[k] == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWdefboxregion", __FILE__, __LINE__);
			    free(flag);
			    free(lonArr);
			    free(latArr);
			    return(-1);
			}

			/* Store file and swath ID */
			/* ----------------------- */
			SWXRegion[k]->fid = fid;
			SWXRegion[k]->swathID = swathID;


			/* Set Start & Stop Vertical arrays to -1 */
			/* -------------------------------------- */
			for (j = 0; j < 8; j++)
			{
			    SWXRegion[k]->StartVertical[j] = -1;
			    SWXRegion[k]->StopVertical[j] = -1;
			    SWXRegion[k]->StartScan[j] = -1;
			    SWXRegion[k]->StopScan[j] = -1;
			}


			/* Set region ID */
			/* ------------- */
			regionID = k;
			break;
		    }
		}
		if (k >= NSWATHREGN)
		  {
		    HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
		    HEreport("regionID exceeded NSWATHREGN.\n");
		    free(flag);
		    free(lonArr);
		    free(latArr);
                    return (-1);
		  }

		/* Find start and stop of regions */
		/* ------------------------------ */

		/* Subtract previous flag value from current one */
		/* --------------------------------------------- */

		/*
		 * Transisition points will have flag value (+1) start or
		 * (255 = (uint8) -1) stop of region
		 */
		for (i = edge[0]; i > 0; i--)
		{
		    flag[i] -= flag[i - 1];
		}


		for (i = 0; i <= edge[0]; i++)
		{
		    /* Start of region */
		    /* --------------- */
		    if (flag[i] == 1)
		    {
			/* Increment (multiple) region counter */
			/* ----------------------------------- */
			j = ++SWXRegion[k]->nRegions;

			/* if SWXRegion[k]->nRegions greater than MAXNREGIONS */
			/* free allocated memory and return FAIL */

			if ((SWXRegion[k]->nRegions) > MAXNREGIONS)
			{
			    HEpush(DFE_GENAPP, "SWdefboxregion", __FILE__, __LINE__);
			    HEreport("SWXRegion[%d]->nRegions exceeds MAXNREGIONS= %d.\n", k, MAXNREGIONS);
			    free(lonArr);
			    free(latArr);
			    free(flag);
			    return(-1);
			}

			SWXRegion[k]->StartRegion[j - 1] = i;
		    }

		    /* End of region */
		    /* ------------- */
		    if (flag[i] == 255)
		    {
			SWXRegion[k]->StopRegion[j - 1] = i - 1;
			validReg = 0;
		    }
		}
	    }
	    free(lonArr);
	    free(latArr);
	    free(flag);
	}
    }

    if(validReg==0)
    {
	return (regionID);
    }
    else
    {
	return (-1);
    }

}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWregionindex                                                    |
|                                                                             |
|  DESCRIPTION: Finds swath cross tracks within area of interest and returns  |
|               region index and region ID                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       int32               Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  cornerlon      float64  dec deg    Longitude of opposite corners of box    |
|  cornerlat      float64  dec deg    Latitude of opposite corners of box     |
|  mode           int32               Search mode                             |
|                                     HDFE_MIDPOINT - Use midpoint of Xtrack  |
|                                     HDFE_ENDPOINT - Use endpoints of Xtrack |
|                                     HDFE_ANYPOINT - Use all points of Xtrack|
|                                                                             |
|  OUTPUTS:                                                                   |
|  geodim	  char		      geolocation track dimension             |
|  idxrange	  int32		      indices of region for along track dim.  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Oct 96   Joel Gales    Add ability to handle regions crossing date line    |
|  Dec 96   Joel Gales    Add multiple vertical subsetting capability         |
|  Nov 97   Daw           Add multiple vertical subsetting capability         |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWregionindex(int32 swathID, float64 cornerlon[], float64 cornerlat[],
	       int32 mode, char *geodim, int32 idxrange[])
{
    intn            i;		/* Loop index */
    intn            j = 0;	/* Loop index */
    intn            k;		/* Loop index */

    intn            l=0;	/* Loop index */
    intn            tmpVal = 0;     /* temp value for start region Delyth Jones*/
  /*intn            j1;  */     /* Loop index */
    intn            status;	/* routine return status variable */
    intn	    mapstatus;	/* status for type of mapping */
    intn            statLon;	/* Status from SWfieldinfo for longitude */
    intn            statLat;	/* Status from SWfieldinfo for latitude */
    intn            statCoLat = -1;	/* Status from SWfieldinfo for
					 * Colatitude */
    intn            statGeodeticLat = -1; /* Status from SWfieldinfo for
					 * GeodeticLatitude */

    uint8           found = 0;	/* Found flag */
    uint8          *flag;	/* Pointer to track flag array */
    intn            validReg = -1; /* -1 is invalid validReg */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */
    int32           rank;	/* Rank of geolocation fields */
    int32           nt;		/* Number type of geolocation fields */
    int32           dims[8];	/* Dimensions of geolocation fields */
    int32           nElem;	/* Number of elements to read */
    int32           bndflag;	/* +/-180 longitude boundary flag */
    int32           lonTest;	/* Longitude test flag */
    int32           latTest;	/* Latitude test flag */
    int32           start[2];	/* Start array (read) */
    int32           stride[2] = {1, 1};	/* Stride array (read) */
    int32           edge[2];	/* Edge array (read) */
    int32           regionID = -1;	/* Region ID (return) */
    int32           anyStart[2];/* ANYPOINT start array (read) */
    int32           anyEdge[2];	/* ANYPOINT edge array (read) */

    float32         temp32;	/* Temporary float32 variable */

    float64         lonTestVal;	/* Longitude test value */
    float64         latTestVal;	/* Latitude test value */
    float64         temp64;	/* Temporary float64 variable */

    char           *lonArr;	/* Longitude data array */
    char           *latArr;	/* Latitude data array */
    char            dimlist[256];	/* Dimension list (geolocation
					 * fields) */
    char            latName[17];/* Latitude field name */


    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWregionindex", &fid, &sdInterfaceID,
		       &swVgrpID);

    /* Inclusion mode must be between 0 and 2 */
    /* -------------------------------------- */
    if (mode < 0 || mode > 2)
    {
	status = -1;
	HEpush(DFE_GENAPP, "SWregionindex", __FILE__, __LINE__);
	HEreport("Improper Inclusion Mode: %d.\n", mode);
    }


    if (status == 0)
    {
	/* Get "Longitude" field info */
	/* -------------------------- */
	statLon = SWfieldinfo(swathID, "Longitude", &rank, dims, &nt, dimlist);
	if (statLon != 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWregionindex", __FILE__, __LINE__);
	    HEreport("\"Longitude\" field not found.\n");
	}

	/* Get "Latitude" field info */
	/* -------------------------- */
	statLat = SWfieldinfo(swathID, "Latitude", &rank, dims, &nt, dimlist);
	if (statLat != 0)
	{
	    /* If not found check for "Colatitude" field info */
	    /* ---------------------------------------------- */
	    statCoLat = SWfieldinfo(swathID, "Colatitude", &rank, dims, &nt,
				    dimlist);
	    if (statCoLat != 0)
	    {
	      /* Check again for Geodeticlatitude */
	      statGeodeticLat = SWfieldinfo(swathID,
					    "GeodeticLatitude", &rank,
					    dims, &nt, dimlist);
	      if (statGeodeticLat != 0)
	        {
		  /* Neither "Latitude" nor "Colatitude" field found */
		  /* ----------------------------------------------- */
		  status = -1;
		  HEpush(DFE_GENAPP, "SWregionindex", __FILE__, __LINE__);
		  HEreport(
			   "Neither \"Latitude\" nor \"Colatitude\" fields found.\n");
		}
	      else
		{
		     /* Latitude field is "Colatitude" */
		     /* ------------------------------ */
		     strcpy(latName, "GeodeticLatitude");
		}
	    }
	    else
	    {
		/* Latitude field is "Colatitude" */
		/* ------------------------------ */
		strcpy(latName, "Colatitude");
	    }
	}
	else
	{
	    /* Latitude field is "Latitude" */
	    /* ---------------------------- */
	    strcpy(latName, "Latitude");
	}

        /* This line modifies the dimlist variable so only the along-track */
        /* dimension remains.                                              */
        /* --------------------------------------------------------------- */
        (void) strtok(dimlist,",");
        mapstatus = SWgeomapinfo(swathID,dimlist);
        (void) strcpy(geodim,dimlist);

	if (status == 0)
	{
	    /* Search along entire "Track" dimension from beginning to end */
	    /* ----------------------------------------------------------- */
	    start[0] = 0;
	    edge[0] = dims[0];


	    /* If 1D geolocation fields then set mode to MIDPOINT */
	    /* -------------------------------------------------- */
	    if (rank == 1)
	    {
		mode = HDFE_MIDPOINT;
	    }


	    switch (mode)
	    {
		/* If MIDPOINT search single point in middle of "CrossTrack" */
		/* --------------------------------------------------------- */
	    case HDFE_MIDPOINT:

		start[1] = dims[1] / 2;
		edge[1] = 1;

		break;

		/* If ENDPOINT search 2 points at either end of "CrossTrack" */
		/* --------------------------------------------------------- */
	    case HDFE_ENDPOINT:

		start[1] = 0;
		stride[1] = dims[1] - 1;
		edge[1] = 2;

		break;

		/* If ANYPOINT do initial MIDPOINT search */
		/* -------------------------------------- */
	    case HDFE_ANYPOINT:

		start[1] = dims[1] / 2;
		edge[1] = 1;

		break;
	    }


	    /* Compute number of elements */
	    /* -------------------------- */
	    nElem = edge[0] * edge[1];


	    /* Allocate space for longitude and latitude (float64) */
	    /* --------------------------------------------------- */
	    lonArr = (char *) calloc(nElem, sizeof(float64));
	    if(lonArr == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWregionindex", __FILE__, __LINE__);
		return(-1);
	    }

	    latArr = (char *) calloc(nElem, sizeof(float64));
	    if(latArr == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWregionindex", __FILE__, __LINE__);
		free(lonArr);
		return(-1);
	    }


	    /* Allocate space for flag array (uint8) */
	    /* ------------------------------------- */
	    flag = (uint8 *) calloc(edge[0] + 1, 1);
	    if(flag == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWregionindex", __FILE__, __LINE__);
		free(lonArr);
		free(latArr);
		return(-1);
	    }


	    /* Read Longitude and Latitude fields */
	    /* ---------------------------------- */
	    status = SWreadfield(swathID, "Longitude",
				 start, stride, edge, lonArr);
	    if(status != 0)
	    {
		HEpush(DFE_GENAPP,"SWregionindex", __FILE__, __LINE__);
		free(flag);
		free(lonArr);
		free(latArr);
		return(-1);
	    }
	    status = SWreadfield(swathID, latName,
				 start, stride, edge, latArr);
	    if(status != 0)
	    {
		HEpush(DFE_GENAPP,"SWregionindex", __FILE__, __LINE__);
		free(flag);
		free(lonArr);
		free(latArr);
		return(-1);
	    }


	    /*
	     * If geolocation fields are FLOAT32 then cast each entry as
	     * FLOAT64
	     */
	    if (nt == DFNT_FLOAT32 || nt == DFNT_FLOAT)
	    {
		for (i = nElem - 1; i >= 0; i--)
		{
		    memcpy(&temp32, lonArr + 4 * i, 4);
		    temp64 = (float64) temp32;
		    memcpy(lonArr + 8 * i, &temp64, 8);

		    memcpy(&temp32, latArr + 4 * i, 4);
		    temp64 = (float64) temp32;
		    memcpy(latArr + 8 * i, &temp64, 8);
		}
	    }


	    /* Set boundary flag */
	    /* ----------------- */

	    /*
	     * This variable is set to 1 if the region of interest crosses
	     * the +/- 180 longitude boundary
	     */
	    bndflag = (cornerlon[0] < cornerlon[1]) ? 0 : 1;


	    /* Main Search Loop */
	    /* ---------------- */

	    /* For each track ... */
	    /* ------------------ */
	    for (i = 0; i < edge[0]; i++)
	    {
		/* For each value from Cross Track ... */
		/* ----------------------------------- */
		for (j = 0; j < edge[1]; j++)
		{
		    /* Read in single lon & lat values from data buffers */
		    /* ------------------------------------------------- */
		    memcpy(&lonTestVal, &lonArr[8 * (i * edge[1] + j)], 8);
		    memcpy(&latTestVal, &latArr[8 * (i * edge[1] + j)], 8);


		    /* If longitude value > 180 convert to -180 to 180 range */
		    /* ----------------------------------------------------- */
		    if (lonTestVal > 180)
		    {
			lonTestVal = lonTestVal - 360;
		    }

		    /* If Colatitude value convert to latitude value */
		    /* --------------------------------------------- */
		    if (statCoLat == 0)
		    {
			latTestVal = 90 - latTestVal;
		    }


		    /* Test if lat value is within range */
		    /* --------------------------------- */
		    latTest = (latTestVal >= cornerlat[0] &&
			       latTestVal <= cornerlat[1]);


		    if (bndflag == 1)
		    {
			/*
			 * If boundary flag set test whether longitude value
			 * is outside region and then flip
			 */
			lonTest = (lonTestVal >= cornerlon[1] &&
				   lonTestVal <= cornerlon[0]);
			lonTest = 1 - lonTest;
		    }
		    else
		    {
			lonTest = (lonTestVal >= cornerlon[0] &&
				   lonTestVal <= cornerlon[1]);
		    }


		    /*
		     * If both longitude and latitude are within region set
		     * flag on for this track
		     */
		    if (lonTest + latTest == 2)
		    {
			flag[i] = 1;
			found = 1;
			break;
		    }
		}
	    }



	    /* ANYPOINT search */
	    /* --------------- */
	    if (mode == HDFE_ANYPOINT && rank > 1)
	    {
		free(lonArr);
		free(latArr);

		/* Allocate space for an entire single cross track */
		/* ----------------------------------------------- */
		lonArr = (char *) calloc(dims[1], sizeof(float64));
		if(lonArr == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWregionindex", __FILE__, __LINE__);
		    free(flag);
		    return(-1);
		}
		latArr = (char *) calloc(dims[1], sizeof(float64));
		if(latArr == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWregionindex", __FILE__, __LINE__);
		    free(flag);
		    free(lonArr);
		    return(-1);
		}

		/* Setup start and edge */
		/* -------------------- */
		anyStart[1] = 0;
		anyEdge[0] = 1;
		anyEdge[1] = dims[1];


		/* For each track ... */
		/* ------------------ */
		for (i = 0; i < edge[0]; i++)
		{

		    /* If cross track not in region (with MIDPOINT search ... */
		    /* ------------------------------------------------------ */
		    if (flag[i] == 0)
		    {
			/* Setup track start */
			/* ----------------- */
			anyStart[0] = i;


			/* Read in lon and lat values for cross track */
			/* ------------------------------------------ */
			status = SWreadfield(swathID, "Longitude",
					   anyStart, NULL, anyEdge, lonArr);
			if(status != 0)
			  {
			    HEpush(DFE_GENAPP,"SWregionindex", __FILE__, __LINE__);
			    free(flag);
			    free(lonArr);
			    free(latArr);
			    return(-1);
			  }

			status = SWreadfield(swathID, latName,
					     anyStart, NULL, anyEdge, latArr);
			if(status != 0)
			  {
			    HEpush(DFE_GENAPP,"SWregionindex", __FILE__, __LINE__);
			    free(flag);
			    free(lonArr);
			    free(latArr);
			    return(-1);
			  }

			/*
			 * If geolocation fields are FLOAT32 then cast each
			 * entry as FLOAT64
			 */
			if (nt == DFNT_FLOAT32 || nt == DFNT_FLOAT)
			{
			    for (j = dims[1] - 1; j >= 0; j--)
			    {
				memcpy(&temp32, lonArr + 4 * j, 4);
				temp64 = (float64) temp32;
				memcpy(lonArr + 8 * j, &temp64, 8);

				memcpy(&temp32, latArr + 4 * j, 4);
				temp64 = (float64) temp32;
				memcpy(latArr + 8 * j, &temp64, 8);
			    }
			}


			/* For each value from Cross Track ... */
			/* ----------------------------------- */
			for (j = 0; j < dims[1]; j++)
			{
			    /* Read in single lon & lat values from buffers */
			    /* -------------------------------------------- */
			    memcpy(&lonTestVal, &lonArr[8 * j], 8);
			    memcpy(&latTestVal, &latArr[8 * j], 8);


			    /* If lon value > 180 convert to -180 - 180 range */
			    /* ---------------------------------------------- */
			    if (lonTestVal > 180)
			    {
				lonTestVal = lonTestVal - 360;
			    }

			    /* If Colatitude value convert to latitude value */
			    /* --------------------------------------------- */
			    if (statCoLat == 0)
			    {
				latTestVal = 90 - latTestVal;
			    }


			    /* Test if lat value is within range */
			    /* --------------------------------- */
			    latTest = (latTestVal >= cornerlat[0] &&
				       latTestVal <= cornerlat[1]);


			    if (bndflag == 1)
			    {
				/*
				 * If boundary flag set test whether
				 * longitude value is outside region and then
				 * flip
				 */
				lonTest = (lonTestVal >= cornerlon[1] &&
					   lonTestVal <= cornerlon[0]);
				lonTest = 1 - lonTest;
			    }
			    else
			    {
				lonTest = (lonTestVal >= cornerlon[0] &&
					   lonTestVal <= cornerlon[1]);
			    }


			    /*
			     * If both longitude and latitude are within
			     * region set flag on for this track
			     */
			    if (lonTest + latTest == 2)
			    {
				flag[i] = 1;
				found = 1;
				break;
			    }
			}
		    }
		}
	    }
	    /*
	    for (j1 = 0; j1 < edge[0]; j1++)
	      {
		idxrange[j1] = (int32) flag[j1];
	      }
	    */
	    /* If within region setup Region Structure */
	    /* --------------------------------------- */
	    if (found == 1)
	    {
		/* For all entries in SWXRegion array ... */
		/* -------------------------------------- */
		for (k = 0; k < NSWATHREGN; k++)
		{
		    /* If empty region ... */
		    /* ------------------- */
		    if (SWXRegion[k] == 0)
		    {
			/* Allocate space for region entry */
			/* ------------------------------- */
			SWXRegion[k] = (struct swathRegion *)
			    calloc(1, sizeof(struct swathRegion));
			if(SWXRegion[k] == NULL)
			{
			    HEpush(DFE_NOSPACE,"SWregionindex", __FILE__, __LINE__);
			    free(flag);
			    free(lonArr);
			    free(latArr);
			    return(-1);
			}

			/* Store file and swath ID */
			/* ----------------------- */
			SWXRegion[k]->fid = fid;
			SWXRegion[k]->swathID = swathID;


			/* Set Start & Stop Vertical arrays to -1 */
			/* -------------------------------------- */
			for (j = 0; j < 8; j++)
			{
			    SWXRegion[k]->StartVertical[j] = -1;
			    SWXRegion[k]->StopVertical[j] = -1;
			    SWXRegion[k]->StartScan[j] = -1;
			    SWXRegion[k]->StopScan[j] = -1;
			}


			/* Set region ID */
			/* ------------- */
			regionID = k;
			break;
		    }
		}
		if (k >= NSWATHREGN)
		  {
		    HEpush(DFE_GENAPP, "SWregionindex", __FILE__, __LINE__);
		    HEreport(
			     "regionID exceeded NSWATHREGN.\n");
		    free(flag);
		    free(lonArr);
		    free(latArr);
                    return (-1);
		  }

		/* Find start and stop of regions */
		/* ------------------------------ */

		/* Subtract previous flag value from current one */
		/* --------------------------------------------- */

		/*
		 * Transisition points will have flag value (+1) start or
		 * (255 = (uint8) -1) stop of region
		 */
		for (i = edge[0]; i > 0; i--)
		{
		    flag[i] -= flag[i - 1];
		}


		for (i = 0; i <= edge[0]; i++)
		{
		    /* Start of region */
		    /* --------------- */
		    if (flag[i] == 1)
		    {
			/* Delyth Jones Moved the increment of the region down
			   to next if statement j = ++SWXRegion[k]->nRegions; */

			/* using temp value, if not equal to stop region
			   invalid region otherwise ok Delyth Jones */
			tmpVal = i+1;
		    }

		    /* End of region */
		    /* ------------- */
		    if (flag[i] == 255)
		    {
			if( tmpVal!=i )
			{
			    /* Increment (multiple) region counter */
			    /* ----------------------------------- */
			    j = ++SWXRegion[k]->nRegions;

                            if (mapstatus == 2)
                            {
                               l = i;
                               if ((tmpVal-1) % 2 == 1)
                               {
                                  tmpVal = tmpVal + 1;
                               }

                               if ((l-1) % 2 == 0)
                               {
                                  l = l - 1;
                               }
                            }
			    SWXRegion[k]->StartRegion[j - 1] = tmpVal-1;
                            idxrange[0] = tmpVal - 1;
			    SWXRegion[k]->StopRegion[j - 1] = l - 1;
                            idxrange[1] = l - 1;
			    validReg = 0;
			}
		    }

		}

	    }
	    free(lonArr);
	    free(latArr);
	    free(flag);
	}
    }

    if(validReg==0)
    {
	return (regionID);
    }
    else
    {
	return (-1);
    }

}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdeftimeperiod                                                  |
|                                                                             |
|  DESCRIPTION: Finds swath cross tracks observed during time period and      |
|               returns  period ID                                            |
|                                                                             |
|               region ID                                                     |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  periodID       int32               Period ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  starttime      float64 TAI sec     Start of time period                    |
|  stoptime       float64 TAI sec     Stop of time period                     |
|  mode           int32               Search mode                             |
|                                     HDFE_MIDPOINT - Use midpoint of Xtrack  |
|                                     HDFE_ENDPOINT - Use endpoints of Xtrack |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWdeftimeperiod(int32 swathID, float64 starttime, float64 stoptime,
		int32 mode)
{

    intn            i;		/* Loop index */
    intn            j = 0;	/* Loop index */
    intn            k;		/* Loop index */
    intn            status;	/* routine return status variable */
    intn            statTime;	/* Status from SWfieldinfo for time */
    intn            statusRead;	/* Status from SWreadfield for time */

    uint8           found = 0;	/* Found flag */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */
    int32           rank;	/* Rank of geolocation fields */
    int32           nt;		/* Number type of geolocation fields */
    int32           dims[8];	/* Dimensions of geolocation fields */
    int32           start[2];	/* Start array (read) */
    int32           stride[2] = {1, 1};	/* Stride array (read) */
    int32           edge[2];	/* Edge array (read) */
    int32           periodID = -1;	/* Period ID (return) */
    int32           dum;	/* Dummy (loop) variable */

    float64         time64Test;	/* Time test value */
    float64        *time64 = NULL;	/* Time data array */

    char            dimlist[256];	/* Dimension list (geolocation
					 * fields) */

    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWdeftimeperiod", &fid, &sdInterfaceID,
		       &swVgrpID);

    if (status == 0)
    {
	/* Get "Time" field info */
	/* --------------------- */
	statTime = SWfieldinfo(swathID, "Time", &rank, dims, &nt, dimlist);
	if (statTime != 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWdeftimeperiod", __FILE__, __LINE__);
	    HEreport("\"Time\" field not found.\n");
	}

	if (statTime  == 0)
	{
	    /* Search along entire "Track" dimension from beginning to end */
	    /* ----------------------------------------------------------- */
	    start[0] = 0;
	    edge[0] = dims[0];


	    /* If 1D geolocation fields then set mode to MIDPOINT */
	    /* -------------------------------------------------- */
	    if (rank == 1)
	    {
		mode = HDFE_MIDPOINT;
	    }


	    switch (mode)
	    {

		/* If MIDPOINT search single point in middle of "CrossTrack" */
		/* --------------------------------------------------------- */
	    case HDFE_MIDPOINT:

		start[1] = dims[1] / 2;
		edge[1] = 1;


		/* Allocate space for time data */
		/* ---------------------------- */
		time64 = (float64 *) calloc(edge[0], 8);
		if(time64 == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdeftimeperiod", __FILE__, __LINE__);
		    return(-1);
		}


		/* Read "Time" field */
		/* ----------------- */
		statusRead = SWreadfield(swathID, "Time",
				     start, NULL, edge, time64);
		break;


		/* If ENDPOINT search 2 points at either end of "CrossTrack" */
		/* --------------------------------------------------------- */
	    case HDFE_ENDPOINT:
		start[1] = 0;
		stride[1] = dims[1] - 1;
		edge[1] = 2;


		/* Allocate space for time data */
		/* ---------------------------- */
		time64 = (float64 *) calloc(edge[0] * 2, 8);
		if(time64 == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdeftimeperiod", __FILE__, __LINE__);
		    return(-1);
		}

		/* Read "Time" field */
		/* ----------------- */
		statusRead = SWreadfield(swathID, "Time",
				     start, stride, edge, time64);
		break;

	    }

	    if(statusRead == 0) {

	      /* For each track (from top) ... */
	      /* ----------------------------- */
	      for (i = 0; i < edge[0]; i++)
		{
		  /* For each value from Cross Track ... */
		  /* ----------------------------------- */
		  for (j = 0; j < edge[1]; j++)
		    {

		      /* Get time test value */
		      /* ------------------- */
		      time64Test = time64[i * edge[1] + j];


		      /* If within time period ... */
		      /* ------------------------- */
		      if (time64Test >= starttime &&
			  time64Test <= stoptime)
			{
			  /* Set found flag */
			  /* -------------- */
			  found = 1;


			  /* For all entries in SWXRegion array ... */
			  /* -------------------------------------- */
			  for (k = 0; k < NSWATHREGN; k++)
			    {
			      /* If empty region ... */
			      /* ------------------- */
			      if (SWXRegion[k] == 0)
				{
				  /* Allocate space for region entry */
				  /* ------------------------------- */
				  SWXRegion[k] = (struct swathRegion *)
				    calloc(1, sizeof(struct swathRegion));
				  if(SWXRegion[k] == NULL)
				    {
				      HEpush(DFE_NOSPACE,"SWdeftimeperiod", __FILE__, __LINE__);
				      free(time64);
				      return(-1);
				    }

				  /* Store file and swath ID */
				  /* ----------------------- */
				  SWXRegion[k]->fid = fid;
				  SWXRegion[k]->swathID = swathID;


				  /* Set number of isolated regions to 1 */
				  /* ----------------------------------- */
				  SWXRegion[k]->nRegions = 1;


				  /* Set start of region to first track found */
				  /* ---------------------------------------- */
				  SWXRegion[k]->StartRegion[0] = i;


				  /* Set Start & Stop Vertical arrays to -1 */
				  /* -------------------------------------- */
				  for (dum = 0; dum < 8; dum++)
				    {
				      SWXRegion[k]->StartVertical[dum] = -1;
				      SWXRegion[k]->StopVertical[dum] = -1;
				      SWXRegion[k]->StartScan[dum] = -1;
				      SWXRegion[k]->StopScan[dum] = -1;
				    }


				  /* Set period ID */
				  /* ------------- */
				  periodID = k;

				  break;	/* Break from "k" loop */
				}
			    }
			}
		      if (found == 1)
			{
			  break;	/* Break from "j" loop */
			}
		    }
		  if (found == 1)
		    {
		      break;	/* Break from "i" loop */
		    }
		}


	      /* Clear found flag */
	      /* ---------------- */
	      found = 0;


	      /* For each track (from bottom) ... */
	      /* -------------------------------- */
	      for (i = edge[0] - 1; i >= 0; i--)
		{
		  /* For each value from Cross Track ... */
		  /* ----------------------------------- */
		  for (j = 0; j < edge[1]; j++)
		    {

		      /* Get time test value */
		      /* ------------------- */
		      time64Test = time64[i * edge[1] + j];


		      /* If within time period ... */
		      /* ------------------------- */
		      if (time64Test >= starttime &&
			  time64Test <= stoptime)
			{
			  /* Set found flag */
			  /* -------------- */
			  found = 1;

			  /* Set start of region to first track found */
			  /* ---------------------------------------- */
			  SWXRegion[k]->StopRegion[0] = i;

			  break;	/* Break from "j" loop */
			}
		    }
		  if (found == 1)
		    {
		      break;	/* Break from "i" loop */
		    }
		}
	    }
	    free(time64);
	}
    }

    return (periodID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWextractregion                                                  |
|                                                                             |
|  DESCRIPTION: Retrieves data from specified region.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|  fieldname      char                Fieldname                               |
|  externalflag   int32               External geolocation fields flag        |
|                                     HDFE_INTERNAL (0)                       |
|                                     HDFE_EXTERNAL (1)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                Data buffer containing subsetted region |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Add vertical subsetting                             |
|  Oct 96   Joel Gales    Mapping offset value not read from SWmapinfo        |
|  Dec 96   Joel Gales    Vert Subset overwriting data buffer                 |
|  Dec 96   Joel Gales    Add multiple vertical subsetting capability         |
|  Mar 97   Joel Gales    Add support for index mapping                       |
|  Jul 99   DaW 	  Add support for floating scene subsetting 	      |
|  Feb 03   Terry Haran/                                                      |
|           Abe Taaheri   Forced map offset to 0 so that data is extracted    |
|                         without offset consideration. This will preserve    |
|                         original mapping between geofields and the data     |
|                         field.                                              |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWextractregion(int32 swathID, int32 regionID, const char *fieldname,
		int32 externalflag, VOIDP buffer)

{
    intn            i;		/* Loop index */
    intn            j = 0;      /* Loop index */
    intn            k;		/* Loop index */
    intn            l;		/* Loop index */
    intn            status;	/* routine return status variable */
    intn            long_status = 3;	/* routine return status variable    */
                                        /* for longitude                     */
    intn	    land_status = 3;	/* Used for L7 float scene sub.      */
    intn            statMap = -1;	/* Status from SWmapinfo  */

    uint8           found = 0;		/* Found flag */
    uint8           vfound = 0;		/* Found flag for vertical subsetting*/
                                        /*  --- xhua                         */
    uint8	    scene_cnt = 0;	/* Used for L7 float scene sub.      */
    uint8           detect_cnt = 0;     /* Used to convert scan to scanline  */
                                        /*  L7 float scene sub.              */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */

    int32	    numtype = 0; /* Used for L7 float scene sub. */
    int32	    count = 0;   /* Used for L7 float scene sub. */
    int32           l_index = 0;	/* Geo Dim Index */
    int32           nDim;	/* Number of dimensions */
    int32           slen[64];	/* String length array */
    int32           dum;	/* Dummy variable */
    int32           offset = 0;	/* Mapping offset */
    int32           incr = 0;	/* Mapping increment */
    int32           nXtrk;	/* Number of cross tracks */
    int32           scan_shift = 0; /* Used to take out partial scans */
    int32           dumdims[8];	/* Dimensions from SWfieldinfo */
    int32           start[8];	/* Start array for data read */
    int32           edge[8];	/* Edge array for data read */
    int32           dims[8];	/* Dimensions */
    int32           rank = 0;	/* Field rank */
    int32           rk = 0;	/* Field rank */
    int32           ntype = 0;	/* Field number type */
    int32           bufOffset = 0;	/* Output buffer offset */
    int32           size;	/* Size of data buffer */
    int32           idxMapElem = -1;	/* Number of index map elements  */
    int32          *idxmap = NULL;	/* Pointer to index mapping array */

    int32	startscanline = 0;
    int32	stopscanline = 0;
    char	*dfieldlist = (char *)NULL;
    int32	strbufsize = 0;
    int32	dfrank[8];
    int32	numtype2[8];
    uint16	*buffer2 = (uint16 *)NULL;
    uint16	*tbuffer = (uint16 *)NULL;
    int32	dims2[8];
    int32	nt = 0;
    int32	startscandim = -1;
    int32	stopscandim = -1;
    int32	rank2 = 0;

    char            dimlist[256];	/* Dimension list */
    char            geodim[256];/* Geolocation field dimension list */
    char            tgeodim[256];/* Time field dimension list */
    char            dgeodim[256];/* Data field dimension list for subsetting */
    char            utlbuf[256];/* Utility buffer */
    char           *ptr[64];	/* String pointer array */



    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWextractregion", &fid, &sdInterfaceID,
		       &swVgrpID);


    /* Check for valid region ID */
    /* ------------------------- */
    if (status == 0)
    {
	if (regionID < 0 || regionID >= NSWATHREGN)
	{
	    status = -1;
	    HEpush(DFE_RANGE, "SWextractregion", __FILE__, __LINE__);
	    HEreport("Invalid Region id: %d.\n", regionID);
	}
    }



    /* Check for active region ID */
    /* -------------------------- */
    if (status == 0)
    {
	if (SWXRegion[regionID] == 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
	    HEreport("Inactive Region ID: %d.\n", regionID);
	}
    }

    if (status == 0)
    {
      /* This code checks for the attribute detector_count */
      /* which is found in Landsat 7 files.  It is used    */
      /* for some of the loops.                            */
      /* ================================================= */
      if (SWXRegion[regionID]->scanflag == 1)
	{
	  land_status = SWattrinfo(swathID, "detector_count", &numtype, &count);
	  if (land_status == 0)
	    land_status = SWreadattr(swathID, "detector_count", &detect_cnt);
	}
    }

    /* Check that geo file and data file are same for INTERNAL subsetting */
    /* ------------------------------------------------------------------ */
    if (status == 0)
    {
	if (SWXRegion[regionID]->fid != fid && externalflag != HDFE_EXTERNAL)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
	    HEreport("Region is not defined for this file.\n");
	}
    }



    /* Check that geo swath and data swath are same for INTERNAL subsetting */
    /* -------------------------------------------------------------------- */
    if (status == 0)
    {
	if (SWXRegion[regionID]->swathID != swathID &&
	    externalflag != HDFE_EXTERNAL)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
	    HEreport("Region is not defined for this Swath.\n");
	}
    }



    /* Check for valid fieldname */
    /* ------------------------- */
    if (status == 0)
    {

	/* Get data field info */
	/* ------------------- */
	status = SWfieldinfo(swathID, fieldname, &rank,
			     dims, &ntype, dimlist);

	if (status != 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
	    HEreport("Field \"%s\" Not Found.\n", fieldname);
	}
    }


    /* No problems so proceed ... */
    /* -------------------------- */
    if (status == 0)
    {


	/* Initialize start and edge for all dimensions */
	/* -------------------------------------------- */
	for (j = 0; j < rank; j++)
	{
	    start[j] = 0;
	    edge[j] = dims[j];
	}


	/* Vertical Subset */
	/* --------------- */
	for (j = 0; j < 8; j++)
	{
	    /* If active vertical subset ... */
	    /* ----------------------------- */
	    if (SWXRegion[regionID]->StartVertical[j] != -1)
	    {

		/* Find vertical dimension within dimlist */
		/* -------------------------------------- */
		dum = EHstrwithin(SWXRegion[regionID]->DimNamePtr[j],
				  dimlist, ',');

		/* If dimension found ... */
		/* ---------------------- */
		if (dum != -1)
		{
		    /* Compute start and edge for vertical dimension */
		    /* --------------------------------------------- */
                    vfound = 1;                   /* xhua */
		    start[dum] = SWXRegion[regionID]->StartVertical[j];
		    edge[dum] = SWXRegion[regionID]->StopVertical[j] -
			SWXRegion[regionID]->StartVertical[j] + 1;
		}
		else
		{
		    /* Vertical dimension not found */
		    /* ---------------------------- */
		    status = -1;
		    HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
		    HEreport("Vertical Dimension Not Found: \"%s\".\n",
			     SWXRegion[regionID]->DimNamePtr);
		}
	    }
	} /* End of Vertical Subset loop  */



	/* No problems so proceed ... */
	/* -------------------------- */
	if (status == 0)
	{
	    /* If non-vertical subset regions defined ... */
	    /* ------------------------------------------ */
	    if (SWXRegion[regionID]->nRegions > 0)
	    {

		/* Get geolocation dimension name */
		/* ------------------------------ */
		status = SWfieldinfo(SWXRegion[regionID]->swathID,
				     "Longitude", &dum,
				     dumdims, &dum, geodim);
                long_status = status;

                /* If Time field being used, check for dimensions */
                /* ---------------------------------------------- */
                if (timeflag == 1)
                {
                   /* code change to fix time subset bug for Landsat7 */

                   status = SWfieldinfo(SWXRegion[regionID]->swathID,
                                        "Time", &dum,
                                        dumdims, &dum, tgeodim);

                   if (strcmp(geodim, tgeodim) != 0)
                   {
                      strcpy(geodim, tgeodim);
                   }
                }
                timeflag = 0;

                /* If defscanregion being used, get dimensions    */
                /* of field being used                            */
                /* ---------------------------------------------- */
                if (SWXRegion[regionID]->scanflag == 1)
                {
                   (void) SWnentries(SWXRegion[regionID]->swathID,4,&strbufsize);
                   dfieldlist = (char *)calloc(strbufsize + 1, sizeof(char));
                   (void) SWinqdatafields(SWXRegion[regionID]->swathID,dfieldlist,dfrank,numtype2);
                   status = SWfieldinfo(SWXRegion[regionID]->swathID,dfieldlist,&dum,dumdims,&dum,dgeodim);

                   /* The dimensions have to be switched, because */
                   /* the mappings force a geodim and datadim     */
                   /* so to find the mapping, the dimensions must */
                   /* be switched, but the subsetting will still  */
                   /* be based on the correct dimensions          */
                   /* ------------------------------------------- */
                   if (strcmp(dgeodim,dimlist) != 0 || long_status == -1)
                   {
                      strcpy(geodim,dimlist);
                      strcpy(dimlist,dgeodim);
                   }
                }


		/* Get "Track" (first) Dimension from geo dimlist */
		/* ---------------------------------------------- */
		nDim = EHparsestr(geodim, ',', ptr, slen);
		geodim[slen[0]] = 0;


		/* Parse Data Field Dimlist & find mapping */
		/* --------------------------------------- */
		nDim = EHparsestr(dimlist, ',', ptr, slen);


		/* Loop through all dimensions and search for mapping */
		/* -------------------------------------------------- */
		for (i = 0; i < nDim; i++)
		{
		    memcpy(utlbuf, ptr[i], slen[i]);
		    utlbuf[slen[i]] = 0;
		    statMap = SWmapinfo(swathID, geodim, utlbuf,
					&offset, &incr);


                    /*
                     *  Force offset to 0.
                     *  We're not changing the mapping, so we want
                     *  the original offset to apply to the subsetted data.
                     *  Otherwise, bad things happen, such as subsetting
                     *  past the end of the original data, and being unable
                     *  to read the first <offset> elements of the
                     *  original data.
                     *  The offset is only important for aligning the
                     *  data with interpolated (incr > 0) or decimated
                     *  (incr < 0) geolocation information for the data.
                     */

                    offset = 0;


		    /* Mapping found */
		    /* ------------- */
		    if (statMap == 0)
		    {
			found = 1;
			l_index = i;
			break;
		    }
		}


		/* If mapping not found check for geodim within dimlist */
		/* ---------------------------------------------------- */
		if (found == 0)
		{
		    l_index = EHstrwithin(geodim, dimlist, ',');

		    /* Geo dimension found within subset field dimlist */
		    /* ----------------------------------------------- */
		    if (l_index != -1)
		    {
			found = 1;
			offset = 0;
			incr = 1;
		    }
		}



		/* If mapping not found check for indexed mapping */
		/* ---------------------------------------------- */
		if (found == 0)
		{
		    /* Get size of geo dim & allocate space of index mapping */
		    /* ----------------------------------------------------- */
		    dum = SWdiminfo(swathID, geodim);

                    /* For Landsat files, the index mapping has two values   */
                    /* for each point, a left and right point.  So for a 37  */
                    /* scene band file there are 2x2 points for each scene   */
                    /* meaning, 2x2x37 = 148 values.  The above function     */
                    /* only returns the number of values in the track        */
                    /* dimension.                                            */
                    /* ----------------------------------------------------- */
                    if(land_status == 0)
                       if(strcmp(fieldname, "Latitude") == 0 ||
                          strcmp(fieldname, "Longitude") == 0)
                       {
                          dum = dum * 2;
                       }
		    idxmap = (int32 *) calloc(dum, sizeof(int32));
		    if(idxmap == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWextractregion", __FILE__, __LINE__);
			return(-1);
		    }

		    /* Loop through all dimensions and search for mapping */
		    /* -------------------------------------------------- */
		    for (i = 0; i < nDim; i++)
		    {
			memcpy(utlbuf, ptr[i], slen[i]);
			utlbuf[slen[i]] = 0;

			idxMapElem =
			    SWidxmapinfo(swathID, geodim, utlbuf, idxmap);


			/* Mapping found */
			/* ------------- */
			if (idxMapElem != -1)
			{
			    found = 1;
			    l_index = i;
			    break;
			}
		    }
		}


		/* If regular mapping found ... */
		/* ---------------------------- */
		if (found == 1 && idxMapElem == -1)
		{
		    for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
		    {
			if (k > 0)
			{
			    /* Compute size in bytes of previous region */
			    /* ---------------------------------------- */
			    size = edge[0];
			    for (j = 1; j < rank; j++)
			    {
				size *= edge[j];
			    }
			    size *= DFKNTsize(ntype);


			    /* Compute output buffer offset */
			    /* ---------------------------- */
			    bufOffset += size;
			}
			else
			{
			    /* Initialize output buffer offset */
			    /* ------------------------------- */
			    bufOffset = 0;
			}


			/* Compute number of cross tracks in region */
			/* ---------------------------------------- */
			nXtrk = SWXRegion[regionID]->StopRegion[k] -
			    SWXRegion[regionID]->StartRegion[k] + 1;


			/* Positive increment (geodim <= datadim) */
			/* -------------------------------------- */
			if (incr > 0)
			{
                           if (SWXRegion[regionID]->scanflag == 1)
                           {
                              start[l_index] = SWXRegion[regionID]->StartRegion[k]/incr;
                              if(SWXRegion[regionID]->band8flag == 2 ||
                                 SWXRegion[regionID]->band8flag == 3)
                              {
                                 start[l_index] = (SWXRegion[regionID]->StartRegion[k]+detect_cnt)/incr;
                                 status = SWfieldinfo(SWXRegion[regionID]->swathID,"scan_no",&rank,dims2,&nt,dimlist);
                                 buffer2 = (uint16 *)calloc(dims2[0], sizeof(uint16));
                                 status = SWreadfield(SWXRegion[regionID]->swathID,"scan_no",NULL,NULL,NULL,buffer2);
                                 if(incr == 1)
                                    start[l_index] = start[l_index] - (buffer2[0] * detect_cnt);
                                 else
                                    start[l_index] = start[l_index] - buffer2[0];
                                 free(buffer2);
                              }
                              scan_shift = nXtrk % incr;
                              if(scan_shift != 0)
                                 nXtrk = nXtrk - scan_shift;
			      edge[l_index] = nXtrk / incr;
                              if (nXtrk % incr != 0)
                                 edge[l_index]++;
                              if(long_status == -1 || incr == 1)
                              {
				if(detect_cnt == 0)
				  return -1;
                                 scan_shift = nXtrk % detect_cnt;
                                 if(scan_shift != 0)
                                    edge[l_index] = nXtrk - scan_shift;
                              }

                           }
                           else
                           {
			      start[l_index] = SWXRegion[regionID]->StartRegion[k] * incr + offset;
			      edge[l_index] = nXtrk * incr - offset;
                           }
			}
			else
			{
			    /* Negative increment (geodim > datadim) */
			    /* ------------------------------------- */
			    start[l_index] = SWXRegion[regionID]->StartRegion[k]
				/ (-incr) + offset;
			    edge[l_index] = nXtrk / (-incr);

			    /*
			     * If Xtrk not exactly divisible by incr, round
			     * edge to next highest integer
			     */

			    if (nXtrk % (-incr) != 0)
			    {
				edge[l_index]++;
			    }
			}


			/* Read Data into output buffer */
			/* ---------------------------- */
			status = SWreadfield(swathID, fieldname,
					     start, NULL, edge,
					     (uint8 *) buffer + bufOffset);
		    }
		}
		else if (found == 1 && idxMapElem != -1)
		{
		    /* Indexed Mapping */
		    /* --------------- */
		    for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
		    {
			if (k > 0)
			{
			    /* Compute size in bytes of previous region */
			    /* ---------------------------------------- */
			    size = edge[0];
			    for (j = 1; j < rank; j++)
			    {
				size *= edge[j];
			    }
			    size *= DFKNTsize(ntype);


			    /* Compute output buffer offset */
			    /* ---------------------------- */
			    bufOffset += size;
			}
			else
			{
			    /* Initialize output buffer offset */
			    /* ------------------------------- */
			    bufOffset = 0;
			}


			/* Compute start & edge from index mappings */
			/* ---------------------------------------- */
                        if (SWXRegion[regionID]->scanflag == 1 &&
                            strcmp(fieldname, "Latitude") == 0 ||
                            strcmp(fieldname, "Longitude") == 0)
                        {
                           if (land_status == 0)
                              status = SWreadattr(swathID, "scene_count", &scene_cnt);
                           startscanline = SWXRegion[regionID]->StartRegion[k];
                           stopscanline = SWXRegion[regionID]->StopRegion[k];
                           if(SWXRegion[regionID]->band8flag == 2 || SWXRegion[regionID]->band8flag == 3)
                           {
                               status = SWfieldinfo(swathID,"scan_no",&rk,dims2,&nt,dimlist);
                               tbuffer = (uint16 *)calloc(dims2[0], sizeof(uint16));
                               status =SWreadfield(swathID,"scan_no",NULL,NULL,NULL,tbuffer);
                               startscanline = startscanline - ((tbuffer[0] * detect_cnt) - detect_cnt);
                               stopscanline = stopscanline - ((tbuffer[0] * detect_cnt) - 1);
                           }
                           if(SWXRegion[regionID]->band8flag == 2 ||
                              SWXRegion[regionID]->band8flag == 3)
                           {
                              if(startscandim == -1)
                                 if(startscanline < idxmap[0])
                                 {
                                    startscandim = 0;
                                    start[l_index] = 0;
                                    if(stopscanline > idxmap[scene_cnt * 2 - 1])
                                    {
                                       stopscandim = scene_cnt*2 - startscandim;
                                       edge[l_index] = scene_cnt*2 - startscandim;
                                    }
                                 }
                           }
                           j = 0;
                           for (l = 0; l < scene_cnt; l++)
                           {
                              if(idxmap[j] <= startscanline && idxmap[j+1] >= startscanline)
                                 if(startscandim == -1)
                                 {
                                    start[l_index] = j;
                                    startscandim = j;
                                 }
                              if(idxmap[j] <= stopscanline && idxmap[j+1] >= stopscanline)
                                 if(startscandim != -1)
                                 {
                                    edge[l_index] = j - start[l_index] + 2;
                                    stopscandim = j - start[l_index] + 1;
                                 }
                              j = j + 2;
                           }
                           if(SWXRegion[regionID]->band8flag == 1 ||
                              SWXRegion[regionID]->band8flag == 2)
                           {
                              if(startscandim == -1)
                                 if(startscanline < idxmap[0])
                                 {
                                    startscandim = 0;
                                    start[l_index] = 0;
                                 }
                              if(stopscandim == -1)
                                 if(stopscanline > idxmap[scene_cnt * 2 - 1])
                                 {
                                    stopscandim = scene_cnt*2 - start[l_index];
                                    edge[l_index] = scene_cnt*2 - start[l_index];
                                 }
                           }
                           if(SWXRegion[regionID]->band8flag == 2)
                           {
                              if(startscandim == -1)
                                 if(startscanline > idxmap[j - 1])
                                 {
                                    status = SWfieldinfo(SWXRegion[regionID]->swathID,"scan_no",&rank2,dims2,&nt,dimlist);
                                    buffer2 = (uint16 *)calloc(dims2[0], sizeof(uint16));
                                    status = SWreadfield(SWXRegion[regionID]->swathID,"scan_no",NULL,NULL,NULL,buffer2);
                                    startscanline = startscanline - (buffer2[0] * detect_cnt);
                                    stopscanline = stopscanline - (buffer2[0] * detect_cnt);
                                    free(buffer2);
                                    j = 0;
                                    for (l = 0; l < scene_cnt; l++)
                                    {
                                       if(idxmap[j] <= startscanline && idxmap[j+1] >= startscanline)
                                       {
                                          start[l_index] = j;
                                       }
                                       if(idxmap[j] <= stopscanline && idxmap[j+1] >= stopscanline)
                                          edge[l_index] = j - start[l_index] + 2;
                                       j = j + 2;
                                       if(idxmap[j] == 0  || idxmap[j+1] == 0)
                                          l = scene_cnt;
                                    }

                                 }
                           }

                        }
                        else if(SWXRegion[regionID]->scanflag == 1 &&
                        strcmp(fieldname, "scene_center_latitude") == 0 ||
                        strcmp(fieldname, "scene_center_longitude") == 0)
                        {
                           if (land_status == 0)
                              status = SWreadattr(swathID, "scene_count", &scene_cnt);
                           startscanline = SWXRegion[regionID]->StartRegion[k];
                           stopscanline = SWXRegion[regionID]->StopRegion[k];
                           if(startscanline < idxmap[0])
                           {
                              startscandim = 0;
                              start[l_index] = 0;
                           }
                           for (l = 0; l < scene_cnt-1; l++)
                           {
                              if(idxmap[l] <= startscanline && idxmap[l+1] >= startscanline)
                                 if(startscandim == -1)
                                 {
                                    start[l_index] = l;
                                    startscandim = l;
                                 }
                              if(idxmap[l] <= stopscanline && idxmap[l+1] >= stopscanline)
                                 if(stopscandim == -1)
                                 {
                                    edge[l_index] = l - start[l_index] + 2;
                                    stopscandim = l + 1;
                                 }
                            }
                            if(stopscandim == -1)
                            {
                               if(stopscanline > idxmap[scene_cnt - 1])
                               {
                                  edge[l_index] = scene_cnt - start[l_index];
                                  stopscandim = scene_cnt - 1;
                               }
                            }

                            if(SWXRegion[regionID]->band8flag == 1)
                            {
                               if(stopscandim == -1)
                                  if(stopscanline > idxmap[scene_cnt - 1])
                                  {
                                     edge[l_index] = scene_cnt - start[l_index];
                                     stopscandim = scene_cnt -1;
                                  }
                            }
                            if(SWXRegion[regionID]->band8flag == 2 ||
                               SWXRegion[regionID]->band8flag == 3)
                            {
                               if(startscandim == -1)
                               {
                                  if(startscanline < idxmap[0])
                                  {
                                     startscandim = 0;
                                     start[l_index] = 0;
                                     edge[l_index] = stopscandim - startscandim + 1;
                                  }
                               }
                               if(startscandim == -1)
                               {
                                  startscanline = SWXRegion[regionID]->StartScan[k] * detect_cnt - detect_cnt;
                                  stopscanline = SWXRegion[regionID]->StopScan[k] * detect_cnt - 1;
                                  for (l = 0; l < scene_cnt-1; l++)
                                  {
                                     if(idxmap[l] <= startscanline && idxmap[l+1] >= startscanline)
                                        start[l_index] = l;
                                     if(idxmap[l] <= stopscanline && idxmap[l+1] >= stopscanline)
                                        edge[l_index] = l - start[l_index] + 1;
                                  }
                               }
                           }
                        }
                        else
                        {
                           if (SWXRegion[regionID]->scanflag == 1 &&
                               strcmp(fieldname,dfieldlist) == 0)
                           {
                              start[l_index] = SWXRegion[regionID]->StartRegion[k];
                              edge[l_index] = SWXRegion[regionID]->StopRegion[k] -
                                             SWXRegion[regionID]->StartRegion[k] + 1;
                              if(SWXRegion[regionID]->band8flag == 2 ||
				 SWXRegion[regionID]->band8flag == 3 )
                              {
                                 status = SWfieldinfo(SWXRegion[regionID]->swathID,"scan_no",&rank,dims2,&nt,dimlist);
                                 buffer2 = (uint16 *)calloc(dims2[0], sizeof(uint16));
                                 status = SWreadfield(SWXRegion[regionID]->swathID,"scan_no",NULL,NULL,NULL,buffer2);
                                 start[l_index] = start[l_index] - (buffer2[0] * detect_cnt - detect_cnt);
                                 free(buffer2);
                              }
                           }
                           else
                           {
			      start[l_index] = idxmap[SWXRegion[regionID]->StartRegion[k]];

			      edge[l_index] = idxmap[SWXRegion[regionID]->StopRegion[k]] -
			                 idxmap[SWXRegion[regionID]->StartRegion[k]] + 1;
                           }
                        }
			/* Read Data into output buffer */
			/* ---------------------------- */
			status = SWreadfield(swathID, fieldname,
					     start, NULL, edge,
					     buffer);
                        if (SWXRegion[regionID]->scanflag == 1)
                        {

                           if (strcmp(fieldname,"Longitude") == 0)
                           {
                              status = SWscan2longlat(swathID, fieldname, buffer, start,
                                              edge, idxmap, startscanline, stopscanline);
                           }
                           if (strcmp(fieldname,"Latitude") == 0)
                           {
                              status = SWscan2longlat(swathID, fieldname, buffer, start,
                                              edge, idxmap, startscanline, stopscanline);
                           }
                        }
		    }
		}
		else if(vfound == 1)                          /* Vertical subsetting */
                {                                             /* found previously,   */
                   status = SWreadfield(swathID, fieldname,   /* perform the vertical*/
                                        start, NULL, edge,    /* subsetting.         */
                                        (uint8 *) buffer);    /* -- xhua             */
                }
                else
		{
		    /* Mapping not found */
		    /* ----------------- */
		    status = -1;
		    HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
		    HEreport("Mapping Not Defined for \"%s\" Dimension.\n",
			     geodim);
		}
	    }
	    else
	    {
		/* Read Data (Vert SS only) */
		/* ------------------------ */
		status = SWreadfield(swathID, fieldname,
				     start, NULL, edge,
				     (uint8 *) buffer);
	    }
	}
    }

    /* Free index mappings if applicable */
    /* --------------------------------- */
    if (idxmap != NULL)
    {
	free(idxmap);
    }
    if(dfieldlist != NULL)
       free(dfieldlist);

    return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWscan2longlat                                                   |
|                                                                             |
|  DESCRIPTION:  Convert scanline to Long/Lat for floating scene subsetting.  |
|                This will calculate/interpolate the long/lat for a given     |
|                scanline.                                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  fieldname      char                Fieldname                               |
|  buffer	  void		      Values to update                        |
|  start	  int32		                                              |
|  edge		  int32							      |
|  idxmap	  int32 *	      Buffer of index mapping values          |
|  startscanline  int32		      Start of scan region		      |
|  stopscanline   int32		      Stop of scan region		      |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jul 99   DaW           Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWscan2longlat(int32 swathID, const char *fieldname, VOIDP buffer, int32 start[],
int32 edge[], int32 *idxmap, int32 startscanline, int32 stopscanline)
{

   enum corner {UL, UR, LL, LR};
   enum corner pos = UL;
   enum corner pos2 = UL;

   uint8	scene_cnt = 0;		/* Used to convert scan to scanline  */
                                        /*  L7 float scene sub.              */
   float32	*buffer2;
   float32	*bufferc;
   float32	deg2rad = (float32)(M_PI/180.00);

   float32	p1_long = 0.0;	/* point 1, longitude */
   float32	p2_long = 0.0;	/* point 2, longitude */
   float32	pi_long = 0.0;	/* interpolated point, longitude */
   int32	scanline_p1 = 0;

   float32	p1_lat = 0.0;	/* point 1, latitude */
   float32	p2_lat = 0.0;	/* point 2, latitude */
   float32	pi_lat = 0.0;	/* interpolated point, latitude */
   int32	scanline_p2 = 0;


   float32	x_p1 = 0.0;		/* Cartesian coordinates */
   float32	y_p1 = 0.0;		/* point 1               */
   float32	z_p1 = 0.0;

   float32	x_p2 = 0.0;		/* Cartesian coordinates */
   float32	y_p2 = 0.0;		/* point 2		 */
   float32	z_p2 = 0.0;

   float32	x_pi = 0.0;		/* Cartesian coordinates */
   float32	y_pi = 0.0;		/* interpolated point    */
   float32	z_pi = 0.0;
   int32	scanline_pi = 0;

   intn		status = -1;

   int		i = 0;
   int		p1_long_l90_flag = 0;
   int		p1_long_g90_flag = 0;
   int		p2_long_l90_flag = 0;
   int		p2_long_g90_flag = 0;
   int		fieldflag = 0;

   int	numofval = 0;

   numofval = edge[0] * 2;

   buffer2 = (float32 *)calloc(numofval, sizeof(float32));
   bufferc = (float32 *)calloc(numofval, sizeof(float32));
   memmove(bufferc, buffer, numofval*sizeof(float32));

   (void) SWreadattr(swathID, "scene_count", &scene_cnt);

   if (strcmp(fieldname, "Longitude") == 0)
   {
      fieldflag = 1;
      status = SWreadfield(swathID, "Latitude", start, NULL, edge, buffer2);
   }
   else if (strcmp(fieldname, "Latitude") == 0)
   {
      fieldflag = 2;
      status = SWreadfield(swathID, "Longitude", start, NULL, edge, buffer2);
   }

   for(i=0; i<4; i++)
   {
      switch(pos)
      {
         case UL:
            if (fieldflag == 1)
            {
               p1_long = bufferc[0];
               p2_long = bufferc[2];
               p1_lat = buffer2[0];
               p2_lat = buffer2[2];
            }
            if (fieldflag == 2)
            {
               p1_long = buffer2[0];
               p2_long = buffer2[2];
               p1_lat = bufferc[0];
               p2_lat = bufferc[2];
            }
            scanline_p1 = idxmap[start[0]];
            scanline_p2 = idxmap[start[0]+1];
            scanline_pi = startscanline;
            pos = UR;
            break;
         case UR:
            if (fieldflag == 1)
            {
               p1_long = bufferc[1];
               p2_long = bufferc[3];
               p1_lat = buffer2[1];
               p2_lat = buffer2[3];
            }
            if (fieldflag == 2)
            {
               p1_long = buffer2[1];
               p2_long = buffer2[3];
               p1_lat = bufferc[1];
               p2_lat = bufferc[3];
            }
            scanline_p1 = idxmap[start[0]];
            scanline_p2 = idxmap[start[0]+1];
            scanline_pi = startscanline;
            pos = LL;
            break;
         case LL:
            if (fieldflag == 1)
            {
               p1_long = bufferc[numofval-4];
               p2_long = bufferc[numofval-2];
               p1_lat = buffer2[numofval-4];
               p2_lat = buffer2[numofval-2];
            }
            if (fieldflag == 2)
            {
               p1_long = buffer2[numofval-4];
               p2_long = buffer2[numofval-2];
               p1_lat = bufferc[numofval-4];
               p2_lat = bufferc[numofval-2];
            }
            scanline_p1 = idxmap[start[0] + edge[0] - 2];
            scanline_p2 = idxmap[start[0] + edge[0] - 1];
            scanline_pi = stopscanline;
            pos = LR;
            break;
         case LR:
            if (fieldflag == 1)
            {
               p1_long = bufferc[numofval-3];
               p2_long = bufferc[numofval-1];
               p1_lat = buffer2[numofval-3];
               p2_lat = buffer2[numofval-1];
            }
            if (fieldflag == 2)
            {
               p1_long = buffer2[numofval-3];
               p2_long = buffer2[numofval-1];
               p1_lat = bufferc[numofval-3];
               p2_lat = bufferc[numofval-1];
            }
            scanline_p1 = idxmap[start[0] + edge[0] - 2];
            scanline_p2 = idxmap[start[0] + edge[0] - 1];
            scanline_pi = stopscanline;
            break;
      }



   if (p1_long <= -90.0)
   {
      if (p2_long >= 90.0)
      {
         p1_long = p1_long + 180.0f;
         p2_long = p2_long - 180.0f;
         p1_long_l90_flag = 2;
      }
      else
      {
         p1_long = p1_long + 180.0f;
         p1_long_l90_flag = 1;
      }
   }
   if (p1_long >= 90.0 && p1_long_l90_flag != 2)
   {
      if(p2_long <= -90.0)
      {
         p1_long = p1_long - 180.0f;
         p2_long = p2_long + 180.0f;
         p1_long_g90_flag = 2;
      }
      else
      {
         p1_long = p1_long - 90.0f;
         p1_long_g90_flag = 1;
      }
   }
   if (p2_long <= -90.0)
   {
      if (p1_long < 0.0)
      {
         p2_long = p2_long + 90.0f;
         p1_long = p1_long + 90.0f;
         p2_long_l90_flag = 2;
      }
      else
      {
         p2_long = p2_long + 180.0f;
         p2_long_l90_flag = 1;
      }
   }
   if (p2_long >= 90.0 && p1_long_l90_flag != 2)
   {
      p2_long = p2_long - 90.0f;
      p2_long_g90_flag = 1;
   }


   x_p1 = (float)(RADOE * cos((p1_long*deg2rad)) * sin((p1_lat*deg2rad)));
   y_p1 = (float)(RADOE * sin((p1_long*deg2rad)) * sin((p1_lat*deg2rad)));
   z_p1 = (float)(RADOE * cos((p1_lat*deg2rad)));


   x_p2 = (float)(RADOE * cos((p2_long*deg2rad)) * sin((p2_lat*deg2rad)));
   y_p2 = (float)(RADOE * sin((p2_long*deg2rad)) * sin((p2_lat*deg2rad)));
   z_p2 = (float)(RADOE * cos((p2_lat*deg2rad)));

   x_pi = x_p1 + (x_p2 - x_p1)*(scanline_pi-scanline_p1)/(scanline_p2-scanline_p1);
   y_pi = y_p1 + (y_p2 - y_p1)*(scanline_pi-scanline_p1)/(scanline_p2-scanline_p1);
   z_pi = z_p1 + (z_p2 - z_p1)*(scanline_pi-scanline_p1)/(scanline_p2-scanline_p1);

   if (fieldflag == 1)
   {
     pi_long = (float)(atan(y_pi/x_pi)*180.0/M_PI);
      if (p1_long_l90_flag == 1 || p2_long_l90_flag == 1)
      {
         pi_long = pi_long - 180.0f;
         p1_long_l90_flag = 0;
	 p2_long_l90_flag = 0;
      }
      if (p1_long_g90_flag == 1 || p2_long_g90_flag == 1)
      {
         pi_long = pi_long + 90.0f;
         p1_long_g90_flag = 0;
         p2_long_g90_flag = 0;
      }
      if (p1_long_l90_flag == 2)
      {
         if (pi_long > 0.0)
            pi_long = pi_long - 180.0f;
         else if (pi_long < 0.0)
            pi_long = pi_long + 180.0f;
         p1_long_l90_flag = 0;
      }
      if (p1_long_g90_flag == 2)
      {
         if (pi_long > 0.0)
            pi_long = pi_long - 180.0f;
         else if (pi_long < 0.0)
            pi_long = pi_long + 180.0f;
         p1_long_g90_flag = 0;
      }
      if (p2_long_l90_flag == 2)
      {
         pi_long = pi_long - 90.0f;
         p2_long_l90_flag = 0;
      }



      switch(pos2)
      {
      case UL:
         bufferc[0] = pi_long;
         pos2 = UR;
         break;
      case UR:
         bufferc[1] = pi_long;
         pos2 = LL;
         break;
      case LL:
         if(stopscanline > idxmap[scene_cnt*2 - 1])
            break;
         bufferc[numofval-2] = pi_long;
         pos2 = LR;
         break;
      case LR:
         if(stopscanline > idxmap[scene_cnt*2 - 1])
            break;
         bufferc[numofval-1] = pi_long;
         break;
      }

    }
    if (fieldflag == 2)
    {
      pi_lat = (float)(atan((sqrt(x_pi*x_pi + y_pi*y_pi)/z_pi))*180.0/M_PI);
      switch(pos2)
      {
      case UL:
         bufferc[0] = pi_lat;
         pos2 = UR;
         break;
      case UR:
         bufferc[1] = pi_lat;
         pos2 = LL;
         break;
      case LL:
         if(stopscanline > idxmap[scene_cnt*2 - 1])
            break;
         bufferc[numofval-2] = pi_lat;
         pos2 = LR;
         break;
      case LR:
         if(stopscanline > idxmap[scene_cnt*2 - 1])
            break;
         bufferc[numofval-1] = pi_lat;
         break;
      }
   }
   }
   memmove(buffer, bufferc, numofval*sizeof(float32));
   free(buffer2);
   free(bufferc);
   return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWextractperiod                                                  |
|                                                                             |
|  DESCRIPTION: Retrieves data from specified period.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  periodID       int32               Period ID                               |
|  fieldname      char                Fieldname                               |
|  externalflag   int32               External geolocation fields flag        |
|                                     HDFE_INTERNAL (0)                       |
|                                     HDFE_EXTERNAL (1)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                Data buffer containing subsetted region |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Jun 03   Abe Taaheri   added clearing timeflag if SWextractregion fails    |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWextractperiod(int32 swathID, int32 periodID, const char *fieldname,
		int32 externalflag, VOIDP buffer)

{
    intn            status;	/* routine return status variable */

    timeflag = 1;

    /* Call SWextractregion routine */
    /* ---------------------------- */
    status = SWextractregion(swathID, periodID, fieldname, externalflag,
			     (char *) buffer);
    if (status != 0) timeflag = 0; /*clear timeflag if SWextractregion failed*/
    return (status);
}







/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdupregion                                                      |
|                                                                             |
|  DESCRIPTION: Duplicates a region                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  newregionID    int32               New region ID                           |
|                                                                             |
|  INPUTS:                                                                    |
|  oldregionID    int32               Old region ID                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jan 97   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWdupregion(int32 oldregionID)
{
    intn            i;		/* Loop index */

    int32           newregionID = -1;	/* New region ID */


    /* Find first empty (inactive) region */
    /* ---------------------------------- */
    for (i = 0; i < NSWATHREGN; i++)
    {
	if (SWXRegion[i] == 0)
	{
	    /* Allocate space for new swath region entry */
	    /* ----------------------------------------- */
	    SWXRegion[i] = (struct swathRegion *)
		calloc(1, sizeof(struct swathRegion));
	    if(SWXRegion[i] == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdupregion", __FILE__, __LINE__);
		return(-1);
	    }

	    /* Copy old region structure data to new region */
	    /* -------------------------------------------- */
	    *SWXRegion[i] = *SWXRegion[oldregionID];


	    /* Define new region ID */
	    /* -------------------- */
	    newregionID = i;

	    break;
	}
    }

    return (newregionID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWregioninfo                                                     |
|                                                                             |
|  DESCRIPTION: Returns size of region in bytes                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|  fieldname      char                Fieldname                               |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int32               field number type                       |
|  rank           int32               field rank                              |
|  dims           int32               dimensions of field region              |
|  size           int32               size in bytes of field region           |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Add vertical subsetting                             |
|  Dec 96   Joel Gales    Add multiple vertical subsetting capability         |
|  Mar 97   Joel Gales    Add support for index mapping                       |
|  Jul 99   DaW           Add support for floating scene subsetting           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWregioninfo(int32 swathID, int32 regionID, const char *fieldname,
	     int32 * ntype, int32 * rank, int32 dims[], int32 * size)

{
    intn            i;		/* Loop index */
    intn            j = 0;	/* Loop index */
    intn            k = 0;		/* Loop index */
    intn            l = 0;		/* Loop index */
    intn            status;	/* routine return status variable */
    intn            long_status = 3;	/* routine return status variable for longitude */
    intn            land_status = 3;    /* Used for L7 float scene sub.      */
    intn            statMap = -1;   /* Status from SWmapinfo  */

    uint8           found = 0;	/* Found flag */
    uint8           detect_cnt = 0;	/* Used for L7 float scene sub.      */

    int32           numtype = 0; /* Used for L7 float scene sub. */
    int32           count = 0;   /* Used for L7 float scene sub. */


    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */

    int32           l_index = 0;	/* Geo Dim Index */
    int32           nDim;	/* Number of dimensions */
    int32           slen[64];	/* String length array */
    int32           dum;	/* Dummy variable */
    int32           incr = 0;	/* Mapping increment */
    int32           nXtrk = 0;	/* Number of cross tracks */
    int32	    scan_shift = 0; /* Used to take out partial scans */
    int32	    startscandim = -1;    /* Used for floating scene region size */
    int32	    stopscandim = -1;    /* Used for floating scene region size */
    int32           dumdims[8];	/* Dimensions from SWfieldinfo */
    int32           idxMapElem = -1;	/* Number of index map elements  */
    int32          *idxmap = NULL;	/* Pointer to index mapping array */
    int32	    datafld = 0;

   uint8	scene_cnt = 0;		/* Number of scenes in swath */
   int32	startscanline = 0;
   int32	stopscanline = 0;
   char		*dfieldlist = (char *)NULL;
   int32	strbufsize = 0;
   int32	dfrank[8];
   int32	numtype2[8];
   int32	rank2 = 0;
   int32	rk = 0;
   int32	dims2[8];
   int32	nt = 0;
   uint16	*buffer2 = (uint16 *)NULL;
   uint16	*tbuffer = (uint16 *)NULL;

    char            dimlist[256];	/* Dimension list */
    char            geodim[256];/* Geolocation field dimension list */
    char            tgeodim[256];/* Time Geolocation field dimension list */
    char            dgeodim[256];/* Data Subsetting field dimension list */
    char            utlbuf[256];/* Utility buffer */
    char           *ptr[64];	/* String pointer array */
    const char     *errMesg = "Vertical Dimension Not Found: \"%s\".\n";



    /* Set region size to -1 */
    /* --------------------- */
    *size = -1;


    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWregioninfo", &fid, &sdInterfaceID,
		       &swVgrpID);


    /* Check for valid region ID */
    /* ------------------------- */
    if (status == 0)
    {
	if (regionID < 0 || regionID >= NSWATHREGN)
	{
	    status = -1;
	    HEpush(DFE_RANGE, "SWregioninfo", __FILE__, __LINE__);
	    HEreport("Invalid Region id: %d.\n", regionID);
	}
    }



    /* Check for active region ID */
    /* -------------------------- */
    if (status == 0)
    {
	if (SWXRegion[regionID] == 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWregioninfo", __FILE__, __LINE__);
	    HEreport("Inactive Region ID: %d.\n", regionID);
	}
    }

    if (status == 0)
    {
      /* This code checks for the attribute detector_count */
      /* which is found in Landsat 7 files.  It is used    */
      /* for some of the loops.                            */
      /* ================================================= */
      if (SWXRegion[regionID]->scanflag == 1)
	{
	  land_status = SWattrinfo(swathID, "detector_count", &numtype, &count);
	  if (land_status == 0)
	    {
	      land_status = SWreadattr(swathID, "detector_count", &detect_cnt);
	      land_status = SWreadattr(swathID, "scene_count", &scene_cnt);

	    }
	}
    }


    /* Check for valid fieldname */
    /* ------------------------- */
    if (status == 0)
    {
	/* Get data field info */
	/* ------------------- */
	status = SWfieldinfo(swathID, fieldname, rank,
			     dims, ntype, dimlist);

	if (status != 0)
	{
	    status = -1;
	    HEpush(DFE_GENAPP, "SWregioninfo", __FILE__, __LINE__);
	    HEreport("Field \"%s\" Not Found.\n", fieldname);
	}
    }



    /* No problems so proceed ... */
    /* -------------------------- */
    if (status == 0)
    {
	/* If non-vertical subset regions defined ... */
	/* ------------------------------------------ */
	if (SWXRegion[regionID]->nRegions > 0 || SWXRegion[regionID]->scanflag == 1)
	{

	    /* Get geolocation dimension name */
	    /* ------------------------------ */
	    status = SWfieldinfo(SWXRegion[regionID]->swathID,
				 "Longitude", &dum,
				 dumdims, &dum, geodim);
            long_status = status;

            /* If Time field being used, check for dimensions */
            /* ---------------------------------------------- */
            if (timeflag == 1)
            {
               /* code change to fix time subset bug for Landsat7 */

               status = SWfieldinfo(SWXRegion[regionID]->swathID,
                                    "Time", &dum,
                                    dumdims, &dum, tgeodim);

               if (strcmp(geodim, tgeodim) != 0)
               {
                  strcpy(geodim, tgeodim);
               }
            timeflag = 0;
            }

            /* If defscanregion being used, get dimensions    */
            /* of field being used                            */
            /* ---------------------------------------------- */
            if (SWXRegion[regionID]->scanflag == 1)
            {
               (void) SWnentries(SWXRegion[regionID]->swathID,4,&strbufsize);
               dfieldlist = (char *)calloc(strbufsize + 1, sizeof(char));
               (void) SWinqdatafields(SWXRegion[regionID]->swathID,dfieldlist,dfrank,numtype2);
               status = SWfieldinfo(SWXRegion[regionID]->swathID,dfieldlist,&dum,dumdims,&dum,dgeodim);

                  /* The dimensions have to be switched, because */
                  /* the mappings force a geodim and datadim     */
                  /* so to find the mapping, the dimensions must */
                  /* be switched, but the subsetting will still  */
                  /* be based on the correct dimensions          */
                  /* "long_status == -1" added for CAL file which   */
                  /* doesn't have a Traditional geolocation field   */
                  /* ---------------------------------------------- */
                  if (strcmp(dgeodim,dimlist) != 0 || long_status == -1)
                  {
                      strcpy(geodim,dimlist);
                      strcpy(dimlist,dgeodim);
                  }
            }


	    /* Get "Track" (first) Dimension from geo dimlist */
	    /* ---------------------------------------------- */
	    nDim = EHparsestr(geodim, ',', ptr, slen);
	    geodim[slen[0]] = 0;


	    /* Parse Data Field Dimlist & find mapping */
	    /* --------------------------------------- */
	    nDim = EHparsestr(dimlist, ',', ptr, slen);


	    /* Loop through all dimensions and search for mapping */
	    /* -------------------------------------------------- */
	    for (i = 0; i < nDim; i++)
	    {
		memcpy(utlbuf, ptr[i], slen[i]);
		utlbuf[slen[i]] = 0;
		statMap = SWmapinfo(swathID, geodim, utlbuf,
				    &dum, &incr);

		/* Mapping found */
		/* ------------- */
		if (statMap == 0)
		{
		    found = 1;
		    l_index = i;
		    break;
		}
	    }


	    /* If mapping not found check for geodim within dimlist */
	    /* ---------------------------------------------------- */
	    if (found == 0)
	    {
		l_index = EHstrwithin(geodim, dimlist, ',');

		/* Geo dimension found within subset field dimlist */
		/* ----------------------------------------------- */
		if (l_index != -1)
		{
		    found = 1;
		    incr = 1;
		}
	    }



	    /* If mapping not found check for indexed mapping */
	    /* ---------------------------------------------- */
	    if (found == 0)
	    {
		/* Get size of geo dim & allocate space of index mapping */
		/* ----------------------------------------------------- */
		dum = SWdiminfo(swathID, geodim);
		idxmap = (int32 *) calloc(dum, sizeof(int32));
		if(idxmap == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWregioninfo", __FILE__, __LINE__);
		    return(-1);
		}

		/* Loop through all dimensions and search for mapping */
		/* -------------------------------------------------- */
		for (i = 0; i < nDim; i++)
		{
		    memcpy(utlbuf, ptr[i], slen[i]);
		    utlbuf[slen[i]] = 0;

		    idxMapElem = SWidxmapinfo(swathID, geodim, utlbuf, idxmap);


		    /* Mapping found */
		    /* ------------- */
		    if (idxMapElem != -1)
		    {
			found = 1;
			l_index = i;
			break;
		    }
		}
	    }


	    /* Regular Mapping Found */
	    /* --------------------- */
	    if (found == 1 && idxMapElem == -1)
	    {
		dims[l_index] = 0;

		/* Loop through all regions */
		/* ------------------------ */
		for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
		{
		    /* Get number of cross tracks in particular region */
		    /* ----------------------------------------------- */
		    nXtrk = SWXRegion[regionID]->StopRegion[k] -
			SWXRegion[regionID]->StartRegion[k] + 1;


		    /* If increment is positive (geodim <= datadim) ... */
		    /* ------------------------------------------------ */
		    if (incr > 0)
		    {
                        if (SWXRegion[regionID]->scanflag == 1)
                        {
                            scan_shift = nXtrk % incr;
                            if(scan_shift != 0)
                               nXtrk = nXtrk - scan_shift;
                            dims[l_index] += nXtrk/incr;
                            if(long_status == -1 || incr == 1)
                            {
			      if(detect_cnt == 0)
				return -1;
                               scan_shift = nXtrk % detect_cnt;
                               if(scan_shift != 0)
                                  dims[l_index] = nXtrk - scan_shift;
                            }
                        }
			else
                        {
			   dims[l_index] += nXtrk * incr;
                        }
		    }
		    else
		    {
			/* Negative increment (geodim > datadim) */
			/* ------------------------------------- */
			dims[l_index] += nXtrk / (-incr);

			/*
			 * If Xtrk not exactly divisible by incr, round dims
			 * to next highest integer
			 */
			if (nXtrk % (-incr) != 0)
			{
			    dims[l_index]++;
			}
		    }
		}
	    }
	    else if (found == 1 && idxMapElem != -1)
	    {

		/* Indexed Mapping */
		/* --------------- */

		dims[l_index] = 0;

		/* Loop through all regions */
		/* ------------------------ */
		for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
		{
                   j = 0;
                   if(SWXRegion[regionID]->scanflag == 1)
                   {
                      startscanline = SWXRegion[regionID]->StartRegion[k];
                      stopscanline = SWXRegion[regionID]->StopRegion[k];
                      if (strcmp(fieldname,dfieldlist) == 0)
                      {
                         dims[l_index] = stopscanline - startscanline + 1;
                         datafld = 1;
                      }
                      if (strcmp(fieldname, "Latitude") == 0 ||
                          strcmp(fieldname, "Longitude") == 0)
                      {
                         if(SWXRegion[regionID]->band8flag == 2 || SWXRegion[regionID]->band8flag == 3)
                         {
                            status = SWfieldinfo(swathID,"scan_no",&rk,dims2,&nt,dimlist);
			    if(status == 0){
			      tbuffer = (uint16 *)calloc(dims2[0], sizeof(uint16));
			      status =SWreadfield(swathID,"scan_no",NULL,NULL,NULL,tbuffer);
			      if(status == 0){
				startscanline = startscanline - ((tbuffer[0] * detect_cnt) - detect_cnt);
				stopscanline = stopscanline - ((tbuffer[0] * detect_cnt) - 1);
			      }
			      else
				{
				  status = -1;
				  HEpush(DFE_GENAPP, "SWregioninfo",
					 __FILE__, __LINE__);
				  HEreport("Cannot read field \"%s\".\n", "scan_no");
				  return(status);
				}
			    }
			    else
			      {
				status = -1;
				HEpush(DFE_GENAPP, "SWregioninfo",
				       __FILE__, __LINE__);
				HEreport("Cannot get field info for \"%s\".\n","scan_no");
				  return(status);
			      }
			 }
                         if(SWXRegion[regionID]->band8flag == 2 ||
                            SWXRegion[regionID]->band8flag == 3)
                         {
                            if(startscandim == -1)
                               if(startscanline < idxmap[0])
                               {
                                  startscandim = 0;
                                  dims[l_index] = 0;
                                  if(stopscanline > idxmap[scene_cnt *2 - 1])
                                  {
                                     stopscandim = scene_cnt*2 - startscandim;
                                     dims[l_index] = scene_cnt*2 - startscandim;
                                  }
                               }
                         }
                         for (l = 0; l < scene_cnt; l++)
                         {
                            if(idxmap[j] <= startscanline && idxmap[j+1] >= startscanline)
                               if(startscandim == -1)
                               {
                                  dims[l_index] = j;
                                  startscandim = j;
                               }
                            if(idxmap[j] <= stopscanline && idxmap[j+1] >= stopscanline)
                               if(startscandim != -1)
                               {
                                  dims[l_index] = j - startscandim + 2;
                                  stopscandim = j + 1;
                               }
                            j = j + 2;
                            if(idxmap[j] == 0  || idxmap[j+1] == 0)
                               l = scene_cnt;
                         }
                         if(SWXRegion[regionID]->band8flag == 1 ||
                            SWXRegion[regionID]->band8flag == 2)
                         {
                            if(stopscandim == -1)
                               if(stopscanline > idxmap[scene_cnt * 2 - 1])
                               {
                                  stopscandim = scene_cnt*2 - dims[l_index];
                                  dims[l_index] = scene_cnt*2 - dims[l_index];
                               }
                         }
                         if(SWXRegion[regionID]->band8flag == 3)
                         {
                            if(startscandim == -1)
                               if(startscanline < idxmap[0])
                               {
                                  startscandim = 0;
                                  if(stopscandim != -1)
                                     dims[l_index] = stopscandim - startscandim + 1;
                               }
                         }
                         if(SWXRegion[regionID]->band8flag == 2)
                         {
                            if(startscandim == -1)
                               if(startscanline > idxmap[j - 1])
                               {
                                  status = SWfieldinfo(SWXRegion[regionID]->swathID,"scan_no",&rank2,dims2,&nt,dimlist);
                                  buffer2 = (uint16 *)calloc(dims2[0], sizeof(uint16));
                                  status = SWreadfield(SWXRegion[regionID]->swathID,"scan_no",NULL,NULL,NULL,buffer2);
                                  startscanline = startscanline - (buffer2[0] * detect_cnt);
                                  stopscanline = stopscanline - (buffer2[0] * detect_cnt);
                                  free(buffer2);
                                  j = 0;
                                  for (l = 0; l < scene_cnt; l++)
                                  {
                                     if(idxmap[j] <= startscanline && idxmap[j+1] >= startscanline)
                                     {
                                        dims[l_index] = j;
                                        startscandim = j;
                                     }
                                     if(idxmap[j] <= stopscanline && idxmap[j+1] >= stopscanline)
                                        dims[l_index] = j - startscandim + 2;
                                     j = j + 2;
                                     if(idxmap[j] == 0  || idxmap[j+1] == 0)
                                        l = scene_cnt;
                                  }

                               }
                         }
                      }
                      if (strcmp(fieldname, "scene_center_latitude") == 0 ||
                          strcmp(fieldname, "scene_center_longitude") == 0)
                      {
                         startscanline = SWXRegion[regionID]->StartRegion[k];
                         stopscanline = SWXRegion[regionID]->StopRegion[k];
                         if(startscanline < idxmap[0])
                         {
                            startscandim = 0;
                            dims[l_index] = 0;
                         }
                         for (l = 0; l < scene_cnt-1; l++)
                         {
                            if(idxmap[l] <= startscanline && idxmap[l+1] >= startscanline)
                               if(startscandim == -1)
                               {
                                  dims[l_index] = l;
                                  startscandim = l;
                               }
                            if(idxmap[l] <= stopscanline && idxmap[l+1] >= stopscanline)
                            {
                               dims[l_index] = l - startscandim + 2;
                               stopscandim = l + 1;
                            }
                         }
                         if(stopscandim == -1)
                         {
                            if(stopscanline > idxmap[scene_cnt - 1])
                            {
                               dims[l_index] = scene_cnt - startscandim;
                               stopscandim = scene_cnt - 1;
                            }
                         }
                         if(SWXRegion[regionID]->band8flag == 1)
                         {
                            if(stopscandim == -1)
                               if(stopscanline > idxmap[scene_cnt - 1])
                               {
                                  dims[l_index] = scene_cnt - startscandim;
                                  stopscandim = scene_cnt - 1;
                               }
                         }
                         if(SWXRegion[regionID]->band8flag == 2 ||
                            SWXRegion[regionID]->band8flag == 3)
                         {
                            if(startscandim == -1)
                            {
                               if(startscanline < idxmap[0])
                               {
                                  startscandim = 0;
                                  dims[l_index] = stopscandim - startscandim + 1;
                               }
                            }
                            if(startscandim == -1)
                            {
                               startscanline = SWXRegion[regionID]->StartScan[k] * detect_cnt;
                               stopscanline = SWXRegion[regionID]->StopScan[k] * detect_cnt;
                               for (l = 0; l < scene_cnt-1; l++)
                               {
                                  if(idxmap[l] <= startscanline && idxmap[l+1] >= startscanline)
                                     dims[l_index] = l;
                                  if(idxmap[l] <= stopscanline && idxmap[l+1] >= stopscanline)
                                     dims[l_index] = l - dims[l_index] + 1;
                               }
                            }
                         }
                      }
                   }
                   else
                   {
                      if (datafld != 1)
                      {
		         /* Get number of cross tracks in particular region */
		         /* ----------------------------------------------- */
		         nXtrk = idxmap[SWXRegion[regionID]->StopRegion[k]] -
			         idxmap[SWXRegion[regionID]->StartRegion[k]] + 1;

		         dims[l_index] += nXtrk;
                      }
                    }
		}
	    }
	    else
	    {
		/* Mapping not found */
		/* ----------------- */
	        status = -1;
		HEpush(DFE_GENAPP, "SWregioninfo",
		       __FILE__, __LINE__);
		HEreport(
			 "Mapping Not Defined for \"%s\" Dimension.\n",
			 geodim);
	    }
	}



	/* Vertical Subset */
	/* --------------- */
	if (status == 0 || status == -1)  /* check the vertical subset in any case -- xhua */
	{
	    for (j = 0; j < 8; j++)
	    {
		/* If active vertical subset ... */
		/* ----------------------------- */
		if (SWXRegion[regionID]->StartVertical[j] != -1)
		{

		    /* Find vertical dimension within dimlist */
		    /* -------------------------------------- */
		    l_index = EHstrwithin(SWXRegion[regionID]->DimNamePtr[j],
					dimlist, ',');

		    /* If dimension found ... */
		    /* ---------------------- */
		    if (l_index != -1)
		    {
			/* Compute dimension size */
			/* ---------------------- */
			dims[l_index] =
			    SWXRegion[regionID]->StopVertical[j] -
			    SWXRegion[regionID]->StartVertical[j] + 1;
		    }
		    else
		    {
			/* Vertical dimension not found */
			/* ---------------------------- */
			status = -1;
			*size = -1;
			HEpush(DFE_GENAPP, "SWregioninfo", __FILE__, __LINE__);
			HEreport(errMesg, SWXRegion[regionID]->DimNamePtr[j]);
		    }
		}
	    }



	    /* Compute size of region data buffer */
	    /* ---------------------------------- */
	    if (status == 0)
	    {
                if(idxMapElem == 1 && SWXRegion[regionID]->scanflag == 1 && land_status == 0)
                {
                    if(startscandim == dims[0])
                       dims[0] = scene_cnt*2 - startscandim;
                }

		/* Compute number of total elements */
		/* -------------------------------- */
		*size = dims[0];
		for (j = 1; j < *rank; j++)
		{
		    *size *= dims[j];
		}

		/* Multiply by size in bytes of numbertype */
		/* --------------------------------------- */
		*size *= DFKNTsize(*ntype);
	    }
	}
    }



    /* Free index mappings if applicable */
    /* --------------------------------- */
    if (idxmap != NULL)
    {
	free(idxmap);
    }
    if(dfieldlist != NULL)
       free(dfieldlist);

    return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWreginfo                                                        |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper around SWregioninfo                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|  fieldname      char                Fieldname                               |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int32               field number type                       |
|  rank           int32               field rank                              |
|  dims           int32               dimensions of field region              |
|                                     (FORTRAN order)                         |
|  size           int32               size in bytes of field region           |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWreginfo(int32 swathID, int32 regionID, const char *fieldname,
	  int32 * ntype, int32 * rank, int32 dims[], int32 * size)
{
    intn            j;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           swap;	/* Temporary swap variable */


    /* Call SWregioninfo */
    /* ----------------- */
    status = SWregioninfo(swathID, regionID, fieldname,
			  ntype, rank, dims, size);


    /* Change dimensions to FORTRAN order */
    /* ---------------------------------- */
    for (j = 0; j < *rank / 2; j++)
    {
	swap = dims[*rank - 1 - j];
	dims[*rank - 1 - j] = dims[j];
	dims[j] = swap;
    }
    return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWperiodinfo                                                     |
|                                                                             |
|  DESCRIPTION: Returns size in bytes of region                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  periodID       int32               Period ID                               |
|  fieldname      char                Fieldname                               |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int32               field number type                       |
|  rank           int32               field rank                              |
|  dims           int32               dimensions of field region              |
|  size           int32               size in bytes of field region           |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Jun 03   Abe Taaheri   added clearing timeflag if SWregioninfo fails       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWperiodinfo(int32 swathID, int32 periodID, const char *fieldname,
	     int32 * ntype, int32 * rank, int32 dims[], int32 * size)
{
    intn            status;	/* routine return status variable */


    timeflag = 1;
    /* Call SWregioninfo */
    /* ----------------- */
    status = SWregioninfo(swathID, periodID, fieldname, ntype, rank,
			  dims, size);
    if (status != 0) timeflag = 0;/* clear timeflag if SWregioninfo failed */
    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWperinfo                                                        |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper around SWperiodinfo                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  periodID       int32               Period ID                               |
|  fieldname      char                Fieldname                               |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int32               field number type                       |
|  rank           int32               field rank                              |
|  dims           int32               dimensions of field region              |
|                                     (FORTRAN order)                         |
|  size           int32               size in bytes of field region           |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Jul 96   Joel Gales    Fix FORTRAN ordering of dims omitted in original    |
|                         version                                             |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWperinfo(int32 swathID, int32 periodID, const char *fieldname,
	  int32 * ntype, int32 * rank, int32 dims[], int32 * size)
{
    intn            j;		/* Loop index */
    intn            status;	/* routine return status variable */

    int32           swap;	/* Temporary swap variable */


    /* Call SWreginfo */
    /* -------------- */
    status = SWreginfo(swathID, periodID, fieldname, ntype, rank,
		       dims, size);

    if(status == 0) {
      /* Change dimensions to FORTRAN order */
      /* ---------------------------------- */
      for (j = 0; j < *rank / 2; j++)
	{
	  swap = dims[*rank - 1 - j];
	  dims[*rank - 1 - j] = dims[j];
	  dims[j] = swap;
	}
    }
    return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefvrtregion                                                   |
|                                                                             |
|  DESCRIPTION: Finds elements of a monotonic field within a given range.     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       int32               Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|  vertObj        char                Vertical object to subset               |
|  range          float64             Vertical subsetting range               |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 96   Joel Gales    Original Programmer                                 |
|  Dec 96   Joel Gales    Add multiple vertical subsetting capability         |
|  May 97   Joel Gales    Check for supported field types                     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/


/* Macro to initialize swath region entry */
/* -------------------------------------- */

/*
 * 1) Find empty (inactive) region. 2) Allocate space for region entry. 3)
 * Store file ID and swath ID. 4) Set region ID. 5) Initialize vertical
 * subset entries to -1.
 */

#define SETSWTHREG \
\
for (k = 0; k < NSWATHREGN; k++) \
{ \
    if (SWXRegion[k] == 0) \
    { \
        SWXRegion[k] = (struct swathRegion *) \
	  calloc(1, sizeof(struct swathRegion)); \
	SWXRegion[k]->fid = fid; \
	SWXRegion[k]->swathID = swathID; \
	regionID = k; \
	for (j=0; j<8; j++) \
        { \
             SWXRegion[k]->StartVertical[j] = -1; \
             SWXRegion[k]->StopVertical[j]  = -1; \
             SWXRegion[k]->StartScan[j] = -1; \
             SWXRegion[k]->StopScan[j]  = -1; \
             SWXRegion[k]->band8flag  = -1; \
        } \
	break; \
     } \
}


/* Macro to fill vertical subset entry */
/* ----------------------------------- */

/*
 * 1) Find empty (inactive) vertical region. 2) Set start of vertical region.
 * 3) Allocate space for name of vertical dimension. 4) Write vertical
 * dimension name.
 */

#define FILLVERTREG \
for (j=0; j<8; j++) \
{ \
    if (SWXRegion[regionID]->StartVertical[j] == -1) \
    { \
	SWXRegion[regionID]->StartVertical[j] = i; \
	SWXRegion[regionID]->DimNamePtr[j] = \
	    (char *) malloc(slen + 1); \
	memcpy(SWXRegion[regionID]->DimNamePtr[j], \
	       dimlist, slen + 1); \
	break; \
    } \
} \



int32
SWdefvrtregion(int32 swathID, int32 regionID, const char *vertObj, float64 range[])
{
    intn            i;		/* Loop index */
    intn            j = 0;	/* Loop index */
    intn            k = 0;	/* Loop index */
    intn            status;	/* routine return status variable */

    uint8           found = 0;	/* Found flag */

    int16           vertINT16;	/* Temporary INT16 variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */
    int32           slen;	/* String length */
    int32           rank;	/* Field rank */
    int32           nt;		/* Field numbertype */
    int32           dims[8];	/* Field dimensions */
    int32           size;	/* Size of numbertype in bytes */
    int32           vertINT32;	/* Temporary INT32 variable */

    float32         vertFLT32;	/* Temporary FLT32 variable */

    float64         vertFLT64;	/* Temporary FLT64 variable */

    char           *vertArr;	/* Pointer to vertical field data buffer */
    char            dimlist[256];	/* Dimension list */


    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWdefvrtregion", &fid, &sdInterfaceID,
		       &swVgrpID);

    if (status == 0)
    {
	/* Copy first 4 characters of vertObj into dimlist */
	/* ----------------------------------------------- */
	memcpy(dimlist, vertObj, 4);
	dimlist[4] = 0;



	/* If first 4 characters of vertObj = "DIM:" ... */
	/* --------------------------------------------- */

	/* Vertical Object is dimension name */
	/* --------------------------------- */
	if (strcmp(dimlist, "DIM:") == 0)
	{
	    /* Get string length of vertObj (minus "DIM:) */
	    /* ------------------------------------------ */
	    slen = (int32)strlen(vertObj) - 4;


	    /* If regionID = -1 then setup swath region entry */
	    /* ---------------------------------------------- */
	    if (regionID == -1)
	    {
		SETSWTHREG;
	    }


	    /* Find first empty (inactive) vertical subset entry */
	    /* ------------------------------------------------- */
	    for (j = 0; j < 8; j++)
	    {
		if (SWXRegion[regionID]->StartVertical[j] == -1)
		{
		    /* Store start & stop of vertical region */
		    /* ------------------------------------- */
		    SWXRegion[regionID]->StartVertical[j] = (int32) range[0];
		    SWXRegion[regionID]->StopVertical[j] = (int32) range[1];

		    /* Store vertical dimension name */
		    /* ----------------------------- */
		    SWXRegion[regionID]->DimNamePtr[j] =
			(char *) malloc(slen + 1);
		    if(SWXRegion[regionID]->DimNamePtr[j] == NULL)
		    {
			HEpush(DFE_NOSPACE,"SWdefvrtregion", __FILE__, __LINE__);
			return(-1);
		    }
		    memcpy(SWXRegion[regionID]->DimNamePtr[j],
			   vertObj + 4, slen + 1);
		    break;
		}
	    }
	}
	else
	{

	    /* Vertical Object is fieldname */
	    /* ---------------------------- */


	    /* Check for valid fieldname */
	    /* ------------------------- */
	    status = SWfieldinfo(swathID, vertObj, &rank, dims, &nt,
				 dimlist);

	    if (status != 0)
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWdefvrtregion", __FILE__, __LINE__);
		HEreport("Vertical Field: \"%s\" not found.\n", vertObj);
	    }



	    /* Check for supported field types */
	    /* ------------------------------- */
	    if (nt != DFNT_INT16 &&
		nt != DFNT_INT32 &&
		nt != DFNT_FLOAT32 &&
		nt != DFNT_FLOAT &&
		nt != DFNT_FLOAT64)
	    {
		status = -1;
		HEpush(DFE_GENAPP, "SWdefvrtregion", __FILE__, __LINE__);
		HEreport("Fieldtype: %d not supported for vertical subsetting.\n", nt);
	    }



	    /* Check that vertical dimension is 1D */
	    /* ----------------------------------- */
	    if (status == 0)
	    {
		if (rank != 1)
		{
		    status = -1;
		    HEpush(DFE_GENAPP, "SWdefvrtregion", __FILE__, __LINE__);
		    HEreport("Vertical Field: \"%s\" must be 1-dim.\n",
			     vertObj);
		}
	    }


	    /* If no problems then continue */
	    /* ---------------------------- */
	    if (status == 0)
	    {
		/* Get string length of vertical dimension */
		/* --------------------------------------- */
		slen = (int32)strlen(dimlist);


		/* Get size in bytes of vertical field numbertype */
		/* ---------------------------------------------- */
		size = DFKNTsize(nt);


		/* Allocate space for vertical field */
		/* --------------------------------- */
		vertArr = (char *) calloc(dims[0], size);
		if(vertArr == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdefvrtregion", __FILE__, __LINE__);
		    return(-1);
		}

		/* Read vertical field */
		/* ------------------- */
		status = SWreadfield(swathID, vertObj,
				     NULL, NULL, NULL, vertArr);



		switch (nt)
		{
		case DFNT_INT16:

		    for (i = 0; i < dims[0]; i++)
		    {
			/* Get single element of vertical field */
			/* ------------------------------------ */
			memcpy(&vertINT16, vertArr + i * size, size);


			/* If within range ... */
			/* ------------------- */
			if (vertINT16 >= range[0] &&
			    vertINT16 <= range[1])
			{
			    /* Set found flag */
			    /* -------------- */
			    found = 1;


			    /* If regionID=-1 then setup swath region entry */
			    /* -------------------------------------------- */
			    if (regionID == -1)
			    {
				SETSWTHREG;
			    }


			    /* Fill-in vertical region entries */
			    /* ------------------------------- */
			    FILLVERTREG;

			    break;
			}
		    }


		    /* If found read from "bottom" of data field */
		    /* ----------------------------------------- */
		    if (found == 1)
		    {
			for (i = dims[0] - 1; i >= 0; i--)
			{
			    /* Get single element of vertical field */
			    /* ------------------------------------ */
			    memcpy(&vertINT16, vertArr + i * size, size);


			    /* If within range ... */
			    /* ------------------- */
			    if (vertINT16 >= range[0] &&
				vertINT16 <= range[1])
			    {
				/* Set end of vertical region */
				/* -------------------------- */
				SWXRegion[regionID]->StopVertical[j] = i;
				break;
			    }
			}
		    }
		    else
		    {
			/* No vertical entries within region */
			/* --------------------------------- */
			status = -1;
			HEpush(DFE_GENAPP, "SWdefvrtregion",
			       __FILE__, __LINE__);
			HEreport("No vertical field entries within region.\n");
		    }
		    break;


		case DFNT_INT32:

		    for (i = 0; i < dims[0]; i++)
		    {
			/* Get single element of vertical field */
			/* ------------------------------------ */
			memcpy(&vertINT32, vertArr + i * size, size);


			/* If within range ... */
			/* ------------------- */
			if (vertINT32 >= range[0] &&
			    vertINT32 <= range[1])
			{
			    /* Set found flag */
			    /* -------------- */
			    found = 1;


			    /* If regionID=-1 then setup swath region entry */
			    /* -------------------------------------------- */
			    if (regionID == -1)
			    {
				SETSWTHREG;
			    }


			    /* Fill-in vertical region entries */
			    /* ------------------------------- */
			    FILLVERTREG;

			    break;
			}
		    }


		    /* If found read from "bottom" of data field */
		    /* ----------------------------------------- */
		    if (found == 1)
		    {
			for (i = dims[0] - 1; i >= 0; i--)
			{
			    /* Get single element of vertical field */
			    /* ------------------------------------ */
			    memcpy(&vertINT32, vertArr + i * size, size);


			    /* If within range ... */
			    /* ------------------- */
			    if (vertINT32 >= range[0] &&
				vertINT32 <= range[1])
			    {
				/* Set end of vertical region */
				/* -------------------------- */
				SWXRegion[regionID]->StopVertical[j] = i;
				break;
			    }
			}
		    }
		    else
		    {
			/* No vertical entries within region */
			/* --------------------------------- */
			status = -1;
			HEpush(DFE_GENAPP, "SWdefvrtregion",
			       __FILE__, __LINE__);
			HEreport("No vertical field entries within region.\n");
		    }
		    break;


		case DFNT_FLOAT32:
		    for (i = 0; i < dims[0]; i++)
		    {
			/* Get single element of vertical field */
			/* ------------------------------------ */
			memcpy(&vertFLT32, vertArr + i * size, size);


			/* If within range ... */
			/* ------------------- */
			if (vertFLT32 >= range[0] &&
			    vertFLT32 <= range[1])
			{
			    /* Set found flag */
			    /* -------------- */
			    found = 1;


			    /* If regionID=-1 then setup swath region entry */
			    /* -------------------------------------------- */
			    if (regionID == -1)
			    {
				SETSWTHREG;
			    }


			    /* Fill-in vertical region entries */
			    /* ------------------------------- */
			    FILLVERTREG;

			    break;
			}
		    }


		    /* If found read from "bottom" of data field */
		    /* ----------------------------------------- */
		    if (found == 1)
		    {
			for (i = dims[0] - 1; i >= 0; i--)
			{
			    /* Get single element of vertical field */
			    /* ------------------------------------ */
			    memcpy(&vertFLT32, vertArr + i * size, size);


			    /* If within range ... */
			    /* ------------------- */
			    if (vertFLT32 >= range[0] &&
				vertFLT32 <= range[1])
			    {
				/* Set end of vertical region */
				/* -------------------------- */
				SWXRegion[regionID]->StopVertical[j] = i;
				break;
			    }
			}
		    }
		    else
		    {
			/* No vertical entries within region */
			/* --------------------------------- */
			status = -1;
			HEpush(DFE_GENAPP, "SWdefvrtregion",
			       __FILE__, __LINE__);
			HEreport("No vertical field entries within region.\n");
		    }
		    break;


		case DFNT_FLOAT64:

		    for (i = 0; i < dims[0]; i++)
		    {
			/* Get single element of vertical field */
			/* ------------------------------------ */
			memcpy(&vertFLT64, vertArr + i * size, size);


			/* If within range ... */
			/* ------------------- */
			if (vertFLT64 >= range[0] &&
			    vertFLT64 <= range[1])
			{
			    /* Set found flag */
			    /* -------------- */
			    found = 1;


			    /* If regionID=-1 then setup swath region entry */
			    /* -------------------------------------------- */
			    if (regionID == -1)
			    {
				SETSWTHREG;
			    }


			    /* Fill-in vertical region entries */
			    /* ------------------------------- */
			    FILLVERTREG;

			    break;
			}
		    }


		    /* If found read from "bottom" of data field */
		    /* ----------------------------------------- */
		    if (found == 1)
		    {
			for (i = dims[0] - 1; i >= 0; i--)
			{
			    /* Get single element of vertical field */
			    /* ------------------------------------ */
			    memcpy(&vertFLT64, vertArr + i * size, size);

			    /* If within range ... */
			    /* ------------------- */
			    if (vertFLT64 >= range[0] &&
				vertFLT64 <= range[1])
			    {
				/* Set end of vertical region */
				/* -------------------------- */
				SWXRegion[regionID]->StopVertical[j] = i;
				break;
			    }
			}
		    }
		    else
		    {
			/* No vertical entries within region */
			/* --------------------------------- */
			status = -1;
			HEpush(DFE_GENAPP, "SWdefvrtregion",
			       __FILE__, __LINE__);
			HEreport("No vertical field entries within region.\n");
		    }
		    break;

		}		/* End of switch */
		free(vertArr);
	    }
	}
    }


    /* Set regionID to -1 if bad return status */
    /* --------------------------------------- */
    if (status == -1)
    {
	regionID = -1;
    }


    return (regionID);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefvrtreg                                                      |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper around SWdefvrtregion                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       int32               Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|  vertObj        char                Vertical object to subset               |
|  range          float64             Vertical subsetting range               |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 96   Joel Gales    Original Programmer                                 |
|  Feb 97   Joel Gales    Change call SWdefvrtreg to SWdefvrtregion           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWdefvrtreg(int32 swathID, int32 regionID, const char *vertObj, float64 fortrange[])
{
    float64         range[2];	/* range (C) */

    char            utlbuf[16];	/* Utility buffer */


    /* Copy first four character of vertObj to utlbuf */
    /* ---------------------------------------------- */
    memcpy(utlbuf, vertObj, 4);
    utlbuf[4] = 0;


    /* If subsetting on dimension elements convert FORTRAN indices to C */
    /* ---------------------------------------------------------------- */
    if (strcmp(utlbuf, "DIM:") == 0)
    {
	range[0] = fortrange[0] - 1;
	range[1] = fortrange[1] - 1;
    }
    else
    {
	range[0] = fortrange[0];
	range[1] = fortrange[1];
    }


    /* Call SWdefvrtregion */
    /* ------------------- */
    regionID = SWdefvrtregion(swathID, regionID, vertObj, range);

    return (regionID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdefscanregion                                                  |
|                                                                             |
|  DESCRIPTION: Initialize the region structure for Landsat 7 float scene     |
|               subset							      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       int32               Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  fieldname      char                Field name to subset                    |
|  range          float64             subsetting range                        |
|  mode		  int32		      HDFE_ENDPOINT, HDFE_MIDPOINT or         |
|				      HDFE_ANYPOINT                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  regionID	  int32		      Region ID                               |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jul 99   DaW 	  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWdefscanregion(int32 swathID, const char *fieldname, float64 range[], int32 mode)
{
    intn            j;		/* Loop index */
    intn            k;		/* Loop index */
    intn            status;	/* routine return status variable */
    intn            land_status = 3;	/* routine return status variable */
    intn	    band81flag = 0;
    intn	    band82flag = 0;
    intn	    band83flag = 0;
    uint8           detect_cnt = 0;     /* Used to convert scan to scanline  */
                                        /*  L7 float scene sub.              */
    uint8           scene_cnt = 0;


    int32           nmtype = 0; /* Used for L7 float scene sub. */
    int32           count = 0;   /* Used for L7 float scene sub. */
    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath Vgroup ID */
    int32           slen;	/* String length */
    int32	    dfrank[8];  /* data fields rank */
    int32           rank;	/* Field rank */
    int32	    numtype[8]; /* number type of data fields */
    int32           nt;		/* Field numbertype */
    int32           dims[8];	/* Field dimensions */
    int32           dims2[8];	/* Field dimensions */
    int32	    strbufsize = 0; /* string buffer size */
    int32	    tmprange0 = 0;


    uint16	    *buffer = (uint16 *)NULL;
    int32	    *idxmap = (int32 *)NULL;

    int32	    dimsize = 0;

    int32           regionID = -1;	/* Region ID (return) */

    float64	    scan[2]={0,0};
    float64	    original_scan[2] ={0,0};

    char            dimlist[256];	/* Dimension list */
    char	    swathname[80];
    char	    *dfieldlist = (char *)NULL;  /* data field list  */
    char	    *tfieldname = (char *)NULL;  /* temp field buffer  */
    char	    *band81 = (char *)NULL;
    char	    *band82 = (char *)NULL;
    char	    *band83 = (char *)NULL;


    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWdefscanregion", &fid, &sdInterfaceID,
		       &swVgrpID);

    if(status != 0)
      {
	return(status);
      }

   /* This code checks for the attribute detector_count */
   /* which is found in Landsat 7 files.  It is used    */
   /* for some of the loops. The other code checks if   */
   /* one scan is requested.                            */
   /* ================================================= */
      land_status = SWattrinfo(swathID, "detector_count", &nmtype, &count);
      if (land_status == 0)
      {
         scan[0] = range[0];
         scan[1] = range[1];
         original_scan[0] = range[0];
         original_scan[1] = range[1];

         land_status = SWreadattr(swathID, "scene_count", &scene_cnt);
         land_status = SWreadattr(swathID, "detector_count", &detect_cnt);
         if (range[0] == range[1])
         {
            range[0] = range[0] * detect_cnt - detect_cnt;
            range[1] = range[0] + detect_cnt - 1;
         }
         else
         {
            range[0] = range[0] * detect_cnt - detect_cnt;
            range[1] = range[1] * detect_cnt - 1;
         }

         Vgetname(SWXSwath[0].IDTable, swathname);
         band81 = strstr(swathname, "B81");
         if (band81 != (char *)NULL)
            band81flag = 1;
         band82 = strstr(swathname, "B82");
         if (band82 != (char *)NULL)
            band82flag = 1;
         band83 = strstr(swathname, "B83");
         if (band83 != (char *)NULL)
            band83flag = 1;
      }


    /* If fieldname is null then subsetting Landsat 7 */
    /* floating scene. Get data field name, assume    */
    /* only one data field in swath                   */
    /* ---------------------------------------------- */

    if (fieldname == (char *)NULL)
    {
       (void) SWnentries(swathID, 4, &strbufsize);
       dfieldlist = (char *)calloc(strbufsize + 1, sizeof(char));
       (void) SWinqdatafields(swathID, dfieldlist, dfrank, numtype);
       tfieldname = (char *)calloc(strbufsize + 1, sizeof(char));
       strcpy(tfieldname, dfieldlist);
    }
    else
    {
       slen = (int32)strlen(fieldname);
       tfieldname = (char *)calloc(slen + 1, sizeof(char));
       strcpy(tfieldname, fieldname);
    }

    /* Check for valid fieldname */
    /* ------------------------- */
    status = SWfieldinfo(swathID, tfieldname, &rank, dims, &nt,
	 dimlist);

    if (status != 0)
    {
	status = -1;
	HEpush(DFE_GENAPP, "SWdefscanregion", __FILE__, __LINE__);
	HEreport("Field: \"%s\" not found.\n", tfieldname);
    }


    /* Check if input range values are within range of */
    /* data field                                      */
    /* ----------------------------------------------- */
    if(status == 0)
      {
	status = SWfieldinfo(swathID, "scan_no", &rank, dims2, &nt, dimlist);
	if(status == 0) {
	  buffer = (uint16 *)calloc(dims2[0], sizeof(uint16));
	  if(buffer == NULL)
	    {
	      HEpush(DFE_NOSPACE,"SWdefscanregion", __FILE__, __LINE__);
	      if (dfieldlist != NULL)
		free(dfieldlist);
	      free(tfieldname);
	      return(-1);
	    }
	  status = SWreadfield(swathID,"scan_no", NULL, NULL, NULL, buffer);
	  if(status != 0)
	    {
	      HEpush(DFE_GENAPP,"SWdefscanregion", __FILE__, __LINE__);
	      if (dfieldlist != NULL)
		free(dfieldlist);
	      free(tfieldname);
	      return(-1);
	    }
	}
	else
	  {
	    HEpush(DFE_GENAPP,"SWdefscanregion", __FILE__, __LINE__);
	    if (dfieldlist != NULL)
	      free(dfieldlist);
	    free(tfieldname);
	    return(-1);
	  }

	if(scan[0] > buffer[dims2[0]-1])
          {
	    HEpush(DFE_GENAPP, "SWdefscanregion", __FILE__, __LINE__);
	    HEreport("Range values not within bounds of data field\n");
	    free(buffer);
	    buffer = (uint16 *)NULL;
	    if (dfieldlist != NULL)
	      free(dfieldlist);
	    free(tfieldname);
	    return(-1);
          }

	if(scan[0] < buffer[0])
          {
	    if(scan[1] < buffer[0])
	      {
                HEpush(DFE_GENAPP, "SWdefscanregion", __FILE__, __LINE__);
                HEreport("Range values not within bounds of data field\n");
                free(buffer);
                buffer = (uint16 *)NULL;
                if (dfieldlist != NULL)
		  free(dfieldlist);
                free(tfieldname);
                return(-1);
	      }
	    else
	      {
                scan[0] = buffer[0];
                range[0] = scan[0] * detect_cnt - detect_cnt;
	      }
          }
	if(scan[1] > buffer[dims2[0] - 1])
          {
	    scan[1] = buffer[dims2[0] - 1];
	    range[1] = scan[1] * detect_cnt - 1;
          }
      }

    if(status == 0)
      {
	dimsize = SWdiminfo(swathID, "GeoTrack");
	if(dimsize > 0)
          {
	    idxmap = (int32 *)calloc(dimsize, sizeof(int32));
	    (void) SWidxmapinfo(swathID, "GeoTrack", "ScanLineTrack", idxmap);
	    tmprange0 = (int32)range[0];
	    if(band82flag != 1 && band83flag != 1)
	      {
                if (range[1] > idxmap[scene_cnt*2 - 1])
		  {
		    range[1] = idxmap[scene_cnt*2 - 1];
		    fprintf(stderr,"Data length compared to geolocation length\n");
		  }
	      }
	    if(band82flag == 1 || band83flag == 1)
	      {
		tmprange0 = (int32)(range[0] - (buffer[0] * detect_cnt - detect_cnt));
	      }
	    if(tmprange0 >= idxmap[scene_cnt * 2 - 1])
	      {
                HEpush(DFE_GENAPP, "SWdefscanregion", __FILE__, __LINE__);
                HEreport("Range values not within bounds of Latitude/Longitude field(s)\n");
                if (dfieldlist != NULL)
		  free(dfieldlist);
                free(tfieldname);
                free(buffer);
                free(idxmap);
                return(-1);
	      }
          }
      }

    if (status == 0)
      {
	slen = (int32)strlen(tfieldname);

	SETSWTHREG;

	/* Find first empty (inactive) vertical subset entry */
	/* ------------------------------------------------- */
	for (j = 0; j < 8; j++)
	  {
	    if (SWXRegion[regionID]->StartVertical[j] == -1)
	      {
		/* Store start & stop of region          */
		/* ------------------------------------- */
		SWXRegion[regionID]->StartScan[j] = (int32) original_scan[0];
		SWXRegion[regionID]->StopScan[j] = (int32) original_scan[1];
		SWXRegion[regionID]->StartRegion[j] = (int32) range[0];
		SWXRegion[regionID]->StopRegion[j] = (int32) range[1];
		++SWXRegion[regionID]->nRegions;
		SWXRegion[regionID]->scanflag = 1;
		if(band81flag == 1)
		  SWXRegion[regionID]->band8flag = 1;
		if(band82flag == 1)
		  SWXRegion[regionID]->band8flag = 2;
		if(band83flag == 1)
		  SWXRegion[regionID]->band8flag = 3;
		break;
	      }
	  }
      }


    /* Set regionID to -1 if bad return status */
    /* --------------------------------------- */
    if (status == -1)
      {
	regionID = -1;
      }

    if (dfieldlist != NULL)
      free(dfieldlist);
    free(tfieldname);
    if (buffer != NULL)
      free(buffer);
    if (idxmap != NULL)
      free(idxmap);

    return (regionID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWsetfillvalue                                                   |
|                                                                             |
|  DESCRIPTION: Sets fill value for the specified field.                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|  fillval        void                fill value                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWsetfillvalue(int32 swathID, const char *fieldname, VOIDP fillval)
{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           sdid;	/* SDS id */
    int32           nt;		/* Number type */
    int32           dims[8];	/* Dimensions array */
    int32           dum;	/* Dummy variable */
    int32           solo;	/* "Solo" (non-merged) field flag */

    char            name[84];	/* Fill value "attribute" name */

    /* Check for valid swath ID and get SDS interface ID */
    status = SWchkswid(swathID, "SWsetfillvalue",
		       &fid, &sdInterfaceID, &swVgrpID);

    if (status == 0)
    {
	/* Get field info */
	status = SWfieldinfo(swathID, fieldname, &dum, dims, &nt, NULL);

	if (status == 0)
	{
	    /* Get SDS ID and solo flag */
	    status = SWSDfldsrch(swathID, sdInterfaceID, fieldname,
				 &sdid, &dum, &dum, &dum,
				 dims, &solo);

	    /* If unmerged field then call HDF set field routine */
	    if (solo == 1)
	    {
		status = SDsetfillvalue(sdid, fillval);
	    }

	    /*
	     * Store fill value in attribute.  Name is given by fieldname
	     * prepended with "_FV_"
	     */
	    strcpy(name, "_FV_");
	    strcat(name, fieldname);
	    status = SWwriteattr(swathID, name, nt, 1, fillval);
	}
	else
	{
	    HEpush(DFE_GENAPP, "SWsetfillvalue", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	}
    }
    return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWgetfillvalue                                                   |
|                                                                             |
|  DESCRIPTION: Retrieves fill value for a specified field.                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|  fieldname      char                field name                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fillval        void                fill value                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWgetfillvalue(int32 swathID, const char *fieldname, VOIDP fillval)
{
    intn            status;	/* routine return status variable */

    int32           nt;		/* Number type */
    int32           dims[8];	/* Dimensions array */
    int32           dum;	/* Dummy variable */

    char            name[84];	/* Fill value "attribute" name */

    /* Check for valid swath ID */
    status = SWchkswid(swathID, "SWgetfillvalue", &dum, &dum, &dum);

    if (status == 0)
    {
	/* Get field info */
	status = SWfieldinfo(swathID, fieldname, &dum, dims, &nt, NULL);

	if (status == 0)
	{
	    /* Read fill value attribute */
	    strcpy(name, "_FV_");
	    strcat(name, fieldname);
	    status = SWreadattr(swathID, name, fillval);
	}
	else
	{
	    HEpush(DFE_GENAPP, "SWgetfillvalue", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	}

    }
    return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdetachall                                                      |
|                                                                             |
|  DESCRIPTION: Detaches from all swath interfaces                             |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|             None                                                            |

|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 15   Abe Taaheri   Original Programmer                                 |
|                                                                             |
|                                                                             |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdetachall()
{
  int             i;
  int32           swathID;
  int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
  intn            status = 0;	/* routine return status variable */

  for (i = 0; i < NSWATH; i++)
    {
      if (SWXSwath[i].active == 1)
	{
	  swathID = i + idOffset;
	  status = SWdetach(swathID);
	}
    }
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWdetach                                                         |
|                                                                             |
|  DESCRIPTION: Detachs swath structure and performs housekeeping             |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure ID                      |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|  Aug 96   Joel Gales    Cleanup Region External Structure                   |
|  Sep 96   Joel Gales    Setup dim names for SDsetdimnane in dimbuf1 rather  |
|                         than utlstr                                         |
|  Nov 96   Joel Gales    Call SWchkswid to check for proper swath ID         |
|  Dec 96   Joel Gales    Add multiple vertical subsetting garbage collection |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWdetach(int32 swathID)

{
    intn            i;		/* Loop index */
    intn            j = 0;	/* Loop index */
    intn            k;		/* Loop index */
    intn            status = 0;	/* routine return status variable */
    intn            statusFill = 0;	/* return status from SWgetfillvalue */

    uint8          *buf;	/* Buffer for blank (initial) 1D records */

    int32           vdataID;	/* Vdata ID */
    int32          *namelen;	/* Pointer to name string length array */
    int32          *dimlen;	/* Pointer to dim string length array */
    int32           slen1[3];	/* String length array 1 */
    int32           slen2[3];	/* String length array 2 */
    int32           nflds;	/* Number of fields */
    int32           match[5];	/* Merged field match array */
    int32           cmbfldcnt;	/* Number of fields combined */
    int32           sdid;	/* SDS ID */
    int32           vgid;	/* Vgroup ID */
    int32           dims[3];	/* Dimension array */
    int32          *offset;	/* Pointer to merged field offset array */
    int32          *indvdims;	/* Pointer to merged field size array */
    int32           sdInterfaceID;	/* SDS interface ID */
    int32           sID;	/* Swath ID - offset */
    int32           nflds0;	/* Number of fields */
    int32          *namelen0;	/* Pointer to name string length array */
    int32           rank;	/* Rank of merged field */
    int32           truerank;	/* True rank of merged field */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */
    int32           dum;	/* Dummy variable */

    char           *nambuf;	/* Pointer to name buffer */
    char          **nameptr;	/* Pointer to name string pointer array */
    char          **dimptr;	/* Pointer to dim string pointer array */
    char          **nameptr0;	/* Pointer to name string pointer array */
    char           *ptr1[3];	/* String pointer array */
    char           *ptr2[3];	/* String pointer array */
    char            dimbuf1[128];	/* Dimension buffer 1 */
    char            dimbuf2[128];	/* Dimension buffer 2 */
    char            swathname[VGNAMELENMAX + 1];	/* Swath name */
    char           *utlbuf;	/* Utility buffer */
    char            fillval[32];/* Fill value buffer */

    /* Check for proper swath ID and get SD interface ID */
    /* ------------------------------------------------- */
    status = SWchkswid(swathID, "SWdetach", &dum, &sdInterfaceID, &dum);

    if (status == 0)
    {
	/* Subtract off swath ID offset and get swath name */
	/* ----------------------------------------------- */
	sID = swathID % idOffset;
	Vgetname(SWXSwath[sID].IDTable, swathname);


	/* Create 1D "orphaned" fields */
	/* --------------------------- */
	i = 0;

	/* Find "active" entries in 1d combination array */
	/* --------------------------------------------- */
	while (SWX1dcomb[3 * i] != 0)
	{
	    /* For fields defined within swath... */
	    /* ---------------------------------- */
	    if (SWX1dcomb[3 * i + 1] == SWXSwath[sID].IDTable)
	    {
		/* Get dimension size and vdata ID */
		/* ------------------------------- */
		dims[0] = abs(SWX1dcomb[3 * i]);
		vdataID = SWX1dcomb[3 * i + 2];

		/* Get fieldname (= vdata name) */
		/* ---------------------------- */
		nambuf = (char *) calloc(VSNAMELENMAX + 1, 1);
		if(nambuf == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    return(-1);
		}

		VSgetname(vdataID, nambuf);

		/* Set field within vdata */
		/* ---------------------- */
		VSsetfields(vdataID, nambuf);

		/* Write (blank) records */
		/* --------------------- */
		buf = (uint8 *) calloc(VSsizeof(vdataID, nambuf), dims[0]);
		if(buf == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nambuf);
		    return(-1);
		}
		VSwrite(vdataID, buf, dims[0], FULL_INTERLACE);

		free(buf);
		free(nambuf);

		/* Detach Vdata */
		/* ------------ */
		VSdetach(vdataID);
	    }
	    i++;
	}


	/* SDS combined fields */
	/* ------------------- */
	if ((int32)strlen(SWXSDname) == 0)
	{
	    nflds = 0;

	    /* Allocate "dummy" arrays so free() doesn't bomb later */
	    /* ---------------------------------------------------- */
	    nameptr = (char **) calloc(1, sizeof(char *));
	    if(nameptr == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		return(-1);
	    }
	    namelen = (int32 *) calloc(1, sizeof(int32));
	    if(namelen == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		return(-1);
	    }
	    nameptr0 = (char **) calloc(1, sizeof(char *));
	    if(nameptr0 == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		free(namelen);
		return(-1);
	    }
	    namelen0 = (int32 *) calloc(1, sizeof(int32));
	    if(namelen0 == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		free(namelen);
		free(nameptr0);
		return(-1);
	    }
	    dimptr = (char **) calloc(1, sizeof(char *));
	    if(dimptr == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		free(namelen);
		free(nameptr0);
		free(namelen0);
		return(-1);
	    }
	    dimlen = (int32 *) calloc(1, sizeof(int32));
	    if(dimlen == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		free(namelen);
		free(nameptr0);
		free(namelen0);
		free(dimptr);
		return(-1);
	    }
	    offset = (int32 *) calloc(1, sizeof(int32));
	    if(offset == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		free(namelen);
		free(nameptr0);
		free(namelen0);
		free(dimptr);
		free(dimlen);
		return(-1);
	    }
	    indvdims = (int32 *) calloc(1, sizeof(int32));
	    if(indvdims == NULL)
	    {
		HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		free(nameptr);
		free(namelen);
		free(nameptr0);
		free(namelen0);
		free(dimptr);
		free(dimlen);
		free(offset);
		return(-1);
	    }
	}
	else
	{
	    /*
	     * "Trim Off" trailing "," and ";" in SWXSDname & SWXSDdims
	     * respectively
	     */
	    SWXSDname[(int32)strlen(SWXSDname) - 1] = 0;
	    SWXSDdims[(int32)strlen(SWXSDdims) - 1] = 0;


	    /* Get number of fields from SWXSDname string */
	    /* ------------------------------------------ */
	    nflds = EHparsestr(SWXSDname, ',', NULL, NULL);
	    if(nflds > 0)
	      {
		/* Allocate space for various dynamic arrays */
		/* ----------------------------------------- */
		nameptr = (char **) calloc(nflds, sizeof(char *));
		if(nameptr == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    return(-1);
		  }
		namelen = (int32 *) calloc(nflds, sizeof(int32));
		if(namelen == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    return(-1);
		  }
		nameptr0 = (char **) calloc(nflds, sizeof(char *));
		if(nameptr0 == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    free(namelen);
		    return(-1);
		  }
		namelen0 = (int32 *) calloc(nflds, sizeof(int32));
		if(namelen0 == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    free(namelen);
		    free(nameptr0);
		    return(-1);
		  }
		dimptr = (char **) calloc(nflds, sizeof(char *));
		if(dimptr == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    free(namelen);
		    free(nameptr0);
		    free(namelen0);
		    return(-1);
		  }
		dimlen = (int32 *) calloc(nflds, sizeof(int32));
		if(dimlen == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    free(namelen);
		    free(nameptr0);
		    free(namelen0);
		    free(dimptr);
		    return(-1);
		  }
		offset = (int32 *) calloc(nflds, sizeof(int32));
		if(offset == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    free(namelen);
		    free(nameptr0);
		    free(namelen0);
		    free(dimptr);
		    free(dimlen);
		    return(-1);
		  }
		indvdims = (int32 *) calloc(nflds, sizeof(int32));
		if(indvdims == NULL)
		  {
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nameptr);
		    free(namelen);
		    free(nameptr0);
		    free(namelen0);
		    free(dimptr);
		    free(dimlen);
		    free(offset);
		    return(-1);
		  }
	      }
	    else
	      {
	        HEpush(DFE_GENAPP,"SWdetach", __FILE__, __LINE__);
		return(-1);
	      }

	    /* Parse SWXSDname and SWXSDdims strings */
	    /* ------------------------------------- */
	    nflds = EHparsestr(SWXSDname, ',', nameptr, namelen);
	    nflds = EHparsestr(SWXSDdims, ';', dimptr, dimlen);
	}


	/* Loop through all the fields */
	/* --------------------------- */
	for (i = 0; i < nflds; i++)
	{
	    /* If active entry and field is within swath to be detached ... */
	    /* ------------------------------------------------------------ */
	    if (SWXSDcomb[5 * i] != 0 &&
		SWXSDcomb[5 * i + 3] == SWXSwath[sID].IDTable)
	    {
		nambuf = (char *) calloc(strlen(SWXSDname) + 1, 1);
		if(nambuf == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    return(-1);
		}
		utlbuf = (char *) calloc(2 * (int32)strlen(SWXSDname) + 7, 1);
		if(utlbuf == NULL)
		{
		    HEpush(DFE_NOSPACE,"SWdetach", __FILE__, __LINE__);
		    free(nambuf);
		    return(-1);
		}
		/* Zero out dimbuf1 */
		/* ---------------- */
		for (k = 0; k < (intn)sizeof(dimbuf1); k++)
		{
		    dimbuf1[k] = 0;
		}


		/* Load array to match, name & parse dims */
		/* -------------------------------------- */
		memcpy(match, &SWXSDcomb[5 * i], 20);
		memcpy(nambuf, nameptr[i], namelen[i]);

		memcpy(dimbuf1, dimptr[i], dimlen[i]);
		dum = EHparsestr(dimbuf1, ',', ptr1, slen1);


		/* Separate combined (first) dimension from others */
		/* ----------------------------------------------- */
		dimbuf1[slen1[0]] = 0;

		offset[0] = 0;
		indvdims[0] = abs(match[0]);

		/*
		 * Loop through remaining fields to check for matches with
		 * current one
		 */
		for (j = i + 1, cmbfldcnt = 0; j < nflds; j++)
		{
		    if (SWXSDcomb[5 * j] != 0)
		    {
			/* Zero out dimbuf2 */
			/* ---------------- */
		      for (k = 0; k < (intn)sizeof(dimbuf2); k++)
			{
			    dimbuf2[k] = 0;
			}

			/*
			 * Parse the dimensions and separate first for this
			 * entry
			 */
			memcpy(dimbuf2, dimptr[j], dimlen[j]);
			dum = EHparsestr(dimbuf2, ',', ptr2, slen2);
			dimbuf2[slen2[0]] = 0;


			/*
			 * If 2nd & 3rd dimension values and names (1st and
			 * 2nd for rank=2 array), swath ID, and numbertype
			 * are equal, then these fields can be combined.
			 */
			if (match[1] == SWXSDcomb[5 * j + 1] &&
			    match[2] == SWXSDcomb[5 * j + 2] &&
			    match[3] == SWXSDcomb[5 * j + 3] &&
			    match[4] == SWXSDcomb[5 * j + 4] &&
			    strcmp(dimbuf1 + slen1[0] + 1,
				   dimbuf2 + slen2[0] + 1) == 0)
			{
			    /* Add to combined dimension size */
			    /* ------------------------------ */
			    match[0] += SWXSDcomb[5 * j];

			    /* Concatenate name */
			    /* ---------------- */
			    strcat(nambuf, ",");
			    memcpy(nambuf + strlen(nambuf),
				   nameptr[j], namelen[j]);

			    /*
			     * Increment number of merged fields, store
			     * individual dims and dim offsets
			     */
			    cmbfldcnt++;
			    indvdims[cmbfldcnt] = abs(SWXSDcomb[5 * j]);
			    offset[cmbfldcnt] = offset[cmbfldcnt - 1] +
				indvdims[cmbfldcnt - 1];

			    /* Delete this field from combination list */
			    /* --------------------------------------- */
			    SWXSDcomb[5 * j] = 0;
			}
		    }
		}


		/* Create SDS */
		/* ---------- */

		/* Parse names string */
		/* ------------------ */
		nflds0 = EHparsestr(nambuf, ',', nameptr0, namelen0);

		if (abs(match[0]) == 1)
		{
		    /* Two Dimensional Array (no merging has occurred) */
		    /* ---------------------------------------------- */
		    dims[0] = abs(match[1]);
		    dims[1] = abs(match[2]);

		    /* Create SDS */
		    /* ---------- */
		    rank = 2;
		    sdid = SDcreate(sdInterfaceID, nambuf,
				    SWXSDcomb[5 * i + 4], 2, dims);
		}
		else
		{
		    /* Three Dimensional Array */
		    /* ----------------------- */
		    dims[0] = abs(match[0]);
		    dims[1] = abs(match[1]);
		    dims[2] = abs(match[2]);

		    rank = 3;

		    /*
		     * If merged fields then form string consisting of
		     * "MRGFLD_" + 1st field in merge + ":" + entire merged
		     * field list and store in utlbuf. Then write to
		     * MergedField metadata section
		     */
		    if (cmbfldcnt > 0)
		    {
			strcpy(utlbuf, "MRGFLD_");
			memcpy(utlbuf + 7, nameptr0[0], namelen0[0]);
			utlbuf[7 + namelen0[0]] = 0;
			strcat(utlbuf, ":");
			strcat(utlbuf, nambuf);

			status = EHinsertmeta(sdInterfaceID, swathname, "s",
					      6L, utlbuf, NULL);
		    }
		    else
		    {
			/*
			 * If not merged field then store field name in
			 * utlbuf
			 */
			strcpy(utlbuf, nambuf);
		    }

		    /* Create SDS */
		    /* ---------- */
		    sdid = SDcreate(sdInterfaceID, utlbuf,
				    SWXSDcomb[5 * i + 4], 3, dims);


		    /*
		     * If merged field then store dimensions and offsets as
		     * SD attributes
		     */
		    if (cmbfldcnt > 0)
		    {
			SDsetattr(sdid, "Field Dims", DFNT_INT32,
				  cmbfldcnt + 1, (VOIDP) indvdims);

			SDsetattr(sdid, "Field Offsets", DFNT_INT32,
				  cmbfldcnt + 1, (VOIDP) offset);
		    }
		}



		/* Register Dimensions in SDS */
		/* -------------------------- */
		for (k = 0; k < rank; k++)
		{
		    if (rank == 2)
		    {
			/* Copy k+1th dimension into dimbuf2 if rank = 2 */
			/* --------------------------------------------- */
			memcpy(dimbuf2, ptr1[k + 1], slen1[k + 1]);
			dimbuf2[slen1[k + 1]] = 0;
		    }
		    else
		    {
			/* Copy kth dimension into dimbuf2 if rank > 2 */
			/* ------------------------------------------- */
			memcpy(dimbuf2, ptr1[k], slen1[k]);
			dimbuf2[slen1[k]] = 0;
		    }

		    /*
		     * If first dimension and merged field then generate
		     * dimension name consisting of "MRGDIM:" + swathname +
		     * dimension size
		     */
		    if (k == 0 && cmbfldcnt > 0)
		    {
		      snprintf(dimbuf2, sizeof(dimbuf2), "%s%s_%d", "MRGDIM:",
				swathname, dims[0]);
		    }
		    else
		    {
			/* Otherwise concatenate swathname to dim name */
			/* ------------------------------------------- */
			strcat(dimbuf2, ":");
			strcat(dimbuf2, swathname);
		    }

		    /* Register dimensions using "SDsetdimname" */
		    /* ---------------------------------------- */
		    SDsetdimname(SDgetdimid(sdid, k), (char *) dimbuf2);
		}



		/* Write Fill Value */
		/* ---------------- */
		for (k = 0; k < nflds0; k++)
		{
		    /* Check if fill values has been set */
		    /* --------------------------------- */
		    memcpy(utlbuf, nameptr0[k], namelen0[k]);
		    utlbuf[namelen[k]] = 0;
		    statusFill = SWgetfillvalue(swathID, utlbuf, fillval);

		    if (statusFill == 0)
		    {
			/*
			 * If merged field then fill value must be stored
			 * manually using EHfillfld
			 */
			if (cmbfldcnt > 0)
			{
			    dims[0] = indvdims[k];
			    truerank = (dims[0] == 1) ? 2 : 3;
			    EHfillfld(sdid, rank, truerank,
				      DFKNTsize(match[4]), offset[k],
				      dims, fillval);
			}
			/*
			 * If single field then just use the HDF set fill
			 * function
			 */
			else
			{
			    status = SDsetfillvalue(sdid, fillval);
			}
		    }
		}


		/*
		 * Insert SDS within the appropriate Vgroup (geo or data) and
		 * "detach" newly-created SDS
		 */
		vgid = (match[0] < 0)
		    ? SWXSwath[sID].VIDTable[0]
		    : SWXSwath[sID].VIDTable[1];

		Vaddtagref(vgid, DFTAG_NDG, SDidtoref(sdid));
		SDendaccess(sdid);

		free(nambuf);
		free(utlbuf);
	    }
	}



	/* "Contract" 1dcomb array */
	/* ----------------------- */
	i = 0;
	while (SWX1dcomb[3 * i] != 0)
	{
	    if (SWX1dcomb[3 * i + 1] == SWXSwath[sID].IDTable)
	    {
		memcpy(&SWX1dcomb[3 * i],
		       &SWX1dcomb[3 * (i + 1)],
		       (512 - i - 1) * 3 * 4);
	    }
	    else
		i++;
	}


	/* "Contract" SDcomb array */
	/* ----------------------- */
	for (i = 0; i < nflds; i++)
	{
	    if (SWXSDcomb[5 * i + 3] == SWXSwath[sID].IDTable)
	    {
		if (i == (nflds - 1))
		{
		    SWXSDcomb[5 * i] = 0;
		    *(nameptr[i] - (nflds != 1)) = 0;
		    *(dimptr[i] - (nflds != 1)) = 0;
		}
		else
		{
		    memmove(&SWXSDcomb[5 * i],
			   &SWXSDcomb[5 * (i + 1)],
			   (512 - i - 1) * 5 * 4);

		    memmove(nameptr[i],
			   nameptr[i + 1],
			   nameptr[0] + 2048 - nameptr[i + 1] - 1);

		    memmove(dimptr[i],
			   dimptr[i + 1],
			   dimptr[0] + 2048 * 2 - dimptr[i + 1] - 1);
		}

		i--;
		nflds = EHparsestr(SWXSDname, ',', nameptr, namelen);
		nflds = EHparsestr(SWXSDdims, ';', dimptr, dimlen);
	    }
	}


	/* Replace trailing delimiters on SWXSDname & SWXSDdims */
	/* ---------------------------------------------------- */
	if (nflds != 0)
	{
	    strcat(SWXSDname, ",");
	    strcat(SWXSDdims, ";");
	}



	/* Free up a bunch of dynamically allocated arrays */
	/* ----------------------------------------------- */
	free(nameptr);
	free(namelen);
	free(nameptr0);
	free(namelen0);
	free(dimptr);
	free(dimlen);
	free(offset);
	free(indvdims);




	/* "Detach" from previously attached SDSs */
	/* -------------------------------------- */
	for (k = 0; k < SWXSwath[sID].nSDS; k++)
	{
	    SDendaccess(SWXSwath[sID].sdsID[k]);
	}
	free(SWXSwath[sID].sdsID);
	SWXSwath[sID].sdsID = 0;
	SWXSwath[sID].nSDS = 0;


	/* Detach Swath Vgroups */
	/* -------------------- */
	Vdetach(SWXSwath[sID].VIDTable[0]);
	Vdetach(SWXSwath[sID].VIDTable[1]);
	Vdetach(SWXSwath[sID].VIDTable[2]);
	Vdetach(SWXSwath[sID].IDTable);


	/* Delete entries from External Arrays */
	/* ----------------------------------- */
	SWXSwath[sID].active = 0;
	SWXSwath[sID].VIDTable[0] = 0;
	SWXSwath[sID].VIDTable[1] = 0;
	SWXSwath[sID].VIDTable[2] = 0;
	SWXSwath[sID].IDTable = 0;
	SWXSwath[sID].fid = 0;


	/* Free Region Pointers */
	/* -------------------- */
	for (k = 0; k < NSWATHREGN; k++)
	{
	    if (SWXRegion[k] != 0 &&
		SWXRegion[k]->swathID == swathID)
	    {
		for (i = 0; i < 8; i++)
		{
		    if (SWXRegion[k]->DimNamePtr[i] != 0)
		    {
			free(SWXRegion[k]->DimNamePtr[i]);
		    }
		}

		free(SWXRegion[k]);
		SWXRegion[k] = 0;
	    }
	}

    }
    return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWclose                                                          |
|                                                                             |
|  DESCRIPTION: Closes HDF-EOS file                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            int32               File ID                                 |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 96   Joel Gales    Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWclose(int32 fid)

{
    intn            status = 0;	/* routine return status variable */

    /* Call EHclose to perform file close */
    /* ---------------------------------- */
    status = EHclose(fid);

    return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWupdatescene                                                    |
|                                                                             |
|  DESCRIPTION: Updates the StartRegion and StopRegion values                 |
|               for a specified region.                                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Nov 98   Xinmin Hua    Original developing                                 |
|  Aug 99   Abe Taaheri   Added code to exclude regions that have the same    |
|                         start and stop.                                     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWupdatescene(int32 swathID, int32 regionID)
{
    intn            k;          /* Loop index */
    int32           status;     /* routine return status variable */

    int32           fid;        /* HDF-EOS file ID */
    int32           sdInterfaceID;      /* HDF SDS interface ID */
    int32           swVgrpID;   /* Swath Vgroup ID */

    int32           startReg;   /* Indexed start region */
    int32           stopReg;    /* Indexed stop region */
    int32           l_index[MAXNREGIONS]; /* to store indices when stop and
					   start are different */

    int32           ind;        /* index */
    int32           tempnRegions; /* temp number of regions */

    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWupdatescene", &fid, &sdInterfaceID,
                       &swVgrpID);

    /* Check for valid region ID */
    /* ------------------------- */
    if (status == 0)
    {
        if (regionID < 0 || regionID >= NSWATHREGN)
        {
            status = -1;
            HEpush(DFE_RANGE, "SWupdatescene", __FILE__, __LINE__);
            HEreport("Invalid Region id: %d.\n", regionID);
        }
    }

    /* Check for active region ID */
    /* -------------------------- */
    if (status == 0)
    {
        if (SWXRegion[regionID] == 0)
        {
            status = -1;
            HEpush(DFE_GENAPP, "SWupdatescene", __FILE__, __LINE__);
            HEreport("Inactive Region ID: %d.\n", regionID);
        }
    }

    if (status == 0)
    {
	tempnRegions = SWXRegion[regionID]->nRegions;
	ind =0;

	for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
        {
           startReg = SWXRegion[regionID]->StartRegion[k];
           stopReg = SWXRegion[regionID]->StopRegion[k];
	   if(startReg == stopReg)
	   {
	       /* reduce number of regions by 1, if tempnRegions is 0 issue
		  error and break from loop*/
	       tempnRegions -= 1;

	       if(tempnRegions == 0)
	       {
		   /* first free allocated memory for SWXRegion[regionID]
		      in the function SWdefboxregion and make regionID
		      inactive */
		   free(SWXRegion[regionID]);
		   SWXRegion[regionID] = 0;
		   status = -1;
		   HEpush(DFE_GENAPP, "SWupdatescene", __FILE__, __LINE__);
		   HEreport("Inactive Region ID: %d.\n", regionID);
		   break;
	       }
	   }
	   else
	   {
	       /* store index number of regions that have different start and
		  stop */
	       l_index[ind] = k;
	       ind += 1;
	   }
	}
	if (status != 0)
	{
	    return (status);
	}
	else
	{
	    SWXRegion[regionID]->nRegions = tempnRegions;
	}
	/* keep starts and stops that are different in the structure  */
	for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
	{
	    SWXRegion[regionID]->StartRegion[k] =
	      SWXRegion[regionID]->StartRegion[l_index[k]];
	    SWXRegion[regionID]->StopRegion[k] =
	      SWXRegion[regionID]->StopRegion[l_index[k]];
	}

    }


    if (status == 0)
    {

        for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
        {

           startReg = SWXRegion[regionID]->StartRegion[k];
           stopReg = SWXRegion[regionID]->StopRegion[k];

           if(startReg % 2 == 1) {

              SWXRegion[regionID]->StartRegion[k] = ++startReg;

           }
           if(stopReg % 2 == 0) {

              SWXRegion[regionID]->StopRegion[k] = --stopReg;

           }

        }

    }

    return(status);

}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWupdateidxmap                                                   |
|                                                                             |
|  DESCRIPTION: Updates the map index for a specified region.                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nout           int32               return Number of elements in output     |
|                                     index array if SUCCEED, (-1) FAIL       |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath structure ID                      |
|  regionID       int32               Region ID                               |
|  indexin        int32               array of index values                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  indexout       int32               array of index values                   |
|  indicies	  int32		      array of start and stop in region       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 97   Abe Taaheri   Original Programmer                                 |
|  AUG 97   Abe Taaheri   Add support for index mapping                       |
|  Sep 99   DaW		  Add support for Floating Scene Subsetting Landsat 7 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWupdateidxmap(int32 swathID, int32 regionID, int32 indexin[], int32 indexout[], int32 indicies[])
{
    intn            i;          /* Loop index */
    intn            j = 0;      /* Loop index */
    intn            k;          /* Loop index */
    int32           status;     /* routine return status variable */
    int32           land_status = 3;     /* routine return status variable */

    int32           fid;        /* HDF-EOS file ID */
    int32           sdInterfaceID;      /* HDF SDS interface ID */
    int32           swVgrpID;   /* Swath Vgroup ID */

    int32           numtype = 0; /* Used for L7 float scene sub. */
    int32           count = 0;   /* Used for L7 float scene sub. */

    int32           startReg = 0;   /* Indexed start region */
    int32           stopReg = 0;    /* Indexed stop region */
    int32           nout=-1;       /* Number of elements in output index array */
    int32	    indexoffset = 0;
    uint8	    scene_cnt = 0;	/* Used for L7 float scene sub.      */
    uint8           detect_cnt = 0;     /* Used to convert scan to scanline  */
    intn	    gtflag = 0;
    intn	    ngtflag = 0;
    int32           *buffer1 = (int32 *)NULL;
    int32           *buffer2 = (int32 *)NULL;

    /* Check for valid swath ID */
    /* ------------------------ */
    status = SWchkswid(swathID, "SWupdateidxmap", &fid, &sdInterfaceID,
                       &swVgrpID);

    /* Check for valid region ID */
    /* ------------------------- */
    if (status == 0)
    {
        if (regionID < 0 || regionID >= NSWATHREGN)
        {
            status = -1;
            HEpush(DFE_RANGE, "SWupdateidxmap", __FILE__, __LINE__);
            HEreport("Invalid Region id: %d.\n", regionID);
        }
    }

    /* Check for active region ID */
    /* -------------------------- */
    if (status == 0)
    {
        if (SWXRegion[regionID] == 0)
        {
            status = -1;
            HEpush(DFE_GENAPP, "SWextractregion", __FILE__, __LINE__);
            HEreport("Inactive Region ID: %d.\n", regionID);
        }
    }

    if (status == 0)
    {
	/* Loop through all regions */
	/* ------------------------ */
	for (k = 0; k < SWXRegion[regionID]->nRegions; k++)
	{

	    /* fix overlap index mapping problem for Landsat 7 */

	    startReg = SWXRegion[regionID]->StartRegion[k];
	    stopReg = SWXRegion[regionID]->StopRegion[k];


            if(SWXRegion[regionID]->scanflag == 1)
            {
               indicies[0] = -1;
               indicies[1] = -1;
               j = 0;
            /* This code checks for the attribute detector_count */
            /* which is found in Landsat 7 files.  It is used    */
            /* for some of the loops.                            */
            /* ================================================= */
               land_status = SWattrinfo(swathID, "scene_count", &numtype, &count);
               if (land_status == 0)
               {
                  land_status = SWreadattr(swathID, "scene_count", &scene_cnt);
                  land_status = SWreadattr(swathID, "detector_count", &detect_cnt);
               }


	      /* calculate the offsets first */
	      buffer1 = (int32 *)calloc(74, sizeof(int32));
	      buffer2 = (int32 *)calloc(74, sizeof(int32));

	      status = SWidxmapinfo(swathID,"GeoTrack",
				    "ScanLineTrack", (int32*)buffer1);
	      status = SWidxmapinfo(swathID,"UpperTrack",
				    "ScanLineTrack", (int32*)buffer2);

	      indexoffset = buffer2[0] - buffer1[0];
	      free(buffer1);
	      free(buffer2);

               if(SWXRegion[regionID]->band8flag == -1)
               {
                  for(i=0; i<scene_cnt;i++)
                  {
                     if(indexin[j] <= startReg && indexin[j+1] >= startReg)
                        if(indicies[0] == -1)
                           indicies[0] = j;
                     if(indexin[j] <= stopReg && indexin[j+1] >= stopReg)
                        indicies[1] = j + 1;
                     j = j + 2;
                     if(indexin[j] == 0 || indexin[j+1] == 0)
                        i = scene_cnt;
                  }
                  if(indicies[0] == -1)
                  {
                     if(startReg <= indexin[0])
                        indicies[0] = 0;
                  }
                  if(indicies[0] == -1)
                  {
                     j = 0;
                     for(i=0; i<scene_cnt; i++)
                     {
                        if(indexin[j] <= startReg && indexin[j+1] >= startReg)
                           if(indicies[0] == -1)
                              indicies[0] = j;
                        j = j + 1;
                        if(indexin[j] == 0 || indexin[j+1] == 0)
                           i = scene_cnt;
                     }
                  }
                  if(indicies[1] == -1)
                  {
                     j = 0;
                     for(i=0; i<scene_cnt; i++)
                     {
                        if(indexin[j] <= stopReg && indexin[j+1] >= stopReg)
                           if(indicies[1] == -1)
                              indicies[1] = j + 1;
                        j = j + 1;
                        if(indexin[j] == 0 || indexin[j+1] == 0)
                           i = scene_cnt;
                     }
                  }
                  if(indicies[1] == -1)
                     if(stopReg > indexin[scene_cnt - 1])
                        indicies[1] = scene_cnt - 1;
               }

	       /* This section of code handles exceptions in Landsat 7  */
	       /* data.  The Band 8 data - multiple files, data gaps	*/
               /* ===================================================== */
               if(SWXRegion[regionID]->band8flag == 1 ||
                  SWXRegion[regionID]->band8flag == 2 ||
                  SWXRegion[regionID]->band8flag == 3)
               {
                  j = 0;
                  for(i=0; i<scene_cnt; i++)
                  {
                     j = j + 2;
                     if(indexin[j] == 0 || indexin[j+1] == 0)
                     {
                        if(indexin[j] == 0)
                           gtflag = 1;
                        else
                           ngtflag = 1;
                        i = scene_cnt;
                     }
                  }
                  j = 0;
                  if(gtflag == 1)
                  {
                     for(i=0; i<scene_cnt; i++)
                     {
		      if( startReg >= (indexin[j] + indexoffset - detect_cnt) &&
			  startReg <= (indexin[j+1] + indexoffset - detect_cnt) )
                           if(indicies[0] == -1)
                              indicies[0] = j;
		      if( stopReg >= (indexin[j] + indexoffset - detect_cnt ) &&
			  stopReg <= (indexin[j+1] + indexoffset - detect_cnt ) )
                           indicies[1] = j + 1;
                        j = j + 2;
                        if(indexin[j] == 0 || indexin[j+1] == 0)
                           i = scene_cnt;
                     }
                     if(SWXRegion[regionID]->band8flag == 1)
                     {
                        if(indicies[1] == -1)
                           if(stopReg > (indexin[j - 1] + indexoffset - detect_cnt))
                              indicies[1] = j - 1;
                     }
                     if(SWXRegion[regionID]->band8flag == 2 ||
                        SWXRegion[regionID]->band8flag == 3)
                     {

                        if(startReg >= (indexin[j - 1] + indexoffset - detect_cnt))
                        {
                           indicies[0] = -1;
                           indicies[1] = -1;
                           /* status = SWfieldinfo(swathID, "scan_no", &rank, dims2, &nt, dimlist);
                           buffer = (uint16 *)calloc(dims2[0], sizeof(uint16));
                           status = SWreadfield(swathID,"scan_no", NULL, NULL, NULL, buffer);
                           indexoffset = buffer[0] * detect_cnt;
                           free(buffer);
                           startReg = startReg - (indexoffset - detect_cnt);
                           stopReg = stopReg - (indexoffset - 1); */
                           j = 0;
                           for(i=0; i<scene_cnt; i++)
                           {
			     if( startReg >= (indexin[j] + indexoffset - detect_cnt) &&
				 startReg <= (indexin[j+1] + indexoffset - detect_cnt) )
			       if(indicies[0] == -1)
				 indicies[0] = j;
			     if( stopReg >= (indexin[j] + indexoffset - detect_cnt ) &&
				 stopReg <= (indexin[j+1] + indexoffset - detect_cnt ) )
			       indicies[1] = j + 1;
                              j = j + 2;
                              if(indexin[j] == 0 || indexin[j+1] == 0)
                                 i = scene_cnt;
                           }
                        }

                        if(indicies[0] == -1)
                        {
                           j = 0;
                           for(i=0; i<scene_cnt; i++)
                           {
			     if( startReg >= (indexin[j] + indexoffset - detect_cnt) &&
				 startReg <= (indexin[j+1] + indexoffset - detect_cnt) )
			       if(indicies[0] == -1)
				 indicies[0] = j;

			     j = j + 2;
			     if(indexin[j] == 0 || indexin[j+1] == 0)
			       i = scene_cnt;
                           }
                        }
                        if(indicies[1] == -1)
                           if(stopReg > (indexin[j - 1] + indexoffset - detect_cnt) )
                              indicies[1] = j - 1;
                     }
                     if(indicies[1] == -1)
                     {
                        j = 0;
                        for(i=0; i<scene_cnt; i++)
                        {
			  if( stopReg >= (indexin[j] + indexoffset - detect_cnt ) &&
			      stopReg <= (indexin[j+1] + indexoffset - detect_cnt ) )
			    indicies[1] = j;
			  j = j + 2;
			  if(indexin[j] == 0 || indexin[j+1] == 0)
			    i = scene_cnt;
                        }
                     }
                  }

                  if(ngtflag == 1)
                  {
                     for(i=0; i<scene_cnt; i++)
                     {
		      if( startReg >= indexin[j] && startReg <= indexin[j+1])
                           if(indicies[0] == -1)
                              indicies[0] = j;
		      if( stopReg >= indexin[j] && stopReg <= indexin[j+1])
                           indicies[1] = j + 1;
                        j = j + 2;
                        if(indexin[j] == 0 || indexin[j+1] == 0)
                           i = scene_cnt;
                     }
                     if(SWXRegion[regionID]->band8flag == 2)
                     {
                        if(startReg >= indexin[j] )
                        {
                           if(indicies[0] == -1)
                              indicies[0] = j;
                           if(indicies[1] == -1)
                              indicies[1] = j;
                        }
                        if(indicies[0] == -1)
                           if(startReg <= indexin[0])
                              indicies[0] = 0;
                        if(indicies[1] == -1)
                           if(stopReg > indexin[j])
                              indicies[1] = j;
                     }
                     if(indicies[0] == -1)
                     {
                        j = 0;
                        for(i=0; i<scene_cnt; i++)
                        {
			  if( startReg >= indexin[j] && startReg <= indexin[j+1])
			    indicies[0] = j;
                           j = j + 2;
                           if(indexin[j] == 0 || indexin[j+1] == 0)
                              i = scene_cnt;
                        }
                     }
                     if(indicies[1] == -1)
                     {
                        j = 0;
                        for(i=0; i<scene_cnt; i++)
                        {
		      if( stopReg >= indexin[j] && stopReg <= indexin[j+1])
                              indicies[1] = j;
                           j = j + 2;
                           if(indexin[j] == 0 || indexin[j+1] == 0)
                              i = scene_cnt;
                        }
                     }
                     if(indicies[1] == -1)
                     {
                        if(stopReg > indexin[j])
                           indicies[1] = j;
                     }
                  }
                  if(indicies[0] == -1)
                  {
                     if(startReg <= (indexin[0]+ indexoffset - detect_cnt) )
                        indicies[0] = 0;
                     if(indicies[1] == -1)
                        if(stopReg > (indexin[j] + indexoffset - detect_cnt))
                           indicies[1] = j;
                  }
               }
               if (indicies[1] == -1)
               {
                  if(SWXRegion[regionID]->band8flag == 2 ||
                     SWXRegion[regionID]->band8flag == 3)
                  {
                     if(stopReg < (indexin[0] + indexoffset - detect_cnt))
                     {
		       /*status = SWfieldinfo(swathID, "scan_no", &rank, dims2, &nt, dimlist);
                        buffer = (uint16 *)calloc(dims2[0], sizeof(uint16));
                        status = SWreadfield(swathID,"scan_no", NULL, NULL, NULL, buffer);
                        indexoffset = buffer[0] * detect_cnt;
                        free(buffer);
                        startReg = startReg + (indexoffset - detect_cnt);
                        stopReg = stopReg + (indexoffset - 1); */
                        if(stopReg >= (indexin[scene_cnt - 1] + indexoffset - detect_cnt))
                        {
                           indicies[1] = scene_cnt - 1;
                        }
                        else
                        {
                           j = 0;
                           for(i=0;i<scene_cnt;i++)
                           {
		      if( stopReg >= (indexin[j] + indexoffset - detect_cnt ) &&
			  stopReg <= (indexin[j+1] + indexoffset - detect_cnt ) )
			         indicies[1] = j;
			      j = j + 2;
                              if(indexin[j] == 0 || indexin[j+1] == 0)
                                 i = scene_cnt;
                           }
                        }
                     }

                     if(startReg > (indexin[j - 1] + indexoffset - detect_cnt ))
                     {
                        indicies[0] = -1;
                        indicies[1] = -1;
                        /*status = SWfieldinfo(swathID, "scan_no", &rank, dims2, &nt, dimlist);
                        buffer = (uint16 *)calloc(dims2[0], sizeof(uint16));
                        status = SWreadfield(swathID,"scan_no", NULL, NULL, NULL, buffer);
                        indexoffset = buffer[0] * detect_cnt;
                        free(buffer);
                        startReg = startReg - (indexoffset - detect_cnt);
                        stopReg = stopReg - (indexoffset - 1);*/
                        j = 0;
                        for(i=0; i<scene_cnt; i++)
                        {
		      if( startReg >= (indexin[j] + indexoffset - detect_cnt) &&
			  startReg <= (indexin[j+1] + indexoffset - detect_cnt) )
                              if(indicies[0] == -1)
                                 indicies[0] = j;
		      if( stopReg >= (indexin[j] + indexoffset - detect_cnt ) &&
			  stopReg <= (indexin[j+1] + indexoffset - detect_cnt ) )
                              indicies[1] = j + 1;
                           j = j + 2;
                           if(indexin[j] == 0 || indexin[j+1] == 0)
                              i = scene_cnt;
                        }
                        if(indicies[0] == -1)
                           if(startReg < (indexin[0] +  indexoffset - detect_cnt))
                              indicies[0] = 0;
                        if(indicies[1] == -1)
                           if(stopReg > (indexin[j - 1] + indexoffset - detect_cnt))
                              indicies[1] = j - 1;
                     }
                  }
               }
            } 					/* end of if for floating scene update */
            else
            {
	       /* If start of region is odd then increment */
	       /* ---------------------------------------- */
	       if (startReg % 2 == 1)
	       {
		  startReg++;
	       }

	       /* If end of region is even then decrement */
	       /* --------------------------------------- */
	       if (stopReg % 2 == 0)
	       {
		  stopReg--;
	       }

               indicies[0]=startReg;
               indicies[1]=stopReg;
	   }
        }

	if (indexout != NULL)
	{
           if(SWXRegion[regionID]->scanflag == 1)
           {
              nout = (indicies[1] - indicies[0] + 1);
              j = 0;
              if (nout == 1)
                 indexout[0] = indexin[indicies[0]];
              for(i=0; i<nout;i++)
              {
                 indexout[i] = indexin[indicies[0] + i];
              }
           }
           else
           {
	      /* get new index values */
              /* ==================== */
	      for(i = startReg; i <= stopReg  ; i++)
	      {
	         indexout[i-startReg] = indexin[i];
	      }
	      nout = (stopReg - startReg) + 1;
           }
        }
        else
        {
           nout = indicies[1] - indicies[0] + 1;
	}
     }


    if(status == -1)
    {
	return(status);
    }
    else
    {
        return(nout);
    }

}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWgeomapinfo                                                     |
|                                                                             |
|  DESCRIPTION: Returns mapping information for dimension                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                2 for indexed mapping, 1 for regular    |
|                                     mapping, 0 if the dimension is not      |
|                                     and (-1) FAIL                           |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               swath structure id                      |
|  geodim         char                geolocation dimension name              |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NONE                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 97   Abe Taaheri   Original Programmer                                 |
|  Sept 97  DaW 	  Modified return value so errors can be trapped
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
intn
SWgeomapinfo(int32 swathID, const char *geodim)

{
    intn            status;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           swVgrpID;	/* Swath root Vgroup ID */
    int32           idOffset = SWIDOFFSET;	/* Swath ID offset */

    char           *metabufr;	/* Pointer to structural metadata (SM) */
    char           *metabufi;	/* Pointer to structural metadata (SM) */
    char           *metaptrsr[2];/* Pointers to begin and end of SM section */
    char           *metaptrsi[2];/* Pointers to begin and end of SM section */
    char            swathname[80];	/* Swath Name */
    char           *utlstrr;	 /* Utility string */
    char           *utlstri;	 /* Utility string */


    /* Allocate space for utility string */
    /* --------------------------------- */
    utlstrr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstrr == NULL)
    {
	HEpush(DFE_NOSPACE,"SWgeomapinfo", __FILE__, __LINE__);
	return(-1);
    }
    utlstri = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
    if(utlstri == NULL)
    {
	HEpush(DFE_NOSPACE,"SWgeomapinfo", __FILE__, __LINE__);
	free(utlstrr);
	return(-1);
    }
    status = -1;

    /* Check for valid swath id */
    status = SWchkswid(swathID, "SWgeomapinfo", &fid, &sdInterfaceID, &swVgrpID);
    if (status == 0)
    {
	/* Get swath name */
	Vgetname(SWXSwath[swathID % idOffset].IDTable, swathname);

	/* Get pointers to "DimensionMap" section within SM */
	metabufr = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "DimensionMap", metaptrsr);

	if(metabufr == NULL)
	{
	    free(utlstrr);
	    free(utlstri);
	    return(-1);
	}
	/* Search for mapping - GeoDim/DataDim (surrounded by quotes) */
	snprintf(utlstrr, UTLSTR_MAX_SIZE, "%s%s%s", "\t\t\t\tGeoDimension=\"", geodim,
		"\"\n\t\t\t\tDataDimension=");
	metaptrsr[0] = strstr(metaptrsr[0], utlstrr);

	/* Get pointers to "IndexDimensionMap" section within SM */
	metabufi = (char *) EHmetagroup(sdInterfaceID, swathname, "s",
				       "IndexDimensionMap", metaptrsi);
	if(metabufi == NULL)
	{
	    free(utlstrr);
	    free(utlstri);
	    return(-1);
	}
	/* Search for mapping - GeoDim/DataDim (surrounded by quotes) */
	snprintf(utlstri, UTLSTR_MAX_SIZE, "%s%s%s", "\t\t\t\tGeoDimension=\"", geodim,
		"\"\n\t\t\t\tDataDimension=");
	metaptrsi[0] = strstr(metaptrsi[0], utlstri);

	/*
	** If regular mapping found add 1 to status
        ** If indexed mapping found add 2
        */
	if (metaptrsr[0] < metaptrsr[1] && metaptrsr[0] != NULL)
	{
	    status = status + 1;
        }

        if (metaptrsi[0] < metaptrsi[1] && metaptrsi[0] != NULL)
        {
           status = status + 2;
        }

	free(metabufr);
	free(metabufi);
    }

    free(utlstrr);
    free(utlstri);

    return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWindexinfo                                                      |
|                                                                             |
|  DESCRIPTION: Returns indices of a subsetted region                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int32               return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  regionID       int32               Region ID                               |
|  object         char*               field name                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int32               field rank                              |
|  dimlist        char*               field dimension list                    |
|  indices        int32               indices of region for along track dim.  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 04   M. Porricelli Original development, derived from HDFEOS5          |
|  Oct 11   Abe Taaheri   Modified correcting indices for fields with        |
|                         ranks larger than 2                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWindexinfo(int32 regionID, const char *object, int32 *rank, char *dimlist, int32 *indices[])
{

  int32           status = -1;   /* routine return status variable */
  intn            j,k, fi, gi;   /* loop index                     */

  int32           nt;            /* number types                   */
  int32           dims[8];       /* Dimension array                */
  char            tempdimlist[HDFE_DIMBUFSIZE];/* Dimension list   */

  char            errbuf[256];   /* Error buffer                   */
  int32           index0, index1;

  /* Check for valid region ID */
  /* ------------------------- */
  if (regionID < 0 || regionID >= NSWATHREGN)
  {
      status = -1;
      snprintf(errbuf, sizeof(errbuf), "Invalid Region ID: %d.\n", regionID);
      HEpush(DFE_GENAPP, "SWindexinfo", __FILE__, __LINE__);
      HEreport(errbuf, __FILE__, __LINE__);
      return(status);
  }
  /* regionID is reasonable number, continue ...*/
  /* Check for active region ID */
  /* -------------------------- */
  if (SWXRegion[regionID] == 0)
  {
      status = -1;
      snprintf(errbuf, sizeof(errbuf), "Inactive Region ID: %d.\n", regionID);
      HEpush(DFE_GENAPP, "SWindexinfo", __FILE__, __LINE__);
      HEreport(errbuf, __FILE__, __LINE__);
      return(status);
  }

  /* Initialize dims[] array */
  /* ----------------------- */
  for (k = 0; k < 8; k++)
      dims[k] = 0;

  /* Get field info for given object */
  /* ------------------------------- */
  status = SWfieldinfo(SWXRegion[regionID]->swathID, object, rank, dims, &nt, tempdimlist);
  if (status != 0)
  {
    snprintf(errbuf, sizeof(errbuf), "Field \"%s\" not found.\n", object);
    HEpush(DFE_GENAPP, "SWindexinfo", __FILE__, __LINE__);
    HEreport(errbuf, __FILE__, __LINE__);
    return(-1);
  }

  strcpy(dimlist, tempdimlist);

  /* Find out Field indices corresponding to the 1st and 2nd indices of
   * Longitude (which automatically will be the same for Latitude or
   * Colatitude) field. For 2 or multi-dimansional fields, other than
   * Longitude, Latitude (or  Colatitude) it is important to know these
   * indices.
   */
  status = SWllmapedidxinfo(SWXRegion[regionID]->swathID,object,&index0,&index1);
  if (status != 0)
  {
    snprintf(errbuf, sizeof(errbuf), "Field \"%s\" not found.\n", object);
    HEpush(DFE_GENAPP, "SWindexinfo", __FILE__, __LINE__);
    HEreport(errbuf, __FILE__, __LINE__);
    return(-1);
  }

  /* index0 is field index correcponding to the 0 index of Longitude */
  /* index1 is field index correcponding to the 1 index of Longitude */

  /* Vertical Subset or regular subset*/
  /* -------------------------------- */
  for (j = 0; j < *rank; j++)
  {
    if(j == index0)
      {
	gi = 0;
	fi = index0;
      }
    else if(j == index1)
      {
	gi = 1;
	fi = index1;
      }
    else
      {
	if (j <index0)
	  {
	    gi = j + 2;
	    if(gi > 7) gi = 7;
	  }
	else
	  {
	    gi = j;
	  }
	fi = j;
      }

      if (SWXRegion[regionID]->StartVertical[gi] == -1)
      {
          indices[fi][0] = SWXRegion[regionID]->StartRegion[gi];
      }
      else
      {
          indices[fi][0] = SWXRegion[regionID]->StartVertical[gi];
      }


      if (SWXRegion[regionID]->StopVertical[gi] == -1)
      {
          if (SWXRegion[regionID]->StopRegion[gi] == 0)
          {
              indices[fi][1] = dims[fi] - 1;
          }
          else
          {
              indices[fi][1] = SWXRegion[regionID]->StopRegion[gi];
          }
      }
      else
      {
          if (SWXRegion[regionID]->StopVertical[gi] == 0)
          {
              indices[fi][1] = dims[fi] - 1;
          }
          else
          {
              indices[fi][1] = SWXRegion[regionID]->StopVertical[gi];
          }
      }
  }

  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWllmapedidxinfo                                                 |
|                                                                             |
|  DESCRIPTION: Returns indices of a subsetted region                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int32               return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        int32               Swath ID                                |
|  object         char*               field name                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  indices        int32               0th and 1st indices of the field        |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 11   Abe Taaheri   Original development,                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWllmapedidxinfo(int32 swathID, const char *object, int32 *index0, int32 *index1)
{
  int32           status = -1;   /* routine return status variable */
  intn            statMap = -1;  /* Status from SWmapinfo          */
  char            dimlist[HDFE_DIMBUFSIZE];/* Dimension list       */
  intn            i,j,k, iDim;   /* loop index                     */
  char            errbuf[256];   /* Error buffer                   */
  int32           nt, ntype;     /* number types                   */
  int32           dims[8];       /* Dimension array                */
  int32           rank;
  char            dimname0[HDFE_DIMBUFSIZE],dimname1[HDFE_DIMBUFSIZE];
  char            geodim[256];   /* Geolocation field dimension list */
  char            geodimbuf[256];/* Geolocation field dimension list */
  int32           nDim;	         /* Number of dimensions            */
  int32           slen[64],slen2[64];       /* String length array  */
  char           *ptr[64],*ptr2[64];	    /* String pointer array */
  int32           dumdims[8];	     /* Dimensions from SWfieldinfo */
  uint8           found = 0;         /* Found flag                  */
  char            utlbuf[256];       /* Utility buffer              */
  int32           incr;	             /* Mapping increment           */
  int32           dum;	             /* Dummy variable              */
  int32          *idxmap = NULL;     /* Pointer to index mapping array */
  int32           idxMapElem = -1;   /* Number of index map elements   */
  int32           l_index[8];

  /* Get data field info */
  /* ------------------- */
  status = SWfieldinfo(swathID, object, &rank,
		       dims, &ntype, dimlist);
  if (status != 0)
    {
      status = -1;
      HEpush(DFE_GENAPP, "SWllmapedidxinfo", __FILE__, __LINE__);
      HEreport("Field \"%s\" Not Found.\n", object);
      return(-1);
    }

  status = SWfieldinfo(swathID, "Longitude", &rank,
		       dumdims, &nt, geodim);
  if (status != 0)
  {
    snprintf(errbuf, sizeof(errbuf), "Field \"%s\" not found.\n", "Longitude");
    HEpush(DFE_GENAPP, "SWllmapedidxinfo", __FILE__, __LINE__);
    HEreport(errbuf, __FILE__, __LINE__);
    return(-1);
  }

   /* Get "Track" (first) Dimension from geo dimlist */
  /* ---------------------------------------------- */
  nDim = EHparsestr(geodim, ',', ptr, slen);

  for(iDim=0; iDim<8; iDim++)
    {
      l_index[iDim] = 0;
    }

  for(iDim=0; iDim<8; iDim++)
    {

      if(ptr[iDim] == NULL) break;
      else
	{
	  memcpy(geodimbuf, ptr[iDim], slen[iDim]);
	  geodimbuf[slen[iDim]] = 0;
	}

      if(strcmp(geodimbuf,"") == 0) break;

      /* Parse Data Field Dimlist & find mapping */
      /* --------------------------------------- */
      nDim = EHparsestr(dimlist, ',', ptr2, slen2);


      /* Loop through all dimensions and search for mapping */
      /* -------------------------------------------------- */
      for (i = 0; i < nDim; i++)
	{
	  memcpy(utlbuf, ptr2[i], slen2[i]);
	  utlbuf[slen2[i]] = 0;

	  statMap = SWmapinfo(swathID, geodimbuf, utlbuf,
			      &dum, &incr);

	  /* Mapping found */
	  /* ------------- */
	  if (statMap == 0)
	    {
	      found = 1;
	      l_index[iDim] = i;
	      break;
	    }
	}

      /* If mapping not found check for geodim within dimlist */
      /* ---------------------------------------------------- */
      if (found == 0)
	{
	  l_index[iDim] = EHstrwithin(geodimbuf, dimlist, ',');

	  /* Geo dimension found within subset field dimlist */
	  /* ----------------------------------------------- */
	  if (l_index[iDim] != -1)
	    {
	      found = 1;
	      incr = 1;
	    }
	}

      /* If mapping not found check for indexed mapping */
      /* ---------------------------------------------- */
      if (found == 0)
	{
	  /* Get size of geo dim & allocate space of index mapping */
	  /* ----------------------------------------------------- */
	  dum = SWdiminfo(swathID, geodimbuf);
	  idxmap = (int32 *) calloc(dum, sizeof(int32));
	  if(idxmap == NULL)
	    {
	      HEpush(DFE_NOSPACE,"SWllmapedidxinfo", __FILE__, __LINE__);
	      return(-1);
	    }

	  /* Loop through all dimensions and search for mapping */
	  /* -------------------------------------------------- */
	  for (i = 0; i < nDim; i++)
	    {
	      memcpy(utlbuf, ptr2[i], slen2[i]);
	      utlbuf[slen2[i]] = 0;

	      idxMapElem = SWidxmapinfo(swathID, geodimbuf, utlbuf, idxmap);


	      /* Mapping found */
	      /* ------------- */
	      if (idxMapElem != -1)
		{
		  found = 1;
		  l_index[iDim] = i;
		  break;
		}
	    }

	  if(idxmap != NULL)
	    {
	      free(idxmap);
	      idxmap = NULL;
	    }
	}
      found = 0;
    }

  *index0 = l_index[0];
  *index1 = l_index[1];;

  return(status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: SWidxinfo                                                        |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper around SWindxinfo                             |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int32               return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  regionID       int32               Region ID                               |
|  object         char*               field name                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int32*              field rank                              |
|  fortdimlist    char*               field dimension list                    |
|  fortindices    int32*              indices of region for along track dim.  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 04   M. Porricelli Original development, derived from HDFEOS5          |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int32
SWidxinfo(int32 regionID, const char *object, int32 rank, char *fortdimlist, int32 *fortindices)
{
  int32     i, j;                        /* Loop index           */

  int32     status     = -1; /* routine return status variable */
  char      errbuf[256];     /* Error message buffer */
  int32     *indices[8];
  int32     swap       = 0;              /* Temporary dimension size   */

  /* Dimension lists in C order */
  /* -------------------------- */
  char      *dimlist   = (char *)NULL;


  /* Allocate space for C order dimension list */
  /* ----------------------------------------- */
  dimlist = (char *)calloc(1024, sizeof(char));    /* in hdfeos5 code, HE5_HDFE_UTLBUFSIZE=1024 */
  if(dimlist == NULL)
  {
    snprintf(errbuf, sizeof(errbuf),"Cannot allocate memory for input list.\n");
    HEpush(DFE_NOSPACE, "SWidxinfo", __FILE__, __LINE__);
    HEreport(errbuf, __FILE__, __LINE__);
    return(-1);
  }

  for (i = 0; i < 8; i++)
  {
          indices[i] = (int32 *)malloc(2*sizeof(int32));
  }

  /* Call SWidxinfo */
  /* ---------------- */
  status = SWindexinfo(regionID, object, &rank, dimlist, indices);
  if (status == -1)
  {
    snprintf(errbuf, sizeof(errbuf),"Cannot get information about indices.\n");
    HEpush(DFE_GENAPP, "SWidxinfo", __FILE__, __LINE__);
    HEreport(errbuf, __FILE__, __LINE__);
    free(dimlist);
    for (i = 0; i < 8; i++)
      {
	free(indices[i]);
	indices[i] = NULL;
      }
    return(-1);
  }

  /* Reverse order of dimensions entries in dimension list */
  /* ----------------------------------------------------- */
  if(fortdimlist != (char *)NULL)
  {
      status = EHrevflds(dimlist, fortdimlist);
      if(status == -1)
      {
	snprintf(errbuf, sizeof(errbuf),"Cannot reverse entries in dimension list.\n");
	HEpush(DFE_GENAPP, "SWidxinfo", __FILE__, __LINE__);
	HEreport(errbuf, __FILE__, __LINE__);
	free(dimlist);
	for (i = 0; i < 8; i++)
          {
	    free(indices[i]);
	    indices[i] = NULL;
          }
	return(-1);
      }
  }

  for (j = 0; j < rank / 2; j++)
  {
      for (i = 0; i < 2; i++)
      {
          swap = indices[rank - 1 - j][i];
          indices[rank - 1 - j][i] = indices[j][i];
          indices[j][i] = swap;
      }
  }


  for (j = 0; j < rank; j++)
  {
      for (i = 0; i < 2; i++)
      {
          fortindices[j*2+i] = (int32)indices[j][i];
      }
  }


  for (i = 0; i < 8; i++)
  {
      free(indices[i]);
      indices[i] = NULL;
  }

  free(dimlist);
  dimlist = NULL;

 return(status);
}


/***********************************************
SWchunkinfo --
     This function queries the field to determine if it is chunked.  If it is
     chunked, one can retrieve some of the characteristics of the chunks.

Author--  Alexis Zubrow

********************************************************/


intn
SWchunkinfo(int32 swathID, char *fieldname, int32 * chunkcode, int32 * chunkrank,
	   int32 chunkdims[])

{
    intn            i;		/* Loop index */
    intn            status = 0;	/* routine return status variable */

    int32           fid;	/* HDF-EOS file ID */
    int32           sdInterfaceID;	/* HDF SDS interface ID */
    int32           sdid;	/* SDS ID */

    int32           dum;	/* Dummy variable */
    int32           rankSDS;	/* Rank of SDS/Field/chunk */

    int32           dims[8];	/* Field/SDS dimensions */
    int32           chunkFlags;	/* flag to determine if field is chunkd */
    HDF_CHUNK_DEF   chunkDef;	/* union holding tiling info. */


    /* Check if improper swathID */
    status = SWchkswid(swathID, "SWchunkinfo", &fid, &sdInterfaceID, &dum);
    if (status == 0)
    {

	/* Get field info */
	status = SWfieldinfo(swathID, fieldname, &rankSDS, dims, &dum, NULL);

	if (status == 0)
	{

	    /* Check whether fieldname is in SDS (multi-dim field) */
	    /* --------------------------------------------------- */
	    status = SWSDfldsrch(swathID, sdInterfaceID, fieldname, &sdid,
				 &rankSDS, &dum, &dum, dims, &dum);

	    if (status != 0) {
	      HEpush(DFE_GENAPP, "SWchunkinfo", __FILE__, __LINE__);
	      HEreport("SDS \"%s\" does not exist.\n", fieldname);
	      status = -1;
	      return ( status );
	    }

	    /* Query field for tiling information */
	    status = SDgetchunkinfo(sdid, &chunkDef, &chunkFlags);

	    /* If field is unchunked, return unchunkd flag */
	    if (chunkFlags == HDF_NONE)
	    {
		*chunkcode = HDFE_NOTILE;
		return (status);
	    }

	    /* IF field is chunkd or chunkd with compression */
	    else if ((chunkFlags == HDF_CHUNK) ||
		     (chunkFlags == (HDF_CHUNK | HDF_COMP)))
	    {
		if (chunkcode != NULL)
		{
		    *chunkcode = HDFE_TILE;
		}
		if (chunkrank != NULL)
		{
		    *chunkrank = rankSDS;
		}
		if (chunkdims != NULL)
		{
		    /* Assign size of chunk dimensions */
		    for (i = 0; i < rankSDS; i++)
		    {
			chunkdims[i] = chunkDef.chunk_lengths[i];
		    }
		}
	    }
	}

	/* Non-existent fieldname */
	else
	{
	    HEpush(DFE_GENAPP, "SWchunkinfo", __FILE__, __LINE__);
	    HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	    status = -1;
	}

    }
    return (status);
}


/*******************************************************
SWchkinfo

This function gets information on the chunking of a field (FORTRAN wrapper around
SWchunkinfo)


Author--
Alexis Zubrow

Date--
3/4/1997
*******************************************************/

intn
SWchkinfo(int32 swathID, char *fieldname, int32 * chunkcode, int32 * chunkrank,
	  int32 fortchunkdims[])
{

    intn            i;		/* Loop index */
    intn            status = 0;	/* routine return status variable */

    int32           rank;	/* Field rank */
    int32           ntype;	/* Field numbertype */
    int32           dims[8];	/* Field dimensions */
    int32          *chunkdims;	/* Pointer dimension size array (C order) */


    status = SWfieldinfo(swathID, fieldname, &rank, dims, &ntype, NULL);

    if (status == 0)
    {
        chunkdims = (int32 *)malloc(rank * sizeof(int32));
	if(chunkdims == NULL)
	{
	    HEpush(DFE_NOSPACE,"SWchkinfo", __FILE__, __LINE__);
	    return(-1);
	}

	/* reverse order of dimensions, converting FORTRAN to C */
	for (i = 0; i < rank; i++)
	{
	    chunkdims[i] = fortchunkdims[rank - 1 - i];
	}

	/* call SWchunkinfo with C ordered array */
	status = SWchunkinfo(swathID, fieldname, chunkcode, chunkrank, chunkdims);

	free(chunkdims);
    }
    else
    {
	HEpush(DFE_GENAPP, "SWchkinfo", __FILE__, __LINE__);
	HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
	status = -1;

    }

    return (status);
}


/* FORTRAN bindings */
#ifdef FORTRAN_API

#define DOUBLE      FLOAT64
#define DOUBLEV     PFLOAT64
#define INT32V      PINT32
#define INTV        PINT

FORTRAN_API_FN(INT32, SWopen, SWOPEN, swopen, STRING, INT)
FORTRAN_API_FN(INT32, SWcreate, SWCREATE, swcreate, INT32, STRING)
FORTRAN_API_FN(INT32, SWattach, SWATTACH, swattach, INT32, STRING)
FORTRAN_API_FN(INT, SWdefdim, SWDEFDIM, swdefdim, INT32, STRING, INT32)
FORTRAN_API_FN(INT, SWdefdimmap, SWDEFMAP, swdefmap, INT32, STRING, STRING, INT32, INT32)
FORTRAN_API_FN(INT, SWdefidxmap, SWDEFIMAP, swdefimap, INT32, STRING, STRING, INT32V)
FORTRAN_API_FN(INT, SWdefgfld, SWDEFGFLD, swdefgfld, INT32, STRING, STRING, INT32, INT32)
FORTRAN_API_FN(INT, SWdefdfld, SWDEFDFLD, swdefdfld, INT32, STRING, STRING, INT32, INT32)
FORTRAN_API_FN(INT, SWdefcomp, SWDEFCOMP, swdefcomp, INT32, INT32, INTV)
FORTRAN_API_FN(INT, SWwrgmeta, SWWRGMETA, swwrgmeta, INT32, STRING, STRING, INT32)
FORTRAN_API_FN(INT, SWwrdmeta, SWWRDMETA, swwrdmeta, INT32, STRING, STRING, INT32)
FORTRAN_API_FN(INT, SWwrfld, SWWRFLD, swwrfld, INT32, STRING, INT32V, INT32V, INT32V, PVOID)
FORTRAN_API_FN(INT, SWrdfld, SWRDFLD, swrdfld, INT32, STRING, INT32V, INT32V, INT32V, PVOID)
FORTRAN_API_FN(INT, SWsetfillvalue, SWSETFILL, swsetfill, INT32, STRING, PVOID)
FORTRAN_API_FN(INT, SWgetfillvalue, SWGETFILL, swgetfill, INT32, STRING, PVOID)
FORTRAN_API_FN(INT, SWwriteattr, SWWRATTR, swwrattr, INT32, STRING, INT32, INT32, PVOID)
FORTRAN_API_FN(INT, SWreadattr, SWRDATTR, swrdattr, INT32, STRING, PVOID)
FORTRAN_API_FN(INT, SWattrinfo, SWATTRINFO, swattrinfo, INT32, STRING, PINT32, PINT32)
FORTRAN_API_FN(INT32, SWinqattrs, SWINQATTRS, swinqattrs, INT32, OUT STRING, PINT32)
FORTRAN_API_FN(INT32, SWinqdims, SWINQDIMS, swinqdims, INT32, OUT STRING, INT32V)
FORTRAN_API_FN(INT32, SWinqmaps, SWINQMAPS, swinqmaps, INT32, OUT STRING, INT32V, INT32V)
FORTRAN_API_FN(INT32, SWupdateidxmap, SWUPIMAP, swupimap,INT32, INT32, INT32V, INT32V, INT32V)
FORTRAN_API_FN(INT, SWupdatescene, SWUPSCENE, swupscene,INT32, INT32)
FORTRAN_API_FN(INT, SWgeomapinfo, SWGMAPINFO, swgmapinfo, INT32, STRING)
FORTRAN_API_FN(INT32, SWinqidxmaps, SWINQIMAPS, swinqimaps, INT32, OUT STRING, INT32V)
FORTRAN_API_FN(INT32, SWinqgeofields, SWINQGFLDS, swinqgflds, INT32, OUT STRING, INT32V, INT32V)
FORTRAN_API_FN(INT32, SWinqdatafields, SWINQDFLDS, swinqdflds, INT32, OUT STRING, INT32V, INT32V)
FORTRAN_API_FN(INT32, SWinqswath, SWINQSWATH, swinqswath, STRING, OUT STRING, PINT32)
FORTRAN_API_FN(INT32, SWnentries, SWNENTRIES, swnentries, INT32, INT32, PINT32)
FORTRAN_API_FN(INT32, SWdiminfo, SWNDIMINFO, swdiminfo, INT32, STRING)
FORTRAN_API_FN(INT, SWmapinfo, SWNMAPINFO, swmapinfo, INT32, STRING, STRING, PINT32, PINT32)
FORTRAN_API_FN(INT32, SWidxmapinfo, SWIMAPINFO, swimapinfo, INT32, STRING, STRING, INT32V)
FORTRAN_API_FN(INT, SWcompinfo, SWCOMPINFO, swcompinfo, INT32, STRING, PINT32, INTV)
FORTRAN_API_FN(INT, SWfldinfo, SWFLDINFO, swfldinfo, INT32, STRING, PINT32, INT32V, PINT32, OUT STRING)
FORTRAN_API_FN(INT32, SWdefboxregion, SWDEFBOXREG, swdefboxreg, INT32, DOUBLEV, DOUBLEV, INT32)
FORTRAN_API_FN(INT32, SWregionindex, SWREGIDX, swregidx, INT32, DOUBLEV, DOUBLEV, INT32, STRING, INT32V)
FORTRAN_API_FN(INT32, SWdefvrtreg, SWDEFVRTREG, swdefvrtreg, INT32, INT32, STRING, DOUBLEV)
FORTRAN_API_FN(INT32, SWdeftimeperiod, SWDEFTMEPER, swdeftmeper, INT32, DOUBLE, DOUBLE, INT32)
FORTRAN_API_FN(INT, SWreginfo, SWREGINFO, swreginfo, INT32, INT32, STRING, PINT32, PINT32, INT32V, PINT32)
FORTRAN_API_FN(INT, SWperinfo, SWPERINFO, swperinfo, INT32, INT32, STRING, PINT32, PINT32, INT32V, PINT32)
FORTRAN_API_FN(INT, SWextractregion, SWEXTREG, swextreg, INT32, INT32, STRING, INT32, PVOID)
FORTRAN_API_FN(INT, SWextractperiod, SWEXTPER, swextper, INT32, INT32, STRING, INT32, PVOID)
FORTRAN_API_FN(INT32, SWdupregion, SWDUPREG, swdupreg, INT32)
FORTRAN_API_FN(INT, SWdetach, SWDETACH, swdetach, INT32)
FORTRAN_API_FN(INT, SWclose, SWCLOSE, swclose, INT32)
FORTRAN_API_FN(INT32, SWidxinfo, SWIDXINFO, swidxinfo, INT32, STRING, INT32, OUT STRING, PINT32)
FORTRAN_API_FN(INT, SWdefdimscale, SWDEFDIMSCALE, swdefdimscale, INT32, STRING, INT32, INT32, PVOID)
FORTRAN_API_FN(INT, SWsetdimscale, SWSETDIMSCALE, swsetdimscale, INT32, STRING, STRING, INT32, INT32, PVOID)
FORTRAN_API_FN(INT, SWgetdimscale, SWGETDIMSCALE, swgetdimscale, INT32, STRING, STRING, PINT32, PINT32, PVOID)
FORTRAN_API_FN(INT, SWdefdimstrs, SWDEFDIMSTRS, swdefdimstrs, INT32, STRING, STRING, STRING, STRING)
FORTRAN_API_FN(INT, SWsetdimstrs, SWSETDIMSTRS, swsetdimstrs, INT32, STRING, STRING, STRING, STRING, STRING)
FORTRAN_API_FN(INT, SWgetdimstrs, SWGETDIMSTRS, swgetdimstrs, INT32, STRING, STRING, OUT STRING, OUT STRING, OUT STRING,INT)
FORTRAN_API_FN(INT, SWchkinfo, SWCHKINFO, swchkinfo, INT32, STRING, PINT32, PINT32, INT32V)

#endif // FORTRAN_API