LCOV - code coverage report
Current view: directory - frmts/adrg - srpdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 389 19 4.9 %
Date: 2012-04-28 Functions: 24 2 8.3 %

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

Generated by: LCOV version 1.7