LCOV - code coverage report
Current view: directory - frmts/jaxapalsar - jaxapalsardataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 207 18 8.7 %
Date: 2010-01-09 Functions: 13 3 23.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: jaxapalsardataset.cpp 17664 2009-09-21 21:16:45Z 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 17664 2009-09-21 21:16:45Z 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                 : };
     143                 : 
     144                 : enum ePolarization {
     145                 :   hh = 0,
     146                 :   hv,
     147                 :   vh,
     148                 :   vv
     149                 : };
     150                 : 
     151                 : /************************************************************************/
     152                 : /* ==================================================================== */
     153                 : /*                        PALSARJaxaDataset                             */
     154                 : /* ==================================================================== */
     155                 : /************************************************************************/
     156                 : 
     157                 : class PALSARJaxaRasterBand;
     158                 : 
     159                 : class PALSARJaxaDataset : public GDALPamDataset {
     160                 :     friend class PALSARJaxaRasterBand;
     161                 : private:
     162                 :     GDAL_GCP *pasGCPList;
     163                 :     int nGCPCount;
     164                 :     eFileType nFileType;
     165                 : public:
     166                 :     PALSARJaxaDataset();
     167                 :     ~PALSARJaxaDataset();
     168                 : 
     169                 :     int GetGCPCount();
     170                 :     const GDAL_GCP *GetGCPs();
     171                 : 
     172                 :     static GDALDataset *Open( GDALOpenInfo *poOpenInfo );
     173                 :     static int Identify( GDALOpenInfo *poOpenInfo );
     174                 :     static void ReadMetadata( PALSARJaxaDataset *poDS, FILE *fp );
     175                 : };
     176                 : 
     177               0 : PALSARJaxaDataset::PALSARJaxaDataset()
     178                 : {
     179               0 :     pasGCPList = NULL;
     180               0 :     nGCPCount = 0;
     181               0 : }
     182                 : 
     183               0 : PALSARJaxaDataset::~PALSARJaxaDataset()
     184                 : {
     185               0 :     if( nGCPCount > 0 ) 
     186                 :     {
     187               0 :         GDALDeinitGCPs( nGCPCount, pasGCPList ); 
     188               0 :         CPLFree( pasGCPList ); 
     189                 :     }
     190               0 : }
     191                 : 
     192                 : /************************************************************************/
     193                 : /* ==================================================================== */
     194                 : /*                        PALSARJaxaRasterBand                          */
     195                 : /* ==================================================================== */
     196                 : /************************************************************************/
     197                 : 
     198                 : class PALSARJaxaRasterBand : public GDALRasterBand {
     199                 :     FILE *fp;
     200                 :     int nRasterXSize;
     201                 :     int nRasterYSize;
     202                 :     ePolarization nPolarization;
     203                 :     eFileType nFileType;
     204                 :     int nBitsPerSample;
     205                 :     int nSamplesPerGroup;
     206                 :     int nRecordSize;
     207                 : public:
     208                 :     PALSARJaxaRasterBand( PALSARJaxaDataset *poDS, int nBand, FILE *fp );
     209                 :     ~PALSARJaxaRasterBand();
     210                 : 
     211                 :     CPLErr IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage );
     212                 : };
     213                 : 
     214                 : /************************************************************************/
     215                 : /*                         PALSARJaxaRasterBand()                       */
     216                 : /************************************************************************/
     217                 : 
     218               0 : PALSARJaxaRasterBand::PALSARJaxaRasterBand( PALSARJaxaDataset *poDS, 
     219               0 :   int nBand, FILE *fp ) 
     220                 : {
     221               0 :     this->fp = fp;
     222                 : 
     223                 :     /* Read image options record to determine the type of data */
     224               0 :     VSIFSeekL( fp, BITS_PER_SAMPLE_OFFSET, SEEK_SET );
     225               0 :     nBitsPerSample = 0;
     226               0 :     nSamplesPerGroup = 0;
     227               0 :     READ_CHAR_VAL( nBitsPerSample, BITS_PER_SAMPLE_LENGTH, fp );
     228               0 :     READ_CHAR_VAL( nSamplesPerGroup, SAMPLES_PER_GROUP_LENGTH, fp );
     229                 : 
     230               0 :     if (nBitsPerSample == 32 && nSamplesPerGroup == 2) {
     231               0 :         eDataType = GDT_CFloat32;
     232               0 :         nFileType = level_11;
     233                 :     }
     234                 :     else {
     235               0 :         eDataType = GDT_Int16;
     236               0 :         nFileType = level_15;
     237                 :     }
     238                 : 
     239               0 :     poDS->nFileType = nFileType;
     240                 : 
     241                 :     /* Read number of range/azimuth lines */
     242               0 :     VSIFSeekL( fp, NUMBER_LINES_OFFSET, SEEK_SET );
     243               0 :     READ_CHAR_VAL( nRasterYSize, NUMBER_LINES_LENGTH, fp );
     244               0 :     VSIFSeekL( fp, SAR_DATA_RECORD_LENGTH_OFFSET, SEEK_SET );
     245               0 :     READ_CHAR_VAL( nRecordSize, SAR_DATA_RECORD_LENGTH_LENGTH, fp );
     246                 :     nRasterXSize = (nRecordSize - 
     247                 :                     (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET))
     248               0 :         / ((nBitsPerSample / 8) * nSamplesPerGroup);
     249                 : 
     250               0 :     poDS->nRasterXSize = nRasterXSize;
     251               0 :     poDS->nRasterYSize = nRasterYSize;
     252                 : 
     253                 :     /* Polarization */
     254               0 :     switch (nBand) {
     255                 :       case 0:
     256               0 :         nPolarization = hh;
     257               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "HH" );
     258               0 :         break;
     259                 :       case 1:
     260               0 :         nPolarization = hv;
     261               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "HV" );
     262               0 :         break;
     263                 :       case 2:
     264               0 :         nPolarization = vh;
     265               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "VH" );
     266               0 :         break;
     267                 :       case 3:
     268               0 :         nPolarization = vv;
     269               0 :         SetMetadataItem( "POLARIMETRIC_INTERP", "VV" );
     270                 :         break;
     271                 :     }
     272                 :   
     273                 :     /* size of block we can read */
     274               0 :     nBlockXSize = nRasterXSize;
     275               0 :     nBlockYSize = 1;
     276                 : 
     277                 :     /* set the file pointer to the first SAR data record */
     278               0 :     VSIFSeekL( fp, IMAGE_OPT_DESC_LENGTH, SEEK_SET );
     279               0 : } 
     280                 : 
     281                 : /************************************************************************/
     282                 : /*                        ~PALSARJaxaRasterBand()                       */
     283                 : /************************************************************************/
     284                 : 
     285               0 : PALSARJaxaRasterBand::~PALSARJaxaRasterBand()
     286                 : {
     287               0 :     if (fp)
     288               0 :         VSIFCloseL(fp);
     289               0 : }
     290                 : 
     291                 : /************************************************************************/
     292                 : /*                             IReadBlock()                             */
     293                 : /************************************************************************/
     294                 : 
     295               0 : CPLErr PALSARJaxaRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     296                 :   void *pImage )
     297                 : {
     298               0 :     int nNumBytes = 0;
     299               0 :     if (nFileType == level_11) {
     300               0 :         nNumBytes = 8;
     301                 :     }
     302                 :     else {
     303               0 :         nNumBytes = 2;
     304                 :     }
     305                 : 
     306                 :     int nOffset = IMAGE_OPT_DESC_LENGTH + ((nBlockYOff - 1) * nRecordSize) + 
     307               0 :         (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET);
     308                 : 
     309               0 :     VSIFSeekL( fp, nOffset, SEEK_SET );
     310               0 :     VSIFReadL( pImage, nNumBytes, nRasterXSize, fp );
     311                 : 
     312                 : #ifdef CPL_LSB
     313               0 :     if (nFileType == level_11)
     314               0 :         GDALSwapWords( pImage, 4, nBlockXSize * 2, 4 );
     315                 :     else 
     316               0 :         GDALSwapWords( pImage, 2, nBlockXSize, 2 );
     317                 : #endif
     318                 : 
     319               0 :     return CE_None;
     320                 : }
     321                 : 
     322                 : 
     323                 : /************************************************************************/
     324                 : /* ==================================================================== */
     325                 : /*      PALSARJaxaDataset           */
     326                 : /* ==================================================================== */
     327                 : /************************************************************************/
     328                 : 
     329                 : /************************************************************************/
     330                 : /*                          ReadMetadata()                              */
     331                 : /************************************************************************/
     332                 : 
     333               0 : int PALSARJaxaDataset::GetGCPCount() {
     334               0 :     return nGCPCount;
     335                 : }
     336                 : 
     337                 : 
     338                 : /************************************************************************/
     339                 : /*                             GetGCPs()                                */
     340                 : /************************************************************************/
     341                 : 
     342               0 : const GDAL_GCP *PALSARJaxaDataset::GetGCPs() {
     343               0 :     return pasGCPList;
     344                 : }
     345                 : 
     346                 : 
     347                 : /************************************************************************/
     348                 : /*                            ReadMetadata()                            */
     349                 : /************************************************************************/
     350                 : 
     351               0 : void PALSARJaxaDataset::ReadMetadata( PALSARJaxaDataset *poDS, FILE *fp ) {
     352                 :     /* seek to the end fo the leader file descriptor */
     353               0 :     VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH, SEEK_SET );
     354               0 :     if (poDS->nFileType == level_11) {
     355               0 :         poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.1" );
     356               0 :         poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" );
     357                 :     }
     358                 :     else {
     359               0 :         poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.5" );
     360                 :         /* extract equivalent number of looks */
     361                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + 
     362               0 :                   EFFECTIVE_LOOKS_AZIMUTH_OFFSET, SEEK_SET );
     363                 :         char pszENL[17];
     364                 :         double dfENL;
     365               0 :         READ_CHAR_FLOAT(dfENL, 16, fp);
     366               0 :         sprintf( pszENL, "%-16.1f", dfENL );
     367               0 :         poDS->SetMetadataItem( "AZIMUTH_LOOKS", pszENL );
     368                 : 
     369                 :         /* extract pixel spacings */
     370                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
     371               0 :                   DATA_SET_SUMMARY_LENGTH + PIXEL_SPACING_OFFSET, SEEK_SET );
     372                 :         double dfPixelSpacing;
     373                 :         double dfLineSpacing;
     374                 :         char pszPixelSpacing[33];
     375                 :         char pszLineSpacing[33];
     376               0 :         READ_CHAR_FLOAT(dfPixelSpacing, 16, fp);
     377               0 :         READ_CHAR_FLOAT(dfLineSpacing, 16, fp);
     378               0 :         sprintf( pszPixelSpacing, "%-32.1f",dfPixelSpacing );
     379               0 :         sprintf( pszLineSpacing, "%-32.1f", dfLineSpacing );
     380               0 :         poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing );
     381               0 :         poDS->SetMetadataItem( "LINE_SPACING", pszPixelSpacing );
     382                 : 
     383                 :         /* Alphanumeric projection name */
     384                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
     385                 :                   DATA_SET_SUMMARY_LENGTH + ALPHANUMERIC_PROJECTION_NAME_OFFSET,
     386               0 :                   SEEK_SET );
     387                 :         char pszProjName[33];
     388               0 :         READ_STRING(pszProjName, 32, fp);
     389               0 :         poDS->SetMetadataItem( "PROJECTION_NAME", pszProjName );
     390                 :     
     391                 :         /* Extract corner GCPs */
     392               0 :         poDS->nGCPCount = 4;
     393                 :         poDS->pasGCPList = (GDAL_GCP *)CPLCalloc( sizeof(GDAL_GCP), 
     394               0 :                                                   poDS->nGCPCount );
     395               0 :         GDALInitGCPs( poDS->nGCPCount, poDS->pasGCPList );
     396                 : 
     397                 :         /* setup the GCPs */
     398                 :         int i;
     399               0 :         for (i = 0; i < poDS->nGCPCount; i++) {
     400                 :             char pszID[2];
     401               0 :             sprintf( pszID, "%d", i + 1);
     402               0 :             CPLFree(poDS->pasGCPList[i].pszId);
     403               0 :             poDS->pasGCPList[i].pszId = CPLStrdup( pszID );
     404               0 :             poDS->pasGCPList[i].dfGCPZ = 0.0;
     405                 :         }
     406                 : 
     407               0 :         double dfTemp = 0.0;
     408                 :         /* seek to start of GCPs */
     409                 :         VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
     410               0 :                   DATA_SET_SUMMARY_LENGTH + TOP_LEFT_LAT_OFFSET, SEEK_SET );
     411                 :     
     412                 :         /* top-left GCP */
     413               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     414               0 :         poDS->pasGCPList[0].dfGCPY = dfTemp;
     415               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     416               0 :         poDS->pasGCPList[0].dfGCPX = dfTemp;
     417               0 :         poDS->pasGCPList[0].dfGCPLine = 0.5;
     418               0 :         poDS->pasGCPList[0].dfGCPPixel = 0.5;
     419                 : 
     420                 :         /* top right GCP */
     421               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     422               0 :         poDS->pasGCPList[1].dfGCPY = dfTemp;
     423               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     424               0 :         poDS->pasGCPList[1].dfGCPX = dfTemp;
     425               0 :         poDS->pasGCPList[1].dfGCPLine = 0.5;
     426               0 :         poDS->pasGCPList[1].dfGCPPixel = poDS->nRasterYSize - 0.5;
     427                 : 
     428                 :         /* bottom right GCP */
     429               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     430               0 :         poDS->pasGCPList[2].dfGCPY = dfTemp;
     431               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     432               0 :         poDS->pasGCPList[2].dfGCPX = dfTemp;
     433               0 :         poDS->pasGCPList[2].dfGCPLine = poDS->nRasterYSize - 0.5;
     434               0 :         poDS->pasGCPList[2].dfGCPPixel = poDS->nRasterYSize - 0.5;
     435                 : 
     436                 :         /* bottom left GCP */
     437               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     438               0 :         poDS->pasGCPList[3].dfGCPY = dfTemp;
     439               0 :         READ_CHAR_FLOAT(dfTemp, 16, fp);
     440               0 :         poDS->pasGCPList[3].dfGCPX = dfTemp;
     441               0 :         poDS->pasGCPList[3].dfGCPLine = poDS->nRasterYSize - 0.5;
     442               0 :         poDS->pasGCPList[3].dfGCPPixel = 0.5;
     443                 :     }
     444                 : 
     445                 :     /* some generic metadata items */
     446               0 :     poDS->SetMetadataItem( "SENSOR_BAND", "L" ); /* PALSAR is L-band */
     447               0 :     poDS->SetMetadataItem( "RANGE_LOOKS", "1.0" );
     448                 : 
     449                 :     /* Check if this is a PolSAR dataset */
     450               0 :     if ( poDS->GetRasterCount() == 4 ) {
     451                 :         /* PALSAR data is only available from JAXA in Scattering Matrix form */
     452               0 :         poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
     453                 :     }
     454                 : 
     455               0 : }
     456                 : 
     457                 : /************************************************************************/
     458                 : /*                              Identify()                              */
     459                 : /************************************************************************/
     460                 : 
     461            9942 : int PALSARJaxaDataset::Identify( GDALOpenInfo *poOpenInfo ) {
     462            9942 :     if ( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 360 )
     463            8920 :         return 0;
     464                 : 
     465                 :     /* First, check that this is a PALSAR image indeed */
     466            1022 :     if ( !EQUALN((char *)(poOpenInfo->pabyHeader + 60),"AL", 2) 
     467                 :          || !EQUALN(CPLGetBasename((char *)(poOpenInfo->pszFilename)) + 4, 
     468                 :                     "ALPSR", 5) )
     469                 :     {
     470            1022 :         return 0;
     471                 :     }
     472                 : 
     473               0 :     FILE *fpL = VSIFOpenL( poOpenInfo->pszFilename, "r" );
     474               0 :     if( fpL == NULL )
     475               0 :         return FALSE;
     476                 : 
     477                 :     /* Check that this is a volume directory file */
     478               0 :     int nRecordSeq = 0;
     479               0 :     int nRecordSubtype = 0;
     480               0 :     int nRecordType = 0;
     481               0 :     int nSecondSubtype = 0;
     482               0 :     int nThirdSubtype = 0;
     483               0 :     int nLengthRecord = 0;
     484                 : 
     485               0 :     VSIFSeekL(fpL, 0, SEEK_SET);
     486                 : 
     487               0 :     READ_WORD(fpL, nRecordSeq);
     488               0 :     READ_BYTE(fpL, nRecordSubtype);
     489               0 :     READ_BYTE(fpL, nRecordType);
     490               0 :     READ_BYTE(fpL, nSecondSubtype);
     491               0 :     READ_BYTE(fpL, nThirdSubtype);
     492               0 :     READ_WORD(fpL, nLengthRecord);
     493                 : 
     494               0 :     VSIFCloseL( fpL );
     495                 : 
     496                 :     /* Check that we have the right record */
     497               0 :     if ( nRecordSeq == 1 && nRecordSubtype == 192 && nRecordType == 192 &&
     498                 :          nSecondSubtype == 18 && nThirdSubtype == 18 && nLengthRecord == 360 )
     499                 :     {
     500               0 :         return 1;
     501                 :     }
     502                 : 
     503               0 :     return 0;
     504                 : }
     505                 : 
     506                 : /************************************************************************/
     507                 : /*                                Open()                                */
     508                 : /************************************************************************/
     509            2212 : GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
     510                 :     /* Check that this actually is a JAXA PALSAR product */
     511            2212 :     if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
     512            2212 :         return NULL;
     513                 :         
     514                 : /* -------------------------------------------------------------------- */
     515                 : /*      Confirm the requested access is supported.                      */
     516                 : /* -------------------------------------------------------------------- */
     517               0 :     if( poOpenInfo->eAccess == GA_Update )
     518                 :     {
     519                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     520                 :                   "The JAXAPALSAR driver does not support update access to existing"
     521               0 :                   " datasets.\n" );
     522               0 :         return NULL;
     523                 :     }
     524                 :     
     525               0 :     PALSARJaxaDataset *poDS = new PALSARJaxaDataset();
     526                 : 
     527                 :     /* Get the suffix of the filename, we'll need this */
     528                 :     char *pszSuffix = VSIStrdup( (char *)
     529               0 :                                  (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );
     530                 : 
     531                 :     /* Try to read each of the polarizations */
     532                 :     char *pszImgFile = (char *)VSIMalloc( 
     533                 :         strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + 
     534               0 :         strlen( pszSuffix ) + 8 );
     535                 : 
     536               0 :     int nBandNum = 1;
     537                 : 
     538                 :     /* HH */
     539                 :     FILE *fpHH;
     540                 :     sprintf( pszImgFile, "%s%sIMG-HH%s", 
     541               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     542               0 :     fpHH = VSIFOpenL( pszImgFile, "rb" );
     543               0 :     if (fpHH != NULL) { 
     544               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
     545               0 :         nBandNum++;
     546                 :     }
     547                 : 
     548                 :     /* HV */
     549                 :     FILE *fpHV;
     550                 :     sprintf( pszImgFile, "%s%sIMG-HV%s", 
     551               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     552               0 :     fpHV = VSIFOpenL( pszImgFile, "rb" );
     553               0 :     if (fpHV != NULL) {
     554               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
     555               0 :         nBandNum++;
     556                 :     }
     557                 : 
     558                 :     /* VH */
     559                 :     FILE *fpVH;
     560                 :     sprintf( pszImgFile, "%s%sIMG-VH%s", 
     561               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     562               0 :     fpVH = VSIFOpenL( pszImgFile, "rb" );
     563               0 :     if (fpVH != NULL) {
     564               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
     565               0 :         nBandNum++;
     566                 :     }
     567                 : 
     568                 :     /* VV */
     569                 :     FILE *fpVV;
     570                 :     sprintf( pszImgFile, "%s%sIMG-VV%s",
     571               0 :              CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
     572               0 :     fpVV = VSIFOpenL( pszImgFile, "rb" );
     573               0 :     if (fpVV != NULL) {
     574               0 :         poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
     575               0 :         nBandNum++;
     576                 :     }
     577                 : 
     578               0 :     VSIFree( pszImgFile );
     579                 : 
     580                 :     /* did we get at least one band? */
     581               0 :     if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
     582                 :         CPLError( CE_Failure, CPLE_AppDefined,
     583               0 :                   "Unable to find any image data. Aborting opening as PALSAR image.");
     584               0 :         delete poDS;
     585               0 :         return NULL;
     586                 :     }
     587                 : 
     588                 :     /* read metadata from Leader file. */
     589                 :     char *pszLeaderFilename = (char *)VSIMalloc( 
     590                 :         strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + 
     591               0 :         strlen(pszSuffix) + 5 );
     592                 :     sprintf( pszLeaderFilename, "%s%sLED%s", 
     593               0 :              CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );
     594                 : 
     595               0 :     FILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
     596                 :     /* check if the leader is actually present */
     597               0 :     if (fpLeader != NULL) {
     598               0 :         ReadMetadata(poDS, fpLeader);
     599               0 :         VSIFCloseL(fpLeader);
     600                 :     }
     601                 : 
     602               0 :     VSIFree(pszLeaderFilename);
     603                 : 
     604               0 :     VSIFree( pszSuffix );
     605                 : 
     606                 : /* -------------------------------------------------------------------- */
     607                 : /*      Initialize any PAM information.                                 */
     608                 : /* -------------------------------------------------------------------- */
     609               0 :     poDS->SetDescription( poOpenInfo->pszFilename );
     610               0 :     poDS->TryLoadXML();
     611                 : 
     612                 : /* -------------------------------------------------------------------- */
     613                 : /*      Check for overviews.                                            */
     614                 : /* -------------------------------------------------------------------- */
     615               0 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     616                 : 
     617               0 :     return poDS;
     618                 : }
     619                 : 
     620                 : /************************************************************************/
     621                 : /*                      GDALRegister_PALSARJaxa()                       */
     622                 : /************************************************************************/
     623                 : 
     624             338 : void GDALRegister_PALSARJaxa() {
     625                 :     GDALDriver  *poDriver;
     626                 : 
     627             338 :     if( GDALGetDriverByName( "JAXAPALSAR" ) == NULL ) {
     628             336 :         poDriver = new GDALDriver();
     629             336 :         poDriver->SetDescription( "JAXAPALSAR" );
     630                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     631             336 :                                    "JAXA PALSAR Product Reader (Level 1.1/1.5)" );
     632                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     633             336 :                                    "frmt_palsar.html" );
     634             336 :         poDriver->pfnOpen = PALSARJaxaDataset::Open;
     635             336 :         poDriver->pfnIdentify = PALSARJaxaDataset::Identify;
     636             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     637                 :     }
     638             338 : }

Generated by: LCOV version 1.7