LCOV - code coverage report
Current view: directory - frmts/adrg - srpdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 359 262 73.0 %
Date: 2012-12-26 Functions: 20 13 65.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: srpdataset.cpp 25311 2012-12-15 12:48:14Z rouault $
       3                 :  * Purpose:  ASRP/USRP Reader
       4                 :  * Author:   Frank Warmerdam (warmerdam@pobox.com)
       5                 :  *
       6                 :  * Derived from ADRG driver by Even Rouault, even.rouault at mines-paris.org.
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Even Rouault
      10                 :  * Copyright (c) 2009, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "gdal_pam.h"
      32                 : #include "ogr_spatialref.h"
      33                 : #include "cpl_string.h"
      34                 : #include "iso8211.h"
      35                 : 
      36                 : CPL_CVSID("$Id: srpdataset.cpp 25311 2012-12-15 12:48:14Z rouault $");
      37                 : 
      38                 : class SRPDataset : public GDALPamDataset
      39                 : {
      40                 :     friend class SRPRasterBand;
      41                 : 
      42                 :     static CPLString ResetTo01( const char* str );
      43                 : 
      44                 :     VSILFILE*        fdIMG;
      45                 :     int*         TILEINDEX;
      46                 :     int          offsetInIMG;
      47                 :     CPLString    osProduct;
      48                 :     CPLString    osSRS;
      49                 :     CPLString    osGENFilename;
      50                 :     CPLString    osQALFilename;
      51                 :     int          NFC;
      52                 :     int          NFL;
      53                 :     int          ZNA;
      54                 :     double       LSO;
      55                 :     double       PSO;
      56                 :     double       LOD;
      57                 :     double       LAD;
      58                 :     int          ARV;
      59                 :     int          BRV;
      60                 :     int          PCB;
      61                 :     int          PVB;
      62                 : 
      63                 :     GDALColorTable oCT;
      64                 : 
      65                 :   public:
      66                 :                  SRPDataset();
      67                 :     virtual     ~SRPDataset();
      68                 :     
      69                 :     virtual const char *GetProjectionRef(void);
      70                 :     virtual CPLErr GetGeoTransform( double * padfGeoTransform );
      71                 : 
      72                 :     virtual char **GetFileList();
      73                 : 
      74                 :     int                 GetFromRecord( const char* pszFileName, 
      75                 :                                        DDFRecord * record);
      76                 : 
      77                 :     static GDALDataset *Open( GDALOpenInfo * );
      78                 : };
      79                 : 
      80                 : /************************************************************************/
      81                 : /* ==================================================================== */
      82                 : /*                            SRPRasterBand                            */
      83                 : /* ==================================================================== */
      84                 : /************************************************************************/
      85                 : 
      86                 : class SRPRasterBand : public GDALPamRasterBand
      87               6 : {
      88                 :     friend class SRPDataset;
      89                 : 
      90                 :   public:
      91                 :                             SRPRasterBand( SRPDataset *, int );
      92                 : 
      93                 :     virtual CPLErr          IReadBlock( int, int, void * );
      94                 : 
      95                 :     virtual double          GetNoDataValue( int *pbSuccess = NULL );
      96                 : 
      97                 :     virtual GDALColorInterp GetColorInterpretation();
      98                 :     virtual GDALColorTable *GetColorTable();
      99                 : };
     100                 : 
     101                 : 
     102                 : /************************************************************************/
     103                 : /*                           SRPRasterBand()                            */
     104                 : /************************************************************************/
     105                 : 
     106               6 : SRPRasterBand::SRPRasterBand( SRPDataset *poDS, int nBand )
     107                 : 
     108                 : {
     109               6 :     this->poDS = poDS;
     110               6 :     this->nBand = nBand;
     111                 :     
     112               6 :     eDataType = GDT_Byte;
     113                 : 
     114               6 :     nBlockXSize = 128;
     115               6 :     nBlockYSize = 128;
     116               6 : }
     117                 : 
     118                 : /************************************************************************/
     119                 : /*                            GetNoDataValue()                          */
     120                 : /************************************************************************/
     121                 : 
     122               0 : double  SRPRasterBand::GetNoDataValue( int *pbSuccess )
     123                 : {
     124               0 :     if (pbSuccess)
     125               0 :         *pbSuccess = TRUE;
     126                 : 
     127               0 :     return 0;
     128                 : }
     129                 : 
     130                 : /************************************************************************/
     131                 : /*                       GetColorInterpretation()                       */
     132                 : /************************************************************************/
     133                 : 
     134               3 : GDALColorInterp SRPRasterBand::GetColorInterpretation()
     135                 : 
     136                 : {
     137               3 :     SRPDataset* poDS = (SRPDataset*)this->poDS;
     138                 : 
     139               3 :     if( poDS->oCT.GetColorEntryCount() > 0 )
     140               3 :         return GCI_PaletteIndex;
     141                 :     else
     142               0 :         return GCI_GrayIndex;
     143                 : }
     144                 : 
     145                 : /************************************************************************/
     146                 : /*                           GetColorTable()                            */
     147                 : /************************************************************************/
     148                 : 
     149               3 : GDALColorTable *SRPRasterBand::GetColorTable()
     150                 : 
     151                 : {
     152               3 :     SRPDataset* poDS = (SRPDataset*)this->poDS;
     153                 : 
     154               3 :     if( poDS->oCT.GetColorEntryCount() > 0 )
     155               3 :         return &(poDS->oCT);
     156                 :     else
     157               0 :         return NULL;
     158                 : }
     159                 : 
     160                 : /************************************************************************/
     161                 : /*                             IReadBlock()                             */
     162                 : /************************************************************************/
     163                 : 
     164               3 : CPLErr SRPRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     165                 :                                    void * pImage )
     166                 : 
     167                 : {
     168               3 :     SRPDataset* poDS = (SRPDataset*)this->poDS;
     169                 :     int offset;
     170               3 :     int nBlock = nBlockYOff * poDS->NFC + nBlockXOff;
     171               3 :     if (nBlockXOff >= poDS->NFC || nBlockYOff >= poDS->NFL)
     172                 :     {
     173                 :         CPLError(CE_Failure, CPLE_AppDefined, "nBlockXOff=%d, NFC=%d, nBlockYOff=%d, NFL=%d",
     174               0 :                  nBlockXOff, poDS->NFC, nBlockYOff, poDS->NFL);
     175               0 :         return CE_Failure;
     176                 :     }
     177                 : 
     178                 : /* -------------------------------------------------------------------- */
     179                 : /*      Is this a null block?                                           */
     180                 : /* -------------------------------------------------------------------- */
     181               3 :     if (poDS->TILEINDEX && poDS->TILEINDEX[nBlock] == 0)
     182                 :     {
     183               0 :         memset(pImage, 0, 128 * 128);
     184               0 :         return CE_None;
     185                 :     }
     186                 : 
     187                 : /* -------------------------------------------------------------------- */
     188                 : /*      Compute the offset to the block.                                */
     189                 : /* -------------------------------------------------------------------- */
     190               3 :     if (poDS->TILEINDEX)
     191                 :     {
     192               2 :         if( poDS->PCB == 0 ) // uncompressed 
     193               0 :             offset = poDS->offsetInIMG + (poDS->TILEINDEX[nBlock] - 1) * 128 * 128;
     194                 :         else // compressed 
     195               2 :             offset = poDS->offsetInIMG + (poDS->TILEINDEX[nBlock] - 1);
     196                 :     }
     197                 :     else
     198               1 :         offset = poDS->offsetInIMG + nBlock * 128 * 128;
     199                 :     
     200                 : /* -------------------------------------------------------------------- */
     201                 : /*      Seek to target location.                                        */
     202                 : /* -------------------------------------------------------------------- */
     203               3 :     if (VSIFSeekL(poDS->fdIMG, offset, SEEK_SET) != 0)
     204                 :     {
     205               0 :         CPLError(CE_Failure, CPLE_FileIO, "Cannot seek to offset %d", offset);
     206               0 :         return CE_Failure;
     207                 :     }
     208                 : 
     209                 : /* -------------------------------------------------------------------- */
     210                 : /*      For uncompressed case we read the 128x128 and return with no    */
     211                 : /*      further processing.                                             */
     212                 : /* -------------------------------------------------------------------- */
     213               3 :     if( poDS->PCB == 0 )
     214                 :     {
     215               1 :         if( VSIFReadL(pImage, 1, 128 * 128, poDS->fdIMG) != 128*128 )
     216                 :         {
     217                 :             CPLError(CE_Failure, CPLE_FileIO, 
     218               0 :                      "Cannot read data at offset %d", offset);
     219               0 :             return CE_Failure;
     220                 :         }
     221                 :     }
     222                 : 
     223                 : /* -------------------------------------------------------------------- */
     224                 : /*      If this is compressed data, we read a goodly chunk of data      */
     225                 : /*      and then decode it.                                             */
     226                 : /* -------------------------------------------------------------------- */
     227               2 :     else if( poDS->PCB != 0 )
     228                 :     {
     229               2 :         int    nBufSize = 128*128*2;
     230               2 :         int    nBytesRead, iPixel, iSrc, bHalfByteUsed = FALSE;
     231               2 :         GByte *pabyCData = (GByte *) CPLCalloc(nBufSize,1);
     232                 : 
     233               2 :         nBytesRead = VSIFReadL(pabyCData, 1, nBufSize, poDS->fdIMG);
     234               2 :         if( nBytesRead == 0 )
     235                 :         {
     236                 :             CPLError(CE_Failure, CPLE_FileIO, 
     237               0 :                      "Cannot read data at offset %d", offset);
     238               0 :             return CE_Failure;
     239                 :         }
     240                 :         
     241               2 :         CPLAssert( poDS->PVB == 8 );
     242               2 :         CPLAssert( poDS->PCB == 4 || poDS->PCB == 8 );
     243                 : 
     244            1796 :         for( iSrc = 0, iPixel = 0; iPixel < 128 * 128; )
     245                 :         {
     246            1792 :             if( iSrc + 2 > nBytesRead )
     247                 :             {
     248               0 :                 CPLFree( pabyCData );
     249                 :                 CPLError(CE_Failure, CPLE_AppDefined, 
     250                 :                          "Out of data decoding image block, only %d available.",
     251               0 :                          iSrc );
     252               0 :                 return CE_Failure;
     253                 :             }
     254                 : 
     255            1792 :             int nCount = 0;
     256            1792 :             int nValue = 0;
     257                 : 
     258            1792 :             if( poDS->PCB == 8 )
     259                 :             {
     260             640 :                 nCount = pabyCData[iSrc++];
     261             640 :                 nValue = pabyCData[iSrc++];
     262                 :             }
     263            1152 :             else if( poDS->PCB == 4 )
     264                 :             {
     265            1152 :                 if( (iPixel % 128) == 0 && bHalfByteUsed )
     266                 :                 {
     267             127 :                     iSrc++;
     268             127 :                     bHalfByteUsed = FALSE;
     269                 :                 }
     270                 : 
     271            1152 :                 if( bHalfByteUsed )
     272                 :                 {
     273             512 :                     nCount = pabyCData[iSrc++] & 0xf;
     274             512 :                     nValue = pabyCData[iSrc++];
     275             512 :                     bHalfByteUsed = FALSE;
     276                 :                 }
     277                 :                 else
     278                 :                 {
     279             640 :                     nCount = pabyCData[iSrc] >> 4;
     280             640 :                     nValue = ((pabyCData[iSrc] & 0xf) << 4)
     281             640 :                         + (pabyCData[iSrc+1] >> 4);
     282             640 :                     bHalfByteUsed = TRUE;
     283             640 :                     iSrc++;
     284                 :                 }
     285                 :             }
     286                 : 
     287            1792 :             if( iPixel + nCount > 128 * 128 )
     288                 :             {
     289               0 :                 CPLFree( pabyCData );
     290                 :                 CPLError(CE_Failure, CPLE_AppDefined, 
     291               0 :                       "Too much data decoding image block, likely corrupt." );
     292               0 :                 return CE_Failure;
     293                 :             }
     294                 : 
     295           36352 :             while( nCount > 0 )
     296                 :             {
     297           32768 :                 ((GByte *) pImage)[iPixel++] = (GByte) nValue;
     298           32768 :                 nCount--;
     299                 :             }
     300                 :         }
     301                 : 
     302               2 :         CPLFree( pabyCData );
     303                 :     }
     304                 :     
     305               3 :     return CE_None;
     306                 : }
     307                 : 
     308                 : /************************************************************************/
     309                 : /*                          SRPDataset()                               */
     310                 : /************************************************************************/
     311                 : 
     312               6 : SRPDataset::SRPDataset()
     313                 : {
     314               6 :     fdIMG = NULL;
     315               6 :     TILEINDEX = NULL;
     316               6 :     offsetInIMG = 0;
     317               6 : }
     318                 : 
     319                 : /************************************************************************/
     320                 : /*                          ~SRPDataset()                              */
     321                 : /************************************************************************/
     322                 : 
     323               6 : SRPDataset::~SRPDataset()
     324                 : {
     325               6 :     if (fdIMG)
     326                 :     {
     327               6 :         VSIFCloseL(fdIMG);
     328                 :     }
     329                 :     
     330               6 :     if (TILEINDEX)
     331                 :     {
     332               4 :         delete [] TILEINDEX;
     333                 :     }
     334               6 : }
     335                 : 
     336                 : /************************************************************************/
     337                 : /*                          ResetTo01()                                 */
     338                 : /* Replace the DD in ZZZZZZDD.XXX with 01.                              */
     339                 : /************************************************************************/
     340                 : 
     341               6 : CPLString SRPDataset::ResetTo01( const char* str )
     342                 : {
     343               6 :     CPLString osResult = str;
     344                 : 
     345               6 :     osResult[6] = '0';
     346               6 :     osResult[7] = '1';
     347                 : 
     348               0 :     return osResult;
     349                 : }
     350                 : 
     351                 : /************************************************************************/
     352                 : /*                        GetProjectionRef()                            */
     353                 : /************************************************************************/
     354                 : 
     355               3 : const char* SRPDataset::GetProjectionRef()
     356                 : {
     357               3 :     return osSRS;
     358                 : }
     359                 : 
     360                 : /************************************************************************/
     361                 : /*                        GetGeoTransform()                             */
     362                 : /************************************************************************/
     363                 : 
     364               3 : CPLErr SRPDataset::GetGeoTransform( double * padfGeoTransform)
     365                 : {
     366               3 :     if( EQUAL(osProduct,"ASRP") )
     367                 :     {
     368               0 :         if( ZNA == 9 || ZNA == 18 )
     369                 :         {
     370               0 :             padfGeoTransform[0] = -1152000.0;
     371               0 :             padfGeoTransform[1] = 500.0;
     372               0 :             padfGeoTransform[2] = 0.0;
     373               0 :             padfGeoTransform[3] = 1152000.0;
     374               0 :             padfGeoTransform[4] = 0.0;
     375               0 :             padfGeoTransform[5] = -500.0;
     376                 : 
     377                 :         }
     378                 :         else
     379                 :         {
     380               0 :             padfGeoTransform[0] = LSO/3600.0;
     381               0 :             padfGeoTransform[1] = 360. / ARV;
     382               0 :             padfGeoTransform[2] = 0.0;
     383               0 :             padfGeoTransform[3] = PSO/3600.0;
     384               0 :             padfGeoTransform[4] = 0.0;
     385               0 :             padfGeoTransform[5] = - 360. / BRV;
     386                 :         }
     387                 : 
     388               0 :         return CE_None;
     389                 :     }
     390               3 :     else if( EQUAL(osProduct,"USRP") )
     391                 :     {
     392               3 :         padfGeoTransform[0] = LSO;
     393               3 :         padfGeoTransform[1] = LOD;
     394               3 :         padfGeoTransform[2] = 0.0;
     395               3 :         padfGeoTransform[3] = PSO;
     396               3 :         padfGeoTransform[4] = 0.0;
     397               3 :         padfGeoTransform[5] = -LAD;
     398               3 :         return CE_None;
     399                 :     }
     400                 : 
     401               0 :     return CE_Failure;
     402                 : }
     403                 : 
     404                 : /************************************************************************/
     405                 : /*                           GetFromRecord()                            */
     406                 : /************************************************************************/
     407                 : 
     408               6 : int SRPDataset::GetFromRecord(const char* pszFileName, DDFRecord * record)
     409                 : {
     410               6 :     CPLString osBAD;
     411                 :     int i;
     412                 : 
     413                 :     DDFField* field;
     414                 :     DDFFieldDefn *fieldDefn;
     415                 :     int bSuccess;
     416                 :     int nSTR;
     417                 : 
     418                 : /* -------------------------------------------------------------------- */
     419                 : /*      Read a variety of header fields of interest from the .GEN       */
     420                 : /*      file.                                                           */
     421                 : /* -------------------------------------------------------------------- */
     422               6 :     nSTR = record->GetIntSubfield( "GEN", 0, "STR", 0, &bSuccess );
     423               6 :     if( !bSuccess || nSTR != 4 )
     424                 :     {
     425               0 :         CPLDebug( "SRP", "Failed to extract STR, or not 4." );
     426               0 :         return FALSE;
     427                 :     }
     428                 :         
     429               6 :     int SCA = record->GetIntSubfield( "GEN", 0, "SCA", 0, &bSuccess );
     430               6 :     CPLDebug("SRP", "SCA=%d", SCA);
     431                 :         
     432               6 :     ZNA = record->GetIntSubfield( "GEN", 0, "ZNA", 0, &bSuccess );
     433               6 :     CPLDebug("SRP", "ZNA=%d", ZNA);
     434                 :         
     435               6 :     double PSP = record->GetFloatSubfield( "GEN", 0, "PSP", 0, &bSuccess );
     436               6 :     CPLDebug("SRP", "PSP=%f", PSP);
     437                 :         
     438               6 :     ARV = record->GetIntSubfield( "GEN", 0, "ARV", 0, &bSuccess );
     439               6 :     CPLDebug("SRP", "ARV=%d", ARV);
     440                 : 
     441               6 :     BRV = record->GetIntSubfield( "GEN", 0, "BRV", 0, &bSuccess );
     442               6 :     CPLDebug("SRP", "BRV=%d", BRV);
     443                 : 
     444               6 :     LSO = record->GetFloatSubfield( "GEN", 0, "LSO", 0, &bSuccess );
     445               6 :     CPLDebug("SRP", "LSO=%f", LSO);
     446                 : 
     447               6 :     PSO = record->GetFloatSubfield( "GEN", 0, "PSO", 0, &bSuccess );
     448               6 :     CPLDebug("SRP", "PSO=%f", PSO);
     449                 : 
     450               6 :     LAD = record->GetFloatSubfield( "GEN", 0, "LAD", 0 );
     451               6 :     LOD = record->GetFloatSubfield( "GEN", 0, "LOD", 0 );
     452                 : 
     453               6 :     NFL = record->GetIntSubfield( "SPR", 0, "NFL", 0, &bSuccess );
     454               6 :     CPLDebug("SRP", "NFL=%d", NFL);
     455                 : 
     456               6 :     NFC = record->GetIntSubfield( "SPR", 0, "NFC", 0, &bSuccess );
     457               6 :     CPLDebug("SRP", "NFC=%d", NFC);
     458                 : 
     459               6 :     int PNC = record->GetIntSubfield( "SPR", 0, "PNC", 0, &bSuccess );
     460               6 :     CPLDebug("SRP", "PNC=%d", PNC);
     461                 : 
     462               6 :     int PNL = record->GetIntSubfield( "SPR", 0, "PNL", 0, &bSuccess );
     463               6 :     CPLDebug("SRP", "PNL=%d", PNL);
     464                 : 
     465               6 :     if( PNL != 128 || PNC != 128 )
     466                 :     {
     467               0 :         CPLError( CE_Failure, CPLE_AppDefined,"Unsupported PNL or PNC value.");
     468               0 :         return FALSE;
     469                 :     }
     470                 : 
     471               6 :     PCB = record->GetIntSubfield( "SPR", 0, "PCB", 0 );
     472               6 :     PVB = record->GetIntSubfield( "SPR", 0, "PVB", 0 );
     473               6 :     if( (PCB != 8 && PCB != 4 && PCB != 0) || PVB != 8 )
     474                 :     {
     475                 :         CPLError( CE_Failure, CPLE_AppDefined,
     476               0 :                   "PCB(%d) or PVB(%d) value unsupported.", PCB, PVB );
     477               0 :         return FALSE;
     478                 :     }
     479                 : 
     480               6 :     osBAD = record->GetStringSubfield( "SPR", 0, "BAD", 0, &bSuccess );
     481                 :     {
     482               6 :         char* c = (char*) strchr(osBAD, ' ');
     483               6 :         if (c)
     484               0 :             *c = 0;
     485                 :     }
     486               6 :     CPLDebug("SRP", "BAD=%s", osBAD.c_str());
     487                 :     
     488                 : /* -------------------------------------------------------------------- */
     489                 : /*      Read the tile map if available.                                 */
     490                 : /* -------------------------------------------------------------------- */
     491               6 :     int TIF = EQUAL(record->GetStringSubfield( "SPR", 0, "TIF", 0 ),"Y");
     492               6 :     CPLDebug("SRP", "TIF=%d", TIF);
     493                 :     
     494               6 :     if (TIF)
     495                 :     {
     496               4 :         field = record->FindField( "TIM" );
     497               4 :         if( field == NULL )
     498               0 :             return FALSE;
     499                 : 
     500               4 :         fieldDefn = field->GetFieldDefn();
     501               4 :         DDFSubfieldDefn *subfieldDefn = fieldDefn->FindSubfieldDefn( "TSI" );
     502               4 :         if( subfieldDefn == NULL )
     503               0 :             return FALSE;
     504                 : 
     505               4 :         int nIndexValueWidth = subfieldDefn->GetWidth();
     506                 : 
     507                 :         /* Should be strict comparison, but apparently a few datasets */
     508                 :         /* have GetDataSize() greater than the required minimum (#3862) */
     509               4 :         if (field->GetDataSize() < nIndexValueWidth * NFL * NFC + 1)
     510                 :         {
     511               0 :             return FALSE;
     512                 :         }
     513                 :     
     514               4 :         TILEINDEX = new int [NFL * NFC];
     515               4 :         const char* ptr = field->GetData();
     516               4 :         char offset[30]={0};
     517               4 :         offset[nIndexValueWidth] = '\0';
     518                 : 
     519               8 :         for(i=0;i<NFL*NFC;i++)
     520                 :         {
     521               4 :             strncpy(offset, ptr, nIndexValueWidth);
     522               4 :             ptr += nIndexValueWidth;
     523               4 :             TILEINDEX[i] = atoi(offset);
     524                 :             //CPLDebug("SRP", "TSI[%d]=%d", i, TILEINDEX[i]);
     525                 :         }
     526                 :     }
     527                 :     
     528                 : /* -------------------------------------------------------------------- */
     529                 : /*      Open the .IMG file.  Try to recover gracefully if the case      */
     530                 : /*      of the filename is wrong.                                       */
     531                 : /* -------------------------------------------------------------------- */
     532               6 :     CPLString osDirname = CPLGetDirname(pszFileName);
     533               6 :     CPLString osImgName = CPLFormCIFilename(osDirname, osBAD, NULL);
     534                 : 
     535               6 :     fdIMG = VSIFOpenL(osImgName, "rb");
     536               6 :     if (fdIMG == NULL)
     537                 :     {
     538               0 :         CPLError( CE_Failure, CPLE_AppDefined, "Cannot find %s", osImgName.c_str());
     539               0 :         return FALSE;
     540                 :     }
     541                 :     
     542                 : /* -------------------------------------------------------------------- */
     543                 : /*      Establish the offset to the first byte of actual image data     */
     544                 : /*      in the IMG file, skipping the ISO8211 header.                   */
     545                 : /*                                                                      */
     546                 : /*      This code is awfully fragile!                                   */
     547                 : /* -------------------------------------------------------------------- */
     548                 :     char c;
     549                 :     char recordName[3];
     550               6 :     if (VSIFReadL(&c, 1, 1, fdIMG) != 1)
     551                 :     {
     552               0 :         return FALSE;
     553                 :     }
     554            1314 :     while (!VSIFEofL(fdIMG))
     555                 :     {
     556            1308 :         if (c == 30)
     557                 :         {
     558              36 :             if (VSIFReadL(recordName, 1, 3, fdIMG) != 3)
     559                 :             {
     560               0 :                 return FALSE;
     561                 :             }
     562              36 :             offsetInIMG += 3;
     563              36 :             if (strncmp(recordName,"IMG",3) == 0)
     564                 :             {
     565               6 :                 offsetInIMG += 4;
     566               6 :                 if (VSIFSeekL(fdIMG,3,SEEK_CUR) != 0)
     567                 :                 {
     568               0 :                     return FALSE;
     569                 :                 }
     570               6 :                 if (VSIFReadL(&c, 1, 1, fdIMG) != 1)
     571                 :                 {
     572               0 :                     return FALSE;
     573                 :                 }
     574           23148 :                 while( c != 30 )
     575                 :                 {
     576           23136 :                     offsetInIMG ++;
     577           23136 :                     if (VSIFReadL(&c, 1, 1, fdIMG) != 1)
     578                 :                     {
     579               0 :                         return FALSE;
     580                 :                     }
     581                 :                 }
     582               6 :                 offsetInIMG ++;
     583               6 :                 break;
     584                 :             }
     585                 :         }
     586                 : 
     587            1302 :         offsetInIMG ++;
     588            1302 :         if (VSIFReadL(&c, 1, 1, fdIMG) != 1)
     589                 :         {
     590               0 :             return FALSE;
     591                 :         }
     592                 :     }
     593                 :     
     594               6 :     if (VSIFEofL(fdIMG))
     595                 :     {
     596               0 :         return FALSE;
     597                 :     }
     598                 :     
     599               6 :     CPLDebug("SRP", "Img offset data = %d", offsetInIMG);
     600                 :     
     601                 : /* -------------------------------------------------------------------- */
     602                 : /*      Establish the SRP Dataset.                                     */
     603                 : /* -------------------------------------------------------------------- */
     604               6 :     nRasterXSize = NFC * 128;
     605               6 :     nRasterYSize = NFL * 128;
     606                 :     
     607                 :     char pszValue[32];
     608               6 :     sprintf(pszValue, "%d", SCA);
     609               6 :     SetMetadataItem( "SRP_SCA", pszValue );
     610                 :     
     611               6 :     nBands = 1;
     612              12 :     for( i = 0; i < nBands; i++ )
     613               6 :         SetBand( i+1, new SRPRasterBand( this, i+1 ) );
     614                 : 
     615                 : /* -------------------------------------------------------------------- */
     616                 : /*      Try to collect a color map from the .QAL file.                  */
     617                 : /* -------------------------------------------------------------------- */
     618               6 :     CPLString osBasename = CPLGetBasename(pszFileName);
     619               6 :     osQALFilename = CPLFormCIFilename(osDirname, osBasename, "QAL");
     620                 : 
     621               6 :     DDFModule oQALModule;
     622                 : 
     623               6 :     if( oQALModule.Open( osQALFilename, TRUE ) )
     624                 :     {
     625               6 :         while( (record = oQALModule.ReadRecord()) != NULL
     626                 :                && record->FindField( "COL" ) == NULL ) {}
     627                 : 
     628               6 :         if( record != NULL )
     629                 :         {
     630                 :             int            iColor;
     631                 :             int            nColorCount = 
     632               6 :                 record->FindField("COL")->GetRepeatCount();
     633                 : 
     634              30 :             for( iColor = 0; iColor < nColorCount; iColor++ )
     635                 :             {
     636                 :                 int bSuccess;
     637                 :                 int nCCD, nNSR, nNSG, nNSB;
     638                 :                 GDALColorEntry sEntry;
     639                 : 
     640                 :                 nCCD = record->GetIntSubfield( "COL", 0, "CCD", iColor,
     641              24 :                                                &bSuccess );
     642              24 :                 if( !bSuccess )
     643               0 :                     break;
     644                 : 
     645              24 :                 nNSR = record->GetIntSubfield( "COL", 0, "NSR", iColor );
     646              24 :                 nNSG = record->GetIntSubfield( "COL", 0, "NSG", iColor );
     647              24 :                 nNSB = record->GetIntSubfield( "COL", 0, "NSB", iColor );
     648                 : 
     649              24 :                 sEntry.c1 = (short) nNSR;
     650              24 :                 sEntry.c2 = (short) nNSG;
     651              24 :                 sEntry.c3 = (short) nNSB;
     652              24 :                 sEntry.c4 = 255;
     653                 : 
     654              24 :                 oCT.SetColorEntry( nCCD, &sEntry );
     655                 :             }
     656                 :         }
     657                 :     }
     658                 :     else
     659                 :     {
     660               0 :         osQALFilename = "";
     661                 :         CPLError( CE_Warning, CPLE_AppDefined,
     662               0 :                   "Unable to find .QAL file, no color table applied." );
     663                 :     }
     664                 : 
     665                 : /* -------------------------------------------------------------------- */
     666                 : /*      Derive the coordinate system.                                   */
     667                 : /* -------------------------------------------------------------------- */
     668               6 :     if( EQUAL(osProduct,"ASRP") )
     669                 :     {
     670               0 :         osSRS = SRS_WKT_WGS84;
     671                 : 
     672               0 :         if( ZNA == 9 )
     673                 :         {
     674               0 :             osSRS = "PROJCS[\"unnamed\",GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],PROJECTION[\"Azimuthal_Equidistant\"],PARAMETER[\"latitude_of_center\",90],PARAMETER[\"longitude_of_center\",0],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0]]";
     675                 :         }
     676                 : 
     677               0 :         if (ZNA == 18)
     678                 :         {
     679               0 :             osSRS = "PROJCS[\"unnamed\",GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],PROJECTION[\"Azimuthal_Equidistant\"],PARAMETER[\"latitude_of_center\",-90],PARAMETER[\"longitude_of_center\",0],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0]]";
     680                 :         }
     681                 :     }
     682                 :     else
     683                 :     {
     684               6 :         OGRSpatialReference oSRS;
     685                 : 
     686              12 :         if( ABS(ZNA) >= 1 && ABS(ZNA) <= 60 )
     687                 :         {
     688               6 :             oSRS.SetUTM( ABS(ZNA), ZNA > 0 );
     689               6 :             oSRS.SetWellKnownGeogCS( "WGS84" );
     690                 :         }
     691               0 :         else if( ZNA == 61 )
     692                 :         {
     693               0 :             oSRS.importFromEPSG( 32661 ); // WGS84 UPS North 
     694                 :         }
     695               0 :         else if( ZNA == -61 )
     696                 :         {
     697               0 :             oSRS.importFromEPSG( 32761 ); // WGS84 UPS South 
     698                 :         }
     699                 : 
     700               6 :         char *pszWKT = NULL;
     701               6 :         oSRS.exportToWkt( &pszWKT );
     702               6 :         osSRS = pszWKT;
     703               6 :         CPLFree( pszWKT );
     704                 :     }
     705                 : 
     706               6 :     return TRUE;
     707                 : }
     708                 : 
     709                 : /************************************************************************/
     710                 : /*                            GetFileList()                             */
     711                 : /************************************************************************/
     712                 : 
     713               0 : char **SRPDataset::GetFileList()
     714                 : 
     715                 : {
     716               0 :      char **papszFileList = GDALPamDataset::GetFileList();
     717                 : 
     718               0 :      papszFileList = CSLAddString( papszFileList, osGENFilename );
     719                 : 
     720               0 :      if( strlen(osQALFilename) > 0 )
     721               0 :          papszFileList = CSLAddString( papszFileList, osQALFilename );
     722                 : 
     723               0 :      return papszFileList;
     724                 : }
     725                 : 
     726                 : /************************************************************************/
     727                 : /*                                Open()                                */
     728                 : /************************************************************************/
     729                 : 
     730           11793 : GDALDataset *SRPDataset::Open( GDALOpenInfo * poOpenInfo )
     731                 : {
     732           11793 :     DDFModule module;
     733                 :     DDFRecord * record;
     734           11793 :     CPLString osFileName(poOpenInfo->pszFilename);
     735           11793 :     CPLString osNAM;
     736                 : 
     737                 : /* -------------------------------------------------------------------- */
     738                 : /*      Verify that this appears to be a valid ISO8211 .IMG file.       */
     739                 : /* -------------------------------------------------------------------- */
     740           11793 :     if( poOpenInfo->nHeaderBytes < 500 )
     741           11372 :         return NULL;
     742                 : 
     743             421 :     if (!EQUAL(CPLGetExtension(osFileName), "img"))
     744             415 :         return NULL;
     745                 : 
     746                 :     static const size_t nLeaderSize = 24;
     747                 :     int         i;
     748                 : 
     749             150 :     for( i = 0; i < (int)nLeaderSize; i++ )
     750                 :     {
     751             288 :         if( poOpenInfo->pabyHeader[i] < 32 
     752             144 :             || poOpenInfo->pabyHeader[i] > 126 )
     753               0 :             return NULL;
     754                 :     }
     755                 : 
     756              12 :     if( poOpenInfo->pabyHeader[5] != '1' 
     757               6 :         && poOpenInfo->pabyHeader[5] != '2' 
     758               0 :         && poOpenInfo->pabyHeader[5] != '3' )
     759               0 :         return NULL;
     760                 : 
     761               6 :     if( poOpenInfo->pabyHeader[6] != 'L' )
     762               0 :         return NULL;
     763               6 :     if( poOpenInfo->pabyHeader[8] != '1' && poOpenInfo->pabyHeader[8] != ' ' )
     764               0 :         return NULL;
     765                 : 
     766                 : /* -------------------------------------------------------------------- */
     767                 : /*      Find and open the .GEN file.                                    */
     768                 : /* -------------------------------------------------------------------- */
     769                 :     VSIStatBufL sStatBuf;
     770                 : 
     771               6 :     CPLString basename = CPLGetBasename( osFileName );
     772               6 :     if( basename.size() != 8 )
     773                 :     {
     774               0 :         CPLDebug("SRP", "Invalid basename file");
     775               0 :         return NULL;
     776                 :     }
     777                 : 
     778               6 :     int zoneNumber = CPLScanLong( basename + 6, 2 );
     779                 : 
     780               6 :     CPLString path = CPLGetDirname( osFileName );
     781               6 :     CPLString basename01 = ResetTo01( basename );
     782               6 :     osFileName = CPLFormFilename( path, basename01, ".IMG" );
     783                 : 
     784               6 :     osFileName = CPLResetExtension( osFileName, "GEN" );
     785               6 :     if( VSIStatL( osFileName, &sStatBuf ) != 0 )
     786                 :     {
     787               0 :         osFileName = CPLResetExtension( osFileName, "gen" );
     788               0 :         if( VSIStatL( osFileName, &sStatBuf ) != 0 )
     789               0 :             return NULL;
     790                 :     }
     791                 : 
     792               6 :     if (!module.Open(osFileName, TRUE))
     793               0 :         return NULL;
     794                 : 
     795               6 :     if( poOpenInfo->eAccess == GA_Update )
     796                 :     {
     797                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     798                 :                   "The SRP driver does not support update access to existing"
     799               0 :                   " datasets.\n" );
     800               0 :         return NULL;
     801                 :     }
     802                 : 
     803                 : /* -------------------------------------------------------------------- */
     804                 : /*      Loop processing records - we are basically looking for the      */
     805                 : /*      GIN record which is normally first in the .GEN file.            */
     806                 : /* -------------------------------------------------------------------- */
     807               6 :     int recordIndex = 0;
     808               0 :     while (TRUE)
     809                 :     {
     810               6 :         CPLPushErrorHandler( CPLQuietErrorHandler );
     811               6 :         record = module.ReadRecord();
     812               6 :         CPLPopErrorHandler();
     813               6 :         CPLErrorReset();
     814               6 :         if (record == NULL)
     815                 :           break;
     816               6 :         if ( ++recordIndex < zoneNumber )
     817               0 :           continue;
     818                 : 
     819               6 :         const char* RTY = record->GetStringSubfield( "001", 0, "RTY", 0 );
     820               6 :         if( RTY == NULL || !EQUAL(RTY,"GIN") )
     821               0 :             continue;
     822                 : 
     823               6 :         const char *PRT = record->GetStringSubfield( "DSI", 0, "PRT", 0 );
     824               6 :         if( PRT == NULL )
     825               0 :             continue;
     826                 : 
     827               6 :         CPLString osPRT = PRT;
     828               6 :         osPRT.resize(4);
     829               6 :         if( !EQUAL(osPRT,"ASRP") && !EQUAL(osPRT,"USRP") )
     830               0 :             continue;
     831                 : 
     832               6 :         osNAM = record->GetStringSubfield( "DSI", 0, "NAM", 0 );
     833               6 :         CPLDebug("SRP", "NAM=%s", osNAM.c_str());
     834                 : 
     835               6 :         SRPDataset *poDS = new SRPDataset();
     836                 :         
     837               6 :         poDS->osProduct = osPRT;
     838               6 :         poDS->osGENFilename = osFileName;
     839               6 :         poDS->SetMetadataItem( "SRP_NAM", osNAM );
     840               6 :         poDS->SetMetadataItem( "SRP_PRODUCT", osPRT );
     841                 : 
     842               6 :         if (!poDS->GetFromRecord( osFileName, record ) )
     843                 :         {
     844               0 :             delete poDS;
     845               0 :             continue;
     846                 :         }
     847                 :         
     848                 :         /* ---------------------------------------------------------- */
     849                 :         /*      Initialize any PAM information.                       */
     850                 :         /* ---------------------------------------------------------- */
     851               6 :         poDS->SetDescription( poOpenInfo->pszFilename );
     852               6 :         poDS->TryLoadXML();
     853                 : 
     854                 :         /* ---------------------------------------------------------- */
     855                 :         /*      Check for external overviews.                         */
     856                 :         /* ---------------------------------------------------------- */
     857               6 :         poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     858                 : 
     859               6 :         return poDS;
     860                 :     }
     861                 :     
     862               0 :     return NULL;
     863                 : }
     864                 : 
     865                 : /************************************************************************/
     866                 : /*                         GDALRegister_SRP()                          */
     867                 : /************************************************************************/
     868                 : 
     869             582 : void GDALRegister_SRP()
     870                 : 
     871                 : {
     872                 :     GDALDriver  *poDriver;
     873                 : 
     874             582 :     if( GDALGetDriverByName( "SRP" ) == NULL )
     875                 :     {
     876             561 :         poDriver = new GDALDriver();
     877                 :         
     878             561 :         poDriver->SetDescription( "SRP" );
     879                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     880             561 :                                    "Standard Raster Product (ASRP/USRP)" );
     881                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     882             561 :                                    "frmt_various.html#SRP" );
     883             561 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "img" );
     884             561 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     885                 : 
     886             561 :         poDriver->pfnOpen = SRPDataset::Open;
     887                 : 
     888             561 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     889                 :     }
     890             582 : }
     891                 : 

Generated by: LCOV version 1.7