Changeset 14459

Show
Ignore:
Timestamp:
05/14/08 09:38:32 (2 months ago)
Author:
dron
Message:

Added support for NOAA-18(N) and METOP-2 datasets; tiny code refactoring.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/frmts/l1b/l1bdataset.cpp

    r12227 r14459  
    5353    NOAA15,     // NOAA-15(K) 
    5454    NOAA16,     // NOAA-16(L) 
    55     NOAA17      // NOAA-17(M) 
     55    NOAA17,     // NOAA-17(M) 
     56    NOAA18,     // NOAA-18(M) 
     57    METOP2      // METOP-2(A) 
    5658}; 
    5759 
    58 enum {          // Types of dataset
     60enum {          // Product type
    5961    HRPT, 
    6062    LAC, 
    61     GAC 
     63    GAC, 
     64    FRAC 
    6265}; 
    6366 
     
    97100static const char *apszBandDesc[] = 
    98101{ 
    99     // NOAA-7 -- NOAA-17 channels 
     102    // NOAA-7 -- METOP-2 channels 
    100103    "AVHRR Channel 1:  0.58  micrometers -- 0.68 micrometers", 
    101104    "AVHRR Channel 2:  0.725 micrometers -- 1.10 micrometers", 
     
    105108    // NOAA-13 
    106109    "AVHRR Channel 5:  11.4  micrometers -- 12.4 micrometers", 
    107     // NOAA-15 -- NOAA-17 
     110    // NOAA-15 -- METOP-2 
    108111    "AVHRR Channel 3A: 1.58  micrometers -- 1.64 micrometers", 
    109112    "AVHRR Channel 3B: 3.55  micrometers -- 3.93 micrometers" 
     
    161164    friend class L1BRasterBand; 
    162165 
    163     GByte        pabyTBMHeader[TBM_HEADER_SIZE]; 
    164166    char        pszRevolution[6]; // Five-digit number identifying spacecraft revolution 
    165     int         iSource;        // Source of data (receiving station name) 
    166     int         iProcCenter;    // Data processing center 
     167    int         eSource;        // Source of data (receiving station name) 
     168    int         eProcCenter;    // Data processing center 
    167169    TimeCode    sStartTime; 
    168170    TimeCode    sStopTime; 
     
    173175    int         iGCPCodeOffset; 
    174176    int         nGCPsPerLine; 
    175     int         iLocationIndicator, iGCPStart, iGCPStep; 
     177    int         eLocationIndicator, iGCPStart, iGCPStep; 
    176178 
    177179    int         nBufferSize; 
    178     int         iSpacecraftID; 
    179     int         iDataType;      // LAC, GAC, HRPT 
     180    int         eSpacecraftID; 
     181    int         eProductType;   // LAC, GAC, HRPT, FRAC 
    180182    int         iDataFormat;    // 10-bit packed or 16-bit unpacked 
    181183    int         nRecordDataStart; 
     
    201203                ~L1BDataset(); 
    202204     
    203     virtual int   GetGCPCount(); 
     205    virtual int GetGCPCount(); 
    204206    virtual const char *GetGCPProjection(); 
    205207    virtual const GDAL_GCP *GetGCPs(); 
     208 
     209    static int  Identify( GDALOpenInfo * ); 
    206210    static GDALDataset *Open( GDALOpenInfo * ); 
    207211 
     
    257261/*      Seek to data.                                                   */ 
    258262/* -------------------------------------------------------------------- */ 
    259     iDataOffset = (poGDS->iLocationIndicator == DESCEND)? 
     263    iDataOffset = (poGDS->eLocationIndicator == DESCEND)? 
    260264            poGDS->nDataStartOffset + nBlockYOff * poGDS->nRecordSize: 
    261265            poGDS->nDataStartOffset + 
    262266            (poGDS->GetRasterYSize() - nBlockYOff - 1) * poGDS->nRecordSize; 
    263     VSIFSeek(poGDS->fp, iDataOffset, SEEK_SET); 
     267    VSIFSeekL(poGDS->fp, iDataOffset, SEEK_SET); 
    264268 
    265269/* -------------------------------------------------------------------- */ 
     
    272276                // Read packed scanline 
    273277                GUInt32 *iRawScan = (GUInt32 *)CPLMalloc(poGDS->nRecordSize); 
    274                 VSIFRead( iRawScan, 1, poGDS->nRecordSize, poGDS->fp ); 
     278                VSIFReadL( iRawScan, 1, poGDS->nRecordSize, poGDS->fp ); 
    275279 
    276280                iScan = (GUInt16 *)CPLMalloc(poGDS->nBufferSize); 
     
    296300                // Read unpacked scanline 
    297301                GUInt16 *iRawScan = (GUInt16 *)CPLMalloc(poGDS->nRecordSize); 
    298                 VSIFRead( iRawScan, 1, poGDS->nRecordSize, poGDS->fp ); 
     302                VSIFReadL( iRawScan, 1, poGDS->nRecordSize, poGDS->fp ); 
    299303 
    300304                iScan = (GUInt16 *)CPLMalloc(poGDS->GetRasterXSize() 
     
    315319                // Read 8-bit unpacked scanline 
    316320                GByte   *byRawScan = (GByte *)CPLMalloc(poGDS->nRecordSize); 
    317                 VSIFRead( byRawScan, 1, poGDS->nRecordSize, poGDS->fp ); 
     321                VSIFReadL( byRawScan, 1, poGDS->nRecordSize, poGDS->fp ); 
    318322                 
    319323                iScan = (GUInt16 *)CPLMalloc(poGDS->GetRasterXSize() 
     
    330334     
    331335    int nBlockSize = nBlockXSize * nBlockYSize; 
    332     if (poGDS->iLocationIndicator == DESCEND) 
     336    if (poGDS->eLocationIndicator == DESCEND) 
    333337        for( i = 0, j = 0; i < nBlockSize; i++ ) 
    334338        { 
     
    359363    pszGCPProjection = CPLStrdup( "GEOGCS[\"WGS 72\",DATUM[\"WGS_1972\",SPHEROID[\"WGS 72\",6378135,298.26,AUTHORITY[\"EPSG\",7043]],TOWGS84[0,0,4.5,0,0,0.554,0.2263],AUTHORITY[\"EPSG\",6322]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",8901]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",9108]],AXIS[\"Lat\",\"NORTH\"],AXIS[\"Long\",\"EAST\"],AUTHORITY[\"EPSG\",4322]]" ); 
    360364    nBands = 0; 
    361     iLocationIndicator = DESCEND; // XXX: should be initialised 
     365    eLocationIndicator = DESCEND; // XXX: should be initialised 
    362366    iChannels = 0; 
    363367    iInstrumentStatus = 0; 
     
    381385        CPLFree( pszGCPProjection ); 
    382386    if( fp != NULL ) 
    383         VSIFClose( fp ); 
     387        VSIFCloseL( fp ); 
    384388} 
    385389 
     
    438442 
    439443/************************************************************************/ 
    440 /*      Fetch timecode from the record header (NOAA15-NOAA17 version)   */ 
     444/*      Fetch timecode from the record header (NOAA15-METOP2 version)   */ 
    441445/************************************************************************/ 
    442446 
     
    483487 
    484488    // GCPs are located at center of pixel, so we will add a half pixel offset 
    485     dfPixel = (iLocationIndicator == DESCEND) ? 
     489    dfPixel = (eLocationIndicator == DESCEND) ? 
    486490        iGCPStart + 0.5 : (GetRasterXSize() - (iGCPStart + 0.5)); 
    487491    j = iGCPOffset / (int)sizeof(piRecordHeader[0]); 
     
    507511        pasGCPList[nGCPCount].dfGCPZ = 0.0; 
    508512        pasGCPList[nGCPCount].dfGCPPixel = dfPixel; 
    509         dfPixel += (iLocationIndicator == DESCEND) ? iGCPStep : -iGCPStep; 
     513        dfPixel += (eLocationIndicator == DESCEND) ? iGCPStep : -iGCPStep; 
    510514        pasGCPList[nGCPCount].dfGCPLine = 
    511             (double)((iLocationIndicator == DESCEND) ? 
     515            (double)((eLocationIndicator == DESCEND) ? 
    512516            iLine : GetRasterYSize() - iLine - 1) + 0.5; 
    513517        nGCPCount++; 
     
    516520 
    517521/************************************************************************/ 
    518 /* Fetch the GCPs from the individual scanlines (NOAA15-NOAA17 version) */ 
     522/* Fetch the GCPs from the individual scanlines (NOAA15-METOP2 version) */ 
    519523/************************************************************************/ 
    520524 
     
    526530 
    527531    // GCPs are located at center of pixel, so we will add a half pixel offset 
    528     dfPixel = (iLocationIndicator == DESCEND) ? 
     532    dfPixel = (eLocationIndicator == DESCEND) ? 
    529533        iGCPStart + 0.5 : (GetRasterXSize() - (iGCPStart + 0.5)); 
    530534    j = iGCPOffset / (int)sizeof(piRecordHeader[0]); 
     
    551555        pasGCPList[nGCPCount].dfGCPZ = 0.0; 
    552556        pasGCPList[nGCPCount].dfGCPPixel = dfPixel; 
    553         dfPixel += (iLocationIndicator == DESCEND) ? iGCPStep : -iGCPStep; 
     557        dfPixel += (eLocationIndicator == DESCEND) ? iGCPStep : -iGCPStep; 
    554558        pasGCPList[nGCPCount].dfGCPLine = 
    555             (double)((iLocationIndicator == DESCEND) ? 
     559            (double)((eLocationIndicator == DESCEND) ? 
    556560            iLine : GetRasterYSize() - iLine - 1) + 0.5; 
    557561        nGCPCount++; 
     
    569573 
    570574    piRecordHeader = CPLMalloc(nRecordDataStart); 
    571     VSIFSeek(fp, nDataStartOffset, SEEK_SET); 
    572     VSIFRead(piRecordHeader, 1, nRecordDataStart, fp); 
    573  
    574     if (iSpacecraftID <= NOAA14) 
     575    VSIFSeekL(fp, nDataStartOffset, SEEK_SET); 
     576    VSIFReadL(piRecordHeader, 1, nRecordDataStart, fp); 
     577 
     578    if (eSpacecraftID <= NOAA14) 
    575579        FetchNOAA9TimeCode(&sStartTime, (GByte *) piRecordHeader, &iLocInd); 
    576580    else 
    577581        FetchNOAA15TimeCode(&sStartTime, (GUInt16 *) piRecordHeader, &iLocInd); 
    578     iLocationIndicator = iLocInd; 
    579     VSIFSeek( fp, nDataStartOffset + (GetRasterYSize() - 1) * nRecordSize, 
     582    eLocationIndicator = iLocInd; 
     583    VSIFSeekL( fp, nDataStartOffset + (GetRasterYSize() - 1) * nRecordSize, 
    580584              SEEK_SET); 
    581     VSIFRead( piRecordHeader, 1, nRecordDataStart, fp ); 
    582     if (iSpacecraftID <= NOAA14) 
     585    VSIFReadL( piRecordHeader, 1, nRecordDataStart, fp ); 
     586    if (eSpacecraftID <= NOAA14) 
    583587        FetchNOAA9TimeCode(&sStopTime, (GByte *) piRecordHeader, &iLocInd); 
    584588    else 
     
    616620            iLine = nLineSkip * iStep; 
    617621 
    618         VSIFSeek( fp, nDataStartOffset + iLine * nRecordSize, SEEK_SET ); 
    619         VSIFRead( piRecordHeader, 1, nRecordDataStart, fp ); 
    620  
    621         if ( iSpacecraftID <= NOAA14 ) 
     622        VSIFSeekL( fp, nDataStartOffset + iLine * nRecordSize, SEEK_SET ); 
     623        VSIFReadL( piRecordHeader, 1, nRecordDataStart, fp ); 
     624 
     625        if ( eSpacecraftID <= NOAA14 ) 
    622626            FetchNOAA9GCPs( pasGCPList, (GInt16 *)piRecordHeader, iLine ); 
    623627        else 
     
    667671    GUInt16 *piHeader; 
    668672    piHeader = (GUInt16 *)CPLMalloc(nDataStartOffset); 
    669     VSIFSeek( fp, 0, SEEK_SET ); 
    670     VSIFRead( piHeader, 1, nDataStartOffset, fp ); 
    671     if (iSpacecraftID > NOAA14) 
     673    VSIFSeekL( fp, 0, SEEK_SET ); 
     674    VSIFReadL( piHeader, 1, nDataStartOffset, fp ); 
     675    if (eSpacecraftID > NOAA14) 
    672676    { 
    673677        iInstrumentStatus = (piHeader + 512)[58]; 
     
    680684 
    681685/************************************************************************/ 
    682 /*                                Open()                                */ 
    683 /************************************************************************/ 
    684  
    685 GDALDataset *L1BDataset::Open( GDALOpenInfo * poOpenInfo ) 
    686  
    687 
    688     int i = 0; 
    689  
     686/*                              Identify()                              */ 
     687/************************************************************************/ 
     688 
     689int L1BDataset::Identify( GDALOpenInfo *poOpenInfo ) 
     690 
     691
    690692    if( poOpenInfo->fp == NULL ) 
    691         return NULL
     693        return FALSE
    692694 
    693695    // XXX: Signature is not very good 
     
    699701        !EQUALN((const char *) poOpenInfo->pabyHeader + 60, ".", 1) || 
    700702        !EQUALN((const char *) poOpenInfo->pabyHeader + 69, ".", 1) ) 
     703        return FALSE; 
     704 
     705    return TRUE; 
     706} 
     707 
     708/************************************************************************/ 
     709/*                                Open()                                */ 
     710/************************************************************************/ 
     711 
     712GDALDataset *L1BDataset::Open( GDALOpenInfo * poOpenInfo ) 
     713 
     714{ 
     715    if ( !Identify(poOpenInfo) ) 
    701716        return NULL; 
    702717 
     
    710725    poDS = new L1BDataset(); 
    711726 
    712     poDS->fp = poOpenInfo->fp; 
    713     poOpenInfo->fp = NULL; 
     727    poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); 
     728    if ( !poDS->fp ) 
     729    { 
     730        CPLDebug( "L1B", "Can't open file \"%s\".", poOpenInfo->pszFilename ); 
     731        goto bad; 
     732    } 
    714733     
    715734/* -------------------------------------------------------------------- */ 
    716735/*      Read the header.                                                */ 
    717736/* -------------------------------------------------------------------- */ 
    718     VSIFSeek( poDS->fp, 0, SEEK_SET ); 
    719     VSIFRead( poDS->pabyTBMHeader, 1, TBM_HEADER_SIZE, poDS->fp ); 
     737    GByte       pabyTBMHeader[TBM_HEADER_SIZE]; 
     738    int         i; 
     739 
     740    if ( VSIFSeekL( poDS->fp, 0, SEEK_SET ) < 0 
     741         || VSIFReadL( pabyTBMHeader, 1, TBM_HEADER_SIZE, poDS->fp ) < TBM_HEADER_SIZE ) 
     742    { 
     743        CPLDebug( "L1B", "Can't read TBM header." ); 
     744        goto bad; 
     745    } 
    720746 
    721747    // Determine processing center where the dataset was created 
    722     if ( EQUALN((const char *) poDS->pabyTBMHeader + 30, "CMS", 3) ) 
    723          poDS->iProcCenter = CMS; 
    724     else if ( EQUALN((const char *) poDS->pabyTBMHeader + 30, "DSS", 3) ) 
    725          poDS->iProcCenter = DSS; 
    726     else if ( EQUALN((const char *) poDS->pabyTBMHeader + 30, "NSS", 3) ) 
    727          poDS->iProcCenter = NSS; 
    728     else if ( EQUALN((const char *) poDS->pabyTBMHeader + 30, "UKM", 3) ) 
    729          poDS->iProcCenter = UKM; 
     748    if ( EQUALN((const char *) pabyTBMHeader + 30, "CMS", 3) ) 
     749         poDS->eProcCenter = CMS; 
     750    else if ( EQUALN((const char *) pabyTBMHeader + 30, "DSS", 3) ) 
     751         poDS->eProcCenter = DSS; 
     752    else if ( EQUALN((const char *) pabyTBMHeader + 30, "NSS", 3) ) 
     753         poDS->eProcCenter = NSS; 
     754    else if ( EQUALN((const char *) pabyTBMHeader + 30, "UKM", 3) ) 
     755         poDS->eProcCenter = UKM; 
    730756    else 
    731          poDS->iProcCenter = UNKNOWN_CENTER; 
     757         poDS->eProcCenter = UNKNOWN_CENTER; 
    732758     
    733759    // Determine spacecraft type 
    734     if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NA", 2) ) 
    735          poDS->iSpacecraftID = NOAA6; 
    736     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NB", 2) ) 
    737          poDS->iSpacecraftID = NOAAB; 
    738     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NC", 2) ) 
    739          poDS->iSpacecraftID = NOAA7; 
    740     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NE", 2) ) 
    741          poDS->iSpacecraftID = NOAA8; 
    742     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NF", 2) ) 
    743          poDS->iSpacecraftID = NOAA9; 
    744     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NG", 2) ) 
    745          poDS->iSpacecraftID = NOAA10; 
    746     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NH", 2) ) 
    747          poDS->iSpacecraftID = NOAA11; 
    748     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "ND", 2) ) 
    749          poDS->iSpacecraftID = NOAA12; 
    750     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NI", 2) ) 
    751          poDS->iSpacecraftID = NOAA13; 
    752     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NJ", 2) ) 
    753          poDS->iSpacecraftID = NOAA14; 
    754     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NK", 2) ) 
    755          poDS->iSpacecraftID = NOAA15; 
    756     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NL", 2) ) 
    757          poDS->iSpacecraftID = NOAA16; 
    758     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 39, "NM", 2) ) 
    759          poDS->iSpacecraftID = NOAA17; 
     760    if ( EQUALN((const char *)pabyTBMHeader + 39, "NA", 2) ) 
     761         poDS->eSpacecraftID = NOAA6; 
     762    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NB", 2) ) 
     763         poDS->eSpacecraftID = NOAAB; 
     764    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NC", 2) ) 
     765         poDS->eSpacecraftID = NOAA7; 
     766    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NE", 2) ) 
     767         poDS->eSpacecraftID = NOAA8; 
     768    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NF", 2) ) 
     769         poDS->eSpacecraftID = NOAA9; 
     770    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NG", 2) ) 
     771         poDS->eSpacecraftID = NOAA10; 
     772    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NH", 2) ) 
     773         poDS->eSpacecraftID = NOAA11; 
     774    else if ( EQUALN((const char *)pabyTBMHeader + 39, "ND", 2) ) 
     775         poDS->eSpacecraftID = NOAA12; 
     776    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NI", 2) ) 
     777         poDS->eSpacecraftID = NOAA13; 
     778    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NJ", 2) ) 
     779         poDS->eSpacecraftID = NOAA14; 
     780    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NK", 2) ) 
     781         poDS->eSpacecraftID = NOAA15; 
     782    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NL", 2) ) 
     783         poDS->eSpacecraftID = NOAA16; 
     784    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NM", 2) ) 
     785         poDS->eSpacecraftID = NOAA17; 
     786    else if ( EQUALN((const char *)pabyTBMHeader + 39, "NN", 2) ) 
     787         poDS->eSpacecraftID = NOAA18; 
     788    else if ( EQUALN((const char *)pabyTBMHeader + 39, "M2", 2) ) 
     789         poDS->eSpacecraftID = METOP2; 
    760790    else 
     791    { 
     792#ifdef DEBUG 
     793        CPLDebug( "L1B", "Unknown spacecraft type \"%.2s\".", 
     794                  pabyTBMHeader + 39 ); 
     795#endif 
    761796         goto bad; 
     797    } 
    762798            
    763     // Determine dataset type 
    764     if ( EQUALN((const char *)poDS->pabyTBMHeader + 34, "HRPT", 4) ) 
    765          poDS->iDataType = HRPT; 
    766     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 34, "LHRR", 4) ) 
    767          poDS->iDataType = LAC; 
    768     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 34, "GHRR", 4) ) 
    769          poDS->iDataType = GAC; 
     799    // Determine product type 
     800    if ( EQUALN((const char *)pabyTBMHeader + 34, "HRPT", 4) ) 
     801         poDS->eProductType = HRPT; 
     802    else if ( EQUALN((const char *)pabyTBMHeader + 34, "LHRR", 4) ) 
     803         poDS->eProductType = LAC; 
     804    else if ( EQUALN((const char *)pabyTBMHeader + 34, "GHRR", 4) ) 
     805         poDS->eProductType = GAC; 
     806    else if ( EQUALN((const char *)pabyTBMHeader + 34, "FRAC", 4) ) 
     807         poDS->eProductType = FRAC; 
    770808    else 
     809    { 
     810#ifdef DEBUG 
     811        CPLDebug( "L1B", "Unknown product type \"%.4s\".", 
     812                  pabyTBMHeader + 34 ); 
     813#endif 
    771814         goto bad; 
     815    } 
    772816 
    773817    // Get revolution number as string, we don't need this value for processing 
    774     memcpy(poDS->pszRevolution, poDS->pabyTBMHeader + 62, 5); 
    775     poDS->pszRevolution[5] = 0
     818    memcpy(poDS->pszRevolution, pabyTBMHeader + 62, 5); 
     819    poDS->pszRevolution[5] = '\0'
    776820 
    777821    // Get receiving station name 
    778     if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "DU", 2) ) 
    779          poDS->iSource = DU; 
    780     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "GC", 2) ) 
    781          poDS->iSource = GC; 
    782     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "HO", 2) ) 
    783          poDS->iSource = HO; 
    784     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "MO", 2) ) 
    785          poDS->iSource = MO; 
    786     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "WE", 2) ) 
    787          poDS->iSource = WE; 
    788     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "SO", 2) ) 
    789          poDS->iSource = SO; 
    790     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 70, "WI", 2) ) 
    791          poDS->iSource = WI; 
     822    if ( EQUALN((const char *)pabyTBMHeader + 70, "DU", 2) ) 
     823         poDS->eSource = DU; 
     824    else if ( EQUALN((const char *)pabyTBMHeader + 70, "GC", 2) ) 
     825         poDS->eSource = GC; 
     826    else if ( EQUALN((const char *)pabyTBMHeader + 70, "HO", 2) ) 
     827         poDS->eSource = HO; 
     828    else if ( EQUALN((const char *)pabyTBMHeader + 70, "MO", 2) ) 
     829         poDS->eSource = MO; 
     830    else if ( EQUALN((const char *)pabyTBMHeader + 70, "WE", 2) ) 
     831         poDS->eSource = WE; 
     832    else if ( EQUALN((const char *)pabyTBMHeader + 70, "SO", 2) ) 
     833         poDS->eSource = SO; 
     834    else if ( EQUALN((const char *)pabyTBMHeader + 70, "WI", 2) ) 
     835         poDS->eSource = WI; 
    792836    else 
    793          poDS->iSource = UNKNOWN_STATION; 
    794  
    795     // Determine number of bands and data format 
    796     // (10-bit packed or 16-bit unpacked) 
     837         poDS->eSource = UNKNOWN_STATION; 
     838 
     839    // Determine number of bands 
    797840    for ( i = 97; i < 117; i++ ) 
    798         if (poDS->pabyTBMHeader[i] == 1 || poDS->pabyTBMHeader[i] == 'Y') 
     841    { 
     842        if (pabyTBMHeader[i] == 1 || pabyTBMHeader[i] == 'Y') 
    799843        { 
    800844            poDS->nBands++; 
    801845            poDS->iChannels |= (1 << (i - 97)); 
    802846        } 
     847    } 
    803848    if (poDS->nBands == 0 || poDS->nBands > 5) 
    804849    { 
     
    806851        poDS->iChannels = 0x1F; 
    807852    } 
    808     if ( EQUALN((const char *)poDS->pabyTBMHeader + 117, "10", 2) || 
    809          EQUALN((const char *)poDS->pabyTBMHeader + 117, "  ", 2) ) 
     853 
     854    // Determine data format (10-bit packed or 8/16-bit unpacked) 
     855    if ( EQUALN((const char *)pabyTBMHeader + 117, "10", 2) || 
     856         EQUALN((const char *)pabyTBMHeader + 117, "  ", 2) ) 
    810857        poDS->iDataFormat = PACKED10BIT; 
    811     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 117, "16", 2) ) 
     858    else if ( EQUALN((const char *)pabyTBMHeader + 117, "16", 2) ) 
    812859        poDS->iDataFormat = UNPACKED16BIT; 
    813     else if ( EQUALN((const char *)poDS->pabyTBMHeader + 117, "08", 2) ) 
     860    else if ( EQUALN((const char *)pabyTBMHeader + 117, "08", 2) ) 
    814861        poDS->iDataFormat = UNPACKED8BIT; 
    815862    else 
     863    { 
     864#ifdef DEBUG 
     865        CPLDebug( "L1B", "Unknown data format \"%.2s\".", 
     866                  pabyTBMHeader + 117 ); 
     867#endif 
    816868        goto bad; 
    817  
    818     switch( poDS->iDataType ) 
     869    } 
     870 
     871    switch( poDS->eProductType ) 
    819872    { 
    820873        case HRPT: 
    821874        case LAC: 
     875        case FRAC: 
    822876            poDS->nRasterXSize = 2048; 
    823877            poDS->nBufferSize = 20484; 
     
    825879            poDS->iGCPStep = 40; 
    826880            poDS->nGCPsPerLine = 51; 
    827             if (poDS->iSpacecraftID <= NOAA14) 
     881            if (poDS->eSpacecraftID <= NOAA14) 
    828882            { 
    829883                if (poDS->iDataFormat == PACKED10BIT) 
     
    889943                poDS->iGCPOffset = 104; 
    890944            } 
    891             else if (poDS->iSpacecraftID <= NOAA17
     945            else if ( poDS->eSpacecraftID <= METOP2
    892946            { 
    893947                if (poDS->iDataFormat == PACKED10BIT) 
     
    9621016            poDS->iGCPStep = 8; 
    9631017            poDS->nGCPsPerLine = 51; 
    964             if (poDS->iSpacecraftID <= NOAA14) 
     1018            if (poDS->eSpacecraftID <= NOAA14) 
    9651019            { 
    9661020                if (poDS->iDataFormat == PACKED10BIT) 
     
    10241078                poDS->iGCPOffset = 104; 
    10251079            } 
    1026             else if (poDS->iSpacecraftID <= NOAA17
     1080            else if ( poDS->eSpacecraftID <= METOP2
    10271081            { 
    10281082                if (poDS->iDataFormat == PACKED10BIT) 
     
    11151169         
    11161170        // Channels descriptions 
    1117         if ( poDS->iSpacecraftID >= NOAA6 && poDS->iSpacecraftID <= NOAA17
     1171        if ( poDS->eSpacecraftID >= NOAA6 && poDS->eSpacecraftID <= METOP2
    11181172        { 
    11191173            if ( !(i & 0x01) && poDS->iChannels & 0x01 ) 
     
    11311185            if ( !(i & 0x04) && poDS->iChannels & 0x04 ) 
    11321186            { 
    1133                 if (poDS->iSpacecraftID >= NOAA15 && poDS->iSpacecraftID <= NOAA17) 
     1187                if ( poDS->eSpacecraftID >= NOAA15 
     1188                     && poDS->eSpacecraftID <= METOP2 ) 
    11341189                    if (poDS->iInstrumentStatus & 0x0400) 
    11351190                        poDS->GetRasterBand(iBand)->SetDescription( apszBandDesc[7] ); 
     
    11491204            if ( !(i & 0x10) && poDS->iChannels & 0x10 ) 
    11501205            { 
    1151                 if (poDS->iSpacecraftID == NOAA13)              // 5 NOAA-13 
     1206                if (poDS->eSpacecraftID == NOAA13)              // 5 NOAA-13 
    11521207                    poDS->GetRasterBand(iBand)->SetDescription( apszBandDesc[5] ); 
    1153                 else if (poDS->iSpacecraftID == NOAA6 || 
    1154                          poDS->iSpacecraftID == NOAA8 || 
    1155                          poDS->iSpacecraftID == NOAA10)         // 4 NOAA-6,-8,-10 
     1208                else if (poDS->eSpacecraftID == NOAA6 || 
     1209                         poDS->eSpacecraftID == NOAA8 || 
     1210                         poDS->eSpacecraftID == NOAA10)         // 4 NOAA-6,-8,-10 
    11561211                    poDS->GetRasterBand(iBand)->SetDescription( apszBandDesc[3] ); 
    11571212                else 
     
    11661221/*      Do we have GCPs?                                                */ 
    11671222/* -------------------------------------------------------------------- */ 
    1168     if ( EQUALN((const char *)poDS->pabyTBMHeader + 96, "Y", 1) ) 
     1223    if ( EQUALN((const char *)pabyTBMHeader + 96, "Y", 1) ) 
    11691224    { 
    11701225        poDS->ProcessRecordHeaders(); 
     
    11821237        poDS->SetMetadataItem( "Y_BAND", "2" , "GEOLOCATION" ); 
    11831238 
    1184         osTMP.Printf( "%d", (poDS->iLocationIndicator == DESCEND) ? 
     1239        osTMP.Printf( "%d", (poDS->eLocationIndicator == DESCEND) ? 
    11851240            poDS->iGCPStart : (poDS->nRasterXSize - poDS->iGCPStart) ); 
    11861241        poDS->SetMetadataItem( "PIXEL_OFFSET", osTMP, "GEOLOCATION" ); 
    1187         osTMP.Printf( "%d", (poDS->iLocationIndicator == DESCEND) ? poDS->iGCPStep : -poDS->iGCPStep ); 
     1242        osTMP.Printf( "%d", (poDS->eLocationIndicator == DESCEND) ? poDS->iGCPStep : -poDS->iGCPStep ); 
    11881243        poDS->SetMetadataItem( "PIXEL_STEP", osTMP, "GEOLOCATION" ); 
    11891244 
     
    11971252/* -------------------------------------------------------------------- */ 
    11981253    const char *pszText; 
    1199     switch( poDS->iSpacecraftID ) 
     1254    switch( poDS->eSpacecraftID ) 
    12001255    { 
    12011256        case TIROSN: 
     
    12411296            pszText = "NOAA-17(M)"; 
    12421297        break; 
     1298        case NOAA18: 
     1299            pszText = "NOAA-18(N)"; 
     1300        break; 
     1301        case METOP2: 
     1302            pszText = "METOP-2(A)"; 
     1303        break; 
    12431304        default: 
    12441305            pszText = "Unknown"; 
    12451306    } 
    12461307    poDS->SetMetadataItem( "SATELLITE",  pszText ); 
    1247     switch( poDS->iDataType ) 
     1308    switch( poDS->eProductType ) 
    12481309    { 
    12491310        case LAC: 
     
    12561317            pszText = "AVHRR GAC"; 
    12571318        break; 
     1319        case FRAC: 
     1320            pszText = "AVHRR FRAC"; 
     1321        break; 
    12581322        default: 
    12591323            pszText = "Unknown"; 
     
    12611325    poDS->SetMetadataItem( "DATA_TYPE",  pszText ); 
    12621326    poDS->SetMetadataItem( "REVOLUTION",  poDS->pszRevolution ); 
    1263     switch( poDS->iSource ) 
     1327    switch( poDS->eSource ) 
    12641328    { 
    12651329        case DU: 
     
    12881352    } 
    12891353    poDS->SetMetadataItem( "SOURCE",  pszText ); 
    1290     switch( poDS->iProcCenter ) 
     1354    switch( poDS->eProcCenter ) 
    12911355    { 
    12921356        case CMS: 
     
    13111375    poDS->SetMetadataItem( "STOP",  poDS->sStopTime.PrintTime() ); 
    13121376    // AVHRR Earth location indication 
    1313     switch(poDS->iLocationIndicator) 
     1377    switch(poDS->eLocationIndicator) 
    13141378    { 
    13151379        case ASCEND: 
    1316         poDS->SetMetadataItem( "LOCATION", "Ascending" ); 
    1317         break; 
     1380            poDS->SetMetadataItem( "LOCATION", "Ascending" ); 
     1381            break; 
    13181382        case DESCEND: 
    13191383        default: 
    1320         poDS->SetMetadataItem( "LOCATION", "Descending" ); 
    1321         break; 
     1384            poDS->SetMetadataItem( "LOCATION", "Descending" ); 
     1385            break; 
    13221386    } 
    13231387 
     
    13291393 
    13301394    return( poDS ); 
     1395 
    13311396bad: 
    13321397    delete poDS;