LCOV - code coverage report
Current view: directory - frmts/airsar - airsardataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 217 14 6.5 %
Date: 2012-04-28 Functions: 15 2 13.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: airsardataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       3                 :  *
       4                 :  * Project:  AirSAR Reader
       5                 :  * Purpose:  Implements read support for AirSAR Polarimetric data.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
      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 "gdal_pam.h"
      31                 : #include "cpl_string.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_vsi.h"
      34                 : 
      35                 : CPL_CVSID("$Id: airsardataset.cpp 17664 2009-09-21 21:16:45Z rouault $");
      36                 : 
      37                 : CPL_C_START
      38                 : void  GDALRegister_AirSAR(void);
      39                 : CPL_C_END
      40                 : 
      41                 : /************************************************************************/
      42                 : /* ==================================================================== */
      43                 : /*        AirSARDataset       */
      44                 : /* ==================================================================== */
      45                 : /************************************************************************/
      46                 : 
      47                 : class AirSARRasterBand;
      48                 : 
      49                 : class AirSARDataset : public GDALPamDataset
      50                 : {
      51                 :     friend class AirSARRasterBand;
      52                 : 
      53                 :     FILE  *fp;
      54                 : 
      55                 :     int         nLoadedLine;
      56                 :     GByte       *pabyCompressedLine;
      57                 :     double      *padfMatrix;
      58                 : 
      59                 :     int         nDataStart;
      60                 :     int         nRecordLength;
      61                 : 
      62                 :     CPLErr      LoadLine(int iLine);
      63                 : 
      64                 :     static char  **ReadHeader( FILE * fp, int nFileOffset, 
      65                 :                                const char *pszPrefix, int nMaxLines );
      66                 : 
      67                 :   public:
      68                 :                 AirSARDataset();
      69                 :     ~AirSARDataset();
      70                 :     
      71                 :     static GDALDataset *Open( GDALOpenInfo * );
      72                 : };
      73                 : 
      74                 : /************************************************************************/
      75                 : /* ==================================================================== */
      76                 : /*                            AirSARRasterBand                          */
      77                 : /* ==================================================================== */
      78                 : /************************************************************************/
      79                 : 
      80                 : class AirSARRasterBand : public GDALPamRasterBand
      81                 : {
      82                 :   public:
      83                 :         AirSARRasterBand( AirSARDataset *, int );
      84                 :     virtual     ~AirSARRasterBand();
      85                 :     
      86                 :     virtual CPLErr IReadBlock( int, int, void * );
      87                 : };
      88                 : 
      89                 : /* locations of stokes matrix values within padfMatrix ... same order as they
      90                 :    are computed in the document. */
      91                 : 
      92                 : #define M11 0
      93                 : #define M12 1
      94                 : #define M13 2
      95                 : #define M14 3
      96                 : #define M23 4
      97                 : #define M24 5
      98                 : #define M33 6
      99                 : #define M34 7
     100                 : #define M44 8
     101                 : #define M22 9
     102                 : 
     103                 : /************************************************************************/
     104                 : /*                          AirSARRasterBand()                          */
     105                 : /************************************************************************/
     106                 : 
     107               0 : AirSARRasterBand::AirSARRasterBand( AirSARDataset *poDS,
     108               0 :                                     int nBand )
     109                 : 
     110                 : {
     111               0 :     this->poDS = poDS;
     112               0 :     this->nBand = nBand;
     113                 : 
     114               0 :     nBlockXSize = poDS->GetRasterXSize();
     115               0 :     nBlockYSize = 1;
     116                 : 
     117               0 :     if( this->nBand == 2 || this->nBand == 3 || this->nBand == 5 )
     118               0 :         eDataType = GDT_CFloat32;
     119                 :     else
     120               0 :         eDataType = GDT_Float32;
     121                 : 
     122               0 :     switch( nBand )
     123                 :     {
     124                 :       case 1:
     125               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "Covariance_11" );
     126               0 :         SetDescription( "Covariance_11" );
     127               0 :         eDataType = GDT_CFloat32;
     128               0 :         break;
     129                 : 
     130                 :       case 2:
     131               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "Covariance_12" );
     132               0 :         SetDescription( "Covariance_12" );
     133               0 :         eDataType = GDT_CFloat32;
     134               0 :         break;
     135                 : 
     136                 :       case 3:
     137               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "Covariance_13" );
     138               0 :         SetDescription( "Covariance_13" );
     139               0 :         eDataType = GDT_CFloat32;
     140               0 :         break;
     141                 : 
     142                 :       case 4:
     143               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "Covariance_22" );
     144               0 :         SetDescription( "Covariance_22" );
     145               0 :         eDataType = GDT_CFloat32;
     146               0 :         break;
     147                 : 
     148                 :       case 5:
     149               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "Covariance_23" );
     150               0 :         SetDescription( "Covariance_23" );
     151               0 :         eDataType = GDT_CFloat32;
     152               0 :         break;
     153                 : 
     154                 :       case 6:
     155               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "Covariance_33" );
     156               0 :         SetDescription( "Covariance_33" );
     157               0 :         eDataType = GDT_CFloat32;
     158                 :         break;
     159                 :     }
     160               0 : }
     161                 : 
     162                 : /************************************************************************/
     163                 : /*                         ~AirSARRasterBand()                          */
     164                 : /************************************************************************/
     165                 : 
     166               0 : AirSARRasterBand::~AirSARRasterBand()
     167                 : 
     168                 : {
     169               0 : }
     170                 : 
     171                 : /************************************************************************/
     172                 : /*                             IReadBlock()                             */
     173                 : /************************************************************************/
     174                 : 
     175               0 : CPLErr AirSARRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     176                 :                                       void * pImage )
     177                 : 
     178                 : {
     179                 :     CPLErr eErr;
     180               0 :     float *pafLine = (float *) pImage;
     181                 :     int iPixel;
     182                 :     double *padfMatrix;
     183                 : 
     184               0 :     eErr = ((AirSARDataset *)poDS)->LoadLine( nBlockYOff );
     185               0 :     if( eErr != CE_None )
     186               0 :         return eErr;
     187                 : 
     188               0 :     padfMatrix = ((AirSARDataset *) poDS)->padfMatrix;
     189                 : 
     190                 : #define SQRT_2 1.4142135623730951
     191                 : 
     192               0 :     if( nBand == 1 ) /* C11 */
     193                 :     {
     194               0 :         for( iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     195                 :         {
     196               0 :             double *m = padfMatrix + 10 * iPixel;
     197                 : 
     198               0 :             pafLine[iPixel*2+0] = (float)(m[M11] + m[M22] + 2 * m[M12]);
     199               0 :             pafLine[iPixel*2+1] = 0.0;
     200                 :         }
     201                 :     }
     202               0 :     else if( nBand == 2 ) /* C12 */
     203                 :     {
     204               0 :         for( iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     205                 :         {
     206               0 :             double *m = padfMatrix + 10 * iPixel;
     207                 :             
     208                 :             // real
     209               0 :             pafLine[iPixel*2 + 0] = (float)(SQRT_2 * (m[M13] + m[M23]));
     210                 : 
     211                 :             // imaginary
     212               0 :             pafLine[iPixel*2 + 1] = (float)(- SQRT_2 * (m[M24] + m[M14]));
     213                 :         }
     214                 :     }
     215               0 :     else if( nBand == 3 ) /* C13 */
     216                 :     {
     217               0 :         for( iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     218                 :         {
     219               0 :             double *m = padfMatrix + 10 * iPixel;
     220                 :             
     221                 :             // real
     222               0 :             pafLine[iPixel*2 + 0] = (float)(2*m[M33] + m[M22] - m[M11]);
     223                 : 
     224                 :             // imaginary
     225               0 :             pafLine[iPixel*2 + 1] = (float)(-2 * m[M34]);
     226                 :         }
     227                 :     }
     228               0 :     else if( nBand == 4 ) /* C22 */
     229                 :     {
     230               0 :         for( iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     231                 :         {
     232               0 :             double *m = padfMatrix + 10 * iPixel;
     233                 :             
     234               0 :             pafLine[iPixel*2+0] = (float)(2 * (m[M11] - m[M22]));
     235               0 :             pafLine[iPixel*2+1] = 0.0;
     236                 :         }
     237                 :     }
     238               0 :     else if( nBand == 5 ) /* C23 */
     239                 :     {
     240               0 :         for( iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     241                 :         {
     242               0 :             double *m = padfMatrix + 10 * iPixel;
     243                 :             
     244                 :             // real
     245               0 :             pafLine[iPixel*2 + 0] = (float)(SQRT_2 * (m[M13] - m[M23]));
     246                 : 
     247                 :             // imaginary
     248               0 :             pafLine[iPixel*2 + 1] = (float)(SQRT_2 * (m[M23] - m[M14]));
     249                 :         }
     250                 :     }
     251               0 :     else if( nBand == 6 ) /* C33 */
     252                 :     {
     253               0 :         for( iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     254                 :         {
     255               0 :             double *m = padfMatrix + 10 * iPixel;
     256                 :             
     257               0 :             pafLine[iPixel*2+0] = (float)(m[M11] + m[M22] - 2 * m[M12]);
     258               0 :             pafLine[iPixel*2+1] = 0.0;
     259                 :         }
     260                 :     }
     261                 : 
     262               0 :     return CE_None;
     263                 : }
     264                 : 
     265                 : /************************************************************************/
     266                 : /* ==================================================================== */
     267                 : /*        AirSARDataset       */
     268                 : /* ==================================================================== */
     269                 : /************************************************************************/
     270                 : 
     271                 : /************************************************************************/
     272                 : /*                           AirSARDataset()                            */
     273                 : /************************************************************************/
     274                 : 
     275               0 : AirSARDataset::AirSARDataset()
     276                 : 
     277                 : {
     278               0 :     fp = NULL;
     279                 : 
     280               0 :     nLoadedLine = -1;
     281               0 :     pabyCompressedLine = NULL;
     282               0 :     padfMatrix = NULL;
     283               0 : }
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                           ~AirSARDataset()                           */
     287                 : /************************************************************************/
     288                 : 
     289               0 : AirSARDataset::~AirSARDataset()
     290                 : 
     291                 : {
     292               0 :     FlushCache();
     293               0 :     if( pabyCompressedLine != NULL )
     294                 :     {
     295               0 :         CPLFree( pabyCompressedLine );
     296               0 :         CPLFree( padfMatrix );
     297                 :     }
     298                 : 
     299               0 :     if( fp != NULL )
     300                 :     {
     301               0 :         VSIFClose( fp );
     302               0 :         fp = NULL;
     303                 :     }
     304               0 : }
     305                 : 
     306                 : /************************************************************************/
     307                 : /*                              LoadLine()                              */
     308                 : /************************************************************************/
     309                 : 
     310               0 : CPLErr AirSARDataset::LoadLine( int iLine )
     311                 : 
     312                 : {
     313               0 :     if( iLine == nLoadedLine )
     314               0 :         return CE_None;
     315                 : 
     316                 : /* -------------------------------------------------------------------- */
     317                 : /*      allocate working buffers if we don't have them already.         */
     318                 : /* -------------------------------------------------------------------- */
     319               0 :     if( pabyCompressedLine == NULL )
     320                 :     {
     321               0 :         pabyCompressedLine = (GByte *) VSIMalloc2(nRasterXSize, 10);
     322                 : 
     323               0 :         padfMatrix = (double *) VSIMalloc2(10* sizeof(double), nRasterXSize);
     324               0 :         if (pabyCompressedLine == NULL ||
     325                 :             padfMatrix == NULL)
     326                 :         {
     327                 :             CPLError(CE_Failure, CPLE_OutOfMemory,
     328                 :                      "AirSARDataset::LoadLine : Out of memory. "
     329                 :                      "Probably due to corrupted dataset (nRasterXSize = %d)",
     330               0 :                      nRasterXSize);
     331               0 :             CPLFree (pabyCompressedLine);
     332               0 :             CPLFree (padfMatrix);
     333               0 :             return CE_Failure;
     334                 :         }
     335                 :     }
     336                 : 
     337               0 :     CPLAssert( nRecordLength == nRasterXSize * 10 );
     338                 : 
     339                 : /* -------------------------------------------------------------------- */
     340                 : /*      Load raw compressed data.                                       */
     341                 : /* -------------------------------------------------------------------- */
     342               0 :     if( VSIFSeek( fp, nDataStart + iLine * nRecordLength, SEEK_SET ) != 0 
     343                 :         || ((int) VSIFRead( pabyCompressedLine, 10, nRasterXSize, fp ))
     344                 :                  != nRasterXSize )
     345                 :     {
     346                 :         CPLError( CE_Failure, CPLE_FileIO, 
     347                 :                   "Error reading %d bytes for line %d at offset %d.\n%s",
     348                 :                   nRasterXSize * 10, iLine, nDataStart + iLine * nRecordLength,
     349               0 :                   VSIStrerror( errno ) );
     350               0 :         return CE_Failure;
     351                 :     }
     352                 : 
     353                 : /* -------------------------------------------------------------------- */
     354                 : /*      Build stokes matrix                                             */
     355                 : /* -------------------------------------------------------------------- */
     356               0 :     for( int iPixel = 0; iPixel < nRasterXSize; iPixel++ )
     357                 :     {
     358               0 :         double *M = padfMatrix + 10 * iPixel;
     359               0 :         signed char *byte = (signed char *) pabyCompressedLine + 10*iPixel - 1;
     360               0 :         double gen_fac = 1.0; // should we have a general scale factor?
     361                 :         
     362               0 :         M[M11] = (byte[2] / 254.0 + 1.5) * pow(2.0,byte[1]) * gen_fac;
     363               0 :         M[M12] = byte[3] * M[M11] / 127.0;
     364               0 :         M[M13] = byte[4] * fabs((double) byte[4]) * M[M11] / (127*127);
     365               0 :         M[M14] = byte[5] * fabs((double) byte[5]) * M[M11] / (127*127);
     366               0 :         M[M23] = byte[6] * fabs((double) byte[6]) * M[M11] / (127*127);
     367               0 :         M[M24] = byte[7] * fabs((double) byte[7]) * M[M11] / (127*127);
     368               0 :         M[M33] = byte[8] * M[M11] / 127;
     369               0 :         M[M34] = byte[9] * M[M11] / 127;
     370               0 :         M[M44] = byte[10] * M[M11] / 127;
     371               0 :         M[M22] = M[M11] - M[M33] - M[M44];
     372                 :     }
     373                 : 
     374               0 :     return CE_None;
     375                 : }
     376                 : 
     377                 : /************************************************************************/
     378                 : /*                             ReadHeader()                             */
     379                 : /*                                                                      */
     380                 : /*      Read the AirSAR header.  We assume an equal sign seperates      */
     381                 : /*      the keyword name from the value.  If not, assume the last       */
     382                 : /*      "blank delimited" word is the value and everything else is a    */
     383                 : /*      keyword.                                                        */
     384                 : /*                                                                      */
     385                 : /*      The records are 50 characters each.  Read till we get an all    */
     386                 : /*      blank record or some zero bytes.                                */
     387                 : /************************************************************************/
     388                 : 
     389               0 : char ** AirSARDataset::ReadHeader( FILE * fp, int nFileOffset, 
     390                 :                                    const char *pszPrefix, int nMaxLines )
     391                 : 
     392                 : {
     393               0 :     char **papszHeadInfo = NULL;
     394                 :     char szLine[51];
     395                 :     int  iLine;
     396                 : 
     397               0 :     VSIFSeek( fp, nFileOffset, SEEK_SET );
     398                 : 
     399                 : /* ==================================================================== */
     400                 : /*      Loop collecting one line at a time.                             */
     401                 : /* ==================================================================== */
     402               0 :     for( iLine = 0; iLine < nMaxLines; iLine++ )
     403                 :     {
     404                 : /* -------------------------------------------------------------------- */
     405                 : /*      Read a 50 byte header record.                                   */
     406                 : /* -------------------------------------------------------------------- */
     407               0 :         if( VSIFRead( szLine, 1, 50, fp ) != 50 )
     408                 :         {
     409                 :             CPLError( CE_Failure, CPLE_FileIO,
     410               0 :                       "Read error collecting AirSAR header." );
     411               0 :             return NULL;
     412                 :         }
     413                 : 
     414               0 :         szLine[50] = '\0';
     415                 : 
     416                 : /* -------------------------------------------------------------------- */
     417                 : /*      Is it all spaces, or does it have a zero byte?                  */
     418                 : /* -------------------------------------------------------------------- */
     419               0 :         int bAllSpaces = TRUE;
     420               0 :         int bHasIllegalChars = FALSE;
     421                 :         int i;
     422                 : 
     423               0 :         for( i = 0; i < 50; i++ )
     424                 :         {
     425               0 :             if( szLine[i] == '\0' )
     426               0 :                 break;
     427                 : 
     428               0 :             if( szLine[i] != ' ' )
     429               0 :                 bAllSpaces = FALSE;
     430                 :             
     431               0 :             if( ((unsigned char *) szLine)[i] > 127 
     432               0 :                 || ((unsigned char *) szLine)[i] < 10 )
     433               0 :                 bHasIllegalChars = TRUE;
     434                 :         }
     435                 : 
     436               0 :         if( bAllSpaces || bHasIllegalChars )
     437               0 :             break;
     438                 : 
     439                 : /* -------------------------------------------------------------------- */
     440                 : /*      Find the pivot between the keyword name and value.              */
     441                 : /* -------------------------------------------------------------------- */
     442               0 :         int iPivot = -1;
     443                 : 
     444               0 :         for( i = 0; i < 50; i++ )
     445                 :         {
     446               0 :             if( szLine[i] == '=' )
     447                 :             {
     448               0 :                 iPivot = i;
     449               0 :                 break;
     450                 :             }
     451                 :         }
     452                 : 
     453                 :         // If no "=" found, split on first double white space
     454               0 :         if( iPivot == -1 )
     455                 :         {
     456               0 :             for( i = 48; i >= 0; i-- )
     457                 :             {
     458               0 :                 if( szLine[i] == ' ' && szLine[i+1] == ' ' )
     459                 :                 {
     460               0 :                     iPivot = i;
     461               0 :                     break;
     462                 :                 }
     463                 :             }
     464                 :         }
     465                 : 
     466               0 :         if( iPivot == -1 ) // Yikes!
     467                 :         {
     468                 :             CPLDebug( "AIRSAR", "No pivot in line `%s'.", 
     469               0 :                       szLine );
     470               0 :             CPLAssert( iPivot != -1 );
     471               0 :             break;
     472                 :         }
     473                 : 
     474                 : /* -------------------------------------------------------------------- */
     475                 : /*      Trace ahead to the first non-white space value character.       */
     476                 : /* -------------------------------------------------------------------- */
     477               0 :         int iValue = iPivot + 1;
     478                 : 
     479               0 :         while( iValue < 50 && szLine[iValue] == ' ' )
     480               0 :             iValue++;
     481                 : 
     482                 : /* -------------------------------------------------------------------- */
     483                 : /*      Strip any white space off the keyword.                          */
     484                 : /* -------------------------------------------------------------------- */
     485               0 :         int iKeyEnd = iPivot - 1;
     486                 :         
     487               0 :         while( iKeyEnd > 0 && szLine[iKeyEnd] == ' ' )
     488               0 :             iKeyEnd--;
     489                 : 
     490               0 :         szLine[iKeyEnd+1] = '\0';
     491                 : 
     492                 : /* -------------------------------------------------------------------- */
     493                 : /*      Convert spaces or colons into underscores in the key name.      */
     494                 : /* -------------------------------------------------------------------- */
     495               0 :         for( i = 0; szLine[i] != '\0'; i++ )
     496                 :         {
     497               0 :             if( szLine[i] == ' ' || szLine[i] == ':' || szLine[i] == ',' )
     498               0 :                 szLine[i] = '_';
     499                 :         }
     500                 : 
     501                 : /* -------------------------------------------------------------------- */
     502                 : /*      Prefix key name with provided prefix string.                    */
     503                 : /* -------------------------------------------------------------------- */
     504                 :         char szPrefixedKeyName[55];
     505                 : 
     506               0 :         sprintf( szPrefixedKeyName, "%s_%s", pszPrefix, szLine );
     507                 : 
     508                 :         papszHeadInfo = 
     509               0 :             CSLSetNameValue( papszHeadInfo, szPrefixedKeyName, szLine+iValue );
     510                 :         
     511                 :     }
     512                 : 
     513               0 :     return papszHeadInfo;
     514                 : }
     515                 : 
     516                 : 
     517                 : /************************************************************************/
     518                 : /*                                Open()                                */
     519                 : /************************************************************************/
     520                 : 
     521           25704 : GDALDataset *AirSARDataset::Open( GDALOpenInfo * poOpenInfo )
     522                 : 
     523                 : {
     524           25704 :     if( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 800 )
     525           23026 :         return NULL;
     526                 : 
     527                 : /* -------------------------------------------------------------------- */
     528                 : /*      Check for AirSAR/ keyword.                                      */
     529                 : /* -------------------------------------------------------------------- */
     530            2678 :     if( !EQUALN((char *) poOpenInfo->pabyHeader, "RECORD LENGTH IN BYTES",22) )
     531            2678 :         return NULL;
     532                 : 
     533               0 :     if( strstr((char *) poOpenInfo->pabyHeader, "COMPRESSED") == NULL 
     534                 :         || strstr((char *) poOpenInfo->pabyHeader, "JPL AIRCRAFT") == NULL )
     535               0 :         return NULL;
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      Parse the header fields.  We turn all the transform the         */
     539                 : /*      keywords by converting spaces to underscores so they will be    */
     540                 : /*      "well behaved" as metadata keywords.                            */
     541                 : /* -------------------------------------------------------------------- */
     542               0 :     char **papszMD = ReadHeader( poOpenInfo->fp, 0, "MH", 20 );
     543                 :     
     544               0 :     if( papszMD == NULL )
     545               0 :         return NULL;
     546                 : 
     547                 : /* -------------------------------------------------------------------- */
     548                 : /*      Confirm the requested access is supported.                      */
     549                 : /* -------------------------------------------------------------------- */
     550               0 :     if( poOpenInfo->eAccess == GA_Update )
     551                 :     {
     552                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     553                 :                   "The AIRSAR driver does not support update access to existing"
     554               0 :                   " datasets.\n" );
     555               0 :         return NULL;
     556                 :     }
     557                 : /* -------------------------------------------------------------------- */
     558                 : /*      Create a corresponding GDALDataset.                             */
     559                 : /* -------------------------------------------------------------------- */
     560                 :     AirSARDataset   *poDS;
     561                 : 
     562               0 :     poDS = new AirSARDataset();
     563                 : 
     564                 : /* -------------------------------------------------------------------- */
     565                 : /*      Extract some key information.                                   */
     566                 : /* -------------------------------------------------------------------- */
     567                 : 
     568                 :     poDS->nRasterXSize = 
     569               0 :         atoi(CSLFetchNameValue(papszMD,"MH_NUMBER_OF_SAMPLES_PER_RECORD"));
     570                 :     poDS->nRasterYSize = 
     571               0 :         atoi(CSLFetchNameValue(papszMD,"MH_NUMBER_OF_LINES_IN_IMAGE"));
     572                 : 
     573                 :     poDS->nRecordLength = atoi(
     574               0 :         CSLFetchNameValue( papszMD, "MH_RECORD_LENGTH_IN_BYTES" ) );
     575                 : 
     576                 :     poDS->nDataStart = atoi(
     577               0 :         CSLFetchNameValue( papszMD, "MH_BYTE_OFFSET_OF_FIRST_DATA_RECORD" ));
     578                 : 
     579                 : /* -------------------------------------------------------------------- */
     580                 : /*      Adopt the openinfo file pointer.                                */
     581                 : /* -------------------------------------------------------------------- */
     582               0 :     poDS->fp = poOpenInfo->fp;
     583               0 :     poOpenInfo->fp = NULL;
     584                 : 
     585                 : /* -------------------------------------------------------------------- */
     586                 : /*      Read and merge parameter header into metadata.  Prefix          */
     587                 : /*      parameter header values with PH_.                               */
     588                 : /* -------------------------------------------------------------------- */
     589               0 :     int nPHOffset = 0;
     590                 : 
     591               0 :     if( CSLFetchNameValue( papszMD, 
     592                 :                            "MH_BYTE_OFFSET_OF_PARAMETER_HEADER" ) != NULL )
     593                 :     {
     594                 :         nPHOffset = atoi(CSLFetchNameValue( 
     595               0 :                         papszMD, "MH_BYTE_OFFSET_OF_PARAMETER_HEADER"));
     596               0 :         char **papszPHInfo = ReadHeader( poDS->fp, nPHOffset, "PH", 100 );
     597                 : 
     598               0 :         papszMD = CSLInsertStrings( papszMD, CSLCount(papszMD), papszPHInfo );
     599                 : 
     600               0 :         CSLDestroy( papszPHInfo );
     601                 :     }
     602                 : 
     603                 : /* -------------------------------------------------------------------- */
     604                 : /*      Read and merge calibration header into metadata.  Prefix        */
     605                 : /*      parameter header values with CH_.                               */
     606                 : /* -------------------------------------------------------------------- */
     607               0 :     if( nPHOffset != 0 )
     608                 :     {
     609                 :         char **papszCHInfo = ReadHeader( poDS->fp, 
     610                 :                                          nPHOffset+poDS->nRecordLength, 
     611               0 :                                          "CH", 18 );
     612                 : 
     613               0 :         papszMD = CSLInsertStrings( papszMD, CSLCount(papszMD), papszCHInfo );
     614                 : 
     615               0 :         CSLDestroy( papszCHInfo );
     616                 :     }
     617                 : 
     618                 : /* -------------------------------------------------------------------- */
     619                 : /*      Assign metadata to dataset.                                     */
     620                 : /* -------------------------------------------------------------------- */
     621               0 :     poDS->SetMetadata( papszMD );
     622               0 :     CSLDestroy( papszMD );
     623                 : 
     624                 : /* -------------------------------------------------------------------- */
     625                 : /*      Create band information objects.                                */
     626                 : /* -------------------------------------------------------------------- */
     627               0 :     poDS->SetBand( 1, new AirSARRasterBand( poDS, 1 ));
     628               0 :     poDS->SetBand( 2, new AirSARRasterBand( poDS, 2 ));
     629               0 :     poDS->SetBand( 3, new AirSARRasterBand( poDS, 3 ));
     630               0 :     poDS->SetBand( 4, new AirSARRasterBand( poDS, 4 ));
     631               0 :     poDS->SetBand( 5, new AirSARRasterBand( poDS, 5 ));
     632               0 :     poDS->SetBand( 6, new AirSARRasterBand( poDS, 6 ));
     633                 : 
     634               0 :     poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SYMMETRIZED_COVARIANCE" );
     635                 : 
     636                 : /* -------------------------------------------------------------------- */
     637                 : /*      Initialize any PAM information.                                 */
     638                 : /* -------------------------------------------------------------------- */
     639               0 :     poDS->SetDescription( poOpenInfo->pszFilename );
     640               0 :     poDS->TryLoadXML();
     641                 : 
     642               0 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     643                 : 
     644               0 :     return( poDS );
     645                 : }
     646                 : 
     647                 : /************************************************************************/
     648                 : /*                        GDALRegister_AirSAR()                            */
     649                 : /************************************************************************/
     650                 : 
     651            1135 : void GDALRegister_AirSAR()
     652                 : 
     653                 : {
     654                 :     GDALDriver  *poDriver;
     655                 : 
     656            1135 :     if( GDALGetDriverByName( "AirSAR" ) == NULL )
     657                 :     {
     658            1093 :         poDriver = new GDALDriver();
     659                 :         
     660            1093 :         poDriver->SetDescription( "AirSAR" );
     661                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     662            1093 :                                    "AirSAR Polarimetric Image" );
     663            1093 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "frmt_airsar.html" );
     664            1093 :         poDriver->pfnOpen = AirSARDataset::Open;
     665                 : 
     666            1093 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     667                 :     }
     668            1135 : }

Generated by: LCOV version 1.7