/*****************************************************************************
FILE: convert_l2lpgs_to_espa.c
  
PURPOSE: Contains functions for reading Level-2 LPGS input GeoTIFF products and
writing to ESPA raw binary format.

PROJECT:  Land Satellites Data System Science Research and Development (LSRD)
at the USGS EROS

LICENSE TYPE:  NASA Open Source Agreement Version 1.3

NOTES:
  1. The XML metadata format written via this library follows the ESPA internal
     metadata format found in ESPA Raw Binary Format vx.y.doc.  The schema for
     the ESPA internal metadata format is available at
     http://espa.cr.usgs.gov/schema/espa_internal_metadata_vx.y.xsd.
*****************************************************************************/
#include <unistd.h>
#include <math.h>
#include "convert_l2lpgs_to_espa.h"

/******************************************************************************
MODULE:  parse_data_type

PURPOSE: Grabs the data type from the tokenptr and returns the ESPA data
type integer value.

RETURN VALUE:
Type = int
Value               Description
-----               -----------
ESPA_INT8           Value is an INT8
ESPA_UINT8          Value is a UINT8
ESPA_INT16          Value is an INT16
ESPA_UINT16         Value is a UINT16
ESPA_INT_META_FILL  Unexpected data type

NOTES:
******************************************************************************/
int parse_data_type
(
    char *tokenptr   /* I: pointer to the token character string */
)
{
    if (!strcmp (tokenptr, "UINT8"))
        return (ESPA_UINT8);
    else if (!strcmp (tokenptr, "INT8"))
        return (ESPA_INT8);
    else if (!strcmp (tokenptr, "UINT16"))
        return (ESPA_UINT16);
    else if (!strcmp (tokenptr, "INT16"))
        return (ESPA_INT16);
    else
        return (ESPA_INT_META_FILL);
}


/******************************************************************************
MODULE:  read_l2lpgs_mtl

PURPOSE: Read the Level-2 LPGS MTL metadata file and populate the ESPA internal
metadata structure

RETURN VALUE:
Type = int
Value           Description
-----           -----------
ERROR           Error reading the metadata file
SUCCESS         Successfully populated the ESPA metadata structure

NOTES:
1. When processing Level-2 metadata, stop when we get to the Level-1 metadata
   or we will overwrite the Level-2 information.
2. Band gain/bias are not available in the MTL.txt file for some of the ST
   bands.  Only the ST_B6 and ST_B10 have gains and biases represented in the
   C2 Level-2 metadata, even though the other bands have gains.  That
   information will need to be hard-coded in this application for the ESPA
   metadata.  The fill is also not represented for any band, along with
   other metadata that is needed.  The L8-9 and L4-7 product guides are
   available from the following URLs.
   https://www.usgs.gov/media/files/landsat-8-collection-2-level-2-science-product-guide
   https://www.usgs.gov/media/files/landsat-4-7-collection-2-level-2-science-product-guide
******************************************************************************/
int read_l2lpgs_mtl
(
    char *mtl_file,                  /* I: name of the MTL metadata file to
                                           be read */
    Espa_internal_meta_t *metadata,  /* I/O: input metadata structure to be
                                           populated from the MTL file */
    int *nlpgs_bands,                /* O: number of bands in LPGS product */
    char lpgs_bands[][STR_SIZE]      /* O: array containing the filenames of
                                           the LPGS bands */
)
{
    char FUNC_NAME[] = "read_l2lpgs_mtl";  /* function name */
    char errmsg[STR_SIZE];    /* error message */
    char *cptr = NULL;        /* pointer to the file extension */
    int i;                    /* looping variable */
    int count;                /* number of chars copied in snprintf */
    int band;                 /* index for the current band */
    int band_count = 0;       /* count of the bands processed so we don't have
                                 to specify each band number directly, which
                                 get complicated as we are supporting TM, ETM+,
                                 OLI, etc. */
    bool done_with_mtl;       /* are we done processing the MTL file? */
    bool thermal[MAX_L2LPGS_BANDS]; /* is this band a thermal band? */
    FILE *mtl_fptr=NULL;      /* file pointer to the MTL metadata file */
    Espa_global_meta_t *gmeta = &metadata->global;  /* pointer to the global
                                                       metadata structure */
    Espa_band_meta_t *bmeta;  /* pointer to the array of bands metadata */
    Espa_band_meta_t tmp_bmeta;    /* for temporary storage of the band-related
                                      metadata for reflective bands */
    Espa_band_meta_t tmp_bmeta_th; /* for temporary storage of the band-related
                                      metadata for thermal bands */
    Space_def_t geoloc_def;  /* geolocation space information */
    Geoloc_t *geoloc_map = NULL;  /* geolocation mapping information */
    Geo_bounds_t bounds;     /* image boundary for the scene */
    double ur_corner[2];     /* geographic UR lat, long */
    double ll_corner[2];     /* geographic LL lat, long */
    char band_fname[MAX_L2LPGS_BANDS][STR_SIZE]; /* filename for each band */
    char band_lname[MAX_L2LPGS_BANDS][STR_SIZE]; /* long name for each band */
    char band_sname[MAX_L2LPGS_BANDS][STR_SIZE]; /* short name for each band */
    char category[MAX_L2LPGS_BANDS][STR_SIZE];   /* band category - qa, image */
    char band_name[MAX_L2LPGS_BANDS][STR_SIZE];  /* band name for each band */
    char data_units[MAX_L2LPGS_BANDS][STR_SIZE]; /* data units for band name */
    char product[MAX_L2LPGS_BANDS][STR_SIZE];  /* product type for each band */
    int band_min[MAX_L2LPGS_BANDS];    /* minimum value for each band */
    int band_max[MAX_L2LPGS_BANDS];    /* maximum value for each band */
    int data_type[MAX_L2LPGS_BANDS];   /* data type for each band */
    int fill_val[MAX_L2LPGS_BANDS];    /* fill value for each band */
    float band_gain[MAX_L2LPGS_BANDS]; /* gain values for each band */
    float band_bias[MAX_L2LPGS_BANDS]; /* bias values for each band */

    /* vars used in parameter parsing */
    char buffer[STR_SIZE] = "\0";   /* line buffer from MTL file */
    char *label = NULL;             /* label value in the line */
    char *tokenptr = NULL;          /* pointer to process each line */
    char *seperator = "=\" \t";     /* separator string */
    float fnum;                     /* temporary variable for floating point
                                       numbers */

    /* Initialize the metadata information to metadata fill values in the
       event they aren't used by any particular band */
    for (i = 0; i < MAX_L2LPGS_BANDS; i++)
    {
        thermal[i] = false;
        strcpy (band_fname[i], ESPA_STRING_META_FILL);
        strcpy (band_lname[i], ESPA_STRING_META_FILL);
        strcpy (band_sname[i], ESPA_STRING_META_FILL);
        strcpy (category[i], ESPA_STRING_META_FILL);
        strcpy (band_name[i], ESPA_STRING_META_FILL);
        strcpy (data_units[i], ESPA_STRING_META_FILL);
        strcpy (product[i], ESPA_STRING_META_FILL);
        band_min[i] = ESPA_INT_META_FILL;
        band_max[i] = ESPA_INT_META_FILL;
        data_type[i] = ESPA_INT_META_FILL;
        fill_val[i] = ESPA_INT_META_FILL;
        band_gain[i] = ESPA_FLOAT_META_FILL;
        band_bias[i] = ESPA_FLOAT_META_FILL;
    }

    /* Open the metadata MTL file with read privelages */
    mtl_fptr = fopen (mtl_file, "r");
    if (mtl_fptr == NULL)
    {
        sprintf (errmsg, "Opening %s for read access.", mtl_file);
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    /* The sensor ID is needed for parsing the rest of the MTL.  It needs to
       be read since it falls after many of the other tokens in the MTL. */
    while (fgets (buffer, STR_SIZE, mtl_fptr) != NULL)
    {
        /* If the last character is the end of line, then strip it off */
        if (buffer[strlen(buffer)-1] == '\n')
            buffer[strlen(buffer)-1] = '\0';

        /* Get string token */
        tokenptr = strtok (buffer, seperator);
        label = tokenptr;

        if (tokenptr != NULL)
        {
            tokenptr = strtok (NULL, seperator);

            if (!strcmp (label, "SENSOR_ID"))
            {
                count = snprintf (gmeta->instrument, sizeof (gmeta->instrument),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (gmeta->instrument))
                {
                    sprintf (errmsg, "Overflow of gmeta->instrument string");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }

                break;  /* we have found what we needed */
            }
        } /* end if tokenptr */
    }  /* end while fgets */

    /* Rewind the buffer to the start */
    rewind (mtl_fptr);

    /* Make sure the sensor ID was found */
    if (!gmeta->instrument)
    {
        sprintf (errmsg, "SENSOR ID was not found in the MTL file.");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    /* Process the MTL file line by line */
    done_with_mtl = false;
    while (fgets (buffer, STR_SIZE, mtl_fptr) != NULL)
    {
        /* If the last character is the end of line, then strip it off */
        if (buffer[strlen(buffer)-1] == '\n')
            buffer[strlen(buffer)-1] = '\0';

        /* Get string token */
        tokenptr = strtok (buffer, seperator);
        label = tokenptr;
 
        if (tokenptr != NULL)
        {
            tokenptr = strtok (NULL, seperator);

            /* Process each token */
            if (!strcmp (label, "PROCESSING_LEVEL"))
            {
                /* If we aren't dealing with Level-2 metadata in the metadata
                   file then something has happened and we have blown past
                   our stop in the parsing at the end of the while loop.
                   Support L2SP (SR & ST) and L2SR (SR-only) products. */
                if (strcmp (tokenptr, "L2SP") != 0 &&
                    strcmp (tokenptr, "L2SR") != 0)
                {
                    sprintf (errmsg, "Reading metadata with a processing "
                        "level other than L2SR or L2SP");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "COLLECTION_NUMBER"))
            {
                /* Verify this metadata is for Collection 2 */
                if (strcmp (tokenptr, "02") != 0)
                {
                    sprintf (errmsg, "Reading metadata other than "
                        "Collection 02");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "PROCESSING_SOFTWARE_VERSION"))
            {
                count = snprintf (tmp_bmeta.app_version,
                    sizeof (tmp_bmeta.app_version), "%s", tokenptr);
                if (count < 0 || count >= sizeof (tmp_bmeta.app_version))
                {
                    sprintf (errmsg, "Overflow of tmp_bmeta.app_version");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "DATA_SOURCE_REANALYSIS"))
            {
                count = snprintf (tmp_bmeta.source, sizeof (tmp_bmeta.source),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (tmp_bmeta.source))
                {
                    sprintf (errmsg, "Overflow of tmp_bmeta.source");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "LANDSAT_PRODUCT_ID"))
            {
                count = snprintf (gmeta->product_id, sizeof (gmeta->product_id),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (gmeta->product_id))
                {
                    sprintf (errmsg, "Overflow of gmeta->product_id string");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "SPACECRAFT_ID"))
            {
                if (!strcmp (tokenptr, "LANDSAT_9"))
                    strcpy (gmeta->satellite, "LANDSAT_9");
                else if (!strcmp (tokenptr, "LANDSAT_8"))
                    strcpy (gmeta->satellite, "LANDSAT_8");
                else if (!strcmp (tokenptr, "LANDSAT_7"))
                    strcpy (gmeta->satellite, "LANDSAT_7");
                else if (!strcmp (tokenptr, "LANDSAT_5"))
                    strcpy (gmeta->satellite, "LANDSAT_5");
                else if (!strcmp (tokenptr, "LANDSAT_4"))
                    strcpy (gmeta->satellite, "LANDSAT_4");
                else
                {
                    sprintf (errmsg, "Unsupported satellite type: %s",
                        tokenptr);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "DATE_ACQUIRED"))
            {
                count = snprintf (gmeta->acquisition_date,
                    sizeof (gmeta->acquisition_date), "%s", tokenptr);
                if (count < 0 || count >= sizeof (gmeta->acquisition_date))
                {
                    sprintf (errmsg, "Overflow of gmeta->acquisition_date");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "SCENE_CENTER_TIME"))
            {
                count = snprintf (gmeta->scene_center_time,
                    sizeof (gmeta->scene_center_time), "%s", tokenptr);
                if (count < 0 || count >= sizeof (gmeta->scene_center_time))
                {
                    sprintf (errmsg, "Overflow of gmeta->scene_center_time");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "DATE_PRODUCT_GENERATED"))
            {
                count = snprintf (gmeta->level1_production_date,
                    sizeof (gmeta->level1_production_date), "%s", tokenptr);
                if (count < 0 ||
                    count >= sizeof (gmeta->level1_production_date))
                {
                    sprintf (errmsg,
                        "Overflow of gmeta->level1_production_date");
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "SUN_ELEVATION"))
            {
                sscanf (tokenptr, "%f", &fnum);
                gmeta->solar_zenith = 90.0 - fnum;
            }
            else if (!strcmp (label, "SUN_AZIMUTH"))
                sscanf (tokenptr, "%f", &gmeta->solar_azimuth);
            else if (!strcmp (label, "EARTH_SUN_DISTANCE"))
                sscanf (tokenptr, "%f", &gmeta->earth_sun_dist);
            else if (!strcmp (label, "WRS_PATH"))
                sscanf (tokenptr, "%d", &gmeta->wrs_path);
            else if (!strcmp (label, "WRS_ROW"))
                sscanf (tokenptr, "%d", &gmeta->wrs_row);

            else if (!strcmp (label, "CORNER_UL_LAT_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->ul_corner[0]);
            else if (!strcmp (label, "CORNER_UL_LON_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->ul_corner[1]);
            else if (!strcmp (label, "CORNER_LR_LAT_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->lr_corner[0]);
            else if (!strcmp (label, "CORNER_LR_LON_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->lr_corner[1]);

            else if (!strcmp (label, "CORNER_UR_LAT_PRODUCT"))
                sscanf (tokenptr, "%lf", &ur_corner[0]);
            else if (!strcmp (label, "CORNER_UR_LON_PRODUCT"))
                sscanf (tokenptr, "%lf", &ur_corner[1]);
            else if (!strcmp (label, "CORNER_LL_LAT_PRODUCT"))
                sscanf (tokenptr, "%lf", &ll_corner[0]);
            else if (!strcmp (label, "CORNER_LL_LON_PRODUCT"))
                sscanf (tokenptr, "%lf", &ll_corner[1]);

            else if (!strcmp (label, "CORNER_UL_PROJECTION_X_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.ul_corner[0]);
            else if (!strcmp (label, "CORNER_UL_PROJECTION_Y_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.ul_corner[1]);
            else if (!strcmp (label, "CORNER_LR_PROJECTION_X_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.lr_corner[0]);
            else if (!strcmp (label, "CORNER_LR_PROJECTION_Y_PRODUCT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.lr_corner[1]);

            else if (!strcmp (label, "REFLECTIVE_SAMPLES"))
                sscanf (tokenptr, "%d", &tmp_bmeta.nsamps);
            else if (!strcmp (label, "REFLECTIVE_LINES"))
                sscanf (tokenptr, "%d", &tmp_bmeta.nlines);
            else if (!strcmp (label, "THERMAL_SAMPLES"))
                sscanf (tokenptr, "%d", &tmp_bmeta_th.nsamps);
            else if (!strcmp (label, "THERMAL_LINES"))
                sscanf (tokenptr, "%d", &tmp_bmeta_th.nlines);

            else if (!strcmp (label, "MAP_PROJECTION"))
            {
                if (!strcmp (tokenptr, "UTM"))
                    gmeta->proj_info.proj_type = GCTP_UTM_PROJ;
                else if (!strcmp (tokenptr, "PS"))
                    gmeta->proj_info.proj_type = GCTP_PS_PROJ;
                else if (!strcmp (tokenptr, "AEA"))  /* ALBERS */
                    gmeta->proj_info.proj_type = GCTP_ALBERS_PROJ;
                else
                {
                    sprintf (errmsg, "Unsupported projection type: %s. "
                        "Only UTM, PS, and ALBERS EQUAL AREA are supported "
                        "for LPGS.", tokenptr);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "DATUM"))
            {
                if (!strcmp (tokenptr, "WGS84"))
                    gmeta->proj_info.datum_type = ESPA_WGS84;
                else
                {
                    sprintf (errmsg, "Unexpected datum type: %s", tokenptr);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
            }
            else if (!strcmp (label, "GRID_CELL_SIZE_REFLECTIVE"))
            {
                sscanf (tokenptr, "%lf", &tmp_bmeta.pixel_size[0]);
                tmp_bmeta.pixel_size[1] = tmp_bmeta.pixel_size[0];
            }
            else if (!strcmp (label, "GRID_CELL_SIZE_THERMAL"))
            {
                sscanf (tokenptr, "%lf", &tmp_bmeta_th.pixel_size[0]);
                tmp_bmeta_th.pixel_size[1] = tmp_bmeta_th.pixel_size[0];
            }
            else if (!strcmp (label, "UTM_ZONE"))
                sscanf (tokenptr, "%d", &gmeta->proj_info.utm_zone);

            /* PS projection parameters */
            else if (!strcmp (label, "VERTICAL_LON_FROM_POLE"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.longitude_pole);
            else if (!strcmp (label, "TRUE_SCALE_LAT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.latitude_true_scale);
            else if (!strcmp (label, "FALSE_EASTING"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.false_easting);
            else if (!strcmp (label, "FALSE_NORTHING"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.false_northing);

            /* ALBERS projection parameters (in addition to false easting and
               northing under PS proj params) */
            else if (!strcmp (label, "STANDARD_PARALLEL_1_LAT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.standard_parallel1);
            else if (!strcmp (label, "STANDARD_PARALLEL_2_LAT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.standard_parallel2);
            else if (!strcmp (label, "CENTRAL_MERIDIAN_LON"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.central_meridian);
            else if (!strcmp (label, "ORIGIN_LAT"))
                sscanf (tokenptr, "%lf", &gmeta->proj_info.origin_latitude);

            /* Read the Level-2 band names and identify band-specific metadata
               information */
            else if (!strcmp (label, "FILE_NAME_BAND_1"))
            {
                band = SR_B1;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 1 surface reflectance");
                strcpy (category[band], "image");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_band1");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_2"))
            {
                band = SR_B2;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 2 surface reflectance");
                strcpy (category[band], "image");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_band2");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_3"))
            {
                band = SR_B3;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 3 surface reflectance");
                strcpy (category[band], "image");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_band3");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_4"))
            {
                band = SR_B4;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 4 surface reflectance");
                strcpy (category[band], "image");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_band4");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_5"))
            {
                band = SR_B5;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 5 surface reflectance");
                strcpy (category[band], "image");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_band5");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_6"))
            {
                band = SR_B6;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 6 surface reflectance");
                strcpy (category[band], "image");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_band6");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_7"))
            {
                band = SR_B7;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "band 7 surface reflectance");
                strcpy (&category[band][0], "image");
                strcpy (product[band], "sr_refl");
                strcpy (&band_name[band][0], "sr_band7");
                strcpy (data_units[band], "reflectance");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_ST_B6"))
            {  /* min/max is pulled from the metadata file */
                band = ST_B6;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "ST");
                strcpy (band_lname[band], "band 6 surface temperature");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_band6");
                strcpy (data_units[band], "Kelvin");
                fill_val[band] = 0;
                thermal[band] = true;  /* TM/ETM+ thermal */
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_BAND_ST_B10"))
            {  /* min/max is pulled from the metadata file */
                band = ST_B10;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "ST");
                strcpy (band_lname[band], "band 10 surface temperature");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_band10");
                strcpy (data_units[band], "Kelvin");
                fill_val[band] = 0;
                thermal[band] = true;  /* OLI thermal */
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_THERMAL_RADIANCE"))
            {
                band = ST_TRAD;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STTRAD");
                strcpy (band_lname[band], "thermal radiance");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_trad");
                strcpy (data_units[band], "W/(m2 sr µm)/DN");
                band_min[band] = 0.0;
                band_max[band] = 22000.0;
                band_gain[band] = 0.001;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_UPWELL_RADIANCE"))
            {
                band = ST_URAD;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STURAD");
                strcpy (band_lname[band], "upwell radiance");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_urad");
                strcpy (data_units[band], "W/(m2 sr µm)/DN");
                band_min[band] = 0.0;
                band_max[band] = 28000.0;
                band_gain[band] = 0.001;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_DOWNWELL_RADIANCE"))
            {
                band = ST_DRAD;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STDRAD");
                strcpy (band_lname[band], "downwell radiance");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_drad");
                strcpy (data_units[band], "W/(m2 sr µm)/DN");
                band_min[band] = 0.0;
                band_max[band] = 28000.0;
                band_gain[band] = 0.001;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_ATMOSPHERIC_TRANSMITTANCE"))
            {
                band = ST_ATRAN;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STATRAN");
                strcpy (band_lname[band], "atmospheric transmittance");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_atran");
                strcpy (data_units[band], "ratio");
                band_min[band] = 0.0;
                band_max[band] = 10000.0;
                band_gain[band] = 0.0001;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_EMISSIVITY"))
            {
                band = ST_EMIS;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STEMIS");
                strcpy (band_lname[band],
                    "emissivity estimated from ASTER GED");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_emis");
                strcpy (data_units[band], "ratio");
                band_min[band] = 0.0;
                band_max[band] = 10000.0;
                band_gain[band] = 0.0001;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_EMISSIVITY_STDEV"))
            {
                band = ST_EMSD;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STEMSD");
                strcpy (band_lname[band], "emissivity standard deviation");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_emsd");
                strcpy (data_units[band], "unitless");
                band_min[band] = 0.0;
                band_max[band] = 10000.0;
                band_gain[band] = 0.0001;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_CLOUD_DISTANCE"))
            {
                band = ST_CDIST;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "ST");
                strcpy (band_lname[band], "cloud distance");
                strcpy (category[band], "image");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_cdist");
                strcpy (data_units[band], "kilometers");
                band_min[band] = 0.0;
                band_max[band] = 32767.0;
                band_gain[band] = 0.01;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_ATMOSPHERIC_OPACITY"))
            {
                band = SR_ATMOS_OPACITY;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "atmospheric opacity");
                strcpy (category[band], "qa");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_atmos_opacity");
                strcpy (data_units[band], "unitless");
                band_gain[band] = 0.001;
                fill_val[band] = -9999;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label,
                "FILE_NAME_QUALITY_L2_SURFACE_REFLECTANCE_CLOUD"))
            {
                band = SR_CLOUD_QA;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SR");
                strcpy (band_lname[band], "surface reflectance cloud QA");
                strcpy (category[band], "qa");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_cloud_qa");
                strcpy (data_units[band], "bitmap");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_QUALITY_L2_AEROSOL"))
            {
                band = SR_AEROSOL;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "SRAERO");
                strcpy (band_lname[band], "surface reflectance aerosol mask");
                strcpy (category[band], "qa");
                strcpy (product[band], "sr_refl");
                strcpy (band_name[band], "sr_aerosol");
                strcpy (data_units[band], "bitmap");
                fill_val[band] = 0;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label,
                "FILE_NAME_QUALITY_L2_SURFACE_TEMPERATURE"))
            {
                band = ST_QA;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "STQA");
                strcpy (band_lname[band], "surface temperature uncertainty");
                strcpy (category[band], "qa");
                strcpy (product[band], "surface_temp");
                strcpy (band_name[band], "st_qa");
                strcpy (data_units[band], "Kelvin");
                band_min[band] = 0.0;
                band_max[band] = 32767.0;
                band_gain[band] = 0.01;
                fill_val[band] = -9999;
                thermal[band] = true;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label, "FILE_NAME_QUALITY_L1_PIXEL"))
            {
                band = QA_PIXEL;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "PQA");
                strcpy (band_lname[band], "level-1 pixel quality");
                strcpy (category[band], "qa");
                strcpy (product[band], "L1");
                strcpy (band_name[band], "qa_pixel");
                strcpy (data_units[band], "bitmap");
                fill_val[band] = 1;
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }
            else if (!strcmp (label,
                "FILE_NAME_QUALITY_L1_RADIOMETRIC_SATURATION"))
            {
                band = QA_RADSAT;
                count = snprintf (band_fname[band], sizeof (band_fname[band]),
                    "%s", tokenptr);
                if (count < 0 || count >= sizeof (band_fname[band]))
                {
                    sprintf (errmsg, "Overflow of band_fname[%d] string", band);
                    error_handler (true, FUNC_NAME, errmsg);
                    return (ERROR);
                }
                strcpy (band_sname[band], "RADSAT");
                strcpy (band_lname[band],
                    "level-1 radiometric saturation and terrain occlusion");
                strcpy (category[band], "qa");
                strcpy (product[band], "L1");
                strcpy (band_name[band], "qa_radsat");
                strcpy (data_units[band], "bitmap");
                /* no fill value */
                thermal[band] = false;
                band_count++;  /* increment the band count */
            }

            /* Read the data type */
            else if (!strcmp (label, "DATA_TYPE_BAND_1"))
                data_type[SR_B1] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_2"))
                data_type[SR_B2] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_3"))
                data_type[SR_B3] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_4"))
                data_type[SR_B4] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_5"))
                data_type[SR_B5] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_6"))
                data_type[SR_B6] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_7"))
                data_type[SR_B7] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_ST_B6"))
                data_type[ST_B6] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_BAND_ST_B10"))
                data_type[ST_B10] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_THERMAL_RADIANCE"))
                data_type[ST_TRAD] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_UPWELL_RADIANCE"))
                data_type[ST_URAD] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_DOWNWELL_RADIANCE"))
                data_type[ST_DRAD] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_ATMOSPHERIC_TRANSMITTANCE"))
                data_type[ST_ATRAN] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_EMISSIVITY"))
                data_type[ST_EMIS] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_EMISSIVITY_STDEV"))
                data_type[ST_EMSD] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_CLOUD_DISTANCE"))
                data_type[ST_CDIST] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_ATMOSPHERIC_OPACITY"))
                data_type[SR_ATMOS_OPACITY] = parse_data_type (tokenptr);
            else if (!strcmp (label,
                "DATA_TYPE_QUALITY_L2_SURFACE_REFLECTANCE_CLOUD"))
                data_type[SR_CLOUD_QA] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_QUALITY_L2_AEROSOL"))
                data_type[SR_AEROSOL] = parse_data_type (tokenptr);
            else if (!strcmp (label,
                "DATA_TYPE_QUALITY_L2_SURFACE_TEMPERATURE"))
                data_type[ST_QA] = parse_data_type (tokenptr);
            else if (!strcmp (label, "DATA_TYPE_QUALITY_L1_PIXEL"))
                data_type[QA_PIXEL] = parse_data_type (tokenptr);
            else if (!strcmp (label,
                "DATA_TYPE_QUALITY_L1_RADIOMETRIC_SATURATION"))
                data_type[QA_RADSAT] = parse_data_type (tokenptr);

            /* Read the min pixel values */
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_1"))
                sscanf (tokenptr, "%d", &band_min[SR_B1]);
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_2"))
                sscanf (tokenptr, "%d", &band_min[SR_B2]);
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_3"))
                sscanf (tokenptr, "%d", &band_min[SR_B3]);
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_4"))
                sscanf (tokenptr, "%d", &band_min[SR_B4]);
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_5"))
                sscanf (tokenptr, "%d", &band_min[SR_B5]);
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_6"))
                sscanf (tokenptr, "%d", &band_min[SR_B6]);
            else if (!strcmp (label, "QUANTIZE_CAL_MIN_BAND_7"))
                sscanf (tokenptr, "%d", &band_min[SR_B7]);
            else if (!strcmp (label, "QUANTIZE_CAL_MINIMUM_BAND_ST_B6"))
                sscanf (tokenptr, "%d", &band_min[ST_B6]);
            else if (!strcmp (label, "QUANTIZE_CAL_MINIMUM_BAND_ST_B10"))
                sscanf (tokenptr, "%d", &band_min[ST_B10]);

            /* Read the max pixel values */
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_1"))
                sscanf (tokenptr, "%d", &band_max[SR_B1]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_2"))
                sscanf (tokenptr, "%d", &band_max[SR_B2]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_3"))
                sscanf (tokenptr, "%d", &band_max[SR_B3]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_4"))
                sscanf (tokenptr, "%d", &band_max[SR_B4]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_5"))
                sscanf (tokenptr, "%d", &band_max[SR_B5]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_6"))
                sscanf (tokenptr, "%d", &band_max[SR_B6]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAX_BAND_7"))
                sscanf (tokenptr, "%d", &band_max[SR_B7]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAXIMUM_BAND_ST_B6"))
                sscanf (tokenptr, "%d", &band_max[ST_B6]);
            else if (!strcmp (label, "QUANTIZE_CAL_MAXIMUM_BAND_ST_B10"))
                sscanf (tokenptr, "%d", &band_max[ST_B10]);

            /* Read the reflectance and ST gains */
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_1"))
                sscanf (tokenptr, "%f", &band_gain[SR_B1]);
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_2"))
                sscanf (tokenptr, "%f", &band_gain[SR_B2]);
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_3"))
                sscanf (tokenptr, "%f", &band_gain[SR_B3]);
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_4"))
                sscanf (tokenptr, "%f", &band_gain[SR_B4]);
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_5"))
                sscanf (tokenptr, "%f", &band_gain[SR_B5]);
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_6"))
                sscanf (tokenptr, "%f", &band_gain[SR_B6]);
            else if (!strcmp (label, "REFLECTANCE_MULT_BAND_7"))
                sscanf (tokenptr, "%f", &band_gain[SR_B7]);
            else if (!strcmp (label, "TEMPERATURE_MULT_BAND_ST_B6"))
                sscanf (tokenptr, "%f", &band_gain[ST_B6]);
            else if (!strcmp (label, "TEMPERATURE_MULT_BAND_ST_B10"))
                sscanf (tokenptr, "%f", &band_gain[ST_B10]);

            /* Read the reflectance and ST biases */
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_1"))
                sscanf (tokenptr, "%f", &band_bias[SR_B1]);
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_2"))
                sscanf (tokenptr, "%f", &band_bias[SR_B2]);
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_3"))
                sscanf (tokenptr, "%f", &band_bias[SR_B3]);
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_4"))
                sscanf (tokenptr, "%f", &band_bias[SR_B4]);
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_5"))
                sscanf (tokenptr, "%f", &band_bias[SR_B5]);
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_6"))
                sscanf (tokenptr, "%f", &band_bias[SR_B6]);
            else if (!strcmp (label, "REFLECTANCE_ADD_BAND_7"))
                sscanf (tokenptr, "%f", &band_bias[SR_B7]);
            else if (!strcmp (label, "TEMPERATURE_ADD_BAND_ST_B6"))
                sscanf (tokenptr, "%f", &band_bias[ST_B6]);
            else if (!strcmp (label, "TEMPERATURE_ADD_BAND_ST_B10"))
                sscanf (tokenptr, "%f", &band_bias[ST_B10]);

            /* If we have hit the LEVEL1_PROCESSING_RECORD, then stop parsing
               since we only want the Level-2 metadata */
            else if (!strcmp (label, "GROUP") &&
                !strcmp (tokenptr, "LEVEL1_PROCESSING_RECORD"))
            {
                done_with_mtl = true;
                break;
            }
        } /* end if tokenptr */

        /* If we are done */
        if (done_with_mtl)
            break;
    }  /* end while fgets */

    /* Check the band count to make sure we didn't go over the maximum
       expected */
    if (band_count > MAX_L2LPGS_BANDS)
    {
        sprintf (errmsg, "The total band count of LPGS bands converted for "
            "this product (%d) exceeds the maximum expected (%d).", band_count,
            MAX_L2LPGS_BANDS);
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    /* Set defaults that aren't in the MTL file */
    gmeta->wrs_system = 2;
    gmeta->orientation_angle = 0.0;
    strcpy (gmeta->data_provider, "USGS/EROS");
    strcpy (gmeta->solar_units, "degrees");

    count = snprintf (gmeta->lpgs_metadata_file,
        sizeof (gmeta->lpgs_metadata_file), "%s", mtl_file);
    if (count < 0 || count >= sizeof (gmeta->lpgs_metadata_file))
    {
        sprintf (errmsg, "Overflow of gmeta->lpgs_metadata_file string");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    count = snprintf (gmeta->proj_info.units, sizeof (gmeta->proj_info.units),
        "%s", "meters");
    if (count < 0 || count >= sizeof (gmeta->proj_info.units))
    {
        sprintf (errmsg, "Overflow of gmeta->proj_info.units string");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    /* UL and LR corner projection coords in the MTL file are for the center
       of the pixel.  Given there are different resolution bands, leave the
       corners as the center of the pixel. */
    strcpy (gmeta->proj_info.grid_origin, "CENTER");

    /* Set up the number of total bands */
    metadata->nbands = band_count;
    if (allocate_band_metadata (metadata, metadata->nbands) != SUCCESS)
    {   /* Error messages already printed */
        return (ERROR);
    }
    bmeta = metadata->band;

    /* Reset the band count to keep track of the exact band in the output
       metadata we are working with. The actual band won't necessarily match
       the band number in the l2lpgs_bands and the intermediate arrays that
       have been set up to read the data from the metadata file. The actual
       band number will fluctuate by one or so. */
    band_count = 0;

    /* Fill in the band-related metadata for each of the bands */
    for (i = 0; i < MAX_L2LPGS_BANDS; i++)
    {
        /* If this is not OLI, then skip the SR_B7 band */
        if (strncmp (gmeta->instrument, "OLI", 3) && i == SR_B6)
            continue;

        /* If this is OLI, then skip the atmos_opacity band */
        if (!strncmp (gmeta->instrument, "OLI", 3) && i == SR_ATMOS_OPACITY)
            continue;

        /* If this band doesn't exist, skip to the next band */
        if (!strcmp (band_fname[i], "undefined"))
            continue;

        /* Save the original band names to be returned to the calling routine */
        count = snprintf (lpgs_bands[band_count],
            sizeof (lpgs_bands[band_count]), "%s", band_fname[i]);
        if (count < 0 || count >= sizeof (lpgs_bands[band_count]))
        {
            sprintf (errmsg, "Overflow of lpgs_bands[x] string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        /* Change the .TIF to .img in the band name for the XML file, since
           the .TIF to .img conversion will happen after the XML is written */
        cptr = strrchr (band_fname[i], '.');
        if (cptr == NULL)
        {
            sprintf (errmsg, "No file extension found in the band filename: "
                "%s\n", band_fname[i]);
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }
        strcpy (cptr, ".img");

        /* Handle the general metadata for each band */
        count = snprintf (bmeta[band_count].product,
            sizeof (bmeta[band_count].product), "%s", product[i]);
        if (count < 0 || count >= sizeof (bmeta[band_count].product))
        {
            sprintf (errmsg, "Overflow of bmeta[x].product string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        count = snprintf (bmeta[band_count].category,
            sizeof (bmeta[band_count].category), "%s", category[i]);
        if (count < 0 || count >= sizeof (bmeta[band_count].category))
        {
            sprintf (errmsg, "Overflow of bmeta[x].category string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        count = snprintf (bmeta[band_count].app_version,
            sizeof (bmeta[band_count].app_version), "%s",
            tmp_bmeta.app_version);
        if (count < 0 || count >= sizeof (bmeta[band_count].app_version))
        {
            sprintf (errmsg, "Overflow of bmeta[x].app_version string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        bmeta[band_count].valid_range[0] = (float) band_min[i];
        bmeta[band_count].valid_range[1] = (float) band_max[i];
        bmeta[band_count].scale_factor = band_gain[i];
        bmeta[band_count].add_offset = band_bias[i];
        bmeta[band_count].data_type = data_type[i];
        bmeta[band_count].fill_value = fill_val[i];

        count = snprintf (bmeta[band_count].data_units,
            sizeof (bmeta[band_count].data_units), "%s", data_units[i]);
        if (count < 0 || count >= sizeof (bmeta[band_count].data_units))
        {
            sprintf (errmsg, "Overflow of bmeta[x].data_units string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        count = snprintf (bmeta[band_count].pixel_units,
            sizeof (bmeta[band_count].pixel_units), "%s", "meters");
        if (count < 0 || count >= sizeof (bmeta[band_count].pixel_units))
        {
            sprintf (errmsg, "Overflow of bmeta[x].pixel_units string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        count = snprintf (bmeta[band_count].production_date,
            sizeof (bmeta[band_count].production_date), "%s",
            gmeta->level1_production_date);
        if (count < 0 || count >= sizeof (bmeta[band_count].production_date))
        {
            sprintf (errmsg, "Overflow of bmeta[x].production_date string");
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        if (!strcmp (gmeta->instrument, "TM"))
        {
            if (!strcmp (gmeta->satellite, "LANDSAT_4"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LT04",
                    band_sname[i]);
            else if (!strcmp (gmeta->satellite, "LANDSAT_5"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LT05",
                    band_sname[i]);
        }
        else if (!strncmp (gmeta->instrument, "ETM", 3))
            sprintf (bmeta[band_count].short_name, "%s%s", "LE07",
                band_sname[i]);
        else if (!strcmp (gmeta->instrument, "OLI_TIRS"))
        {
            if (!strcmp (gmeta->satellite, "LANDSAT_8"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LC08",
                    band_sname[i]);
            else if (!strcmp (gmeta->satellite, "LANDSAT_9"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LC09",
                    band_sname[i]);
        }
        else if (!strcmp (gmeta->instrument, "OLI"))
        {
            if (!strcmp (gmeta->satellite, "LANDSAT_8"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LO08",
                    band_sname[i]);
            else if (!strcmp (gmeta->satellite, "LANDSAT_9"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LO09",
                    band_sname[i]);
        }
        else if (!strcmp (gmeta->instrument, "TIRS"))
        {
            if (!strcmp (gmeta->satellite, "LANDSAT_8"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LT08",
                    band_sname[i]);
            else if (!strcmp (gmeta->satellite, "LANDSAT_9"))
                sprintf (bmeta[band_count].short_name, "%s%s", "LT09",
                    band_sname[i]);
        }
        else
        {
            sprintf (errmsg, "Invalid Landsat-based instrument %s",
                gmeta->instrument);
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        /* Set up the band names */
        strcpy (bmeta[band_count].long_name, band_lname[i]);
        strcpy (bmeta[band_count].name, band_name[i]);
        strcpy (bmeta[band_count].file_name, band_fname[i]);

        if (!strcmp (band_name[i], "qa_pixel"))
        {
            bmeta[band_count].valid_range[0] = 0.0;
            bmeta[band_count].valid_range[1] = 65535.0;
            bmeta[band_count].rad_gain = ESPA_FLOAT_META_FILL;
            bmeta[band_count].rad_bias = ESPA_FLOAT_META_FILL;
        }
        else if (!strcmp (band_name[i], "qa_radsat"))
        {
            bmeta[band_count].valid_range[0] = 0.0;
            bmeta[band_count].valid_range[1] = 65535.0;
            bmeta[band_count].rad_gain = ESPA_FLOAT_META_FILL;
            bmeta[band_count].rad_bias = ESPA_FLOAT_META_FILL;
        }

        /* Set up the image size and resolution */
        if (thermal[i])
        {  /* thermal bands */
            bmeta[band_count].nlines = tmp_bmeta_th.nlines;
            bmeta[band_count].nsamps = tmp_bmeta_th.nsamps;
            bmeta[band_count].pixel_size[0] = tmp_bmeta_th.pixel_size[0];
            bmeta[band_count].pixel_size[1] = tmp_bmeta_th.pixel_size[1];
        }
        else
        {  /* QA, per-pixel angles, and reflective bands */
            bmeta[band_count].nlines = tmp_bmeta.nlines;
            bmeta[band_count].nsamps = tmp_bmeta.nsamps;
            bmeta[band_count].pixel_size[0] = tmp_bmeta.pixel_size[0];
            bmeta[band_count].pixel_size[1] = tmp_bmeta.pixel_size[1];
        }

        /* If this is one of the QA bands then write the bitmap definition */
        if (!strcmp (band_name[i], "qa_pixel"))
        {
            if (allocate_bitmap_metadata (&bmeta[band_count], 16) != SUCCESS)
            {
                sprintf (errmsg, "Allocating 16 bits for the bitmap");
                error_handler (true, FUNC_NAME, errmsg);
                return (ERROR);
            }

            strcpy (bmeta[band_count].bitmap_description[0],
                "Data Fill Flag (0 = image data, 1 = fill data)");
            strcpy (bmeta[band_count].bitmap_description[1],
                "Dilated Cloud (0 = cloud not dilated or no cloud, "
                "1 = cloud dilation)");

            if (!strncmp (gmeta->instrument, "OLI", 3))
            {
                strcpy (bmeta[band_count].bitmap_description[2],
                    "Cirrus (0 = no confidence level set or low confidence, "
                    "1 = high confidence cirrus)");
            }
            else
                strcpy (bmeta[band_count].bitmap_description[2], "Not used");

            strcpy (bmeta[band_count].bitmap_description[3],
                "Cloud (0 = cloud confidence is not high, "
                "1 = high confidence cloud)");
            strcpy (bmeta[band_count].bitmap_description[4],
                "Cloud Shadow (0 = cloud shadow confidence is not high, "
                "1 = high confidence cloud shadow)");
            strcpy (bmeta[band_count].bitmap_description[5],
                "Snow (0 = snow/ice confidence is not high, "
                "1 = high confidence snow cover)");
            strcpy (bmeta[band_count].bitmap_description[6],
                "Clear (0 = cloud or dilated cloud bits are set, "
                "1 = cloud and dilated cloud bits are not set");
            strcpy (bmeta[band_count].bitmap_description[7],
                "Water (0 = land or cloud, 1 = for water");
            strcpy (bmeta[band_count].bitmap_description[8],
                "Cloud Confidence");
            strcpy (bmeta[band_count].bitmap_description[9],
                "Cloud Confidence");
            strcpy (bmeta[band_count].bitmap_description[10],
                "Cloud Shadow Confidence");
            strcpy (bmeta[band_count].bitmap_description[11],
                "Cloud Shadow Confidence");
            strcpy (bmeta[band_count].bitmap_description[12],
                "Snow/Ice Confidence");
            strcpy (bmeta[band_count].bitmap_description[13],
                "Snow/Ice Confidence");

            if (!strncmp (gmeta->instrument, "OLI", 3))
            {
                strcpy (bmeta[band_count].bitmap_description[14],
                    "Cirrus Confidence");
                strcpy (bmeta[band_count].bitmap_description[15],
                    "Cirrus Confidence");
            }
            else
            {
                strcpy (bmeta[band_count].bitmap_description[14], "Not used");
                strcpy (bmeta[band_count].bitmap_description[15], "Not used");
            }
        }
        else if (!strcmp (band_name[i], "qa_radsat"))
        {
            if (allocate_bitmap_metadata (&bmeta[band_count], 16) != SUCCESS)
            {
                sprintf (errmsg, "Allocating 16 bits for the bitmap");
                error_handler (true, FUNC_NAME, errmsg);
                return (ERROR);
            }

            strcpy (bmeta[band_count].bitmap_description[0],
                "Band 1 saturation (0 = no saturation, 1 = saturated data)");
            strcpy (bmeta[band_count].bitmap_description[1],
                "Band 2 saturation (0 = no saturation, 1 = saturated data)");
            strcpy (bmeta[band_count].bitmap_description[2],
                "Band 3 saturation (0 = no saturation, 1 = saturated data)");
            strcpy (bmeta[band_count].bitmap_description[3],
                "Band 4 saturation (0 = no saturation, 1 = saturated data)");
            strcpy (bmeta[band_count].bitmap_description[4],
                "Band 5 saturation (0 = no saturation, 1 = saturated data)");

            if (!strncmp (gmeta->instrument, "OLI", 3))
            {
                strcpy (bmeta[band_count].bitmap_description[5],
                    "Band 6 saturation (0 = no saturation, "
                    "1 = saturated data)");
                strcpy (bmeta[band_count].bitmap_description[8],
                    "Band 9 saturation (0 = no saturation, "
                    "1 = saturated data)");
                strcpy (bmeta[band_count].bitmap_description[9], "Not used");
                strcpy (bmeta[band_count].bitmap_description[11],
                    "Terrain occlusion (0 = no terrain occlusion, " 
                    "1 = terrain occlusion");
            }
            else if (!strncmp (gmeta->instrument, "ETM", 3))
            {
                strcpy (bmeta[band_count].bitmap_description[5],
                    "Band 6L saturation (0 = no saturation, "
                    "1 = saturated data)");
                strcpy (bmeta[band_count].bitmap_description[8],
                    "Band 6H saturation (0 = no saturation, "
                    "1 = saturated data)");
                strcpy (bmeta[band_count].bitmap_description[9],
                    "Dropped Pixel");
                strcpy (bmeta[band_count].bitmap_description[11], "Not used");
            }
            else if (!strcmp (gmeta->instrument, "TM"))
            {
                strcpy (bmeta[band_count].bitmap_description[5],
                    "Band 6 saturation (0 = no saturation, "
                    "1 = saturated data)");
                strcpy (bmeta[band_count].bitmap_description[8], "Not used");
                strcpy (bmeta[band_count].bitmap_description[9],
                    "Dropped Pixel");
                strcpy (bmeta[band_count].bitmap_description[11], "Not used");
            }

            strcpy (bmeta[band_count].bitmap_description[6],
                "Band 7 saturation (0 = no saturation, 1 = saturated data)");
            strcpy (bmeta[band_count].bitmap_description[7], "Not used");
            strcpy (bmeta[band_count].bitmap_description[10], "Not used");
            strcpy (bmeta[band_count].bitmap_description[12], "Not used");
            strcpy (bmeta[band_count].bitmap_description[13], "Not used");
            strcpy (bmeta[band_count].bitmap_description[14], "Not used");
            strcpy (bmeta[band_count].bitmap_description[15], "Not used");
        }
        else if (!strcmp (band_name[i], "sr_cloud_qa"))
        {
            if (allocate_bitmap_metadata (&bmeta[band_count], 6) != SUCCESS)
            {
                sprintf (errmsg, "Allocating 6 bits for the bitmap");
                error_handler (true, FUNC_NAME, errmsg);
                return (ERROR);
            }

            strcpy (bmeta[band_count].bitmap_description[0],
                "dark dense vegetation");
            strcpy (bmeta[band_count].bitmap_description[1], "cloud");
            strcpy (bmeta[band_count].bitmap_description[2], "cloud shadow");
            strcpy (bmeta[band_count].bitmap_description[3],
                "adjacent to cloud");
            strcpy (bmeta[band_count].bitmap_description[4], "snow");
            strcpy (bmeta[band_count].bitmap_description[5], "water");
        }
        else if (!strcmp (band_name[i], "sr_aerosol"))
        {
            if (allocate_bitmap_metadata (&bmeta[band_count], 8) != SUCCESS)
            {
                sprintf (errmsg, "Allocating aerosol bitmap.");
                error_handler (true, FUNC_NAME, errmsg);
                return (ERROR);
            }

            strcpy (bmeta[band_count].bitmap_description[0], "fill");
            strcpy (bmeta[band_count].bitmap_description[1],
                "valid aerosol retrieval (center pixel of NxN window)");
            strcpy (bmeta[band_count].bitmap_description[2], "water pixel (or "
                "water pixel was used in the fill-the-window "
                "interpolation)");
            strcpy (bmeta[band_count].bitmap_description[3], "N/A");
            strcpy (bmeta[band_count].bitmap_description[4], "N/A");
            strcpy (bmeta[band_count].bitmap_description[5], "non-center "
                "window pixel for which aerosol was interpolated from "
                "surrounding NxN center pixels");
            strcpy (bmeta[band_count].bitmap_description[6], "aerosol level");
            strcpy (bmeta[band_count].bitmap_description[7], "aerosol level");
        }

        /* Add the Reanalysis data source to the metadata for the ST bands */
        if (i == ST_B6 || i == ST_B10 || i == ST_TRAD || i == ST_URAD ||
            i == ST_DRAD || i == ST_ATRAN || i == ST_EMIS || i == ST_EMSD ||
            i == ST_CDIST || i == ST_QA)
        {
            count = snprintf (bmeta[band_count].source,
                sizeof (bmeta[band_count].source), "%s", tmp_bmeta.source);
            if (count < 0 || count >= sizeof (bmeta[band_count].source))
            {
                sprintf (errmsg, "Overflow of bmeta[x].source string");
                error_handler (true, FUNC_NAME, errmsg);
                return (ERROR);
            }
        }

        /* Increment the valid band counter */
        band_count++;
    }  /* for i */

    /* Store the final band count */
    metadata->nbands = band_count;
    *nlpgs_bands = band_count;

    /* Close the metadata file */
    fclose (mtl_fptr);

    /* Get geolocation information from the XML file to prepare for computing
       the bounding coordinates */
    if (!get_geoloc_info (metadata, &geoloc_def))
    {
        sprintf (errmsg, "Copying the geolocation information from the XML "
            "metadata structure.");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    /* Setup the mapping structure */
    geoloc_map = setup_mapping (&geoloc_def);
    if (geoloc_map == NULL)
    {
        sprintf (errmsg, "Setting up the geolocation mapping structure.");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }
    
    /* Compute the geographic bounds using the reflectance band coordinates */
    /* For ascending scenes and scenes in the polar regions, the scenes are
       flipped upside down.  The bounding coords will be correct in North
       represents the northernmost latitude and South represents the
       southernmost latitude.  However, the UL corner in this case would be
       more south than the LR corner.  Comparing the UL and LR corners will
       allow the user to determine if the scene is flipped. */
    if (!compute_bounds (geoloc_map, tmp_bmeta.nlines, tmp_bmeta.nsamps,
        &bounds))
    {
        sprintf (errmsg, "Setting up the geolocation mapping structure.");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }
    gmeta->bounding_coords[ESPA_WEST] = bounds.min_lon;
    gmeta->bounding_coords[ESPA_EAST] = bounds.max_lon;
    gmeta->bounding_coords[ESPA_NORTH] = bounds.max_lat;
    gmeta->bounding_coords[ESPA_SOUTH] = bounds.min_lat;

    /* Free the geolocation structure */
    free (geoloc_map);

    /* Successful read */
    return (SUCCESS);
}


/******************************************************************************
MODULE:  convert_gtif_to_img

PURPOSE: Convert the LPGS Cloud Optimized GeoTIFF band to ESPA raw binary
(.img) file and writes the associated ENVI header for each band.

RETURN VALUE:
Type = int
Value           Description
-----           -----------
ERROR           Error converting the GeoTIFF file
SUCCESS         Successfully converterd GeoTIFF to raw binary

NOTES:
  1. The GDAL tools will be used for converting the Cloud Optimized GeoTIFF
     to raw binary (ENVI format).
  2. An associated .tfw (ESRI world file) will be generated for each GeoTIFF
     file.
******************************************************************************/
int convert_gtif_to_img
(
    char *gtif_file,           /* I: name of input GeoTIFF file for this band */
    Espa_band_meta_t *bmeta,   /* I: pointer to band metadata for this band */
    Espa_global_meta_t *gmeta  /* I: pointer to global metadata */
)
{
    char FUNC_NAME[] = "convert_gtif_to_img";  /* function name */
    char errmsg[STR_SIZE];    /* error message */
    char gdal_cmd[STR_SIZE];  /* command string for GDAL call */
    char tmpfile[STR_SIZE];   /* filename of file.img.aux.xml */
    int count;                /* number of chars copied in snprintf */

    /* Check if the fill value is defined */
    if ((int) bmeta->fill_value == (int) ESPA_INT_META_FILL)
    {
        /* Fill value is not defined so don't write the nodata tag */
        count = snprintf (gdal_cmd, sizeof (gdal_cmd),
            "gdal_translate -of Envi -q %s %s", gtif_file, bmeta->file_name);
    }
    else
    {
        /* Fill value is defined so use the nodata tag */
        count = snprintf (gdal_cmd, sizeof (gdal_cmd),
         "gdal_translate -of Envi -a_nodata %ld -q %s %s",
            bmeta->fill_value, gtif_file, bmeta->file_name);
    }
    if (count < 0 || count >= sizeof (gdal_cmd))
    {
        sprintf (errmsg, "Overflow of gdal_cmd string");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }
 
    if (system (gdal_cmd) == -1)
    {
        sprintf (errmsg, "Running gdal_translate: %s", gdal_cmd);
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }
 
    /* Remove the {gtif_name}.tif.aux.xml file since it's not needed and
       clutters the results.  Don't worry about testing the unlink
       results.  If it doesn't unlink it's not fatal. */
    count = snprintf (tmpfile, sizeof (tmpfile), "%s.aux.xml",
        bmeta->file_name);
    if (count < 0 || count >= sizeof (tmpfile))
    {
        sprintf (errmsg, "Overflow of tmpfile string");
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }
    unlink (tmpfile);

    /* Successful conversion */
    return (SUCCESS);
}


/******************************************************************************
MODULE:  convert_l2lpgs_to_espa

PURPOSE: Converts the input Level-2 LPGS GeoTIFF files (and associated MTL
file) to the ESPA internal raw binary file format (and associated XML file).

RETURN VALUE:
Type = int
Value           Description
-----           -----------
ERROR           Error converting the GeoTIFF file
SUCCESS         Successfully converted GeoTIFF to raw binary

NOTES:
  1. The LPGS GeoTIFF band files will be deciphered from the LPGS MTL file.
  2. The ESPA raw binary band files will be generated from the ESPA XML
     filename.
******************************************************************************/
int convert_l2lpgs_to_espa
(
    char *lpgs_mtl_file,   /* I: input LPGS MTL metadata filename */
    char *espa_xml_file,   /* I: output ESPA XML metadata filename */
    bool del_src           /* I: should the source .tif files be removed after
                                 conversion? */
)
{
    char FUNC_NAME[] = "convert_lpgs_to_espa";  /* function name */
    char errmsg[STR_SIZE];   /* error message */
    Espa_internal_meta_t xml_metadata;  /* XML metadata structure to be
                                populated by reading the MTL metadata file */
    int i;                   /* looping variable */
    int nlpgs_bands;         /* number of bands in the LPGS product */
    char lpgs_bands[MAX_L2LPGS_BANDS][STR_SIZE];  /* array containing the file
                                names of the LPGS bands */

    /* Initialize the metadata structure */
    init_metadata_struct (&xml_metadata);

    /* Read the Level-2 LPGS MTL file and populate our internal ESPA metadata
       structure */
    if (read_l2lpgs_mtl (lpgs_mtl_file, &xml_metadata, &nlpgs_bands,
        lpgs_bands) != SUCCESS)
    {
        sprintf (errmsg, "Reading the LPGS MTL file: %s", lpgs_mtl_file);
        error_handler (true, FUNC_NAME, errmsg);
        return (ERROR);
    }

    /* Write the metadata from our internal metadata structure to the output
       XML filename */
    if (write_metadata (&xml_metadata, espa_xml_file) != SUCCESS)
    {  /* Error messages already written */
        return (ERROR);
    }

    /* Validate the input metadata file */
    if (validate_xml_file (espa_xml_file) != SUCCESS)
    {  /* Error messages already written */
        return (ERROR);
    }

    /* Convert each of the LPGS GeoTIFF files to raw binary */
    for (i = 0; i < nlpgs_bands; i++)
    {
        printf ("  Band %d: %s to %s\n", i, lpgs_bands[i],
            xml_metadata.band[i].file_name);
        if (convert_gtif_to_img (lpgs_bands[i], &xml_metadata.band[i],
            &xml_metadata.global) != SUCCESS)
        {
            sprintf (errmsg, "Converting band %d: %s", i, lpgs_bands[i]);
            error_handler (true, FUNC_NAME, errmsg);
            return (ERROR);
        }

        /* Remove the source file if specified */
        if (del_src)
        {
            printf ("  Removing %s\n", lpgs_bands[i]);
            if (unlink (lpgs_bands[i]) != 0)
            {
                sprintf (errmsg, "Deleting source file: %s", lpgs_bands[i]);
                error_handler (true, FUNC_NAME, errmsg);
                return (ERROR);
            }
        }
    }

    /* Free the metadata structure */
    free_metadata (&xml_metadata);

    /* Successful conversion */
    return (SUCCESS);
}

