LTP GCOV extension - code coverage report
Current view: directory - frmts/envisat - envisatdataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 262
Code covered: 5.7 % Executed lines: 15

       1                 : /******************************************************************************
       2                 :  * $Id: envisatdataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       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 17664 2009-09-21 21:16:45Z rouault $");
      35                 : 
      36                 : CPL_C_START
      37                 : #include "EnvisatFile.h"
      38                 : CPL_C_END
      39                 : 
      40                 : CPL_C_START
      41                 : void  GDALRegister_Envisat(void);
      42                 : CPL_C_END
      43                 : 
      44                 : /************************************************************************/
      45                 : /* ==================================================================== */
      46                 : /*        EnvisatDataset        */
      47                 : /* ==================================================================== */
      48                 : /************************************************************************/
      49                 : 
      50                 : class EnvisatDataset : public RawDataset
      51                 : {
      52                 :     EnvisatFile *hEnvisatFile;
      53                 :     FILE  *fpImage;
      54                 : 
      55                 :     int         nGCPCount;
      56                 :     GDAL_GCP    *pasGCPList;
      57                 : 
      58                 :     char        **papszTempMD;
      59                 :     
      60                 :     void        ScanForGCPs_ASAR();
      61                 :     void        ScanForGCPs_MERIS();
      62                 : 
      63                 :     void  CollectMetadata( EnvisatFile_HeaderFlag );
      64                 :     void        CollectDSDMetadata();
      65                 : 
      66                 :   public:
      67                 :         EnvisatDataset();
      68                 :               ~EnvisatDataset();
      69                 :     
      70                 :     virtual int    GetGCPCount();
      71                 :     virtual const char *GetGCPProjection();
      72                 :     virtual const GDAL_GCP *GetGCPs();
      73                 :     virtual char **GetMetadata( const char * pszDomain );
      74                 : 
      75                 : 
      76                 :     static GDALDataset *Open( GDALOpenInfo * );
      77                 : };
      78                 : 
      79                 : /************************************************************************/
      80                 : /* ==================================================================== */
      81                 : /*        EnvisatDataset        */
      82                 : /* ==================================================================== */
      83                 : /************************************************************************/
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                            EnvisatDataset()                             */
      87                 : /************************************************************************/
      88                 : 
      89               0 : EnvisatDataset::EnvisatDataset()
      90                 : {
      91               0 :     hEnvisatFile = NULL;
      92               0 :     fpImage = NULL;
      93               0 :     nGCPCount = 0;
      94               0 :     pasGCPList = NULL;
      95               0 :     papszTempMD = NULL;
      96               0 : }
      97                 : 
      98                 : /************************************************************************/
      99                 : /*                            ~EnvisatDataset()                            */
     100                 : /************************************************************************/
     101                 : 
     102               0 : EnvisatDataset::~EnvisatDataset()
     103                 : 
     104                 : {
     105               0 :     FlushCache();
     106                 : 
     107               0 :     if( hEnvisatFile != NULL )
     108               0 :         EnvisatFile_Close( hEnvisatFile );
     109                 : 
     110               0 :     if( fpImage != NULL )
     111               0 :         VSIFClose( fpImage );
     112                 : 
     113               0 :     if( nGCPCount > 0 )
     114                 :     {
     115               0 :         GDALDeinitGCPs( nGCPCount, pasGCPList );
     116               0 :         CPLFree( pasGCPList );
     117                 :     }
     118                 : 
     119               0 :     CSLDestroy( papszTempMD );
     120               0 : }
     121                 : 
     122                 : /************************************************************************/
     123                 : /*                            GetGCPCount()                             */
     124                 : /************************************************************************/
     125                 : 
     126               0 : int EnvisatDataset::GetGCPCount()
     127                 : 
     128                 : {
     129               0 :     return nGCPCount;
     130                 : }
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                          GetGCPProjection()                          */
     134                 : /************************************************************************/
     135                 : 
     136               0 : const char *EnvisatDataset::GetGCPProjection()
     137                 : 
     138                 : {
     139               0 :     if( nGCPCount > 0 )
     140               0 :         return SRS_WKT_WGS84;
     141                 :     else
     142               0 :         return "";
     143                 : }
     144                 : 
     145                 : /************************************************************************/
     146                 : /*                               GetGCP()                               */
     147                 : /************************************************************************/
     148                 : 
     149               0 : const GDAL_GCP *EnvisatDataset::GetGCPs()
     150                 : 
     151                 : {
     152               0 :     return pasGCPList;
     153                 : }
     154                 : 
     155                 : /************************************************************************/
     156                 : /*                          ScanForGCPs_ASAR()                          */
     157                 : /************************************************************************/
     158                 : 
     159               0 : void EnvisatDataset::ScanForGCPs_ASAR()
     160                 : 
     161                 : {
     162                 :     int   nDatasetIndex, nNumDSR, nDSRSize, iRecord;
     163                 : 
     164                 : /* -------------------------------------------------------------------- */
     165                 : /*      Do we have a meaningful geolocation grid?                       */
     166                 : /* -------------------------------------------------------------------- */
     167                 :     nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, 
     168               0 :                                                  "GEOLOCATION GRID ADS" );
     169               0 :     if( nDatasetIndex == -1 )
     170               0 :         return;
     171                 : 
     172               0 :     if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, 
     173                 :                                     NULL, NULL, NULL, NULL, NULL, 
     174                 :                                     &nNumDSR, &nDSRSize ) != SUCCESS )
     175               0 :         return;
     176                 : 
     177               0 :     if( nNumDSR == 0 || nDSRSize != 521 )
     178               0 :         return;
     179                 : 
     180                 : /* -------------------------------------------------------------------- */
     181                 : /*      Collect the first GCP set from each record.     */
     182                 : /* -------------------------------------------------------------------- */
     183                 :     GByte abyRecord[521];
     184               0 :     int   nRange=0, nSample, iGCP;
     185                 :     GUInt32   unValue;
     186                 : 
     187               0 :     nGCPCount = 0;
     188               0 :     pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),(nNumDSR+1) * 11);
     189                 : 
     190               0 :     for( iRecord = 0; iRecord < nNumDSR; iRecord++ )
     191                 :     {
     192               0 :         if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex, 
     193                 :                                            iRecord, abyRecord ) != SUCCESS )
     194               0 :             continue;
     195                 : 
     196               0 :         memcpy( &unValue, abyRecord + 13, 4 );
     197               0 :         nRange = CPL_MSBWORD32( unValue );
     198                 : 
     199               0 :         for( iGCP = 0; iGCP < 11; iGCP++ )
     200                 :         {
     201                 :             char  szId[128];
     202                 : 
     203               0 :             GDALInitGCPs( 1, pasGCPList + nGCPCount );
     204                 : 
     205               0 :             CPLFree( pasGCPList[nGCPCount].pszId );
     206                 :             
     207               0 :             sprintf( szId, "%d", nGCPCount+1 );
     208               0 :             pasGCPList[nGCPCount].pszId = CPLStrdup( szId );
     209                 : 
     210               0 :             memcpy( &unValue, abyRecord + 25 + iGCP*4, 4 );
     211               0 :             nSample = CPL_MSBWORD32(unValue);
     212                 : 
     213               0 :             memcpy( &unValue, abyRecord + 25 + 176 + iGCP*4, 4 );
     214               0 :             pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001;
     215                 : 
     216               0 :             memcpy( &unValue, abyRecord + 25 + 132 + iGCP*4, 4 );
     217               0 :             pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001;
     218                 : 
     219               0 :             pasGCPList[nGCPCount].dfGCPZ = 0.0;
     220                 : 
     221               0 :             pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5;
     222               0 :             pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5;
     223                 :             
     224               0 :             nGCPCount++;
     225                 :         }
     226                 :     }
     227                 : 
     228                 : /* -------------------------------------------------------------------- */
     229                 : /*      We also collect the bottom GCPs from the last granule.          */
     230                 : /* -------------------------------------------------------------------- */
     231               0 :     memcpy( &unValue, abyRecord + 17, 4 );
     232               0 :     nRange = nRange + CPL_MSBWORD32( unValue ) - 1;
     233                 : 
     234               0 :     for( iGCP = 0; iGCP < 11; iGCP++ )
     235                 :     {
     236                 :         char  szId[128];
     237                 : 
     238               0 :         GDALInitGCPs( 1, pasGCPList + nGCPCount );
     239                 : 
     240               0 :         CPLFree( pasGCPList[nGCPCount].pszId );
     241                 :             
     242               0 :         sprintf( szId, "%d", nGCPCount+1 );
     243               0 :         pasGCPList[nGCPCount].pszId = CPLStrdup( szId );
     244                 : 
     245               0 :         memcpy( &unValue, abyRecord + 279 + iGCP*4, 4 );
     246               0 :         nSample = CPL_MSBWORD32(unValue);
     247                 : 
     248               0 :         memcpy( &unValue, abyRecord + 279 + 176 + iGCP*4, 4 );
     249               0 :         pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001;
     250                 : 
     251               0 :         memcpy( &unValue, abyRecord + 279 + 132 + iGCP*4, 4 );
     252               0 :         pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001;
     253                 : 
     254               0 :         pasGCPList[nGCPCount].dfGCPZ = 0.0;
     255                 : 
     256               0 :         pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5;
     257               0 :         pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5;
     258                 :             
     259               0 :         nGCPCount++;
     260                 :     }
     261                 : }
     262                 : 
     263                 : /************************************************************************/
     264                 : /*                         ScanForGCPs_MERIS()                          */
     265                 : /************************************************************************/
     266                 : 
     267               0 : void EnvisatDataset::ScanForGCPs_MERIS()
     268                 : 
     269                 : {
     270                 :     int   nDatasetIndex, nNumDSR, nDSRSize, iRecord;
     271                 : 
     272                 : /* -------------------------------------------------------------------- */
     273                 : /*      Do we have a meaningful geolocation grid?  Seach for a          */
     274                 : /*      DS_TYPE=A and a name containing "geolocation" or "tie           */
     275                 : /*      points".                                                        */
     276                 : /* -------------------------------------------------------------------- */
     277                 :     nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, 
     278               0 :                                                  "Tie points ADS" );
     279               0 :     if( nDatasetIndex == -1 )
     280               0 :         return;
     281                 : 
     282               0 :     if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, 
     283                 :                                     NULL, NULL, NULL, NULL, NULL, 
     284                 :                                     &nNumDSR, &nDSRSize ) != SUCCESS )
     285               0 :         return;
     286                 : 
     287               0 :     if( nNumDSR == 0 )
     288               0 :         return;
     289                 : 
     290                 : /* -------------------------------------------------------------------- */
     291                 : /*      Figure out the tiepoint space, and how many we have.            */
     292                 : /* -------------------------------------------------------------------- */
     293                 :     int  nLinesPerTiePoint, nSamplesPerTiePoint;
     294               0 :     int  nTPPerLine, nTPPerColumn = nNumDSR;
     295                 : 
     296               0 :     if( nNumDSR == 0 )
     297               0 :         return;
     298                 : 
     299                 :     nLinesPerTiePoint = 
     300                 :         EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, 
     301               0 :                                       "LINES_PER_TIE_PT", 0 );
     302                 :     nSamplesPerTiePoint =
     303                 :         EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, 
     304               0 :                                       "SAMPLES_PER_TIE_PT", 0 );
     305                 : 
     306               0 :     if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 )
     307               0 :         return;
     308                 : 
     309                 :     nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1) 
     310               0 :         / nSamplesPerTiePoint;
     311                 : 
     312               0 :     if( (GetRasterXSize() + nSamplesPerTiePoint - 1) 
     313                 :         / nSamplesPerTiePoint  != nTPPerColumn )
     314                 :     {
     315                 :         CPLDebug( "EnvisatDataset", "Got %d instead of %d nTPPerColumn.", 
     316                 :                   (GetRasterXSize()+nSamplesPerTiePoint-1)/nSamplesPerTiePoint,
     317               0 :                   nTPPerColumn );
     318               0 :         return;
     319                 :     }
     320                 : 
     321               0 :     if( 50*nTPPerLine + 13 != nDSRSize )
     322                 :     {
     323                 :         CPLDebug( "EnvisatDataset", 
     324                 :                   "DSRSize=%d instead of expected %d for tiepoints ADS.", 
     325               0 :                   nDSRSize, 50*nTPPerLine + 13 );
     326               0 :         return;
     327                 :     }
     328                 : 
     329                 : /* -------------------------------------------------------------------- */
     330                 : /*      Collect the first GCP set from each record.     */
     331                 : /* -------------------------------------------------------------------- */
     332               0 :     GByte *pabyRecord = (GByte *) CPLMalloc(nDSRSize);
     333                 :     int   iGCP;
     334                 :     GUInt32   unValue;
     335                 : 
     336               0 :     nGCPCount = 0;
     337                 :     pasGCPList = (GDAL_GCP *) 
     338               0 :         CPLCalloc(sizeof(GDAL_GCP),nNumDSR * nTPPerLine);
     339                 : 
     340               0 :     for( iRecord = 0; iRecord < nNumDSR; iRecord++ )
     341                 :     {
     342               0 :         if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex, 
     343                 :                                            iRecord, pabyRecord ) != SUCCESS )
     344               0 :             continue;
     345                 : 
     346               0 :         memcpy( &unValue, pabyRecord + 13, 4 );
     347                 : 
     348               0 :         for( iGCP = 0; iGCP < nTPPerLine; iGCP++ )
     349                 :         {
     350                 :             char  szId[128];
     351                 : 
     352               0 :             GDALInitGCPs( 1, pasGCPList + nGCPCount );
     353                 : 
     354               0 :             CPLFree( pasGCPList[nGCPCount].pszId );
     355                 :             
     356               0 :             sprintf( szId, "%d", nGCPCount+1 );
     357               0 :             pasGCPList[nGCPCount].pszId = CPLStrdup( szId );
     358                 : 
     359               0 :             memcpy( &unValue, pabyRecord + 13 + nTPPerLine*4 + iGCP*4, 4 );
     360                 :             pasGCPList[nGCPCount].dfGCPX = 
     361               0 :                 ((int)CPL_MSBWORD32(unValue))*0.000001;
     362                 : 
     363               0 :             memcpy( &unValue, pabyRecord + 13 + iGCP*4, 4 );
     364                 :             pasGCPList[nGCPCount].dfGCPY = 
     365               0 :                 ((int)CPL_MSBWORD32(unValue))*0.000001;
     366                 : 
     367               0 :             pasGCPList[nGCPCount].dfGCPZ = 0.0;
     368                 : 
     369               0 :             pasGCPList[nGCPCount].dfGCPLine = iRecord*nLinesPerTiePoint + 0.5;
     370               0 :             pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5;
     371                 :             
     372               0 :             nGCPCount++;
     373                 :         }
     374                 :     }
     375               0 :     CPLFree( pabyRecord );
     376                 : }
     377                 : 
     378                 : /************************************************************************/
     379                 : /*                            GetMetadata()                             */
     380                 : /************************************************************************/
     381                 : 
     382               0 : char **EnvisatDataset::GetMetadata( const char * pszDomain )
     383                 : 
     384                 : {
     385               0 :     if( pszDomain == NULL || !EQUALN(pszDomain,"envisat-ds-",11) )
     386               0 :         return GDALDataset::GetMetadata( pszDomain );
     387                 : 
     388                 : /* -------------------------------------------------------------------- */
     389                 : /*      Get the dataset name and record number.                         */
     390                 : /* -------------------------------------------------------------------- */
     391                 :     char  szDSName[128];
     392               0 :     int         i, nRecord = -1;
     393                 : 
     394               0 :     strncpy( szDSName, pszDomain+11, sizeof(szDSName) );
     395               0 :     for( i = 0; i < (int) sizeof(szDSName)-1; i++ )
     396                 :     {
     397               0 :         if( szDSName[i] == '-' )
     398                 :         {
     399               0 :             szDSName[i] = '\0';
     400               0 :             nRecord = atoi(szDSName+1);
     401               0 :             break;
     402                 :         }
     403                 :     }
     404                 : 
     405               0 :     if( nRecord == -1 )
     406               0 :         return NULL;
     407                 : 
     408                 : /* -------------------------------------------------------------------- */
     409                 : /*      Get the dataset index and info.                                 */
     410                 : /* -------------------------------------------------------------------- */
     411               0 :     int nDSIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, szDSName );
     412                 :     int nDSRSize, nNumDSR;
     413                 : 
     414               0 :     if( nDSIndex == -1 )
     415               0 :         return NULL;
     416                 : 
     417                 :     EnvisatFile_GetDatasetInfo( hEnvisatFile, nDSIndex, NULL, NULL, NULL,
     418               0 :                                 NULL, NULL, &nNumDSR, &nDSRSize );
     419                 : 
     420               0 :     if( nDSRSize == -1 || nRecord < 0 || nRecord >= nNumDSR )
     421               0 :         return NULL;
     422                 : 
     423                 : /* -------------------------------------------------------------------- */
     424                 : /*      Read the requested record.                                      */
     425                 : /* -------------------------------------------------------------------- */
     426                 :     char  *pszRecord;
     427                 : 
     428               0 :     pszRecord = (char *) CPLMalloc(nDSRSize+1);
     429                 :     
     430               0 :     if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDSIndex, nRecord, 
     431                 :                                        pszRecord ) == FAILURE )
     432                 :     {
     433               0 :         CPLFree( pszRecord );
     434               0 :         return NULL;
     435                 :     }
     436                 : 
     437                 : /* -------------------------------------------------------------------- */
     438                 : /*      Massage the data into a safe textual format.  For now we        */
     439                 : /*      just turn zero bytes into spaces.                               */
     440                 : /* -------------------------------------------------------------------- */
     441                 :     char *pszEscapedRecord;
     442                 : 
     443               0 :     CSLDestroy( papszTempMD );
     444                 : 
     445                 :     pszEscapedRecord = CPLEscapeString( pszRecord, nDSRSize, 
     446               0 :                                         CPLES_BackslashQuotable );
     447               0 :     papszTempMD = CSLSetNameValue( NULL, "EscapedRecord", pszEscapedRecord );
     448               0 :     CPLFree( pszEscapedRecord );
     449                 : 
     450               0 :     for( i = 0; i < nDSRSize; i++ )
     451               0 :         if( pszRecord[i] == '\0' )
     452               0 :             pszRecord[i] = ' ';
     453                 : 
     454               0 :     papszTempMD = CSLSetNameValue( papszTempMD, "RawRecord", pszRecord );
     455                 : 
     456               0 :     CPLFree( pszRecord );
     457                 : 
     458               0 :     return papszTempMD;
     459                 : }
     460                 : 
     461                 : /************************************************************************/
     462                 : /*                         CollectDSDMetadata()                         */
     463                 : /*                                                                      */
     464                 : /*      Collect metadata based on any DSD entries with filenames        */
     465                 : /*      associated.                                                     */
     466                 : /************************************************************************/
     467                 : 
     468               0 : void EnvisatDataset::CollectDSDMetadata()
     469                 : 
     470                 : {
     471                 :     char  *pszDSName, *pszFilename;
     472                 :     int   iDSD;
     473                 : 
     474               0 :     for( iDSD = 0; 
     475                 :          EnvisatFile_GetDatasetInfo( hEnvisatFile, iDSD, &pszDSName, NULL, 
     476                 :                              &pszFilename, NULL, NULL, NULL, NULL ) == SUCCESS;
     477                 :          iDSD++ )
     478                 :     {
     479               0 :         if( pszFilename == NULL 
     480                 :             || strlen(pszFilename) == 0 
     481                 :             || EQUALN(pszFilename,"NOT USED",8)
     482                 :             || EQUALN(pszFilename,"        ",8))
     483               0 :             continue;
     484                 : 
     485                 :         char  szKey[128], szTrimmedName[128];
     486                 :         int i;
     487                 :         
     488               0 :         strcpy( szKey, "DS_" );
     489               0 :         strcat( szKey, pszDSName );
     490                 : 
     491                 :         // strip trailing spaces. 
     492               0 :         for( i = strlen(szKey)-1; i && szKey[i] == ' '; i-- )
     493               0 :             szKey[i] = '\0';
     494                 : 
     495                 :         // convert spaces into underscores.
     496               0 :         for( i = 0; szKey[i] != '\0'; i++ )
     497                 :         {
     498               0 :             if( szKey[i] == ' ' )
     499               0 :                 szKey[i] = '_';
     500                 :         }
     501                 : 
     502               0 :         strcat( szKey, "_NAME" );
     503                 : 
     504               0 :         strcpy( szTrimmedName, pszFilename );
     505               0 :         for( i = strlen(szTrimmedName)-1; i && szTrimmedName[i] == ' '; i--)
     506               0 :             szTrimmedName[i] = '\0';
     507                 : 
     508               0 :         SetMetadataItem( szKey, szTrimmedName );
     509                 :     }
     510               0 : }
     511                 : 
     512                 : /************************************************************************/
     513                 : /*                          CollectMetadata()                           */
     514                 : /*                                                                      */
     515                 : /*      Collect metadata from the SPH or MPH header fields.             */
     516                 : /************************************************************************/
     517                 : 
     518               0 : void EnvisatDataset::CollectMetadata( EnvisatFile_HeaderFlag  eMPHOrSPH )
     519                 : 
     520                 : {
     521                 :     int   iKey;
     522                 :     
     523               0 :     for( iKey = 0; TRUE; iKey++ )
     524                 :     {
     525                 :         const char *pszValue, *pszKey;
     526                 :         char  szHeaderKey[128];
     527                 : 
     528               0 :         pszKey = EnvisatFile_GetKeyByIndex(hEnvisatFile, eMPHOrSPH, iKey);
     529               0 :         if( pszKey == NULL )
     530               0 :             break;
     531                 : 
     532                 :         pszValue = EnvisatFile_GetKeyValueAsString( hEnvisatFile, eMPHOrSPH,
     533               0 :                                                     pszKey, NULL );
     534                 : 
     535               0 :         if( pszValue == NULL )
     536               0 :             continue;
     537                 : 
     538                 :         // skip some uninteresting structural information.
     539               0 :         if( EQUAL(pszKey,"TOT_SIZE")
     540                 :             || EQUAL(pszKey,"SPH_SIZE")
     541                 :             || EQUAL(pszKey,"NUM_DSD")
     542                 :             || EQUAL(pszKey,"DSD_SIZE")
     543                 :             || EQUAL(pszKey,"NUM_DATA_SETS") )
     544               0 :             continue;
     545                 : 
     546               0 :         if( eMPHOrSPH == MPH )
     547               0 :             sprintf( szHeaderKey, "MPH_%s", pszKey );
     548                 :         else
     549               0 :             sprintf( szHeaderKey, "SPH_%s", pszKey );
     550                 : 
     551               0 :         SetMetadataItem( szHeaderKey, pszValue );
     552                 :     }
     553               0 : }
     554                 : 
     555                 : /************************************************************************/
     556                 : /*                                Open()                                */
     557                 : /************************************************************************/
     558                 : 
     559           11013 : GDALDataset *EnvisatDataset::Open( GDALOpenInfo * poOpenInfo )
     560                 : 
     561                 : {
     562                 :     EnvisatFile *hEnvisatFile;
     563                 :     
     564                 : /* -------------------------------------------------------------------- */
     565                 : /*      Check the header.                                               */
     566                 : /* -------------------------------------------------------------------- */
     567           11013 :     if( poOpenInfo->nHeaderBytes < 8 || poOpenInfo->fp == NULL )
     568            9800 :         return NULL;
     569                 : 
     570            1213 :     if( !EQUALN((const char *) poOpenInfo->pabyHeader, "PRODUCT=",8) )
     571            1213 :         return NULL;
     572                 : 
     573                 : /* -------------------------------------------------------------------- */
     574                 : /*      Try opening the dataset.                                        */
     575                 : /* -------------------------------------------------------------------- */
     576                 :     int   ds_index;
     577                 : 
     578               0 :     if( EnvisatFile_Open( &hEnvisatFile, poOpenInfo->pszFilename, "r" ) 
     579                 :         == FAILURE )
     580               0 :         return NULL;
     581                 : 
     582                 : /* -------------------------------------------------------------------- */
     583                 : /*      Find a Mesurement type dataset to use as our reference          */
     584                 : /*      raster band.                                                    */
     585                 : /* -------------------------------------------------------------------- */
     586                 :     int   dsr_size, num_dsr, ds_offset, bNative;
     587                 :     char        *pszDSType;
     588                 : 
     589               0 :     for( ds_index = 0; TRUE; ds_index++ )
     590                 :     {
     591               0 :         if( EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index, 
     592                 :                                         NULL, &pszDSType, NULL, 
     593                 :                                         &ds_offset, NULL, 
     594                 :                                         &num_dsr, &dsr_size ) == FAILURE )
     595                 :         {
     596                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     597               0 :                       "Unable to find \"MDS1\" measurement datatset in Envisat file." );
     598               0 :             EnvisatFile_Close( hEnvisatFile );
     599               0 :             return NULL;
     600                 :         }
     601                 : 
     602                 :         /* Have we found what we are looking for?  A Measurement ds. */
     603               0 :         if( EQUAL(pszDSType,"M") )
     604               0 :             break;
     605                 :     }
     606                 :     
     607                 : /* -------------------------------------------------------------------- */
     608                 : /*      Confirm the requested access is supported.                      */
     609                 : /* -------------------------------------------------------------------- */
     610               0 :     if( poOpenInfo->eAccess == GA_Update )
     611                 :     {
     612               0 :         EnvisatFile_Close( hEnvisatFile );
     613                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     614                 :                   "The ENVISAT driver does not support update access to existing"
     615               0 :                   " datasets.\n" );
     616               0 :         return NULL;
     617                 :     }
     618                 : /* -------------------------------------------------------------------- */
     619                 : /*      Create a corresponding GDALDataset.                             */
     620                 : /* -------------------------------------------------------------------- */
     621                 :     EnvisatDataset  *poDS;
     622                 : 
     623               0 :     poDS = new EnvisatDataset();
     624                 : 
     625               0 :     poDS->hEnvisatFile = hEnvisatFile;
     626                 : 
     627                 : /* -------------------------------------------------------------------- */
     628                 : /*      Setup image definition.                                         */
     629                 : /* -------------------------------------------------------------------- */
     630                 :     const char  *pszDataType, *pszSampleType, *pszProduct;
     631                 :     GDALDataType eDataType;
     632                 :     int          nPrefixBytes;
     633                 : 
     634                 :     EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index, 
     635                 :                                 NULL, NULL, NULL, &ds_offset, NULL, 
     636               0 :                                 &num_dsr, &dsr_size );
     637                 : 
     638                 :     poDS->nRasterXSize = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
     639               0 :                                                        "LINE_LENGTH", 0 );
     640               0 :     poDS->nRasterYSize = num_dsr;
     641               0 :     poDS->eAccess = GA_ReadOnly;
     642                 : 
     643                 :     pszProduct = EnvisatFile_GetKeyValueAsString( hEnvisatFile, MPH,
     644               0 :                                                   "PRODUCT", "" );
     645                 :     pszDataType = EnvisatFile_GetKeyValueAsString( hEnvisatFile, SPH, 
     646               0 :                                                    "DATA_TYPE", "" );
     647                 :     pszSampleType = EnvisatFile_GetKeyValueAsString( hEnvisatFile, SPH, 
     648               0 :                                                      "SAMPLE_TYPE", "" );
     649               0 :     if( EQUAL(pszDataType,"FLT32") && EQUALN(pszSampleType,"COMPLEX",7))
     650               0 :         eDataType = GDT_CFloat32;
     651               0 :     else if( EQUAL(pszDataType,"FLT32") )
     652               0 :         eDataType = GDT_Float32;
     653               0 :     else if( EQUAL(pszDataType,"UWORD") )
     654               0 :         eDataType = GDT_UInt16;
     655               0 :     else if( EQUAL(pszDataType,"SWORD") && EQUALN(pszSampleType,"COMPLEX",7) )
     656               0 :         eDataType = GDT_CInt16;
     657               0 :     else if( EQUAL(pszDataType,"SWORD") )
     658               0 :         eDataType = GDT_Int16;
     659               0 :     else if( EQUALN(pszProduct,"ATS_TOA_1",8) )
     660                 :     {
     661                 :         /* all 16bit data, no line length provided */
     662               0 :         eDataType = GDT_Int16;
     663               0 :         poDS->nRasterXSize = (dsr_size - 20) / 2;
     664                 :     }
     665               0 :     else if( poDS->nRasterXSize == 0 )
     666                 :     {
     667                 :         CPLError( CE_Warning, CPLE_AppDefined,
     668                 :                   "Envisat product format not recognised.  Assuming 8bit\n"
     669               0 :                   "with no per-record prefix data.  Results may be useless!" );
     670               0 :         eDataType = GDT_Byte;
     671               0 :         poDS->nRasterXSize = dsr_size;
     672                 :     }
     673                 :     else
     674                 :     {
     675               0 :         if( dsr_size >= 2 * poDS->nRasterXSize )
     676               0 :             eDataType = GDT_UInt16;
     677                 :         else
     678               0 :             eDataType = GDT_Byte;
     679                 :     }
     680                 : 
     681                 : #ifdef CPL_LSB 
     682               0 :     bNative = FALSE;
     683                 : #else
     684                 :     bNative = TRUE;
     685                 : #endif
     686                 : 
     687                 :     nPrefixBytes = dsr_size - 
     688               0 :         ((GDALGetDataTypeSize(eDataType) / 8) * poDS->nRasterXSize);
     689                 : 
     690                 : /* -------------------------------------------------------------------- */
     691                 : /*      Fail out if we didn't get non-zero sizes.                       */
     692                 : /* -------------------------------------------------------------------- */
     693               0 :     if( poDS->nRasterXSize < 1 || poDS->nRasterYSize < 1 )
     694                 :     {
     695                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     696                 :                   "Unable to determine organization of dataset.  It would\n"
     697                 :                   "appear this is an Envisat dataset, but an unsupported\n"
     698               0 :                   "data product.  Unable to utilize." );
     699               0 :         delete poDS;
     700               0 :         return NULL;
     701                 :     }
     702                 : 
     703                 : /* -------------------------------------------------------------------- */
     704                 : /*      Assume ownership of the file handled from the GDALOpenInfo.     */
     705                 : /* -------------------------------------------------------------------- */
     706               0 :     poDS->fpImage = poOpenInfo->fp;
     707               0 :     poOpenInfo->fp = NULL;
     708                 : 
     709                 : /* -------------------------------------------------------------------- */
     710                 : /*      Try to collect GCPs.                                            */
     711                 : /* -------------------------------------------------------------------- */
     712                 : 
     713                 : /* -------------------------------------------------------------------- */
     714                 : /*      Scan for all datasets matching the reference dataset.           */
     715                 : /* -------------------------------------------------------------------- */
     716               0 :     int num_dsr2, dsr_size2, iBand = 0;
     717                 :     const char *pszDSName;
     718                 : 
     719               0 :     for( ds_index = 0; 
     720                 :          EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index, 
     721                 :                                      (char **) &pszDSName, NULL, NULL, 
     722                 :                                      &ds_offset, NULL, 
     723                 :                                      &num_dsr2, &dsr_size2 ) == SUCCESS;
     724                 :          ds_index++ )
     725                 :     {
     726               0 :         if( EQUAL(pszDSType,"M") 
     727                 :             && num_dsr2 == num_dsr && dsr_size2 == dsr_size )
     728                 :         {
     729                 :             poDS->SetBand( iBand+1,
     730                 :                        new RawRasterBand( poDS, iBand+1, poDS->fpImage,
     731                 :                                           ds_offset + nPrefixBytes,
     732                 :                                           GDALGetDataTypeSize(eDataType) / 8, 
     733                 :                                           dsr_size, 
     734               0 :                                           eDataType, bNative ) );
     735               0 :             iBand++;
     736                 : 
     737               0 :             poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
     738                 :         }
     739                 :     }
     740                 :     
     741                 : /* -------------------------------------------------------------------- */
     742                 : /*      Collect metadata.                                               */
     743                 : /* -------------------------------------------------------------------- */
     744               0 :     poDS->CollectMetadata( MPH );
     745               0 :     poDS->CollectMetadata( SPH );
     746               0 :     poDS->CollectDSDMetadata();
     747                 : 
     748               0 :     if( EQUALN(pszProduct,"MER",3) )
     749               0 :         poDS->ScanForGCPs_MERIS();
     750                 :     else
     751               0 :         poDS->ScanForGCPs_ASAR();
     752                 : 
     753                 : /* -------------------------------------------------------------------- */
     754                 : /*      Initialize any PAM information.                                 */
     755                 : /* -------------------------------------------------------------------- */
     756               0 :     poDS->SetDescription( poOpenInfo->pszFilename );
     757               0 :     poDS->TryLoadXML();
     758                 : 
     759                 : /* -------------------------------------------------------------------- */
     760                 : /*      Check for overviews.                                            */
     761                 : /* -------------------------------------------------------------------- */
     762               0 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     763                 : 
     764               0 :     return( poDS );
     765                 : }
     766                 : 
     767                 : /************************************************************************/
     768                 : /*                         GDALRegister_Envisat()                       */
     769                 : /************************************************************************/
     770                 : 
     771             409 : void GDALRegister_Envisat()
     772                 : 
     773                 : {
     774                 :     GDALDriver  *poDriver;
     775                 : 
     776             409 :     if( GDALGetDriverByName( "ESAT" ) == NULL )
     777                 :     {
     778             392 :         poDriver = new GDALDriver();
     779                 :         
     780             392 :         poDriver->SetDescription( "ESAT" );
     781                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     782             392 :                                    "Envisat Image Format" );
     783                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     784             392 :                                    "frmt_various.html#Envisat" );
     785             392 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "n1" );
     786                 : 
     787             392 :         poDriver->pfnOpen = EnvisatDataset::Open;
     788                 : 
     789             392 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     790                 :     }
     791             409 : }
     792                 : 

Generated by: LTP GCOV extension version 1.5