LCOV - code coverage report
Current view: directory - frmts/aigrid - aigdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 330 207 62.7 %
Date: 2010-01-09 Functions: 23 18 78.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: aigdataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       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 17664 2009-09-21 21:16:45Z rouault $");
      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              14 : {
      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            5898 : CPLErr AIGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     146                 :                                   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              14 : 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              14 : }
     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               0 :             || EQUAL(papszCoverFiles[i],"..") )
     358               0 :             continue;
     359                 : 
     360                 :         papszFileList = 
     361                 :             CSLAddString( papszFileList, 
     362               0 :                           CPLFormFilename( GetDescription(), 
     363               0 :                                            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                 :         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            9922 : 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            9922 :     CPLString osCoverName;
     519                 : 
     520            9922 :     osCoverName = poOpenInfo->pszFilename;
     521            9922 :     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            9919 :     else if( !poOpenInfo->bIsDirectory )
     533                 :     {
     534            9893 :         return NULL;
     535                 :     }
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      Verify that a few of the "standard" files are available.        */
     539                 : /* -------------------------------------------------------------------- */
     540                 :     VSIStatBufL sStatBuf;
     541              29 :     CPLString osTestName;
     542                 :     
     543              29 :     osTestName.Printf( "%s/hdr.adf", osCoverName.c_str() );
     544              29 :     if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     545                 : 
     546                 :     {
     547              24 :         osTestName.Printf( "%s/HDR.ADF", osCoverName.c_str() );
     548              24 :         if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     549              22 :             return NULL;
     550                 :     }
     551                 : 
     552               7 :     osTestName.Printf( "%s/w001001x.adf", osCoverName.c_str() );
     553               7 :     if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     554                 : 
     555                 :     {
     556               2 :         osTestName.Printf( "%s/W001001X.ADF", osCoverName.c_str() );
     557               2 :         if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     558               0 :             return NULL;
     559                 :     }
     560                 : 
     561               7 :     osTestName.Printf( "%s/w001001.adf", osCoverName.c_str() );
     562               7 :     if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     563                 : 
     564                 :     {
     565               2 :         osTestName.Printf( "%s/W001001.ADF", osCoverName.c_str() );
     566               2 :         if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     567               0 :             return NULL;
     568                 :     }
     569                 :     
     570                 : /* -------------------------------------------------------------------- */
     571                 : /*      Open the file.                                                  */
     572                 : /* -------------------------------------------------------------------- */
     573               7 :     psInfo = AIGOpen( osCoverName.c_str(), "r" );
     574                 :     
     575               7 :     if( psInfo == NULL )
     576                 :     {
     577               0 :         CPLErrorReset();
     578               0 :         return NULL;
     579                 :     }
     580                 :     
     581                 : /* -------------------------------------------------------------------- */
     582                 : /*      Confirm the requested access is supported.                      */
     583                 : /* -------------------------------------------------------------------- */
     584               7 :     if( poOpenInfo->eAccess == GA_Update )
     585                 :     {
     586               0 :         AIGClose(psInfo);
     587                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     588                 :                   "The AIG driver does not support update access to existing"
     589               0 :                   " datasets.\n" );
     590               0 :         return NULL;
     591                 :     }
     592                 : /* -------------------------------------------------------------------- */
     593                 : /*      Create a corresponding GDALDataset.                             */
     594                 : /* -------------------------------------------------------------------- */
     595                 :     AIGDataset  *poDS;
     596                 : 
     597               7 :     poDS = new AIGDataset();
     598                 : 
     599               7 :     poDS->psInfo = psInfo;
     600                 : 
     601                 : /* -------------------------------------------------------------------- */
     602                 : /*      Try to read a color table (.clr).  It seems it is legal to      */
     603                 : /*      have more than one so we just use the first one found.          */
     604                 : /* -------------------------------------------------------------------- */
     605                 :     int  iFile;
     606              14 :     char **papszFiles = CPLReadDir( psInfo->pszCoverName );
     607               7 :     CPLString osClrFilename;
     608               7 :     CPLString osCleanPath = CPLCleanTrailingSlash( psInfo->pszCoverName );
     609                 :   
     610                 :     // first check for any .clr in coverage dir.
     611              96 :     for( iFile = 0; papszFiles != NULL && papszFiles[iFile] != NULL; iFile++ )
     612                 :     {
     613              44 :         if( !EQUAL(CPLGetExtension(papszFiles[iFile]),"clr") && !EQUAL(CPLGetExtension(papszFiles[iFile]),"CLR"))
     614              41 :             continue;
     615                 :       
     616                 :         osClrFilename = CPLFormFilename( psInfo->pszCoverName,
     617               3 :                                          papszFiles[iFile], NULL );
     618               3 :         break;
     619                 :     }
     620                 :   
     621               7 :     CSLDestroy( papszFiles );
     622                 :   
     623                 :     // Look in parent if we don't find a .clr in the coverage dir.
     624               7 :     if( strlen(osClrFilename) == 0 )
     625                 :     {
     626                 :         osTestName.Printf( "%s/../%s.clr",
     627                 :                            psInfo->pszCoverName,
     628               4 :                            CPLGetFilename( osCleanPath ) );
     629                 :       
     630               4 :         if( VSIStatL( osTestName, &sStatBuf ) != 0 )
     631                 : 
     632                 :   {
     633                 :             osTestName.Printf( "%s/../%s.CLR",
     634                 :                                psInfo->pszCoverName,
     635               4 :                                CPLGetFilename( osCleanPath ) );
     636                 :       
     637               4 :             if( !VSIStatL( osTestName, &sStatBuf ) )
     638               2 :                 osClrFilename = osTestName;
     639                 :         }
     640                 :         else
     641               0 :             osClrFilename = osTestName;
     642                 :     }
     643                 :     
     644                 :   
     645               7 :     if( strlen(osClrFilename) > 0 )
     646               5 :         poDS->TranslateColorTable( osClrFilename );
     647                 :   
     648                 : /* -------------------------------------------------------------------- */
     649                 : /*      Establish raster info.                                          */
     650                 : /* -------------------------------------------------------------------- */
     651               7 :     poDS->nRasterXSize = psInfo->nPixels;
     652               7 :     poDS->nRasterYSize = psInfo->nLines;
     653               7 :     poDS->nBands = 1;
     654                 : 
     655                 : /* -------------------------------------------------------------------- */
     656                 : /*      Create band information objects.                                */
     657                 : /* -------------------------------------------------------------------- */
     658               7 :     poDS->SetBand( 1, new AIGRasterBand( poDS, 1 ) );
     659                 : 
     660                 : /* -------------------------------------------------------------------- */
     661                 : /*  Try to read projection file.          */
     662                 : /* -------------------------------------------------------------------- */
     663                 :     const char  *pszPrjFilename;
     664                 : 
     665               7 :     pszPrjFilename = CPLFormCIFilename( psInfo->pszCoverName, "prj", "adf" );
     666               7 :     if( VSIStatL( pszPrjFilename, &sStatBuf ) == 0 )
     667                 :     {
     668               5 :         OGRSpatialReference oSRS;
     669                 : 
     670               5 :         poDS->papszPrj = CSLLoad( pszPrjFilename );
     671                 : 
     672               5 :         if( oSRS.importFromESRI( poDS->papszPrj ) == OGRERR_NONE )
     673                 :         {
     674                 :             // If geographic values are in seconds, we must transform. 
     675                 :             // Is there a code for minutes too? 
     676               5 :             if( oSRS.IsGeographic() 
     677                 :                 && EQUAL(OSR_GDS( poDS->papszPrj, "Units", ""), "DS") )
     678                 :             {
     679               0 :                 psInfo->dfLLX /= 3600.0;
     680               0 :                 psInfo->dfURY /= 3600.0;
     681               0 :                 psInfo->dfCellSizeX /= 3600.0;
     682               0 :                 psInfo->dfCellSizeY /= 3600.0;
     683                 :             }
     684                 : 
     685               5 :             CPLFree( poDS->pszProjection );
     686               5 :             oSRS.exportToWkt( &(poDS->pszProjection) );
     687               5 :         }
     688                 :     }
     689                 : 
     690                 : /* -------------------------------------------------------------------- */
     691                 : /*      Initialize any PAM information.                                 */
     692                 : /* -------------------------------------------------------------------- */
     693               7 :     poDS->SetDescription( psInfo->pszCoverName );
     694               7 :     poDS->TryLoadXML();
     695                 : 
     696                 : /* -------------------------------------------------------------------- */
     697                 : /*      Open overviews.                                                 */
     698                 : /* -------------------------------------------------------------------- */
     699               7 :     poDS->oOvManager.Initialize( poDS, psInfo->pszCoverName );
     700                 : 
     701               7 :     return( poDS );
     702                 : }
     703                 : 
     704                 : /************************************************************************/
     705                 : /*                          GetGeoTransform()                           */
     706                 : /************************************************************************/
     707                 : 
     708               1 : CPLErr AIGDataset::GetGeoTransform( double * padfTransform )
     709                 : 
     710                 : {
     711               1 :     padfTransform[0] = psInfo->dfLLX;
     712               1 :     padfTransform[1] = psInfo->dfCellSizeX;
     713               1 :     padfTransform[2] = 0;
     714                 : 
     715               1 :     padfTransform[3] = psInfo->dfURY;
     716               1 :     padfTransform[4] = 0;
     717               1 :     padfTransform[5] = -psInfo->dfCellSizeY;
     718                 :     
     719               1 :     return( CE_None );
     720                 : }
     721                 : 
     722                 : /************************************************************************/
     723                 : /*                          GetProjectionRef()                          */
     724                 : /************************************************************************/
     725                 : 
     726               1 : const char *AIGDataset::GetProjectionRef()
     727                 : 
     728                 : {
     729               1 :     return pszProjection;
     730                 : }
     731                 : 
     732                 : /************************************************************************/
     733                 : /*                        TranslateColorTable()                         */
     734                 : /************************************************************************/
     735                 : 
     736               5 : void AIGDataset::TranslateColorTable( const char *pszClrFilename )
     737                 : 
     738                 : {
     739                 :     int  iLine;
     740                 :     char **papszClrLines;
     741                 : 
     742               5 :     papszClrLines = CSLLoad( pszClrFilename );
     743               5 :     if( papszClrLines == NULL )
     744               0 :         return;
     745                 : 
     746               5 :     poCT = new GDALColorTable();
     747                 : 
     748            1295 :     for( iLine = 0; papszClrLines[iLine] != NULL; iLine++ )
     749                 :     {
     750            1290 :         char **papszTokens = CSLTokenizeString( papszClrLines[iLine] );
     751                 : 
     752            1290 :         if( CSLCount(papszTokens) >= 4 && papszTokens[0][0] != '#' )
     753                 :         {
     754                 :             int nIndex;
     755                 :             GDALColorEntry sEntry;
     756                 : 
     757            1280 :             nIndex = atoi(papszTokens[0]);
     758            1280 :             sEntry.c1 = (short) atoi(papszTokens[1]);
     759            1280 :             sEntry.c2 = (short) atoi(papszTokens[2]);
     760            1280 :             sEntry.c3 = (short) atoi(papszTokens[3]);
     761            1280 :             sEntry.c4 = 255;
     762                 : 
     763            1280 :             if( (nIndex < 0 || nIndex > 33000) 
     764                 :                 || (sEntry.c1 < 0 || sEntry.c1 > 255)
     765                 :                 || (sEntry.c2 < 0 || sEntry.c2 > 255)
     766                 :                 || (sEntry.c3 < 0 || sEntry.c3 > 255) )
     767                 :             {
     768               0 :                 CSLDestroy( papszTokens );
     769                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     770               0 :                           "Color table entry appears to be corrupt, skipping the rest. " );
     771               0 :                 break;
     772                 :             }
     773                 : 
     774            1280 :             poCT->SetColorEntry( nIndex, &sEntry );
     775                 :         }
     776                 : 
     777            1290 :         CSLDestroy( papszTokens );
     778                 :     }
     779                 : 
     780               5 :     CSLDestroy( papszClrLines );
     781                 : }
     782                 : 
     783                 : /************************************************************************/
     784                 : /*                              OSR_GDS()                               */
     785                 : /************************************************************************/
     786                 : 
     787               0 : static CPLString OSR_GDS( char **papszNV, const char * pszField, 
     788                 :                            const char *pszDefaultValue )
     789                 : 
     790                 : {
     791                 :     int         iLine;
     792                 : 
     793               0 :     if( papszNV == NULL || papszNV[0] == NULL )
     794               0 :         return pszDefaultValue;
     795                 : 
     796               0 :     for( iLine = 0; 
     797               0 :          papszNV[iLine] != NULL && 
     798               0 :              !EQUALN(papszNV[iLine],pszField,strlen(pszField));
     799                 :          iLine++ ) {}
     800                 : 
     801               0 :     if( papszNV[iLine] == NULL )
     802               0 :         return pszDefaultValue;
     803                 :     else
     804                 :     {
     805               0 :         CPLString osResult;
     806                 :         char    **papszTokens;
     807                 :         
     808               0 :         papszTokens = CSLTokenizeString(papszNV[iLine]);
     809                 : 
     810               0 :         if( CSLCount(papszTokens) > 1 )
     811               0 :             osResult = papszTokens[1];
     812                 :         else
     813               0 :             osResult = pszDefaultValue;
     814                 :         
     815               0 :         CSLDestroy( papszTokens );
     816               0 :         return osResult;
     817                 :     }
     818                 : }
     819                 : 
     820                 : /************************************************************************/
     821                 : /*                             AIGRename()                              */
     822                 : /*                                                                      */
     823                 : /*      Custom renamer for AIG dataset.                                 */
     824                 : /************************************************************************/
     825                 : 
     826               0 : static CPLErr AIGRename( const char *pszNewName, const char *pszOldName )
     827                 : 
     828                 : {
     829                 : /* -------------------------------------------------------------------- */
     830                 : /*      Make sure we are talking about paths to the coverage            */
     831                 : /*      directory.                                                      */
     832                 : /* -------------------------------------------------------------------- */
     833               0 :     CPLString osOldPath, osNewPath;
     834                 : 
     835               0 :     if( strlen(CPLGetExtension(pszNewName)) > 0 )
     836               0 :         osNewPath = CPLGetPath(pszNewName);
     837                 :     else
     838               0 :         osNewPath = pszNewName;
     839                 : 
     840               0 :     if( strlen(CPLGetExtension(pszOldName)) > 0 )
     841               0 :         osOldPath = CPLGetPath(pszOldName);
     842                 :     else
     843               0 :         osOldPath = pszOldName;
     844                 : 
     845                 : /* -------------------------------------------------------------------- */
     846                 : /*      Get file list.                                                  */
     847                 : /* -------------------------------------------------------------------- */
     848                 : 
     849               0 :     GDALDatasetH hDS = GDALOpen( osOldPath, GA_ReadOnly );
     850               0 :     if( hDS == NULL )
     851               0 :         return CE_Failure;
     852                 : 
     853               0 :     char **papszFileList = GDALGetFileList( hDS );
     854               0 :     GDALClose( hDS );
     855                 : 
     856               0 :     if( papszFileList == NULL )
     857               0 :         return CE_Failure;
     858                 : 
     859                 : /* -------------------------------------------------------------------- */
     860                 : /*      Work out the corresponding new names.                           */
     861                 : /* -------------------------------------------------------------------- */
     862               0 :     char **papszNewFileList = NULL;
     863                 :     int i;
     864                 :     
     865               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     866                 :     {
     867               0 :         CPLString osNewFilename;
     868                 : 
     869               0 :         if( !EQUALN(papszFileList[i],osOldPath,strlen(osOldPath)) )
     870                 :         {
     871                 :             CPLAssert( FALSE );
     872               0 :             return CE_Failure;
     873                 :         }
     874                 : 
     875               0 :         osNewFilename = osNewPath + (papszFileList[i] + strlen(osOldPath));
     876                 :         
     877               0 :         papszNewFileList = CSLAddString( papszNewFileList, osNewFilename );
     878                 :     }
     879                 : 
     880                 : /* -------------------------------------------------------------------- */
     881                 : /*      Try renaming the directory.                                     */
     882                 : /* -------------------------------------------------------------------- */
     883               0 :     if( VSIRename( osNewPath, osOldPath ) != 0 )
     884                 :     {
     885               0 :         if( VSIMkdir( osNewPath, 0777 ) != 0 )
     886                 :         {
     887                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     888                 :                       "Unable to create directory %s:\n%s",
     889                 :                       osNewPath.c_str(),
     890               0 :                       VSIStrerror(errno) );
     891               0 :             return CE_Failure;
     892                 :         }
     893                 :     }
     894                 : 
     895                 : /* -------------------------------------------------------------------- */
     896                 : /*      Copy/rename any remaining files.                                */
     897                 : /* -------------------------------------------------------------------- */
     898                 :     VSIStatBufL sStatBuf;
     899                 : 
     900               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     901                 :     {
     902               0 :         if( VSIStatL( papszFileList[i], &sStatBuf ) == 0 
     903                 :             && VSI_ISREG( sStatBuf.st_mode ) )
     904                 :         {
     905               0 :             if( CPLMoveFile( papszNewFileList[i], papszFileList[i] ) != 0 )
     906                 :             {
     907                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     908                 :                           "Unable to move %s to %s:\n%s",
     909                 :                           papszFileList[i],
     910                 :                           papszNewFileList[i], 
     911               0 :                           VSIStrerror(errno) );
     912               0 :                 return CE_Failure;
     913                 :             }
     914                 :         }
     915                 :     }
     916                 : 
     917               0 :     if( VSIStatL( osOldPath, &sStatBuf ) == 0 )
     918               0 :         CPLUnlinkTree( osOldPath );
     919                 : 
     920               0 :     return CE_None;
     921                 : }
     922                 : 
     923                 : /************************************************************************/
     924                 : /*                             AIGDelete()                              */
     925                 : /*                                                                      */
     926                 : /*      Custom dataset deleter for AIG dataset.                         */
     927                 : /************************************************************************/
     928                 : 
     929               0 : static CPLErr AIGDelete( const char *pszDatasetname )
     930                 : 
     931                 : {
     932                 : /* -------------------------------------------------------------------- */
     933                 : /*      Get file list.                                                  */
     934                 : /* -------------------------------------------------------------------- */
     935               0 :     GDALDatasetH hDS = GDALOpen( pszDatasetname, GA_ReadOnly );
     936               0 :     if( hDS == NULL )
     937               0 :         return CE_Failure;
     938                 : 
     939               0 :     char **papszFileList = GDALGetFileList( hDS );
     940               0 :     GDALClose( hDS );
     941                 : 
     942               0 :     if( papszFileList == NULL )
     943               0 :         return CE_Failure;
     944                 : 
     945                 : /* -------------------------------------------------------------------- */
     946                 : /*      Delete all regular files.                                       */
     947                 : /* -------------------------------------------------------------------- */
     948                 :     int i;
     949               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     950                 :     {
     951                 :         VSIStatBufL sStatBuf;
     952               0 :         if( VSIStatL( papszFileList[i], &sStatBuf ) == 0 
     953                 :             && VSI_ISREG( sStatBuf.st_mode ) )
     954                 :         {
     955               0 :             if( VSIUnlink( papszFileList[i] ) != 0 )
     956                 :             {
     957                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     958                 :                           "Unable to delete '%s':\n%s", 
     959               0 :                           papszFileList[i], VSIStrerror( errno ) );
     960               0 :                 return CE_Failure;
     961                 :             }
     962                 :         }
     963                 :     }
     964                 : 
     965                 : /* -------------------------------------------------------------------- */
     966                 : /*      Delete directories.                                             */
     967                 : /* -------------------------------------------------------------------- */
     968               0 :     for( i = 0; papszFileList[i] != NULL; i++ )
     969                 :     {
     970                 :         VSIStatBufL sStatBuf;
     971               0 :         if( VSIStatL( papszFileList[i], &sStatBuf ) == 0 
     972                 :             && VSI_ISDIR( sStatBuf.st_mode ) )
     973                 :         {
     974               0 :             if( CPLUnlinkTree( papszFileList[i] ) != 0 )
     975               0 :                 return CE_Failure;
     976                 :         }
     977                 :     }
     978                 : 
     979               0 :     return CE_None;
     980                 : }
     981                 : 
     982                 : /************************************************************************/
     983                 : /*                          GDALRegister_AIG()                        */
     984                 : /************************************************************************/
     985                 : 
     986             338 : void GDALRegister_AIGrid()
     987                 : 
     988                 : {
     989                 :     GDALDriver  *poDriver;
     990                 : 
     991             338 :     if( GDALGetDriverByName( "AIG" ) == NULL )
     992                 :     {
     993             336 :         poDriver = new GDALDriver();
     994                 :         
     995             336 :         poDriver->SetDescription( "AIG" );
     996                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     997             336 :                                    "Arc/Info Binary Grid" );
     998                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     999             336 :                                    "frmt_various.html#AIG" );
    1000                 :         
    1001             336 :         poDriver->pfnOpen = AIGDataset::Open;
    1002                 : 
    1003             336 :         poDriver->pfnRename = AIGRename;
    1004             336 :         poDriver->pfnDelete = AIGDelete;
    1005                 : 
    1006             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1007                 :     }
    1008             338 : }

Generated by: LCOV version 1.7