LCOV - code coverage report
Current view: directory - frmts/jaxapalsar - jaxapalsardataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 220 19 8.6 %
Date: 2012-04-28 Functions: 17 3 17.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: jaxapalsardataset.cpp 22636 2011-07-03 10:39:11Z rouault $
       3                 :  *
       4                 :  * Project:  PALSAR JAXA imagery reader
       5                 :  * Purpose:  Support for PALSAR L1.1/1.5 imagery and appropriate metadata from
       6                 :  *           JAXA and JAXA-supported ground stations (ASF, ESA, etc.). This
       7                 :  *           driver does not support ERSDAC products.
       8                 :  * Author:   Philippe Vachon <philippe@cowpig.ca>
       9                 :  *
      10                 :  ******************************************************************************
      11                 :  * Copyright (c) 2007, Philippe P. Vachon <philippe@cowpig.ca>
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "gdal_pam.h"
      33                 : 
      34                 : CPL_CVSID("$Id: jaxapalsardataset.cpp 22636 2011-07-03 10:39:11Z rouault $");
      35                 : 
      36                 : CPL_C_START
      37                 : void  GDALRegister_PALSARJaxa(void);
      38                 : CPL_C_END
      39                 : 
      40                 : #if defined(WIN32) || defined(WIN32CE)
      41                 : #define SEP_STRING "\\"
      42                 : #else
      43                 : #define SEP_STRING "/"
      44                 : #endif
      45                 : 
      46                 : /* read binary fields */
      47                 : #ifdef CPL_LSB
      48                 : #define READ_WORD(f, x) \
      49                 :   do { \
      50                 :     VSIFReadL( &(x), 4, 1, (f) ); \
      51                 :     (x) = CPL_SWAP32( (x) ); \
      52                 :   } while (0);
      53                 : #define READ_SHORT(f, x) \
      54                 :   do { \
      55                 :     VSIFReadL( &(x), 2, 1, (f) ); \
      56                 :     (x) = CPL_SWAP16( (x) ); \
      57                 :   } while (0);
      58                 : #else
      59                 : #define READ_WORD(f, x) do { VSIFReadL( &(x), 4, 1, (f) ); } while (0);
      60                 : #define READ_SHORT(f, x) do { VSIFReadL( &(x), 2, 1, (f) ); } while (0);
      61                 : #endif /* def CPL_LSB */
      62                 : #define READ_BYTE(f, x) do { VSIFReadL( &(x), 1, 1, (f) ); } while (0);
      63                 : 
      64                 : /* read floating point value stored as ASCII */
      65                 : #define READ_CHAR_FLOAT(n, l, f) \
      66                 :   do {\
      67                 :     char psBuf[(l+1)]; \
      68                 :     psBuf[(l)] = '\0'; \
      69                 :     VSIFReadL( &psBuf, (l), 1, (f) );\
      70                 :     (n) = CPLAtof( psBuf );\
      71                 :   } while (0);
      72                 : 
      73                 : /* read numbers stored as ASCII */
      74                 : #define READ_CHAR_VAL(x, n, f) \
      75                 :   do { \
      76                 :     char psBuf[(n+1)]; \
      77                 :     psBuf[(n)] = '\0';\
      78                 :     VSIFReadL( &psBuf, (n), 1, (f) ); \
      79                 :     (x) = atoi(psBuf); \
      80                 :   } while (0);
      81                 : 
      82                 : /* read string fields 
      83                 :  * note: string must be size of field to be extracted + 1
      84                 :  */
      85                 : #define READ_STRING(s, n, f) \
      86                 :   do { \
      87                 :     VSIFReadL( &(s), 1, (n), (f) ); \
      88                 :     (s)[(n)] = '\0'; \
      89                 :   } while (0);
      90                 : 
      91                 : /*************************************************************************/
      92                 : /* a few key offsets in the volume directory file */
      93                 : #define VOL_DESC_RECORD_LENGTH 360
      94                 : #define FILE_PTR_RECORD_LENGTH 360
      95                 : #define NUM_RECORDS_OFFSET 160
      96                 : 
      97                 : /* a few key offsets and values within the File Pointer record */
      98                 : #define REF_FILE_CLASS_CODE_OFFSET 66
      99                 : #define REF_FILE_CLASS_CODE_LENGTH 4
     100                 : #define FILE_NAME_OFFSET 310
     101                 : 
     102                 : /* some image option descriptor records */
     103                 : #define BITS_PER_SAMPLE_OFFSET 216
     104                 : #define BITS_PER_SAMPLE_LENGTH 4
     105                 : #define SAMPLES_PER_GROUP_OFFSET 220
     106                 : #define SAMPLES_PER_GROUP_LENGTH 4
     107                 : #define NUMBER_LINES_OFFSET 236
     108                 : #define NUMBER_LINES_LENGTH 8
     109                 : #define SAR_DATA_RECORD_LENGTH_OFFSET 186
     110                 : #define SAR_DATA_RECORD_LENGTH_LENGTH 6
     111                 : 
     112                 : #define IMAGE_OPT_DESC_LENGTH 720
     113                 : 
     114                 : #define SIG_DAT_REC_OFFSET 412
     115                 : #define PROC_DAT_REC_OFFSET 192
     116                 : 
     117                 : /* metadata to be extracted from the leader file */
     118                 : #define LEADER_FILE_DESCRIPTOR_LENGTH 720
     119                 : #define DATA_SET_SUMMARY_LENGTH 4096
     120                 : 
     121                 : /* relative to end of leader file descriptor */
     122                 : #define EFFECTIVE_LOOKS_AZIMUTH_OFFSET 1174 /* floating point text */
     123                 : #define EFFECTIVE_LOOKS_AZIMUTH_LENGTH 16
     124                 : 
     125                 : /* relative to leader file descriptor + dataset summary length */
     126                 : #define PIXEL_SPACING_OFFSET 92
     127                 : #define LINE_SPACING_OFFSET 108
     128                 : #define ALPHANUMERIC_PROJECTION_NAME_OFFSET 412
     129                 : #define TOP_LEFT_LAT_OFFSET 1072
     130                 : #define TOP_LEFT_LON_OFFSET 1088
     131                 : #define TOP_RIGHT_LAT_OFFSET 1104
     132                 : #define TOP_RIGHT_LON_OFFSET 1120
     133                 : #define BOTTOM_RIGHT_LAT_OFFSET 1136
     134                 : #define BOTTOM_RIGHT_LON_OFFSET 1152
     135                 : #define BOTTOM_LEFT_LAT_OFFSET 1168
     136                 : #define BOTTOM_LEFT_LON_OFFSET 1184
     137                 : 
     138                 : /* a few useful enums */
     139                 : enum eFileType {
     140                 :   level_11 = 0,
     141                 :   level_15,
     142                 :     level_10
     143                 : };
     144                 : 
     145                 : enum ePolarization {
     146                 :   hh = 0,
     147                 :   hv,
     148                 :   vh,
     149                 :   vv
     150                 : };
     151                 : 
     152                 : /************************************************************************/
     153                 : /* ==================================================================== */
     154                 : /*                        PALSARJaxaDataset                             */
     155                 : /* ==================================================================== */
     156                 : /************************************************************************/
     157                 : 
     158                 : class PALSARJaxaRasterBand;
     159                 : 
     160                 : class PALSARJaxaDataset : public GDALPamDataset {
     161                 :     friend class PALSARJaxaRasterBand;
     162                 : private:
     163                 :     GDAL_GCP *pasGCPList;
     164                 :     int nGCPCount;
     165                 :     eFileType nFileType;
     166                 : public:
     167                 :     PALSARJaxaDataset();
     168                 :     ~PALSARJaxaDataset();
     169                 : 
     170                 :     int GetGCPCount();
     171                 :     const GDAL_GCP *GetGCPs();
     172                 : 
     173                 :     static GDALDataset *Open( GDALOpenInfo *poOpenInfo );
     174                 :     static int Identify( GDALOpenInfo *poOpenInfo );
     175                 :     static void ReadMetadata( PALSARJaxaDataset *poDS, VSILFILE *fp );
     176                 : };
     177                 : 
     178               0 : PALSARJaxaDataset::PALSARJaxaDataset()
     179                 : {
     180               0 :     pasGCPList = NULL;
     181               0 :     nGCPCount = 0;
     182               0 : }
     183                 : 
     184               0 : PALSARJaxaDataset::~PALSARJaxaDataset()
     185                 : {
     186               0 :     if( nGCPCount > 0 ) 
     187                 :     {
     188               0 :         GDALDeinitGCPs( nGCPCount, pasGCPList ); 
     189               0 :         CPLFree( pasGCPList ); 
     190                 :     }
     191               0 : }
     192                 : 
     193                 : /************************************************************************/
     194                 : /* ==================================================================== */
     195                 : /*                        PALSARJaxaRasterBand                          */
     196                 : /* ==================================================================== */
     197                 : /************************************************************************/
     198                 : 
     199                 : class PALSARJaxaRasterBand : public GDALRasterBand {
     200                 :     VSILFILE *fp;
     201                 :     int nRasterXSize;
     202                 :     int nRasterYSize;
     203                 :     ePolarization nPolarization;
     204                 :     eFileType nFileType;
     205                 :     int nBitsPerSample;
     206                 :     int nSamplesPerGroup;
     207                 :     int nRecordSize;
     208                 : public:
     209                 :     PALSARJaxaRasterBand( PALSARJaxaDataset *poDS, int nBand, VSILFILE *fp );
     210                 :     ~PALSARJaxaRasterBand();
     211                 : 
     212                 :     CPLErr IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage );
     213                 : };
     214                 : 
     215                 : /************************************************************************/
     216                 : /*                         PALSARJaxaRasterBand()                       */
     217                 : /************************************************************************/
     218                 : 
     219               0 : PALSARJaxaRasterBand::PALSARJaxaRasterBand( PALSARJaxaDataset *poDS, 
     220               0 :   int nBand, VSILFILE *fp )
     221                 : {
     222               0 :     this->fp = fp;
     223                 : 
     224                 :     /* Read image options record to determine the type of data */
     225               0 :     VSIFSeekL( fp, BITS_PER_SAMPLE_OFFSET, SEEK_SET );
     226               0 :     nBitsPerSample = 0;
     227               0 :     nSamplesPerGroup = 0;
     228               0 :     READ_CHAR_VAL( nBitsPerSample, BITS_PER_SAMPLE_LENGTH, fp );
     229               0 :     READ_CHAR_VAL( nSamplesPerGroup, SAMPLES_PER_GROUP_LENGTH, fp );
     230                 : 
     231               0 :     if (nBitsPerSample == 32 && nSamplesPerGroup == 2) {
     232               0 :         eDataType = GDT_CFloat32;
     233               0 :         nFileType = level_11;
     234                 :     }
     235               0 :     else if (nBitsPerSample == 8 && nSamplesPerGroup == 2) {
     236               0 :         eDataType = GDT_CInt16; /* shuold be 2 x signed byte */
     237               0 :         nFileType = level_10;
     238                 :     }
     239                 :     else {
     240               0 :         eDataType = GDT_UInt16;
     241               0 :         nFileType = level_15;
     242                 :     }
     243                 : 
     244               0 :     poDS->nFileType = nFileType;
     245                 : 
     246                 :     /* Read number of range/azimuth lines */
     247               0 :     VSIFSeekL( fp, NUMBER_LINES_OFFSET, SEEK_SET );
     248               0 :     READ_CHAR_VAL( nRasterYSize, NUMBER_LINES_LENGTH, fp );
     249               0 :     VSIFSeekL( fp, SAR_DATA_RECORD_LENGTH_OFFSET, SEEK_SET );
     250               0 :     READ_CHAR_VAL( nRecordSize, SAR_DATA_RECORD_LENGTH_LENGTH, fp );
     251                 :     nRasterXSize = (nRecordSize -
     252                 :                     (nFileType != level_15 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET))
     253               0 :         / ((nBitsPerSample / 8) * nSamplesPerGroup);
     254                 : 
     255               0 :     poDS->nRasterXSize = nRasterXSize;
     256               0 :     poDS->nRasterYSize = nRasterYSize;
     257                 : 
     258                 :     /* Polarization */
     259               0 :     switch (nBand) {
     260                 :       case 0:
     261               0 :         nPolarization = hh;
     262               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "HH" );
     263               0 :         break;
     264                 :       case 1:
     265               0 :         nPolarization = hv;
     266               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "HV" );
     267               0 :         break;
     268                 :       case 2:
     269               0 :         nPolarization = vh;
     270               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "VH" );
     271               0 :         break;
     272                 :       case 3:
     273               0 :         nPolarization = vv;
     274               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "VV" );
     275                 :         break;
     276                 :     }
     277                 :   
     278                 :     /* size of block we can read */
     279               0 :     nBlockXSize = nRasterXSize;
     280               0 :     nBlockYSize = 1;
     281                 : 
     282                 :     /* set the file pointer to the first SAR data record */
     283               0 :     VSIFSeekL( fp, IMAGE_OPT_DESC_LENGTH, SEEK_SET );
     284               0 : } 
     285                 : 
     286                 : /************************************************************************/
     287                 : /*                        ~PALSARJaxaRasterBand()                       */
     288                 : /************************************************************************/
     289                 : 
     290               0 : PALSARJaxaRasterBand::~PALSARJaxaRasterBand()
     291                 : {
     292               0 :     if (fp)
     293               0 :         VSIFCloseL(fp);
     294               0 : }
     295                 : 
     296                 : /************************************************************************/
     297                 : /*                             IReadBlock()                             */
     298                 : /************************************************************************/
     299                 : 
     300               0 : CPLErr PALSARJaxaRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     301                 :   void *pImage )
     302                 : {
     303               0 :     int nNumBytes = 0;
     304               0 :     if (nFileType == level_11) {
     305               0 :         nNumBytes = 8;
     306                 :     }
     307                 :     else {
     308               0 :         nNumBytes = 2;
     309                 :     }
     310                 : 
     311                 :     int nOffset = IMAGE_OPT_DESC_LENGTH + ((nBlockYOff - 1) * nRecordSize) + 
     312               0 :         (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET);
     313                 : 
     314               0 :     VSIFSeekL( fp, nOffset, SEEK_SET );
     315               0 :     VSIFReadL( pImage, nNumBytes, nRasterXSize, fp );
     316                 : 
     317                 : #ifdef CPL_LSB
     318               0 :     if (nFileType == level_11)
     319               0 :         GDALSwapWords( pImage, 4, nBlockXSize * 2, 4 );
     320                 :     else 
     321               0 :         GDALSwapWords( pImage, 2, nBlockXSize, 2 );
     322                 : #endif
     323                 : 
     324               0 :     return CE_None;
     325                 : }
     326                 : 
     327                 : 
     328                 : /************************************************************************/
     329                 : /* ==================================================================== */
     330                 : /*      PALSARJaxaDataset           */
     331                 : /* ==================================================================== */
     332                 : /************************************************************************/
     333                 : 
     334                 : /************************************************************************/
     335                 : /*                          ReadMetadata()                              */
     336                 : /************************************************************************/
     337                 : 
     338               0 : int PALSARJaxaDataset::GetGCPCount() {
     339               0 :     return nGCPCount;
     340                 : }
     341                 : 
     342                 : 
     343                 : /************************************************************************/
     344                 : /*                             GetGCPs()                                */
     345                 : /************************************************************************/
     346                 : 
     347               0 : const GDAL_GCP *PALSARJaxaDataset::GetGCPs() {
     348               0 :     return pasGCPList;
     349                 : }
     350                 : 
     351                 : 
     352                 : /************************************************************************/
     353                 : /*                            ReadMetadata()                            */
     354                 : /************************************************************************/
     355                 : 
     356               0 : void PALSARJaxaDataset::ReadMetadata( PALSARJaxaDataset *poDS, VSILFILE *fp ) {
     357                 :     /* seek to the end fo the leader file descriptor */
     358               0 :     VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH, SEEK_SET );
     359               0 :     if (poDS->nFileType == level_10) {
     360               0 :         poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.0" );
     361               0 :         poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" );
     362                 :     }
     363               0 :     else if (poDS->nFileType == level_11) {
     364               0 :         poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.1" );
     365               0 :         poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" );
     366                 :     }
     367                 :     else {
     368               0 :         poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.5" );
     369                 :         /* extract equivalent number of looks */
     370                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + 
     371               0 :                   EFFECTIVE_LOOKS_AZIMUTH_OFFSET, SEEK_SET );
     372                 :         char pszENL[17];
     373                 :         double dfENL;
     374               0 :         READ_CHAR_FLOAT(dfENL, 16, fp);
     375               0 :         sprintf( pszENL, "%-16.1f", dfENL );
     376               0 :         poDS->SetMetadataItem( "AZIMUTH_LOOKS", pszENL );
     377                 : 
     378                 :         /* extract pixel spacings */
     379                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
     380               0 :                   DATA_SET_SUMMARY_LENGTH + PIXEL_SPACING_OFFSET, SEEK_SET );
     381                 :         double dfPixelSpacing;
     382                 :         double dfLineSpacing;
     383                 :         char pszPixelSpacing[33];
     384                 :         char pszLineSpacing[33];
     385               0 :         READ_CHAR_FLOAT(dfPixelSpacing, 16, fp);
     386               0 :         READ_CHAR_FLOAT(dfLineSpacing, 16, fp);
     387               0 :         sprintf( pszPixelSpacing, "%-32.1f",dfPixelSpacing );
     388               0 :         sprintf( pszLineSpacing, "%-32.1f", dfLineSpacing );
     389               0 :         poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing );
     390               0 :         poDS->SetMetadataItem( "LINE_SPACING", pszPixelSpacing );
     391                 : 
     392                 :         /* Alphanumeric projection name */
     393                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
     394                 :                   DATA_SET_SUMMARY_LENGTH + ALPHANUMERIC_PROJECTION_NAME_OFFSET,
     395               0 :                   SEEK_SET );
     396                 :         char pszProjName[33];
     397               0 :         READ_STRING(pszProjName, 32, fp);
     398               0 :         poDS->SetMetadataItem( "PROJECTION_NAME", pszProjName );
     399                 :     
     400                 :         /* Extract corner GCPs */
     401               0 :         poDS->nGCPCount = 4;
     402                 :         poDS->pasGCPList = (GDAL_GCP *)CPLCalloc( sizeof(GDAL_GCP), 
     403               0 :                                                   poDS->nGCPCount );
     404               0 :         GDALInitGCPs( poDS->nGCPCount, poDS->pasGCPList );
     405                 : 
     406                 :         /* setup the GCPs */
     407                 :         int i;
     408               0 :         for (i = 0; i < poDS->nGCPCount; i++) {
     409                 :             char pszID[2];
     410               0 :             sprintf( pszID, "%d", i + 1);
     411               0 :             CPLFree(poDS->pasGCPList[i].pszId);
     412               0 :             poDS->pasGCPList[i].pszId = CPLStrdup( pszID );
     413               0 :             poDS->pasGCPList[i].dfGCPZ = 0.0;
     414                 :         }
     415                 : 
     416               0 :         double dfTemp = 0.0;
     417                 :         /* seek to start of GCPs */
     418                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
     419               0 :                   DATA_SET_SUMMARY_LENGTH + TOP_LEFT_LAT_OFFSET, SEEK_SET );
     420                 :     
     421                 :         /* top-left GCP */
     422               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     423               0 :         poDS->pasGCPList[0].dfGCPY = dfTemp;
     424               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     425               0 :         poDS->pasGCPList[0].dfGCPX = dfTemp;
     426               0 :         poDS->pasGCPList[0].dfGCPLine = 0.5;
     427               0 :         poDS->pasGCPList[0].dfGCPPixel = 0.5;
     428                 : 
     429                 :         /* top right GCP */
     430               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     431               0 :         poDS->pasGCPList[1].dfGCPY = dfTemp;
     432               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     433               0 :         poDS->pasGCPList[1].dfGCPX = dfTemp;
     434               0 :         poDS->pasGCPList[1].dfGCPLine = 0.5;
     435               0 :         poDS->pasGCPList[1].dfGCPPixel = poDS->nRasterYSize - 0.5;
     436                 : 
     437                 :         /* bottom right GCP */
     438               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     439               0 :         poDS->pasGCPList[2].dfGCPY = dfTemp;
     440               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     441               0 :         poDS->pasGCPList[2].dfGCPX = dfTemp;
     442               0 :         poDS->pasGCPList[2].dfGCPLine = poDS->nRasterYSize - 0.5;
     443               0 :         poDS->pasGCPList[2].dfGCPPixel = poDS->nRasterYSize - 0.5;
     444                 : 
     445                 :         /* bottom left GCP */
     446               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     447               0 :         poDS->pasGCPList[3].dfGCPY = dfTemp;
     448               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     449               0 :         poDS->pasGCPList[3].dfGCPX = dfTemp;
     450               0 :         poDS->pasGCPList[3].dfGCPLine = poDS->nRasterYSize - 0.5;
     451               0 :         poDS->pasGCPList[3].dfGCPPixel = 0.5;
     452                 :     }
     453                 : 
     454                 :     /* some generic metadata items */
     455               0 :     poDS->SetMetadataItem( "SENSOR_BAND", "L" ); /* PALSAR is L-band */
     456               0 :     poDS->SetMetadataItem( "RANGE_LOOKS", "1.0" );
     457                 : 
     458                 :     /* Check if this is a PolSAR dataset */
     459               0 :     if ( poDS->GetRasterCount() == 4 ) {
     460                 :         /* PALSAR data is only available from JAXA in Scattering Matrix form */
     461               0 :         poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
     462                 :     }
     463                 : 
     464               0 : }
     465                 : 
     466                 : /************************************************************************/
     467                 : /*                              Identify()                              */
     468                 : /************************************************************************/
     469                 : 
     470           26876 : int PALSARJaxaDataset::Identify( GDALOpenInfo *poOpenInfo ) {
     471           26876 :     if ( poOpenInfo->nHeaderBytes < 360 )
     472           22950 :         return 0;
     473                 : 
     474                 :     /* First, check that this is a PALSAR image indeed */
     475            3926 :     if ( !EQUALN((char *)(poOpenInfo->pabyHeader + 60),"AL", 2) 
     476                 :          || !EQUALN(CPLGetBasename((char *)(poOpenInfo->pszFilename)) + 4, 
     477                 :                     "ALPSR", 5) )
     478                 :     {
     479            3926 :         return 0;
     480                 :     }
     481                 : 
     482               0 :     VSILFILE *fpL = VSIFOpenL( poOpenInfo->pszFilename, "r" );
     483               0 :     if( fpL == NULL )
     484               0 :         return FALSE;
     485                 : 
     486                 :     /* Check that this is a volume directory file */
     487               0 :     int nRecordSeq = 0;
     488               0 :     int nRecordSubtype = 0;
     489               0 :     int nRecordType = 0;
     490               0 :     int nSecondSubtype = 0;
     491               0 :     int nThirdSubtype = 0;
     492               0 :     int nLengthRecord = 0;
     493                 : 
     494               0 :     VSIFSeekL(fpL, 0, SEEK_SET);
     495                 : 
     496               0 :     READ_WORD(fpL, nRecordSeq);
     497               0 :     READ_BYTE(fpL, nRecordSubtype);
     498               0 :     READ_BYTE(fpL, nRecordType);
     499               0 :     READ_BYTE(fpL, nSecondSubtype);
     500               0 :     READ_BYTE(fpL, nThirdSubtype);
     501               0 :     READ_WORD(fpL, nLengthRecord);
     502                 : 
     503               0 :     VSIFCloseL( fpL );
     504                 : 
     505                 :     /* Check that we have the right record */
     506               0 :     if ( nRecordSeq == 1 && nRecordSubtype == 192 && nRecordType == 192 &&
     507                 :          nSecondSubtype == 18 && nThirdSubtype == 18 && nLengthRecord == 360 )
     508                 :     {
     509               0 :         return 1;
     510                 :     }
     511                 : 
     512               0 :     return 0;
     513                 : }
     514                 : 
     515                 : /************************************************************************/
     516                 : /*                                Open()                                */
     517                 : /************************************************************************/
     518            7852 : GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
     519                 :     /* Check that this actually is a JAXA PALSAR product */
     520            7852 :     if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
     521            7852 :         return NULL;
     522                 :         
     523                 : /* -------------------------------------------------------------------- */
     524                 : /*      Confirm the requested access is supported.                      */
     525                 : /* -------------------------------------------------------------------- */
     526               0 :     if( poOpenInfo->eAccess == GA_Update )
     527                 :     {
     528                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     529                 :                   "The JAXAPALSAR driver does not support update access to existing"
     530               0 :                   " datasets.\n" );
     531               0 :         return NULL;
     532                 :     }
     533                 :     
     534               0 :     PALSARJaxaDataset *poDS = new PALSARJaxaDataset();
     535                 : 
     536                 :     /* Get the suffix of the filename, we'll need this */
     537                 :     char *pszSuffix = VSIStrdup( (char *)
     538               0 :                                  (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );
     539                 : 
     540                 :     /* Try to read each of the polarizations */
     541                 :     char *pszImgFile = (char *)VSIMalloc( 
     542                 :         strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + 
     543               0 :         strlen( pszSuffix ) + 8 );
     544                 : 
     545               0 :     int nBandNum = 1;
     546                 : 
     547                 :     /* HH */
     548                 :     VSILFILE *fpHH;
     549                 :     sprintf( pszImgFile, "%s%sIMG-HH%s", 
     550               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     551               0 :     fpHH = VSIFOpenL( pszImgFile, "rb" );
     552               0 :     if (fpHH != NULL) { 
     553               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
     554               0 :         nBandNum++;
     555                 :     }
     556                 : 
     557                 :     /* HV */
     558                 :     VSILFILE *fpHV;
     559                 :     sprintf( pszImgFile, "%s%sIMG-HV%s", 
     560               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     561               0 :     fpHV = VSIFOpenL( pszImgFile, "rb" );
     562               0 :     if (fpHV != NULL) {
     563               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
     564               0 :         nBandNum++;
     565                 :     }
     566                 : 
     567                 :     /* VH */
     568                 :     VSILFILE *fpVH;
     569                 :     sprintf( pszImgFile, "%s%sIMG-VH%s", 
     570               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     571               0 :     fpVH = VSIFOpenL( pszImgFile, "rb" );
     572               0 :     if (fpVH != NULL) {
     573               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
     574               0 :         nBandNum++;
     575                 :     }
     576                 : 
     577                 :     /* VV */
     578                 :     VSILFILE *fpVV;
     579                 :     sprintf( pszImgFile, "%s%sIMG-VV%s",
     580               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     581               0 :     fpVV = VSIFOpenL( pszImgFile, "rb" );
     582               0 :     if (fpVV != NULL) {
     583               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
     584               0 :         nBandNum++;
     585                 :     }
     586                 : 
     587               0 :     VSIFree( pszImgFile );
     588                 : 
     589                 :     /* did we get at least one band? */
     590               0 :     if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
     591                 :         CPLError( CE_Failure, CPLE_AppDefined,
     592               0 :                   "Unable to find any image data. Aborting opening as PALSAR image.");
     593               0 :         delete poDS;
     594               0 :         VSIFree( pszSuffix );
     595               0 :         return NULL;
     596                 :     }
     597                 : 
     598                 :     /* Level 1.0 products are not supported */
     599               0 :     if (poDS->nFileType == level_10) {
     600                 :         CPLError( CE_Failure, CPLE_AppDefined,
     601               0 :                   "ALOS PALSAR Level 1.0 products are not supported. Aborting opening as PALSAR image.");
     602               0 :         delete poDS;
     603               0 :         VSIFree( pszSuffix );
     604               0 :         return NULL;
     605                 :     }
     606                 : 
     607                 :     /* read metadata from Leader file. */
     608                 :     char *pszLeaderFilename = (char *)VSIMalloc( 
     609                 :         strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + 
     610               0 :         strlen(pszSuffix) + 5 );
     611                 :     sprintf( pszLeaderFilename, "%s%sLED%s", 
     612               0 :              CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );
     613                 : 
     614               0 :     VSILFILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
     615                 :     /* check if the leader is actually present */
     616               0 :     if (fpLeader != NULL) {
     617               0 :         ReadMetadata(poDS, fpLeader);
     618               0 :         VSIFCloseL(fpLeader);
     619                 :     }
     620                 : 
     621               0 :     VSIFree(pszLeaderFilename);
     622                 : 
     623               0 :     VSIFree( pszSuffix );
     624                 : 
     625                 : /* -------------------------------------------------------------------- */
     626                 : /*      Initialize any PAM information.                                 */
     627                 : /* -------------------------------------------------------------------- */
     628               0 :     poDS->SetDescription( poOpenInfo->pszFilename );
     629               0 :     poDS->TryLoadXML();
     630                 : 
     631                 : /* -------------------------------------------------------------------- */
     632                 : /*      Check for overviews.                                            */
     633                 : /* -------------------------------------------------------------------- */
     634               0 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     635                 : 
     636               0 :     return poDS;
     637                 : }
     638                 : 
     639                 : /************************************************************************/
     640                 : /*                      GDALRegister_PALSARJaxa()                       */
     641                 : /************************************************************************/
     642                 : 
     643            1135 : void GDALRegister_PALSARJaxa() {
     644                 :     GDALDriver  *poDriver;
     645                 : 
     646            1135 :     if( GDALGetDriverByName( "JAXAPALSAR" ) == NULL ) {
     647            1093 :         poDriver = new GDALDriver();
     648            1093 :         poDriver->SetDescription( "JAXAPALSAR" );
     649                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     650            1093 :                                    "JAXA PALSAR Product Reader (Level 1.1/1.5)" );
     651                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     652            1093 :                                    "frmt_palsar.html" );
     653            1093 :         poDriver->pfnOpen = PALSARJaxaDataset::Open;
     654            1093 :         poDriver->pfnIdentify = PALSARJaxaDataset::Identify;
     655            1093 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     656                 : 
     657            1093 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     658                 :     }
     659            1135 : }

Generated by: LCOV version 1.7