LTP GCOV extension - code coverage report
Current view: directory - frmts/aigrid - aigdataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 332
Code covered: 63.3 % Executed lines: 210

       1                 : /******************************************************************************
       2                 :  * $Id: aigdataset.cpp 19496 2010-04-22 15:39:29Z warmerdam $
       3                 :  *
       4                 :  * Project:  Arc/Info Binary Grid Driver
       5                 :  * Purpose:  Implements GDAL interface to underlying library.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_pam.h"
      31                 : #include "cpl_string.h"
      32                 : #include "ogr_spatialref.h"
      33                 : #include "gdal_rat.h"
      34                 : #include "aigrid.h"
      35                 : #include "avc.h"
      36                 : 
      37                 : CPL_CVSID("$Id: aigdataset.cpp 19496 2010-04-22 15:39:29Z warmerdam $");
      38                 : 
      39                 : CPL_C_START
      40                 : void  GDALRegister_AIGrid(void);
      41                 : CPL_C_END
      42                 : 
      43                 : static CPLString OSR_GDS( char **papszNV, const char * pszField, 
      44                 :                            const char *pszDefaultValue );
      45                 : 
      46                 : 
      47                 : /************************************************************************/
      48                 : /* ==================================================================== */
      49                 : /*        AIGDataset        */
      50                 : /* ==================================================================== */
      51                 : /************************************************************************/
      52                 : 
      53                 : class AIGRasterBand;
      54                 : 
      55                 : class CPL_DLL AIGDataset : public GDALPamDataset
      56                 : {
      57                 :     friend class AIGRasterBand;
      58                 :     
      59                 :     AIGInfo_t *psInfo;
      60                 : 
      61                 :     char  **papszPrj;
      62                 :     char  *pszProjection;
      63                 : 
      64                 :     GDALColorTable *poCT;
      65                 :     int         bHasReadRat;
      66                 : 
      67                 :     void        TranslateColorTable( const char * );
      68                 : 
      69                 :     void        ReadRAT();
      70                 :     GDALRasterAttributeTable *poRAT;
      71                 : 
      72                 :   public:
      73                 :                 AIGDataset();
      74                 :                 ~AIGDataset();
      75                 : 
      76                 :     static GDALDataset *Open( GDALOpenInfo * );
      77                 : 
      78                 :     virtual CPLErr GetGeoTransform( double * );
      79                 :     virtual const char *GetProjectionRef(void);
      80                 :     virtual char **GetFileList(void);
      81                 : };
      82                 : 
      83                 : /************************************************************************/
      84                 : /* ==================================================================== */
      85                 : /*                            AIGRasterBand                             */
      86                 : /* ==================================================================== */
      87                 : /************************************************************************/
      88                 : 
      89                 : class AIGRasterBand : public GDALPamRasterBand
      90                 : 
      91               7 : {
      92                 :     friend class AIGDataset;
      93                 : 
      94                 :   public:
      95                 : 
      96                 :                    AIGRasterBand( AIGDataset *, int );
      97                 : 
      98                 :     virtual CPLErr IReadBlock( int, int, void * );
      99                 :     virtual double GetMinimum( int *pbSuccess );
     100                 :     virtual double GetMaximum( int *pbSuccess );
     101                 :     virtual double GetNoDataValue( int *pbSuccess );
     102                 : 
     103                 :     virtual GDALColorInterp GetColorInterpretation();
     104                 :     virtual GDALColorTable *GetColorTable();
     105                 :     virtual const GDALRasterAttributeTable *GetDefaultRAT();
     106                 : };
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                           AIGRasterBand()                            */
     110                 : /************************************************************************/
     111                 : 
     112               7 : AIGRasterBand::AIGRasterBand( AIGDataset *poDS, int nBand )
     113                 : 
     114                 : {
     115               7 :     this->poDS = poDS;
     116               7 :     this->nBand = nBand;
     117                 : 
     118               7 :     nBlockXSize = poDS->psInfo->nBlockXSize;
     119               7 :     nBlockYSize = poDS->psInfo->nBlockYSize;
     120                 : 
     121              12 :     if( poDS->psInfo->nCellType == AIG_CELLTYPE_INT
     122                 :         && poDS->psInfo->dfMin >= 0.0 && poDS->psInfo->dfMax <= 254.0 )
     123                 :     {
     124               5 :         eDataType = GDT_Byte;
     125                 :     }
     126               4 :     else if( poDS->psInfo->nCellType == AIG_CELLTYPE_INT
     127                 :         && poDS->psInfo->dfMin >= -32767 && poDS->psInfo->dfMax <= 32767 )
     128                 :     {
     129               2 :         eDataType = GDT_Int16;
     130                 :     }
     131               0 :     else if( poDS->psInfo->nCellType == AIG_CELLTYPE_INT )
     132                 :     {
     133               0 :         eDataType = GDT_Int32;
     134                 :     }
     135                 :     else
     136                 :     {
     137               0 :         eDataType = GDT_Float32;
     138                 :     }
     139               7 : }
     140                 : 
     141                 : /************************************************************************/
     142                 : /*                             IReadBlock()                             */
     143                 : /************************************************************************/
     144                 : 
     145                 : CPLErr AIGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     146            5898 :                                   void * pImage )
     147                 : 
     148                 : {
     149            5898 :     AIGDataset  *poODS = (AIGDataset *) poDS;
     150                 :     GInt32  *panGridRaster;
     151                 :     int   i;
     152                 : 
     153            5898 :     if( poODS->psInfo->nCellType == AIG_CELLTYPE_INT )
     154                 :     {
     155            5898 :         panGridRaster = (GInt32 *) VSIMalloc3(4,nBlockXSize,nBlockYSize);
     156            5898 :         if( panGridRaster == NULL ||
     157                 :             AIGReadTile( poODS->psInfo, nBlockXOff, nBlockYOff, panGridRaster )
     158                 :             != CE_None )
     159                 :         {
     160               0 :             CPLFree( panGridRaster );
     161               0 :             return CE_Failure;
     162                 :         }
     163                 : 
     164            5898 :         if( eDataType == GDT_Byte )
     165                 :         {
     166            2050 :             for( i = 0; i < nBlockXSize * nBlockYSize; i++ )
     167                 :             {
     168            2048 :                 if( panGridRaster[i] == ESRI_GRID_NO_DATA )
     169            2042 :                     ((GByte *) pImage)[i] = 255;
     170                 :                 else
     171               6 :                     ((GByte *) pImage)[i] = (GByte) panGridRaster[i];
     172                 :             }
     173                 :         }
     174            5896 :         else if( eDataType == GDT_Int16 )
     175                 :         {
     176         6043400 :             for( i = 0; i < nBlockXSize * nBlockYSize; i++ )
     177                 :             {
     178         6037504 :                 if( panGridRaster[i] == ESRI_GRID_NO_DATA )
     179         4967529 :                     ((GInt16 *) pImage)[i] = -32768;
     180                 :                 else
     181         1069975 :                     ((GInt16 *) pImage)[i] = (GInt16) panGridRaster[i];
     182                 :             }
     183                 :         }
     184                 :         else
     185                 :         {
     186               0 :             for( i = 0; i < nBlockXSize * nBlockYSize; i++ )
     187               0 :                 ((GInt32 *) pImage)[i] = panGridRaster[i];
     188                 :         }
     189                 :         
     190            5898 :         CPLFree( panGridRaster );
     191                 : 
     192            5898 :         return CE_None;
     193                 :     }
     194                 :     else
     195                 :     {
     196                 :         return AIGReadFloatTile( poODS->psInfo, nBlockXOff, nBlockYOff,
     197               0 :                                  (float *) pImage );
     198                 :     }
     199                 : }
     200                 : 
     201                 : /************************************************************************/
     202                 : /*                           GetDefaultRAT()                            */
     203                 : /************************************************************************/
     204                 : 
     205               1 : const GDALRasterAttributeTable *AIGRasterBand::GetDefaultRAT()
     206                 : 
     207                 : {
     208               1 :     AIGDataset  *poODS = (AIGDataset *) poDS;
     209                 : 
     210                 : /* -------------------------------------------------------------------- */
     211                 : /*      Read info raster attribute table, if present.                   */
     212                 : /* -------------------------------------------------------------------- */
     213               1 :     if (!poODS->bHasReadRat)
     214                 :     {
     215               1 :         poODS->ReadRAT();
     216               1 :         poODS->bHasReadRat = TRUE;
     217                 :     }
     218                 : 
     219               1 :     return poODS->poRAT;
     220                 : }
     221                 : 
     222                 : /************************************************************************/
     223                 : /*                             GetMinimum()                             */
     224                 : /************************************************************************/
     225                 : 
     226               1 : double AIGRasterBand::GetMinimum( int *pbSuccess )
     227                 : 
     228                 : {
     229               1 :     AIGDataset  *poODS = (AIGDataset *) poDS;
     230                 : 
     231               1 :     if( pbSuccess != NULL )
     232               1 :         *pbSuccess = TRUE;
     233                 : 
     234               1 :     return poODS->psInfo->dfMin;
     235                 : }
     236                 : 
     237                 : /************************************************************************/
     238                 : /*                             GetMaximum()                             */
     239                 : /************************************************************************/
     240                 : 
     241               1 : double AIGRasterBand::GetMaximum( int *pbSuccess )
     242                 : 
     243                 : {
     244               1 :     AIGDataset  *poODS = (AIGDataset *) poDS;
     245                 : 
     246               1 :     if( pbSuccess != NULL )
     247               1 :         *pbSuccess = TRUE;
     248                 : 
     249               1 :     return poODS->psInfo->dfMax;
     250                 : }
     251                 : 
     252                 : /************************************************************************/
     253                 : /*                           GetNoDataValue()                           */
     254                 : /************************************************************************/
     255                 : 
     256               3 : double AIGRasterBand::GetNoDataValue( int *pbSuccess )
     257                 : 
     258                 : {
     259               3 :     if( pbSuccess != NULL )
     260               3 :         *pbSuccess = TRUE;
     261                 : 
     262               3 :     if( eDataType == GDT_Float32 )
     263               0 :         return ESRI_GRID_FLOAT_NO_DATA;
     264               3 :     else if( eDataType == GDT_Int16 )
     265               0 :         return -32768;
     266               3 :     else if( eDataType == GDT_Byte )
     267               3 :         return 255;
     268                 :     else
     269               0 :         return ESRI_GRID_NO_DATA;
     270                 : }
     271                 : 
     272                 : /************************************************************************/
     273                 : /*                       GetColorInterpretation()                       */
     274                 : /************************************************************************/
     275                 : 
     276               0 : GDALColorInterp AIGRasterBand::GetColorInterpretation()
     277                 : 
     278                 : {
     279               0 :     AIGDataset  *poODS = (AIGDataset *) poDS;
     280                 : 
     281               0 :     if( poODS->poCT != NULL )
     282               0 :         return GCI_PaletteIndex;
     283                 :     else
     284               0 :         return GCI_Undefined;
     285                 : }
     286                 : 
     287                 : /************************************************************************/
     288                 : /*                           GetColorTable()                            */
     289                 : /************************************************************************/
     290                 : 
     291               2 : GDALColorTable *AIGRasterBand::GetColorTable()
     292                 : 
     293                 : {
     294               2 :     AIGDataset  *poODS = (AIGDataset *) poDS;
     295                 : 
     296               2 :     return poODS->poCT;
     297                 : }
     298                 : 
     299                 : /************************************************************************/
     300                 : /* ==================================================================== */
     301                 : /*                            AIGDataset                               */
     302                 : /* ==================================================================== */
     303                 : /************************************************************************/
     304                 : 
     305                 : 
     306                 : /************************************************************************/
     307                 : /*                            AIGDataset()                            */
     308                 : /************************************************************************/
     309                 : 
     310               7 : AIGDataset::AIGDataset()
     311                 : 
     312                 : {
     313               7 :     psInfo = NULL;
     314               7 :     papszPrj = NULL;
     315               7 :     pszProjection = CPLStrdup("");
     316               7 :     poCT = NULL;
     317               7 :     poRAT = NULL;
     318               7 :     bHasReadRat = FALSE;
     319               7 : }
     320                 : 
     321                 : /************************************************************************/
     322                 : /*                           ~AIGDataset()                            */
     323                 : /************************************************************************/
     324                 : 
     325               7 : AIGDataset::~AIGDataset()
     326                 : 
     327                 : {
     328               7 :     FlushCache();
     329               7 :     CPLFree( pszProjection );
     330               7 :     CSLDestroy( papszPrj );
     331               7 :     if( psInfo != NULL )
     332               7 :         AIGClose( psInfo );
     333                 : 
     334               7 :     if( poCT != NULL )
     335               5 :         delete poCT;
     336                 : 
     337               7 :     if( poRAT != NULL )
     338               1 :         delete poRAT;
     339               7 : }
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                            GetFileList()                             */
     343                 : /************************************************************************/
     344                 : 
     345               0 : char **AIGDataset::GetFileList()
     346                 : 
     347                 : {
     348               0 :     char **papszFileList = GDALPamDataset::GetFileList();
     349                 : 
     350                 :     // Add in all files in the cover directory.
     351               0 :     char **papszCoverFiles = VSIReadDir( GetDescription() );
     352                 :     int i;
     353                 : 
     354               0 :     for( i = 0; papszCoverFiles != NULL && papszCoverFiles[i] != NULL; i++ )
     355                 :     {
     356               0 :         if( EQUAL(papszCoverFiles[i],".")
     357                 :             || EQUAL(papszCoverFiles[i],"..") )
     358               0 :             continue;
     359                 : 
     360                 :         papszFileList = 
     361                 :             CSLAddString( papszFileList, 
     362                 :                           CPLFormFilename( GetDescription(), 
     363                 :                                            papszCoverFiles[i], 
     364               0 :                                            NULL ) );
     365                 :     }
     366               0 :     CSLDestroy(papszCoverFiles);
     367                 :     
     368               0 :     return papszFileList;
     369                 : }
     370                 : 
     371                 : /************************************************************************/
     372                 : /*                              ReadRAT()                               */
     373                 : /************************************************************************/
     374                 : 
     375               1 : void AIGDataset::ReadRAT()
     376                 : 
     377                 : {
     378                 : #ifndef OGR_ENABLED
     379                 : #else
     380                 : /* -------------------------------------------------------------------- */
     381                 : /*      Check if we have an associated info directory.  If not          */
     382                 : /*      return quietly.                                                 */
     383                 : /* -------------------------------------------------------------------- */
     384               1 :     CPLString osInfoPath, osTableName;
     385                 :     VSIStatBufL sStatBuf;
     386                 : 
     387               1 :     osInfoPath = psInfo->pszCoverName;
     388               1 :     osInfoPath += "/../info";
     389                 :     
     390               1 :     if( VSIStatL( osInfoPath, &sStatBuf ) != 0 )
     391                 :     {
     392                 :         CPLDebug( "AIG", "No associated info directory at: %s, skip RAT.",
     393               0 :                   osInfoPath.c_str() );
     394               0 :         return;
     395                 :     }
     396                 :     
     397               1 :     osInfoPath += "/";
     398                 : 
     399                 : /* -------------------------------------------------------------------- */
     400                 : /*      Attempt to open the VAT table associated with this coverage.    */
     401                 : /* -------------------------------------------------------------------- */
     402               1 :     osTableName = CPLGetFilename(psInfo->pszCoverName);
     403               1 :     osTableName += ".VAT";
     404                 : 
     405                 :     AVCBinFile *psFile = 
     406                 :         AVCBinReadOpen( osInfoPath, osTableName,
     407               1 :                         AVCCoverTypeUnknown, AVCFileTABLE, NULL );
     408                 : 
     409               1 :     CPLErrorReset();
     410               1 :     if( psFile == NULL )
     411                 :         return;
     412                 : 
     413               1 :     AVCTableDef *psTableDef = psFile->hdr.psTableDef;
     414                 : 
     415                 : /* -------------------------------------------------------------------- */
     416                 : /*      Setup columns in corresponding RAT.                             */
     417                 : /* -------------------------------------------------------------------- */
     418                 :     int iField;
     419                 : 
     420               1 :     poRAT = new GDALRasterAttributeTable();
     421                 : 
     422               3 :     for( iField = 0; iField < psTableDef->numFields; iField++ )
     423                 :     {
     424               2 :         AVCFieldInfo *psFDef = psTableDef->pasFieldDef + iField;
     425               2 :         GDALRATFieldUsage eFUsage = GFU_Generic;
     426               2 :         GDALRATFieldType eFType = GFT_String;
     427                 : 
     428               2 :         CPLString osFName = psFDef->szName;
     429               2 :         osFName.Trim();
     430                 : 
     431               2 :         if( EQUAL(osFName,"VALUE") )
     432               1 :             eFUsage = GFU_MinMax;
     433               1 :         else if( EQUAL(osFName,"COUNT") )
     434               1 :             eFUsage = GFU_PixelCount;
     435                 :         
     436               2 :         if( psFDef->nType1 * 10 == AVC_FT_BININT )
     437               2 :             eFType = GFT_Integer;
     438               0 :         else if( psFDef->nType1 * 10 == AVC_FT_BINFLOAT )
     439               0 :             eFType = GFT_Real;
     440                 : 
     441               2 :         poRAT->CreateColumn( osFName, eFType, eFUsage );
     442                 :     }
     443                 : 
     444                 : /* -------------------------------------------------------------------- */
     445                 : /*      Process all records into RAT.                                   */
     446                 : /* -------------------------------------------------------------------- */
     447                 :     AVCField *pasFields;
     448               1 :     int iRecord = 0;
     449                 : 
     450            2644 :     while( (pasFields = AVCBinReadNextTableRec(psFile)) != NULL )
     451                 :     {
     452            2642 :         iRecord++;
     453                 : 
     454            7926 :         for( iField = 0; iField < psTableDef->numFields; iField++ )
     455                 :         {
     456            5284 :             switch( psTableDef->pasFieldDef[iField].nType1 * 10 )
     457                 :             {
     458                 :               case AVC_FT_DATE:
     459                 :               case AVC_FT_FIXINT:
     460                 :               case AVC_FT_CHAR:
     461                 :               case AVC_FT_FIXNUM:
     462                 :               {
     463                 :                   // XXX - I bet mloskot would like to see const_cast + static_cast :-)
     464               0 :                   const char* pszTmp = (const char*)(pasFields[iField].pszStr);
     465               0 :                   CPLString osStrValue( pszTmp );
     466               0 :                   poRAT->SetValue( iRecord-1, iField, osStrValue.Trim() );
     467                 :               }
     468               0 :               break;
     469                 : 
     470                 :               case AVC_FT_BININT:
     471            5284 :                 if( psTableDef->pasFieldDef[iField].nSize == 4 )
     472                 :                     poRAT->SetValue( iRecord-1, iField, 
     473            5284 :                                      pasFields[iField].nInt32 );
     474                 :                 else
     475                 :                     poRAT->SetValue( iRecord-1, iField, 
     476               0 :                                      pasFields[iField].nInt16 );
     477            5284 :                 break;
     478                 : 
     479                 :               case AVC_FT_BINFLOAT:
     480               0 :                 if( psTableDef->pasFieldDef[iField].nSize == 4 )
     481                 :                     poRAT->SetValue( iRecord-1, iField, 
     482               0 :                                      pasFields[iField].fFloat );
     483                 :                 else
     484                 :                     poRAT->SetValue( iRecord-1, iField, 
     485               0 :                                      pasFields[iField].dDouble );
     486                 :                 break;
     487                 :             }
     488                 :         }
     489                 :     }
     490                 : 
     491                 : /* -------------------------------------------------------------------- */
     492                 : /*      Cleanup                                                         */
     493                 : /* -------------------------------------------------------------------- */
     494                 : 
     495               1 :     AVCBinReadClose( psFile );
     496                 : 
     497                 :     /* Workaround against #2447 and #3031, to avoid binding languages */
     498                 :     /* not being able to open the dataset */
     499               1 :     CPLErrorReset();
     500                 : 
     501                 : #endif /* OGR_ENABLED */
     502                 : }
     503                 : 
     504                 : /************************************************************************/
     505                 : /*                                Open()                                */
     506                 : /************************************************************************/
     507                 : 
     508           11341 : GDALDataset *AIGDataset::Open( GDALOpenInfo * poOpenInfo )
     509                 : 
     510                 : {
     511                 :     AIGInfo_t *psInfo;
     512                 : 
     513                 : /* -------------------------------------------------------------------- */
     514                 : /*      If the pass name ends in .adf assume a file within the          */
     515                 : /*      coverage has been selected, and strip that off the coverage     */
     516                 : /*      name.                                                           */
     517                 : /* -------------------------------------------------------------------- */
     518           11341 :     CPLString osCoverName;
     519                 : 
     520           11341 :     osCoverName = poOpenInfo->pszFilename;
     521           11341 :     if( osCoverName.size() > 4 
     522                 :         && EQUAL(osCoverName.c_str()+osCoverName.size()-4,".adf") )
     523                 :     {
     524               3 :         osCoverName = CPLGetDirname( poOpenInfo->pszFilename );
     525               3 :         if( osCoverName == "" )
     526               0 :             osCoverName = ".";
     527                 :     }
     528                 : 
     529                 : /* -------------------------------------------------------------------- */
     530                 : /*      Otherwise verify we were already given a directory.             */
     531                 : /* -------------------------------------------------------------------- */
     532           11338 :     else if( !poOpenInfo->bIsDirectory )
     533                 :     {
     534           11292 :         return NULL;
     535                 :     }
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      Verify that a few of the "standard" files are available.        */
     539                 : /* -------------------------------------------------------------------- */
     540                 :     VSIStatBufL sStatBuf;
     541              49 :     CPLString osTestName;
     542                 :     
     543              49 :     osTestName.Printf( "%s/hdr.adf", osCoverName.c_str() );
     544              49 :     if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     545                 : 
     546                 :     {
     547              44 :         osTestName.Printf( "%s/HDR.ADF", osCoverName.c_str() );
     548              44 :         if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     549              42 :             return NULL;
     550                 :     }
     551                 : 
     552                 : /* -------------------------------------------------------------------- */
     553                 : /*      Confirm we have at least one raster data file.  These can be    */
     554                 : /*      sparse so we don't require particular ones to exists but if     */
     555                 : /*      there are none this is likely not a grid.                       */
     556                 : /* -------------------------------------------------------------------- */
     557               7 :     char **papszFileList = VSIReadDir( osCoverName );
     558                 :     int iFile;
     559               7 :     int bGotOne = FALSE;
     560                 : 
     561              49 :     for( iFile = 0; 
     562                 :          papszFileList != NULL && papszFileList[iFile] != NULL && !bGotOne;
     563                 :          iFile++ )
     564                 :     {
     565              42 :         if( strlen(papszFileList[iFile]) != 11 )
     566              35 :             continue;
     567                 : 
     568                 :         // looking for something like w001001.adf or z001013.adf
     569               7 :         if( papszFileList[iFile][0] != 'w'
     570                 :             && papszFileList[iFile][0] != 'W'
     571                 :             && papszFileList[iFile][0] != 'z'
     572                 :             && papszFileList[iFile][0] != 'Z' )
     573               0 :             continue;
     574                 : 
     575               7 :         if( strncmp(papszFileList[iFile] + 1, "0010", 4) != 0 )
     576               0 :             continue;
     577                 : 
     578               7 :         if( !EQUAL(papszFileList[iFile] + 7, ".adf") )
     579               0 :             continue;
     580                 : 
     581               7 :         bGotOne = TRUE;
     582                 :     }
     583               7 :     CSLDestroy( papszFileList );
     584                 : 
     585               7 :     if( !bGotOne )
     586               0 :         return NULL;
     587                 :     
     588                 : /* -------------------------------------------------------------------- */
     589                 : /*      Open the file.                                                  */
     590                 : /* -------------------------------------------------------------------- */
     591               7 :     psInfo = AIGOpen( osCoverName.c_str(), "r" );
     592                 :     
     593               7 :     if( psInfo == NULL )
     594                 :     {
     595               0 :         CPLErrorReset();
     596               0 :         return NULL;
     597                 :     }
     598                 :     
     599                 : /* -------------------------------------------------------------------- */
     600                 : /*      Confirm the requested access is supported.                      */
     601                 : /* -------------------------------------------------------------------- */
     602               7 :     if( poOpenInfo->eAccess == GA_Update )
     603                 :     {
     604               0 :         AIGClose(psInfo);
     605                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     606                 :                   "The AIG driver does not support update access to existing"
     607               0 :                   " datasets.\n" );
     608               0 :         return NULL;
     609                 :     }
     610                 : /* -------------------------------------------------------------------- */
     611                 : /*      Create a corresponding GDALDataset.                             */
     612                 : /* -------------------------------------------------------------------- */
     613                 :     AIGDataset  *poDS;
     614                 : 
     615               7 :     poDS = new AIGDataset();
     616                 : 
     617               7 :     poDS->psInfo = psInfo;
     618                 : 
     619                 : /* -------------------------------------------------------------------- */
     620                 : /*      Try to read a color table (.clr).  It seems it is legal to      */
     621                 : /*      have more than one so we just use the first one found.          */
     622                 : /* -------------------------------------------------------------------- */
     623              14 :     char **papszFiles = CPLReadDir( psInfo->pszCoverName );
     624               7 :     CPLString osClrFilename;
     625               7 :     CPLString osCleanPath = CPLCleanTrailingSlash( psInfo->pszCoverName );
     626                 :   
     627                 :     // first check for any .clr in coverage dir.
     628              54 :     for( iFile = 0; papszFiles != NULL && papszFiles[iFile] != NULL; iFile++ )
     629                 :     {
     630              50 :         if( !EQUAL(CPLGetExtension(papszFiles[iFile]),"clr") && !EQUAL(CPLGetExtension(papszFiles[iFile]),"CLR"))
     631              47 :             continue;
     632                 :       
     633                 :         osClrFilename = CPLFormFilename( psInfo->pszCoverName,
     634               3 :                                          papszFiles[iFile], NULL );
     635               3 :         break;
     636                 :     }
     637                 :   
     638               7 :     CSLDestroy( papszFiles );
     639                 :   
     640                 :     // Look in parent if we don't find a .clr in the coverage dir.
     641               7 :     if( strlen(osClrFilename) == 0 )
     642                 :     {
     643                 :         osTestName.Printf( "%s/../%s.clr",
     644                 :                            psInfo->pszCoverName,
     645               4 :                            CPLGetFilename( osCleanPath ) );
     646                 :       
     647               4 :         if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     648                 : 
     649                 :   {
     650                 :             osTestName.Printf( "%s/../%s.CLR",
     651                 :                                psInfo->pszCoverName,
     652               4 :                                CPLGetFilename( osCleanPath ) );
     653                 :       
     654               4 :             if( !VSIStatL( osTestName, &sStatBuf ) )
     655               2 :                 osClrFilename = osTestName;
     656                 :         }
     657                 :         else
     658               0 :             osClrFilename = osTestName;
     659                 :     }
     660                 :     
     661                 :   
     662               7 :     if( strlen(osClrFilename) > 0 )
     663               5 :         poDS->TranslateColorTable( osClrFilename );
     664                 :   
     665                 : /* -------------------------------------------------------------------- */
     666                 : /*      Establish raster info.                                          */
     667                 : /* -------------------------------------------------------------------- */
     668               7 :     poDS->nRasterXSize = psInfo->nPixels;
     669               7 :     poDS->nRasterYSize = psInfo->nLines;
     670               7 :     poDS->nBands = 1;
     671                 : 
     672                 : /* -------------------------------------------------------------------- */
     673                 : /*      Create band information objects.                                */
     674                 : /* -------------------------------------------------------------------- */
     675               7 :     poDS->SetBand( 1, new AIGRasterBand( poDS, 1 ) );
     676                 : 
     677                 : /* -------------------------------------------------------------------- */
     678                 : /*  Try to read projection file.          */
     679                 : /* -------------------------------------------------------------------- */
     680                 :     const char  *pszPrjFilename;
     681                 : 
     682               7 :     pszPrjFilename = CPLFormCIFilename( psInfo->pszCoverName, "prj", "adf" );
     683               7 :     if( VSIStatL( pszPrjFilename, &sStatBuf ) == 0 )
     684                 :     {
     685               5 :         OGRSpatialReference oSRS;
     686                 : 
     687               5 :         poDS->papszPrj = CSLLoad( pszPrjFilename );
     688                 : 
     689               5 :         if( oSRS.importFromESRI( poDS->papszPrj ) == OGRERR_NONE )
     690                 :         {
     691                 :             // If geographic values are in seconds, we must transform. 
     692                 :             // Is there a code for minutes too? 
     693               5 :             if( oSRS.IsGeographic() 
     694                 :                 && EQUAL(OSR_GDS( poDS->papszPrj, "Units", ""), "DS") )
     695                 :             {
     696               0 :                 psInfo->dfLLX /= 3600.0;
     697               0 :                 psInfo->dfURY /= 3600.0;
     698               0 :                 psInfo->dfCellSizeX /= 3600.0;
     699               0 :                 psInfo->dfCellSizeY /= 3600.0;
     700                 :             }
     701                 : 
     702               5 :             CPLFree( poDS->pszProjection );
     703               5 :             oSRS.exportToWkt( &(poDS->pszProjection) );
     704               5 :         }
     705                 :     }
     706                 : 
     707                 : /* -------------------------------------------------------------------- */
     708                 : /*      Initialize any PAM information.                                 */
     709                 : /* -------------------------------------------------------------------- */
     710               7 :     poDS->SetDescription( psInfo->pszCoverName );
     711               7 :     poDS->TryLoadXML();
     712                 : 
     713                 : /* -------------------------------------------------------------------- */
     714                 : /*      Open overviews.                                                 */
     715                 : /* -------------------------------------------------------------------- */
     716               7 :     poDS->oOvManager.Initialize( poDS, psInfo->pszCoverName );
     717                 : 
     718               7 :     return( poDS );
     719                 : }
     720                 : 
     721                 : /************************************************************************/
     722                 : /*                          GetGeoTransform()                           */
     723                 : /************************************************************************/
     724                 : 
     725               1 : CPLErr AIGDataset::GetGeoTransform( double * padfTransform )
     726                 : 
     727                 : {
     728               1 :     padfTransform[0] = psInfo->dfLLX;
     729               1 :     padfTransform[1] = psInfo->dfCellSizeX;
     730               1 :     padfTransform[2] = 0;
     731                 : 
     732               1 :     padfTransform[3] = psInfo->dfURY;
     733               1 :     padfTransform[4] = 0;
     734               1 :     padfTransform[5] = -psInfo->dfCellSizeY;
     735                 :     
     736               1 :     return( CE_None );
     737                 : }
     738                 : 
     739                 : /************************************************************************/
     740                 : /*                          GetProjectionRef()                          */
     741                 : /************************************************************************/
     742                 : 
     743               1 : const char *AIGDataset::GetProjectionRef()
     744                 : 
     745                 : {
     746               1 :     return pszProjection;
     747                 : }
     748                 : 
     749                 : /************************************************************************/
     750                 : /*                        TranslateColorTable()                         */
     751                 : /************************************************************************/
     752                 : 
     753               5 : void AIGDataset::TranslateColorTable( const char *pszClrFilename )
     754                 : 
     755                 : {
     756                 :     int  iLine;
     757                 :     char **papszClrLines;
     758                 : 
     759               5 :     papszClrLines = CSLLoad( pszClrFilename );
     760               5 :     if( papszClrLines == NULL )
     761               0 :         return;
     762                 : 
     763               5 :     poCT = new GDALColorTable();
     764                 : 
     765            1295 :     for( iLine = 0; papszClrLines[iLine] != NULL; iLine++ )
     766                 :     {
     767            1290 :         char **papszTokens = CSLTokenizeString( papszClrLines[iLine] );
     768                 : 
     769            1290 :         if( CSLCount(papszTokens) >= 4 && papszTokens[0][0] != '#' )
     770                 :         {
     771                 :             int nIndex;
     772                 :             GDALColorEntry sEntry;
     773                 : 
     774            1280 :             nIndex = atoi(papszTokens[0]);
     775            1280 :             sEntry.c1 = (short) atoi(papszTokens[1]);
     776            1280 :             sEntry.c2 = (short) atoi(papszTokens[2]);
     777            1280 :             sEntry.c3 = (short) atoi(papszTokens[3]);
     778            1280 :             sEntry.c4 = 255;
     779                 : 
     780            1280 :             if( (nIndex < 0 || nIndex > 33000) 
     781                 :                 || (sEntry.c1 < 0 || sEntry.c1 > 255)
     782                 :                 || (sEntry.c2 < 0 || sEntry.c2 > 255)
     783                 :                 || (sEntry.c3 < 0 || sEntry.c3 > 255) )
     784                 :             {
     785               0 :                 CSLDestroy( papszTokens );
     786                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     787               0 :                           "Color table entry appears to be corrupt, skipping the rest. " );
     788               0 :                 break;
     789                 :             }
     790                 : 
     791            1280 :             poCT->SetColorEntry( nIndex, &sEntry );
     792                 :         }
     793                 : 
     794            1290 :         CSLDestroy( papszTokens );
     795                 :     }
     796                 : 
     797               5 :     CSLDestroy( papszClrLines );
     798                 : }
     799                 : 
     800                 : /************************************************************************/
     801                 : /*                              OSR_GDS()                               */
     802                 : /************************************************************************/
     803                 : 
     804                 : static CPLString OSR_GDS( char **papszNV, const char * pszField, 
     805               0 :                            const char *pszDefaultValue )
     806                 : 
     807                 : {
     808                 :     int         iLine;
     809                 : 
     810               0 :     if( papszNV == NULL || papszNV[0] == NULL )
     811               0 :         return pszDefaultValue;
     812                 : 
     813               0 :     for( iLine = 0; 
     814                 :          papszNV[iLine] != NULL && 
     815                 :              !EQUALN(papszNV[iLine],pszField,strlen(pszField));
     816                 :          iLine++ ) {}
     817                 : 
     818               0 :     if( papszNV[iLine] == NULL )
     819               0 :         return pszDefaultValue;
     820                 :     else
     821                 :     {
     822               0 :         CPLString osResult;
     823                 :         char    **papszTokens;
     824                 :         
     825               0 :         papszTokens = CSLTokenizeString(papszNV[iLine]);
     826                 : 
     827               0 :         if( CSLCount(papszTokens) > 1 )
     828               0 :             osResult = papszTokens[1];
     829                 :         else
     830               0 :             osResult = pszDefaultValue;
     831                 :         
     832               0 :         CSLDestroy( papszTokens );
     833               0 :         return osResult;
     834                 :     }
     835                 : }
     836                 : 
     837                 : /************************************************************************/
     838                 : /*                             AIGRename()                              */
     839                 : /*                                                                      */
     840                 : /*      Custom renamer for AIG dataset.                                 */
     841                 : /************************************************************************/
     842                 : 
     843               0 : static CPLErr AIGRename( const char *pszNewName, const char *pszOldName )
     844                 : 
     845                 : {
     846                 : /* -------------------------------------------------------------------- */
     847                 : /*      Make sure we are talking about paths to the coverage            */
     848                 : /*      directory.                                                      */
     849                 : /* -------------------------------------------------------------------- */
     850               0 :     CPLString osOldPath, osNewPath;
     851                 : 
     852               0 :     if( strlen(CPLGetExtension(pszNewName)) > 0 )
     853               0 :         osNewPath = CPLGetPath(pszNewName);
     854                 :     else
     855               0 :         osNewPath = pszNewName;
     856                 : 
     857               0 :     if( strlen(CPLGetExtension(pszOldName)) > 0 )
     858               0 :         osOldPath = CPLGetPath(pszOldName);
     859                 :     else
     860               0 :         osOldPath = pszOldName;
     861                 : 
     862                 : /* -------------------------------------------------------------------- */
     863                 : /*      Get file list.                                                  */
     864                 : /* -------------------------------------------------------------------- */
     865                 : 
     866               0 :     GDALDatasetH hDS = GDALOpen( osOldPath, GA_ReadOnly );
     867               0 :     if( hDS == NULL )
     868               0 :         return CE_Failure;
     869                 : 
     870               0 :     char **papszFileList = GDALGetFileList( hDS );
     871               0 :     GDALClose( hDS );
     872                 : 
     873               0 :     if( papszFileList == NULL )
     874               0 :         return CE_Failure;
     875                 : 
     876                 : /* -------------------------------------------------------------------- */
     877                 : /*      Work out the corresponding new names.                           */
     878                 : /* -------------------------------------------------------------------- */
     879               0 :     char **papszNewFileList = NULL;
     880                 :     int i;
     881                 :     
     882               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     883                 :     {
     884               0 :         CPLString osNewFilename;
     885                 : 
     886               0 :         if( !EQUALN(papszFileList[i],osOldPath,strlen(osOldPath)) )
     887                 :         {
     888               0 :             CPLAssert( FALSE );
     889               0 :             return CE_Failure;
     890                 :         }
     891                 : 
     892               0 :         osNewFilename = osNewPath + (papszFileList[i] + strlen(osOldPath));
     893                 :         
     894               0 :         papszNewFileList = CSLAddString( papszNewFileList, osNewFilename );
     895                 :     }
     896                 : 
     897                 : /* -------------------------------------------------------------------- */
     898                 : /*      Try renaming the directory.                                     */
     899                 : /* -------------------------------------------------------------------- */
     900               0 :     if( VSIRename( osNewPath, osOldPath ) != 0 )
     901                 :     {
     902               0 :         if( VSIMkdir( osNewPath, 0777 ) != 0 )
     903                 :         {
     904                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     905                 :                       "Unable to create directory %s:\n%s",
     906                 :                       osNewPath.c_str(),
     907               0 :                       VSIStrerror(errno) );
     908               0 :             return CE_Failure;
     909                 :         }
     910                 :     }
     911                 : 
     912                 : /* -------------------------------------------------------------------- */
     913                 : /*      Copy/rename any remaining files.                                */
     914                 : /* -------------------------------------------------------------------- */
     915                 :     VSIStatBufL sStatBuf;
     916                 : 
     917               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     918                 :     {
     919               0 :         if( VSIStatL( papszFileList[i], &sStatBuf ) == 0 
     920                 :             && VSI_ISREG( sStatBuf.st_mode ) )
     921                 :         {
     922               0 :             if( CPLMoveFile( papszNewFileList[i], papszFileList[i] ) != 0 )
     923                 :             {
     924                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     925                 :                           "Unable to move %s to %s:\n%s",
     926                 :                           papszFileList[i],
     927                 :                           papszNewFileList[i], 
     928               0 :                           VSIStrerror(errno) );
     929               0 :                 return CE_Failure;
     930                 :             }
     931                 :         }
     932                 :     }
     933                 : 
     934               0 :     if( VSIStatL( osOldPath, &sStatBuf ) == 0 )
     935               0 :         CPLUnlinkTree( osOldPath );
     936                 : 
     937               0 :     return CE_None;
     938                 : }
     939                 : 
     940                 : /************************************************************************/
     941                 : /*                             AIGDelete()                              */
     942                 : /*                                                                      */
     943                 : /*      Custom dataset deleter for AIG dataset.                         */
     944                 : /************************************************************************/
     945                 : 
     946               0 : static CPLErr AIGDelete( const char *pszDatasetname )
     947                 : 
     948                 : {
     949                 : /* -------------------------------------------------------------------- */
     950                 : /*      Get file list.                                                  */
     951                 : /* -------------------------------------------------------------------- */
     952               0 :     GDALDatasetH hDS = GDALOpen( pszDatasetname, GA_ReadOnly );
     953               0 :     if( hDS == NULL )
     954               0 :         return CE_Failure;
     955                 : 
     956               0 :     char **papszFileList = GDALGetFileList( hDS );
     957               0 :     GDALClose( hDS );
     958                 : 
     959               0 :     if( papszFileList == NULL )
     960               0 :         return CE_Failure;
     961                 : 
     962                 : /* -------------------------------------------------------------------- */
     963                 : /*      Delete all regular files.                                       */
     964                 : /* -------------------------------------------------------------------- */
     965                 :     int i;
     966               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     967                 :     {
     968                 :         VSIStatBufL sStatBuf;
     969               0 :         if( VSIStatL( papszFileList[i], &sStatBuf ) == 0 
     970                 :             && VSI_ISREG( sStatBuf.st_mode ) )
     971                 :         {
     972               0 :             if( VSIUnlink( papszFileList[i] ) != 0 )
     973                 :             {
     974                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     975                 :                           "Unable to delete '%s':\n%s", 
     976               0 :                           papszFileList[i], VSIStrerror( errno ) );
     977               0 :                 return CE_Failure;
     978                 :             }
     979                 :         }
     980                 :     }
     981                 : 
     982                 : /* -------------------------------------------------------------------- */
     983                 : /*      Delete directories.                                             */
     984                 : /* -------------------------------------------------------------------- */
     985               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     986                 :     {
     987                 :         VSIStatBufL sStatBuf;
     988               0 :         if( VSIStatL( papszFileList[i], &sStatBuf ) == 0 
     989                 :             && VSI_ISDIR( sStatBuf.st_mode ) )
     990                 :         {
     991               0 :             if( CPLUnlinkTree( papszFileList[i] ) != 0 )
     992               0 :                 return CE_Failure;
     993                 :         }
     994                 :     }
     995                 : 
     996               0 :     return CE_None;
     997                 : }
     998                 : 
     999                 : /************************************************************************/
    1000                 : /*                          GDALRegister_AIG()                        */
    1001                 : /************************************************************************/
    1002                 : 
    1003             409 : void GDALRegister_AIGrid()
    1004                 : 
    1005                 : {
    1006                 :     GDALDriver  *poDriver;
    1007                 : 
    1008             409 :     if( GDALGetDriverByName( "AIG" ) == NULL )
    1009                 :     {
    1010             392 :         poDriver = new GDALDriver();
    1011                 :         
    1012             392 :         poDriver->SetDescription( "AIG" );
    1013                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
    1014             392 :                                    "Arc/Info Binary Grid" );
    1015                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
    1016             392 :                                    "frmt_various.html#AIG" );
    1017                 :         
    1018             392 :         poDriver->pfnOpen = AIGDataset::Open;
    1019                 : 
    1020             392 :         poDriver->pfnRename = AIGRename;
    1021             392 :         poDriver->pfnDelete = AIGDelete;
    1022                 : 
    1023             392 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1024                 :     }
    1025             409 : }

Generated by: LTP GCOV extension version 1.5