LCOV - code coverage report
Current view: directory - frmts/envisat - envisatdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 372 271 72.8 %
Date: 2011-12-18 Functions: 22 14 63.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: envisatdataset.cpp 22870 2011-08-06 19:07:45Z antonio $
       3                 :  *
       4                 :  * Project:  APP ENVISAT Support
       5                 :  * Purpose:  Reader for ENVISAT format image data.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2001, Atlantis Scientific, Inc.
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "rawdataset.h"
      31                 : #include "cpl_string.h"
      32                 : #include "ogr_srs_api.h"
      33                 : 
      34                 : CPL_CVSID("$Id: envisatdataset.cpp 22870 2011-08-06 19:07:45Z antonio $");
      35                 : 
      36                 : CPL_C_START
      37                 : #include "EnvisatFile.h"
      38                 : #include "records.h"
      39                 : CPL_C_END
      40                 : 
      41                 : CPL_C_START
      42                 : void  GDALRegister_Envisat(void);
      43                 : CPL_C_END
      44                 : 
      45                 : /************************************************************************/
      46                 : /* ==================================================================== */
      47                 : /*                        MerisL2FlagBand                         */
      48                 : /* ==================================================================== */
      49                 : /************************************************************************/
      50                 : class MerisL2FlagBand : public GDALPamRasterBand
      51                 : {
      52                 :   public:
      53                 :     MerisL2FlagBand( GDALDataset *, int, FILE*, off_t, off_t );
      54                 :     virtual ~MerisL2FlagBand();
      55                 :     virtual CPLErr IReadBlock( int, int, void * );
      56                 : 
      57                 :   private:
      58                 :     off_t nImgOffset;
      59                 :     off_t nPrefixBytes;
      60                 :     size_t nBytePerPixel;
      61                 :     size_t nRecordSize;
      62                 :     size_t nDataSize;
      63                 :     GByte *pReadBuf;
      64                 :     FILE *fpImage;
      65                 : };
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                        MerisL2FlagBand()                       */
      69                 : /************************************************************************/
      70               7 : MerisL2FlagBand::MerisL2FlagBand( GDALDataset *poDS, int nBand,
      71                 :                                   FILE* fpImage, off_t nImgOffset,
      72               7 :                                   off_t nPrefixBytes )
      73                 : {
      74               7 :     this->poDS = (GDALDataset *) poDS;
      75               7 :     this->nBand = nBand;
      76                 : 
      77               7 :     this->fpImage = fpImage;
      78               7 :     this->nImgOffset = nImgOffset;
      79               7 :     this->nPrefixBytes = nPrefixBytes;
      80                 : 
      81               7 :     eDataType = GDT_UInt32;
      82                 : 
      83               7 :     nBlockXSize = poDS->GetRasterXSize();
      84               7 :     nBlockYSize = 1;
      85               7 :     nBytePerPixel = 3;
      86                 : 
      87               7 :     nDataSize = nBlockXSize * nBytePerPixel;
      88               7 :     nRecordSize = nPrefixBytes + nDataSize;
      89                 : 
      90               7 :     pReadBuf = (GByte *) CPLMalloc( nRecordSize );
      91               7 : }
      92                 : 
      93                 : 
      94                 : /************************************************************************/
      95                 : /*                        ~MerisL2FlagBand()                       */
      96                 : /************************************************************************/
      97               7 : MerisL2FlagBand::~MerisL2FlagBand()
      98                 : {
      99               7 :     CPLFree( pReadBuf );
     100               7 : }
     101                 : 
     102                 : /************************************************************************/
     103                 : /*                             IReadBlock()                             */
     104                 : /************************************************************************/
     105               0 : CPLErr MerisL2FlagBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     106                 :                                     void * pImage )
     107                 : {
     108               0 :     CPLAssert( nBlockXOff == 0 );
     109               0 :     CPLAssert( pReadBuf != NULL );
     110                 : 
     111                 :     off_t nOffset = nImgOffset + nPrefixBytes +
     112               0 :                     nBlockYOff * nBlockYSize * nRecordSize;
     113                 : 
     114               0 :     if ( VSIFSeek( fpImage, nOffset, SEEK_SET ) != 0 )
     115                 :     {
     116                 :         CPLError( CE_Failure, CPLE_FileIO,
     117                 :                   "Seek to %d for scanline %d failed.\n",
     118               0 :                   (int)nOffset, nBlockYOff );
     119               0 :         return CE_Failure;
     120                 :     }
     121                 : 
     122               0 :     if ( VSIFRead( pReadBuf, 1, nDataSize, fpImage ) != nDataSize )
     123                 :     {
     124                 :         CPLError( CE_Failure, CPLE_FileIO,
     125                 :                   "Read of %d bytes for scanline %d failed.\n",
     126               0 :                   (int)nDataSize, nBlockYOff );
     127               0 :         return CE_Failure;
     128                 :     }
     129                 : 
     130                 :     unsigned iImg, iBuf;
     131               0 :     for( iImg = 0, iBuf = 0;
     132                 :          iImg < nBlockXSize * sizeof(GDT_UInt32);
     133                 :          iImg += sizeof(GDT_UInt32), iBuf += nBytePerPixel )
     134                 :     {
     135                 : #ifdef CPL_LSB
     136               0 :         ((GByte*) pImage)[iImg] = pReadBuf[iBuf + 2];
     137               0 :         ((GByte*) pImage)[iImg + 1] = pReadBuf[iBuf + 1];
     138               0 :         ((GByte*) pImage)[iImg + 2] = pReadBuf[iBuf];
     139               0 :         ((GByte*) pImage)[iImg + 3] = 0;
     140                 : #else
     141                 :         ((GByte*) pImage)[iImg] = 0;
     142                 :         ((GByte*) pImage)[iImg + 1] = pReadBuf[iBuf];
     143                 :         ((GByte*) pImage)[iImg + 2] = pReadBuf[iBuf + 1];
     144                 :         ((GByte*) pImage)[iImg + 3] = pReadBuf[iBuf + 2];
     145                 : #endif
     146                 :     }
     147                 : 
     148               0 :     return CE_None;
     149                 : }
     150                 : 
     151                 : 
     152                 : /************************************************************************/
     153                 : /* ==================================================================== */
     154                 : /*        EnvisatDataset        */
     155                 : /* ==================================================================== */
     156                 : /************************************************************************/
     157                 : 
     158                 : class EnvisatDataset : public RawDataset
     159                 : {
     160                 :     EnvisatFile *hEnvisatFile;
     161                 :     FILE  *fpImage;
     162                 : 
     163                 :     int         nGCPCount;
     164                 :     GDAL_GCP    *pasGCPList;
     165                 : 
     166                 :     char        **papszTempMD;
     167                 : 
     168                 :     void        ScanForGCPs_ASAR();
     169                 :     void        ScanForGCPs_MERIS();
     170                 : 
     171                 :     void  CollectMetadata( EnvisatFile_HeaderFlag );
     172                 :     void        CollectDSDMetadata();
     173                 :     void        CollectADSMetadata();
     174                 : 
     175                 :   public:
     176                 :         EnvisatDataset();
     177                 :               ~EnvisatDataset();
     178                 : 
     179                 :     virtual int    GetGCPCount();
     180                 :     virtual const char *GetGCPProjection();
     181                 :     virtual const GDAL_GCP *GetGCPs();
     182                 :     virtual char **GetMetadata( const char * pszDomain );
     183                 : 
     184                 : 
     185                 :     static GDALDataset *Open( GDALOpenInfo * );
     186                 : };
     187                 : 
     188                 : /************************************************************************/
     189                 : /* ==================================================================== */
     190                 : /*        EnvisatDataset        */
     191                 : /* ==================================================================== */
     192                 : /************************************************************************/
     193                 : 
     194                 : /************************************************************************/
     195                 : /*                            EnvisatDataset()                             */
     196                 : /************************************************************************/
     197                 : 
     198              13 : EnvisatDataset::EnvisatDataset()
     199                 : {
     200              13 :     hEnvisatFile = NULL;
     201              13 :     fpImage = NULL;
     202              13 :     nGCPCount = 0;
     203              13 :     pasGCPList = NULL;
     204              13 :     papszTempMD = NULL;
     205              13 : }
     206                 : 
     207                 : /************************************************************************/
     208                 : /*                            ~EnvisatDataset()                            */
     209                 : /************************************************************************/
     210                 : 
     211              13 : EnvisatDataset::~EnvisatDataset()
     212                 : 
     213                 : {
     214              13 :     FlushCache();
     215                 : 
     216              13 :     if( hEnvisatFile != NULL )
     217              13 :         EnvisatFile_Close( hEnvisatFile );
     218                 : 
     219              13 :     if( fpImage != NULL )
     220              13 :         VSIFClose( fpImage );
     221                 : 
     222              13 :     if( nGCPCount > 0 )
     223                 :     {
     224              13 :         GDALDeinitGCPs( nGCPCount, pasGCPList );
     225              13 :         CPLFree( pasGCPList );
     226                 :     }
     227                 : 
     228              13 :     CSLDestroy( papszTempMD );
     229              13 : }
     230                 : 
     231                 : /************************************************************************/
     232                 : /*                            GetGCPCount()                             */
     233                 : /************************************************************************/
     234                 : 
     235               2 : int EnvisatDataset::GetGCPCount()
     236                 : 
     237                 : {
     238               2 :     return nGCPCount;
     239                 : }
     240                 : 
     241                 : /************************************************************************/
     242                 : /*                          GetGCPProjection()                          */
     243                 : /************************************************************************/
     244                 : 
     245               0 : const char *EnvisatDataset::GetGCPProjection()
     246                 : 
     247                 : {
     248               0 :     if( nGCPCount > 0 )
     249               0 :         return SRS_WKT_WGS84;
     250                 :     else
     251               0 :         return "";
     252                 : }
     253                 : 
     254                 : /************************************************************************/
     255                 : /*                               GetGCP()                               */
     256                 : /************************************************************************/
     257                 : 
     258               2 : const GDAL_GCP *EnvisatDataset::GetGCPs()
     259                 : 
     260                 : {
     261               2 :     return pasGCPList;
     262                 : }
     263                 : 
     264                 : /************************************************************************/
     265                 : /*                          ScanForGCPs_ASAR()                          */
     266                 : /************************************************************************/
     267                 : 
     268               6 : void EnvisatDataset::ScanForGCPs_ASAR()
     269                 : 
     270                 : {
     271                 :     int   nDatasetIndex, nNumDSR, nDSRSize, iRecord;
     272                 : 
     273                 : /* -------------------------------------------------------------------- */
     274                 : /*      Do we have a meaningful geolocation grid?                       */
     275                 : /* -------------------------------------------------------------------- */
     276                 :     nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile,
     277               6 :                                                  "GEOLOCATION GRID ADS" );
     278               6 :     if( nDatasetIndex == -1 )
     279               0 :         return;
     280                 : 
     281               6 :     if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex,
     282                 :                                     NULL, NULL, NULL, NULL, NULL,
     283                 :                                     &nNumDSR, &nDSRSize ) != SUCCESS )
     284               0 :         return;
     285                 : 
     286               6 :     if( nNumDSR == 0 || nDSRSize != 521 )
     287               0 :         return;
     288                 : 
     289                 : /* -------------------------------------------------------------------- */
     290                 : /*      Collect the first GCP set from each record.     */
     291                 : /* -------------------------------------------------------------------- */
     292                 :     GByte abyRecord[521];
     293               6 :     int   nRange=0, nSample, iGCP, nRangeOffset=0;
     294                 :     GUInt32   unValue;
     295                 : 
     296               6 :     nGCPCount = 0;
     297               6 :     pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),(nNumDSR+1) * 11);
     298                 : 
     299              24 :     for( iRecord = 0; iRecord < nNumDSR; iRecord++ )
     300                 :     {
     301              18 :         if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex,
     302                 :                                            iRecord, abyRecord ) != SUCCESS )
     303               0 :             continue;
     304                 : 
     305              18 :         memcpy( &unValue, abyRecord + 13, 4 );
     306              18 :         nRange = CPL_MSBWORD32( unValue ) + nRangeOffset;
     307                 : 
     308              18 :         if((iRecord>1) && (int(pasGCPList[nGCPCount-1].dfGCPLine+0.5) > nRange))
     309                 :         {
     310               6 :             int delta = (int) (pasGCPList[nGCPCount-1].dfGCPLine -
     311               6 :                                pasGCPList[nGCPCount-12].dfGCPLine);
     312               6 :             nRange = int(pasGCPList[nGCPCount-1].dfGCPLine+0.5) + delta;
     313               6 :             nRangeOffset = nRange-1;
     314                 :         }
     315                 : 
     316             216 :         for( iGCP = 0; iGCP < 11; iGCP++ )
     317                 :         {
     318                 :             char  szId[128];
     319                 : 
     320             198 :             GDALInitGCPs( 1, pasGCPList + nGCPCount );
     321                 : 
     322             198 :             CPLFree( pasGCPList[nGCPCount].pszId );
     323                 : 
     324             198 :             sprintf( szId, "%d", nGCPCount+1 );
     325             198 :             pasGCPList[nGCPCount].pszId = CPLStrdup( szId );
     326                 : 
     327             198 :             memcpy( &unValue, abyRecord + 25 + iGCP*4, 4 );
     328             198 :             nSample = CPL_MSBWORD32(unValue);
     329                 : 
     330             198 :             memcpy( &unValue, abyRecord + 25 + 176 + iGCP*4, 4 );
     331             198 :             pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001;
     332                 : 
     333             198 :             memcpy( &unValue, abyRecord + 25 + 132 + iGCP*4, 4 );
     334             198 :             pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001;
     335                 : 
     336             198 :             pasGCPList[nGCPCount].dfGCPZ = 0.0;
     337                 : 
     338             198 :             pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5;
     339             198 :             pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5;
     340                 : 
     341             198 :             nGCPCount++;
     342                 :         }
     343                 :     }
     344                 : 
     345                 : /* -------------------------------------------------------------------- */
     346                 : /*      We also collect the bottom GCPs from the last granule.          */
     347                 : /* -------------------------------------------------------------------- */
     348               6 :     memcpy( &unValue, abyRecord + 17, 4 );
     349               6 :     nRange = nRange + CPL_MSBWORD32( unValue ) - 1;
     350                 : 
     351              72 :     for( iGCP = 0; iGCP < 11; iGCP++ )
     352                 :     {
     353                 :         char  szId[128];
     354                 : 
     355              66 :         GDALInitGCPs( 1, pasGCPList + nGCPCount );
     356                 : 
     357              66 :         CPLFree( pasGCPList[nGCPCount].pszId );
     358                 : 
     359              66 :         sprintf( szId, "%d", nGCPCount+1 );
     360              66 :         pasGCPList[nGCPCount].pszId = CPLStrdup( szId );
     361                 : 
     362              66 :         memcpy( &unValue, abyRecord + 279 + iGCP*4, 4 );
     363              66 :         nSample = CPL_MSBWORD32(unValue);
     364                 : 
     365              66 :         memcpy( &unValue, abyRecord + 279 + 176 + iGCP*4, 4 );
     366              66 :         pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001;
     367                 : 
     368              66 :         memcpy( &unValue, abyRecord + 279 + 132 + iGCP*4, 4 );
     369              66 :         pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001;
     370                 : 
     371              66 :         pasGCPList[nGCPCount].dfGCPZ = 0.0;
     372                 : 
     373              66 :         pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5;
     374              66 :         pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5;
     375                 : 
     376              66 :         nGCPCount++;
     377                 :     }
     378                 : }
     379                 : 
     380                 : /************************************************************************/
     381                 : /*                         ScanForGCPs_MERIS()                          */
     382                 : /************************************************************************/
     383                 : 
     384               7 : void EnvisatDataset::ScanForGCPs_MERIS()
     385                 : 
     386                 : {
     387                 :     int   nDatasetIndex, nNumDSR, nDSRSize, iRecord;
     388                 : 
     389                 : /* -------------------------------------------------------------------- */
     390                 : /*      Do we have a meaningful geolocation grid?  Seach for a          */
     391                 : /*      DS_TYPE=A and a name containing "geolocation" or "tie           */
     392                 : /*      points".                                                        */
     393                 : /* -------------------------------------------------------------------- */
     394                 :     nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile,
     395               7 :                                                  "Tie points ADS" );
     396               7 :     if( nDatasetIndex == -1 )
     397               0 :         return;
     398                 : 
     399               7 :     if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex,
     400                 :                                     NULL, NULL, NULL, NULL, NULL,
     401                 :                                     &nNumDSR, &nDSRSize ) != SUCCESS )
     402               0 :         return;
     403                 : 
     404               7 :     if( nNumDSR == 0 )
     405               0 :         return;
     406                 : 
     407                 : /* -------------------------------------------------------------------- */
     408                 : /*      Figure out the tiepoint space, and how many we have.            */
     409                 : /* -------------------------------------------------------------------- */
     410                 :     int  nLinesPerTiePoint, nSamplesPerTiePoint;
     411               7 :     int  nTPPerLine, nTPPerColumn = nNumDSR;
     412                 : 
     413               7 :     if( nNumDSR == 0 )
     414               0 :         return;
     415                 : 
     416                 :     nLinesPerTiePoint =
     417                 :         EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
     418               7 :                                       "LINES_PER_TIE_PT", 0 );
     419                 :     nSamplesPerTiePoint =
     420                 :         EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
     421               7 :                                       "SAMPLES_PER_TIE_PT", 0 );
     422                 : 
     423               7 :     if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 )
     424               0 :         return;
     425                 : 
     426                 :     nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1)
     427               7 :         / nSamplesPerTiePoint;
     428                 : 
     429               7 :     if( (GetRasterYSize() + nLinesPerTiePoint - 1)
     430                 :         / nLinesPerTiePoint != nTPPerColumn )
     431                 :     {
     432                 :         CPLDebug( "EnvisatDataset", "Got %d instead of %d nTPPerColumn.",
     433                 :                   (GetRasterYSize()+nLinesPerTiePoint-1)/nLinesPerTiePoint,
     434               0 :                   nTPPerColumn );
     435               0 :         return;
     436                 :     }
     437                 : 
     438               7 :     if( 50*nTPPerLine + 13 != nDSRSize )
     439                 :     {
     440                 :         CPLDebug( "EnvisatDataset",
     441                 :                   "DSRSize=%d instead of expected %d for tiepoints ADS.",
     442               0 :                   nDSRSize, 50*nTPPerLine + 13 );
     443               0 :         return;
     444                 :     }
     445                 : 
     446                 : /* -------------------------------------------------------------------- */
     447                 : /*      Collect the first GCP set from each record.     */
     448                 : /* -------------------------------------------------------------------- */
     449               7 :     GByte *pabyRecord = (GByte *) CPLMalloc(nDSRSize);
     450                 :     int   iGCP;
     451                 :     GUInt32   unValue;
     452                 : 
     453               7 :     nGCPCount = 0;
     454                 :     pasGCPList = (GDAL_GCP *)
     455               7 :         CPLCalloc(sizeof(GDAL_GCP),nNumDSR * nTPPerLine);
     456                 : 
     457             273 :     for( iRecord = 0; iRecord < nNumDSR; iRecord++ )
     458                 :     {
     459             266 :         if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex,
     460                 :                                            iRecord, pabyRecord ) != SUCCESS )
     461               0 :             continue;
     462                 : 
     463             266 :         memcpy( &unValue, pabyRecord + 13, 4 );
     464                 : 
     465           19152 :         for( iGCP = 0; iGCP < nTPPerLine; iGCP++ )
     466                 :         {
     467                 :             char  szId[128];
     468                 : 
     469           18886 :             GDALInitGCPs( 1, pasGCPList + nGCPCount );
     470                 : 
     471           18886 :             CPLFree( pasGCPList[nGCPCount].pszId );
     472                 : 
     473           18886 :             sprintf( szId, "%d", nGCPCount+1 );
     474           18886 :             pasGCPList[nGCPCount].pszId = CPLStrdup( szId );
     475                 : 
     476           18886 :             memcpy( &unValue, pabyRecord + 13 + nTPPerLine*4 + iGCP*4, 4 );
     477           18886 :             pasGCPList[nGCPCount].dfGCPX =
     478           18886 :                 ((int)CPL_MSBWORD32(unValue))*0.000001;
     479                 : 
     480           18886 :             memcpy( &unValue, pabyRecord + 13 + iGCP*4, 4 );
     481           18886 :             pasGCPList[nGCPCount].dfGCPY =
     482           18886 :                 ((int)CPL_MSBWORD32(unValue))*0.000001;
     483                 : 
     484           18886 :             pasGCPList[nGCPCount].dfGCPZ = 0.0;
     485                 : 
     486           18886 :             pasGCPList[nGCPCount].dfGCPLine = iRecord*nLinesPerTiePoint + 0.5;
     487           18886 :             pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5;
     488                 : 
     489           18886 :             nGCPCount++;
     490                 :         }
     491                 :     }
     492               7 :     CPLFree( pabyRecord );
     493                 : }
     494                 : 
     495                 : /************************************************************************/
     496                 : /*                            GetMetadata()                             */
     497                 : /************************************************************************/
     498                 : 
     499               2 : char **EnvisatDataset::GetMetadata( const char * pszDomain )
     500                 : 
     501                 : {
     502               2 :     if( pszDomain == NULL || !EQUALN(pszDomain,"envisat-ds-",11) )
     503               2 :         return GDALDataset::GetMetadata( pszDomain );
     504                 : 
     505                 : /* -------------------------------------------------------------------- */
     506                 : /*      Get the dataset name and record number.                         */
     507                 : /* -------------------------------------------------------------------- */
     508                 :     char  szDSName[128];
     509               0 :     int         i, nRecord = -1;
     510                 : 
     511               0 :     strncpy( szDSName, pszDomain+11, sizeof(szDSName) );
     512               0 :     szDSName[sizeof(szDSName)-1] = 0;
     513               0 :     for( i = 0; i < (int) sizeof(szDSName)-1; i++ )
     514                 :     {
     515               0 :         if( szDSName[i] == '-' )
     516                 :         {
     517               0 :             szDSName[i] = '\0';
     518               0 :             nRecord = atoi(szDSName+1);
     519               0 :             break;
     520                 :         }
     521                 :     }
     522                 : 
     523               0 :     if( nRecord == -1 )
     524               0 :         return NULL;
     525                 : 
     526                 : /* -------------------------------------------------------------------- */
     527                 : /*      Get the dataset index and info.                                 */
     528                 : /* -------------------------------------------------------------------- */
     529               0 :     int nDSIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, szDSName );
     530                 :     int nDSRSize, nNumDSR;
     531                 : 
     532               0 :     if( nDSIndex == -1 )
     533               0 :         return NULL;
     534                 : 
     535                 :     EnvisatFile_GetDatasetInfo( hEnvisatFile, nDSIndex, NULL, NULL, NULL,
     536               0 :                                 NULL, NULL, &nNumDSR, &nDSRSize );
     537                 : 
     538               0 :     if( nDSRSize == -1 || nRecord < 0 || nRecord >= nNumDSR )
     539               0 :         return NULL;
     540                 : 
     541                 : /* -------------------------------------------------------------------- */
     542                 : /*      Read the requested record.                                      */
     543                 : /* -------------------------------------------------------------------- */
     544                 :     char  *pszRecord;
     545                 : 
     546               0 :     pszRecord = (char *) CPLMalloc(nDSRSize+1);
     547                 : 
     548               0 :     if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDSIndex, nRecord,
     549                 :                                        pszRecord ) == FAILURE )
     550                 :     {
     551               0 :         CPLFree( pszRecord );
     552               0 :         return NULL;
     553                 :     }
     554                 : 
     555                 : /* -------------------------------------------------------------------- */
     556                 : /*      Massage the data into a safe textual format.  For now we        */
     557                 : /*      just turn zero bytes into spaces.                               */
     558                 : /* -------------------------------------------------------------------- */
     559                 :     char *pszEscapedRecord;
     560                 : 
     561               0 :     CSLDestroy( papszTempMD );
     562                 : 
     563                 :     pszEscapedRecord = CPLEscapeString( pszRecord, nDSRSize,
     564               0 :                                         CPLES_BackslashQuotable );
     565               0 :     papszTempMD = CSLSetNameValue( NULL, "EscapedRecord", pszEscapedRecord );
     566               0 :     CPLFree( pszEscapedRecord );
     567                 : 
     568               0 :     for( i = 0; i < nDSRSize; i++ )
     569               0 :         if( pszRecord[i] == '\0' )
     570               0 :             pszRecord[i] = ' ';
     571                 : 
     572               0 :     papszTempMD = CSLSetNameValue( papszTempMD, "RawRecord", pszRecord );
     573                 : 
     574               0 :     CPLFree( pszRecord );
     575                 : 
     576               0 :     return papszTempMD;
     577                 : }
     578                 : 
     579                 : /************************************************************************/
     580                 : /*                         CollectDSDMetadata()                         */
     581                 : /*                                                                      */
     582                 : /*      Collect metadata based on any DSD entries with filenames        */
     583                 : /*      associated.                                                     */
     584                 : /************************************************************************/
     585                 : 
     586              13 : void EnvisatDataset::CollectDSDMetadata()
     587                 : 
     588                 : {
     589                 :     char  *pszDSName, *pszFilename;
     590                 :     int   iDSD;
     591                 : 
     592             373 :     for( iDSD = 0;
     593                 :          EnvisatFile_GetDatasetInfo( hEnvisatFile, iDSD, &pszDSName, NULL,
     594                 :                              &pszFilename, NULL, NULL, NULL, NULL ) == SUCCESS;
     595                 :          iDSD++ )
     596                 :     {
     597             360 :         if( pszFilename == NULL
     598                 :             || strlen(pszFilename) == 0
     599                 :             || EQUALN(pszFilename,"NOT USED",8)
     600                 :             || EQUALN(pszFilename,"        ",8))
     601             253 :             continue;
     602                 : 
     603                 :         char  szKey[128], szTrimmedName[128];
     604                 :         int i;
     605                 : 
     606             107 :         strcpy( szKey, "DS_" );
     607             107 :         strcat( szKey, pszDSName );
     608                 : 
     609                 :         // strip trailing spaces.
     610             607 :         for( i = strlen(szKey)-1; i && szKey[i] == ' '; i-- )
     611             500 :             szKey[i] = '\0';
     612                 : 
     613                 :         // convert spaces into underscores.
     614            2924 :         for( i = 0; szKey[i] != '\0'; i++ )
     615                 :         {
     616            2817 :             if( szKey[i] == ' ' )
     617              42 :                 szKey[i] = '_';
     618                 :         }
     619                 : 
     620             107 :         strcat( szKey, "_NAME" );
     621                 : 
     622             107 :         strcpy( szTrimmedName, pszFilename );
     623             201 :         for( i = strlen(szTrimmedName)-1; i && szTrimmedName[i] == ' '; i--)
     624              94 :             szTrimmedName[i] = '\0';
     625                 : 
     626             107 :         SetMetadataItem( szKey, szTrimmedName );
     627                 :     }
     628              13 : }
     629                 : 
     630                 : /************************************************************************/
     631                 : /*                         CollectADSMetadata()                         */
     632                 : /*                                                                      */
     633                 : /*      Collect metadata from envisat ADS and GADS.                     */
     634                 : /************************************************************************/
     635                 : 
     636              13 : void EnvisatDataset::CollectADSMetadata()
     637                 : {
     638                 :     int nDSIndex, nNumDsr, nDSRSize;
     639                 :     int nRecord;
     640                 :     const char *pszDSName, *pszDSType, *pszDSFilename;
     641                 :     const char *pszProduct;
     642                 :     char *pszRecord;
     643                 :     char szPrefix[128], szKey[128], szValue[1024];
     644                 :     int i;
     645                 :     CPLErr ret;
     646              13 :     const EnvisatRecordDescr *pRecordDescr = NULL;
     647                 :     const EnvisatFieldDescr *pField;
     648                 : 
     649                 :     pszProduct = EnvisatFile_GetKeyValueAsString( hEnvisatFile, MPH,
     650              13 :                                                   "PRODUCT", "" );
     651                 : 
     652             373 :     for( nDSIndex = 0;
     653                 :          EnvisatFile_GetDatasetInfo( hEnvisatFile, nDSIndex,
     654                 :                                      (char **) &pszDSName,
     655                 :                                      (char **) &pszDSType,
     656                 :                                      (char **) &pszDSFilename,
     657                 :                                      NULL, NULL,
     658                 :                                      &nNumDsr, &nDSRSize ) == SUCCESS;
     659                 :          ++nDSIndex )
     660                 :     {
     661             360 :         if( EQUALN(pszDSFilename,"NOT USED",8) || (nNumDsr <= 0) )
     662             293 :             continue;
     663              67 :         if( !EQUAL(pszDSType,"A") && !EQUAL(pszDSType,"G") )
     664              34 :             continue;
     665                 : 
     666             371 :         for ( nRecord = 0; nRecord < nNumDsr; ++nRecord )
     667                 :         {
     668             338 :             strncpy( szPrefix, pszDSName, sizeof(szPrefix) - 1);
     669             338 :             szPrefix[sizeof(szPrefix) - 1] = '\0';
     670                 : 
     671                 :             // strip trailing spaces
     672            5068 :             for( i = strlen(szPrefix)-1; i && szPrefix[i] == ' '; --i )
     673            4730 :                 szPrefix[i] = '\0';
     674                 : 
     675                 :             // convert spaces into underscores
     676            5072 :             for( i = 0; szPrefix[i] != '\0'; i++ )
     677                 :             {
     678            4734 :                 if( szPrefix[i] == ' ' )
     679             641 :                     szPrefix[i] = '_';
     680                 :             }
     681                 : 
     682             338 :             pszRecord = (char *) CPLMalloc(nDSRSize+1);
     683                 : 
     684             338 :             if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDSIndex, nRecord,
     685                 :                                                pszRecord ) == FAILURE )
     686                 :             {
     687               0 :                 CPLFree( pszRecord );
     688               0 :                 return;
     689                 :             }
     690                 : 
     691             338 :             pRecordDescr = EnvisatFile_GetRecordDescriptor(pszProduct, pszDSName);
     692             338 :             if (pRecordDescr)
     693                 :             {
     694              54 :                 pField = pRecordDescr->pFields;
     695            1317 :                 while ( pField && pField->szName )
     696                 :                 {
     697                 :                     ret = EnvisatFile_GetFieldAsString(pszRecord, nDSRSize,
     698            1209 :                                            pField, szValue);
     699            1209 :                     if ( ret == CE_None )
     700                 :                     {
     701            1209 :                         if (nNumDsr == 1)
     702              42 :                             sprintf(szKey, "%s_%s", szPrefix, pField->szName);
     703                 :                         else
     704                 :                             // sprintf(szKey, "%s_%02d_%s", szPrefix, nRecord,
     705                 :                             sprintf(szKey, "%s_%d_%s", szPrefix, nRecord,
     706            1167 :                                     pField->szName);
     707            1209 :                         SetMetadataItem(szKey, szValue, "RECORDS");
     708                 :                     }
     709                 :                     // silently ignore conversion errors
     710                 : 
     711            1209 :                     ++pField;
     712                 :                 }
     713                 :             }
     714             338 :             CPLFree( pszRecord );
     715                 :         }
     716                 :     }
     717                 : }
     718                 : 
     719                 : /************************************************************************/
     720                 : /*                          CollectMetadata()                           */
     721                 : /*                                                                      */
     722                 : /*      Collect metadata from the SPH or MPH header fields.             */
     723                 : /************************************************************************/
     724                 : 
     725              26 : void EnvisatDataset::CollectMetadata( EnvisatFile_HeaderFlag  eMPHOrSPH )
     726                 : 
     727                 : {
     728                 :     int   iKey;
     729                 : 
     730             926 :     for( iKey = 0; TRUE; iKey++ )
     731                 :     {
     732                 :         const char *pszValue, *pszKey;
     733                 :         char  szHeaderKey[128];
     734                 : 
     735             926 :         pszKey = EnvisatFile_GetKeyByIndex(hEnvisatFile, eMPHOrSPH, iKey);
     736             926 :         if( pszKey == NULL )
     737                 :             break;
     738                 : 
     739                 :         pszValue = EnvisatFile_GetKeyValueAsString( hEnvisatFile, eMPHOrSPH,
     740             900 :                                                     pszKey, NULL );
     741                 : 
     742             900 :         if( pszValue == NULL )
     743               0 :             continue;
     744                 : 
     745                 :         // skip some uninteresting structural information.
     746             900 :         if( EQUAL(pszKey,"TOT_SIZE")
     747                 :             || EQUAL(pszKey,"SPH_SIZE")
     748                 :             || EQUAL(pszKey,"NUM_DSD")
     749                 :             || EQUAL(pszKey,"DSD_SIZE")
     750                 :             || EQUAL(pszKey,"NUM_DATA_SETS") )
     751              65 :             continue;
     752                 : 
     753             835 :         if( eMPHOrSPH == MPH )
     754             377 :             sprintf( szHeaderKey, "MPH_%s", pszKey );
     755                 :         else
     756             458 :             sprintf( szHeaderKey, "SPH_%s", pszKey );
     757                 : 
     758             835 :         SetMetadataItem( szHeaderKey, pszValue );
     759                 :     }
     760              26 : }
     761                 : 
     762                 : /************************************************************************/
     763                 : /*                                Open()                                */
     764                 : /************************************************************************/
     765                 : 
     766           12436 : GDALDataset *EnvisatDataset::Open( GDALOpenInfo * poOpenInfo )
     767                 : 
     768                 : {
     769                 :     EnvisatFile *hEnvisatFile;
     770                 : 
     771                 : /* -------------------------------------------------------------------- */
     772                 : /*      Check the header.                                               */
     773                 : /* -------------------------------------------------------------------- */
     774           12436 :     if( poOpenInfo->nHeaderBytes < 8 || poOpenInfo->fp == NULL )
     775           10953 :         return NULL;
     776                 : 
     777            1483 :     if( !EQUALN((const char *) poOpenInfo->pabyHeader, "PRODUCT=",8) )
     778            1470 :         return NULL;
     779                 : 
     780                 : /* -------------------------------------------------------------------- */
     781                 : /*      Try opening the dataset.                                        */
     782                 : /* -------------------------------------------------------------------- */
     783                 :     int   ds_index;
     784                 : 
     785              13 :     if( EnvisatFile_Open( &hEnvisatFile, poOpenInfo->pszFilename, "r" )
     786                 :         == FAILURE )
     787               0 :         return NULL;
     788                 : 
     789                 : /* -------------------------------------------------------------------- */
     790                 : /*      Find a Mesurement type dataset to use as our reference          */
     791                 : /*      raster band.                                                    */
     792                 : /* -------------------------------------------------------------------- */
     793                 :     int   dsr_size, num_dsr, ds_offset, bNative;
     794                 :     char        *pszDSType;
     795                 : 
     796              94 :     for( ds_index = 0; TRUE; ds_index++ )
     797                 :     {
     798              94 :         if( EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index,
     799                 :                                         NULL, &pszDSType, NULL,
     800                 :                                         &ds_offset, NULL,
     801                 :                                         &num_dsr, &dsr_size ) == FAILURE )
     802                 :         {
     803                 :             CPLError( CE_Failure, CPLE_AppDefined,
     804               0 :                       "Unable to find \"MDS1\" measurement datatset in Envisat file." );
     805               0 :             EnvisatFile_Close( hEnvisatFile );
     806               0 :             return NULL;
     807                 :         }
     808                 : 
     809                 :         /* Have we found what we are looking for?  A Measurement ds. */
     810              94 :         if( EQUAL(pszDSType,"M") )
     811                 :             break;
     812                 :     }
     813                 : 
     814                 : /* -------------------------------------------------------------------- */
     815                 : /*      Confirm the requested access is supported.                      */
     816                 : /* -------------------------------------------------------------------- */
     817              13 :     if( poOpenInfo->eAccess == GA_Update )
     818                 :     {
     819               0 :         EnvisatFile_Close( hEnvisatFile );
     820                 :         CPLError( CE_Failure, CPLE_NotSupported,
     821                 :                   "The ENVISAT driver does not support update access to existing"
     822               0 :                   " datasets.\n" );
     823               0 :         return NULL;
     824                 :     }
     825                 : /* -------------------------------------------------------------------- */
     826                 : /*      Create a corresponding GDALDataset.                             */
     827                 : /* -------------------------------------------------------------------- */
     828                 :     EnvisatDataset  *poDS;
     829                 : 
     830              13 :     poDS = new EnvisatDataset();
     831                 : 
     832              13 :     poDS->hEnvisatFile = hEnvisatFile;
     833                 : 
     834                 : /* -------------------------------------------------------------------- */
     835                 : /*      Setup image definition.                                         */
     836                 : /* -------------------------------------------------------------------- */
     837                 :     const char  *pszDataType, *pszSampleType, *pszProduct;
     838                 :     GDALDataType eDataType;
     839                 :     int          nPrefixBytes;
     840                 : 
     841                 :     EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index,
     842                 :                                 NULL, NULL, NULL, &ds_offset, NULL,
     843              13 :                                 &num_dsr, &dsr_size );
     844                 : 
     845                 :     poDS->nRasterXSize = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
     846              13 :                                                        "LINE_LENGTH", 0 );
     847              13 :     poDS->nRasterYSize = num_dsr;
     848              13 :     poDS->eAccess = GA_ReadOnly;
     849                 : 
     850                 :     pszProduct = EnvisatFile_GetKeyValueAsString( hEnvisatFile, MPH,
     851              13 :                                                   "PRODUCT", "" );
     852                 :     pszDataType = EnvisatFile_GetKeyValueAsString( hEnvisatFile, SPH,
     853              13 :                                                    "DATA_TYPE", "" );
     854                 :     pszSampleType = EnvisatFile_GetKeyValueAsString( hEnvisatFile, SPH,
     855              13 :                                                      "SAMPLE_TYPE", "" );
     856              13 :     if( EQUAL(pszDataType,"FLT32") && EQUALN(pszSampleType,"COMPLEX",7))
     857               0 :         eDataType = GDT_CFloat32;
     858              13 :     else if( EQUAL(pszDataType,"FLT32") )
     859               0 :         eDataType = GDT_Float32;
     860              13 :     else if( EQUAL(pszDataType,"UWORD") )
     861               0 :         eDataType = GDT_UInt16;
     862              13 :     else if( EQUAL(pszDataType,"SWORD") && EQUALN(pszSampleType,"COMPLEX",7) )
     863               0 :         eDataType = GDT_CInt16;
     864              13 :     else if( EQUAL(pszDataType,"SWORD") )
     865               0 :         eDataType = GDT_Int16;
     866              13 :     else if( EQUALN(pszProduct,"ATS_TOA_1",8) )
     867                 :     {
     868                 :         /* all 16bit data, no line length provided */
     869               0 :         eDataType = GDT_Int16;
     870               0 :         poDS->nRasterXSize = (dsr_size - 20) / 2;
     871                 :     }
     872              13 :     else if( poDS->nRasterXSize == 0 )
     873                 :     {
     874                 :         CPLError( CE_Warning, CPLE_AppDefined,
     875                 :                   "Envisat product format not recognised.  Assuming 8bit\n"
     876               0 :                   "with no per-record prefix data.  Results may be useless!" );
     877               0 :         eDataType = GDT_Byte;
     878               0 :         poDS->nRasterXSize = dsr_size;
     879                 :     }
     880                 :     else
     881                 :     {
     882              13 :         if( dsr_size >= 2 * poDS->nRasterXSize )
     883               7 :             eDataType = GDT_UInt16;
     884                 :         else
     885               6 :             eDataType = GDT_Byte;
     886                 :     }
     887                 : 
     888                 : #ifdef CPL_LSB
     889              13 :     bNative = FALSE;
     890                 : #else
     891                 :     bNative = TRUE;
     892                 : #endif
     893                 : 
     894                 :     nPrefixBytes = dsr_size -
     895              13 :         ((GDALGetDataTypeSize(eDataType) / 8) * poDS->nRasterXSize);
     896                 : 
     897                 : /* -------------------------------------------------------------------- */
     898                 : /*      Fail out if we didn't get non-zero sizes.                       */
     899                 : /* -------------------------------------------------------------------- */
     900              13 :     if( poDS->nRasterXSize < 1 || poDS->nRasterYSize < 1 )
     901                 :     {
     902                 :         CPLError( CE_Failure, CPLE_AppDefined,
     903                 :                   "Unable to determine organization of dataset.  It would\n"
     904                 :                   "appear this is an Envisat dataset, but an unsupported\n"
     905               0 :                   "data product.  Unable to utilize." );
     906               0 :         delete poDS;
     907               0 :         return NULL;
     908                 :     }
     909                 : 
     910                 : /* -------------------------------------------------------------------- */
     911                 : /*      Assume ownership of the file handled from the GDALOpenInfo.     */
     912                 : /* -------------------------------------------------------------------- */
     913              13 :     poDS->fpImage = poOpenInfo->fp;
     914              13 :     poOpenInfo->fp = NULL;
     915                 : 
     916                 : /* -------------------------------------------------------------------- */
     917                 : /*      Try to collect GCPs.                                            */
     918                 : /* -------------------------------------------------------------------- */
     919                 : 
     920                 : /* -------------------------------------------------------------------- */
     921                 : /*      Scan for all datasets matching the reference dataset.           */
     922                 : /* -------------------------------------------------------------------- */
     923              13 :     int num_dsr2, dsr_size2, iBand = 0;
     924                 :     const char *pszDSName;
     925                 :     char szBandName[128];
     926                 :     bool bMiltiChannel;
     927                 : 
     928             373 :     for( ds_index = 0;
     929                 :          EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index,
     930                 :                                      (char **) &pszDSName, NULL, NULL,
     931                 :                                      &ds_offset, NULL,
     932                 :                                      &num_dsr2, &dsr_size2 ) == SUCCESS;
     933                 :          ds_index++ )
     934                 :     {
     935             360 :         if( !EQUAL(pszDSType,"M") || num_dsr2 != num_dsr )
     936             326 :             continue;
     937                 : 
     938              34 :         if( EQUALN(pszProduct,"MER",3) && (pszProduct[8] == '2') &&
     939                 :             ( (strstr(pszDSName, "MDS(16)") != NULL) ||
     940                 :               (strstr(pszDSName, "MDS(19)") != NULL)) )
     941               0 :             bMiltiChannel = true;
     942                 :         else
     943              34 :             bMiltiChannel = false;
     944                 : 
     945              47 :         if( (dsr_size2 == dsr_size) && !bMiltiChannel )
     946                 :         {
     947                 :             poDS->SetBand( iBand+1,
     948                 :                        new RawRasterBand( poDS, iBand+1, poDS->fpImage,
     949                 :                                           ds_offset + nPrefixBytes,
     950                 :                                           GDALGetDataTypeSize(eDataType) / 8,
     951                 :                                           dsr_size,
     952              13 :                                           eDataType, bNative ) );
     953              13 :             iBand++;
     954                 : 
     955              13 :             poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
     956                 :         }
     957                 : /* -------------------------------------------------------------------- */
     958                 : /*       Handle MERIS Level 2 datasets with data type different from    */
     959                 : /*       the one declared in the SPH                                    */
     960                 : /* -------------------------------------------------------------------- */
     961              28 :         else if( EQUALN(pszProduct,"MER",3) &&
     962                 :                  (strstr(pszDSName, "Flags") != NULL) )
     963                 :         {
     964               7 :             if (pszProduct[8] == '1')
     965                 :             {
     966                 :                 // Flags
     967                 :                 poDS->SetBand( iBand+1,
     968                 :                            new RawRasterBand( poDS, iBand+1, poDS->fpImage,
     969                 :                                               ds_offset + nPrefixBytes, 3,
     970               0 :                                               dsr_size, GDT_Byte, bNative ) );
     971               0 :                 iBand++;
     972                 : 
     973               0 :                 poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
     974                 : 
     975                 :                 // Detector indices
     976                 :                 poDS->SetBand( iBand+1,
     977                 :                            new RawRasterBand( poDS, iBand+1, poDS->fpImage,
     978                 :                                               ds_offset + nPrefixBytes + 1,
     979                 :                                               3, dsr_size, GDT_Int16,
     980               0 :                                               bNative ) );
     981               0 :                 iBand++;
     982                 : 
     983               0 :                 const char *pszSuffix = strstr( pszDSName, "MDS" );
     984               0 :                 if ( pszSuffix != NULL)
     985               0 :                     sprintf( szBandName, "Detector index %s", pszSuffix );
     986                 :                 else
     987               0 :                     sprintf( szBandName, "Detector index" );
     988               0 :                 poDS->GetRasterBand(iBand)->SetDescription( szBandName );
     989                 :             }
     990               7 :             else if ( (pszProduct[8] == '2') &&
     991                 :                       (dsr_size2 >= 3 * poDS->nRasterXSize ) )
     992                 :             {
     993               7 :                 int nFlagPrefixBytes = dsr_size2 - 3 * poDS->nRasterXSize;
     994                 : 
     995                 :                 poDS->SetBand( iBand+1,
     996                 :                        new MerisL2FlagBand( poDS, iBand+1, poDS->fpImage,
     997               7 :                                             ds_offset, nFlagPrefixBytes ) );
     998               7 :                 iBand++;
     999                 : 
    1000               7 :                 poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
    1001                 :             }
    1002                 :         }
    1003              14 :         else if( EQUALN(pszProduct,"MER",3) && (pszProduct[8] == '2') )
    1004                 :         {
    1005                 :             int nPrefixBytes2, nSubBands, nSubBandIdx, nSubBandOffset;
    1006                 : 
    1007              14 :             int nPixelSize = 1;
    1008              14 :             GDALDataType eDataType2 = GDT_Byte;
    1009                 : 
    1010              14 :             nSubBands = dsr_size2 / poDS->nRasterXSize;
    1011              14 :             if( (nSubBands < 1) || (nSubBands > 3) )
    1012               0 :                 nSubBands = 0;
    1013                 : 
    1014                 :             nPrefixBytes2 = dsr_size2 -
    1015              14 :                 (nSubBands * nPixelSize * poDS->nRasterXSize);
    1016                 : 
    1017              28 :             for (nSubBandIdx = 0; nSubBandIdx < nSubBands; ++nSubBandIdx)
    1018                 :             {
    1019                 :                 nSubBandOffset =
    1020              14 :                     ds_offset + nPrefixBytes2 + nSubBandIdx * nPixelSize;
    1021                 :                 poDS->SetBand( iBand+1,
    1022                 :                         new RawRasterBand( poDS, iBand+1, poDS->fpImage,
    1023                 :                                            nSubBandOffset,
    1024                 :                                            nPixelSize * nSubBands,
    1025              14 :                                            dsr_size2, eDataType2, bNative ) );
    1026              14 :                 iBand++;
    1027                 : 
    1028              14 :                 if (nSubBands > 1)
    1029                 :                 {
    1030               0 :                     sprintf( szBandName, "%s (%d)", pszDSName, nSubBandIdx );
    1031               0 :                     poDS->GetRasterBand(iBand)->SetDescription( szBandName );
    1032                 :                 }
    1033                 :                 else
    1034              14 :                     poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
    1035                 :             }
    1036                 :         }
    1037                 :     }
    1038                 : 
    1039                 : /* -------------------------------------------------------------------- */
    1040                 : /*      Collect metadata.                                               */
    1041                 : /* -------------------------------------------------------------------- */
    1042              13 :     poDS->CollectMetadata( MPH );
    1043              13 :     poDS->CollectMetadata( SPH );
    1044              13 :     poDS->CollectDSDMetadata();
    1045              13 :     poDS->CollectADSMetadata();
    1046                 : 
    1047              13 :     if( EQUALN(pszProduct,"MER",3) )
    1048               7 :         poDS->ScanForGCPs_MERIS();
    1049                 :     else
    1050               6 :         poDS->ScanForGCPs_ASAR();
    1051                 : 
    1052                 : /* -------------------------------------------------------------------- */
    1053                 : /*      Initialize any PAM information.                                 */
    1054                 : /* -------------------------------------------------------------------- */
    1055              13 :     poDS->SetDescription( poOpenInfo->pszFilename );
    1056              13 :     poDS->TryLoadXML();
    1057                 : 
    1058                 : /* -------------------------------------------------------------------- */
    1059                 : /*      Check for overviews.                                            */
    1060                 : /* -------------------------------------------------------------------- */
    1061              13 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    1062                 : 
    1063              13 :     return( poDS );
    1064                 : }
    1065                 : 
    1066                 : /************************************************************************/
    1067                 : /*                         GDALRegister_Envisat()                       */
    1068                 : /************************************************************************/
    1069                 : 
    1070             558 : void GDALRegister_Envisat()
    1071                 : 
    1072                 : {
    1073                 :     GDALDriver  *poDriver;
    1074                 : 
    1075             558 :     if( GDALGetDriverByName( "ESAT" ) == NULL )
    1076                 :     {
    1077             537 :         poDriver = new GDALDriver();
    1078                 : 
    1079             537 :         poDriver->SetDescription( "ESAT" );
    1080                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
    1081             537 :                                    "Envisat Image Format" );
    1082                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
    1083             537 :                                    "frmt_various.html#Envisat" );
    1084             537 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "n1" );
    1085                 : 
    1086             537 :         poDriver->pfnOpen = EnvisatDataset::Open;
    1087                 : 
    1088             537 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1089                 :     }
    1090             558 : }
    1091                 : 

Generated by: LCOV version 1.7