LCOV - code coverage report
Current view: directory - frmts/raw - landataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 204 104 51.0 %
Date: 2010-01-09 Functions: 17 10 58.8 %

       1                 : /******************************************************************************
       2                 :  * $Id: landataset.cpp 17117 2009-05-25 19:26:01Z warmerdam $
       3                 :  *
       4                 :  * Project:  eCognition
       5                 :  * Purpose:  Implementation of Erdas .LAN / .GIS format.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, 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 "rawdataset.h"
      31                 : #include "cpl_string.h"
      32                 : #include "ogr_srs_api.h"
      33                 : 
      34                 : CPL_CVSID("$Id: landataset.cpp 17117 2009-05-25 19:26:01Z warmerdam $");
      35                 : 
      36                 : CPL_C_START
      37                 : void  GDALRegister_LAN(void);
      38                 : CPL_C_END
      39                 : 
      40                 : /**
      41                 : 
      42                 : Erdas Header format: "HEAD74"
      43                 : 
      44                 : Offset   Size    Type      Description
      45                 : ------   ----    ----      -----------
      46                 : 0          6     char      magic cookie / version (ie. HEAD74). 
      47                 : 6          2    Int16      Pixel type, 0=8bit, 1=4bit, 2=16bit
      48                 : 8          2    Int16      Number of Bands. 
      49                 : 10         6     char      Unknown.
      50                 : 16         4    Int32      Width
      51                 : 20         4    Int32      Height
      52                 : 24         4    Int32      X Start (offset in original file?)
      53                 : 28         4    Int32      Y Start (offset in original file?)
      54                 : 32        56     char      Unknown.
      55                 : 88         2    Int16      0=LAT, 1=UTM, 2=StatePlane, 3- are projections?
      56                 : 90         2    Int16      Classes in coverage.
      57                 : 92        14     char      Unknown.
      58                 : 106        2    Int16      Area Unit (0=none, 1=Acre, 2=Hectare, 3=Other)
      59                 : 108        4  Float32      Pixel area. 
      60                 : 112        4  Float32      Upper Left corner X (center of pixel?)
      61                 : 116        4  Float32      Upper Left corner Y (center of pixel?)
      62                 : 120        4  Float32      Width of a pixel.
      63                 : 124        4  Float32      Height of a pixel.
      64                 : 
      65                 : Erdas Header format: "HEADER"
      66                 : 
      67                 : Offset   Size    Type      Description
      68                 : ------   ----    ----      -----------
      69                 : 0          6     char      magic cookie / version (ie. HEAD74). 
      70                 : 6          2    Int16      Pixel type, 0=8bit, 1=4bit, 2=16bit
      71                 : 8          2    Int16      Number of Bands. 
      72                 : 10         6     char      Unknown.
      73                 : 16         4  Float32      Width
      74                 : 20         4  Float32      Height
      75                 : 24         4    Int32      X Start (offset in original file?)
      76                 : 28         4    Int32      Y Start (offset in original file?)
      77                 : 32        56     char      Unknown.
      78                 : 88         2    Int16      0=LAT, 1=UTM, 2=StatePlane, 3- are projections?
      79                 : 90         2    Int16      Classes in coverage.
      80                 : 92        14     char      Unknown.
      81                 : 106        2    Int16      Area Unit (0=none, 1=Acre, 2=Hectare, 3=Other)
      82                 : 108        4  Float32      Pixel area. 
      83                 : 112        4  Float32      Upper Left corner X (center of pixel?)
      84                 : 116        4  Float32      Upper Left corner Y (center of pixel?)
      85                 : 120        4  Float32      Width of a pixel.
      86                 : 124        4  Float32      Height of a pixel.
      87                 : 
      88                 : All binary fields are in the same byte order but it may be big endian or
      89                 : little endian depending on what platform the file was written on.  Usually
      90                 : this can be checked against the number of bands though this test won't work
      91                 : if there are more than 255 bands. 
      92                 : 
      93                 : There is also some information on .STA and .TRL files at:
      94                 : 
      95                 :   http://www.pcigeomatics.com/cgi-bin/pcihlp/ERDASWR%7CTRAILER+FORMAT
      96                 : 
      97                 : **/
      98                 : 
      99                 : #define ERD_HEADER_SIZE  128
     100                 : 
     101                 : /************************************************************************/
     102                 : /* ==================================================================== */
     103                 : /*                         LAN4BitRasterBand                            */
     104                 : /* ==================================================================== */
     105                 : /************************************************************************/
     106                 : 
     107                 : class LANDataset;
     108                 : 
     109                 : class LAN4BitRasterBand : public GDALPamRasterBand
     110                 : {
     111                 :     GDALColorTable *poCT;
     112                 :     GDALColorInterp eInterp;
     113                 : 
     114                 :   public:
     115                 :                    LAN4BitRasterBand( LANDataset *, int );
     116                 :                   ~LAN4BitRasterBand();
     117                 : 
     118                 :     virtual GDALColorTable *GetColorTable();
     119                 :     virtual GDALColorInterp GetColorInterpretation();
     120                 :     virtual CPLErr SetColorTable( GDALColorTable * ); 
     121                 :     virtual CPLErr SetColorInterpretation( GDALColorInterp );
     122                 : 
     123                 :     virtual CPLErr IReadBlock( int, int, void * );
     124                 : };
     125                 : 
     126                 : /************************************************************************/
     127                 : /* ==================================================================== */
     128                 : /*        LANDataset        */
     129                 : /* ==================================================================== */
     130                 : /************************************************************************/
     131                 : 
     132                 : class LANDataset : public RawDataset
     133                 : {
     134                 :   public:
     135                 :     FILE  *fpImage; // image data file.
     136                 :     
     137                 :     char  pachHeader[ERD_HEADER_SIZE];
     138                 : 
     139                 :     char        *pszProjection;
     140                 :     
     141                 :     double      adfGeoTransform[6];
     142                 : 
     143                 :     CPLString   osSTAFilename;
     144                 :     void        CheckForStatistics(void);
     145                 : 
     146                 :     virtual char **GetFileList();
     147                 : 
     148                 :   public:
     149                 :         LANDataset();
     150                 :               ~LANDataset();
     151                 :     
     152                 :     virtual CPLErr GetGeoTransform( double * padfTransform );
     153                 :     virtual const char *GetProjectionRef();
     154                 : 
     155                 :     static GDALDataset *Open( GDALOpenInfo * );
     156                 : };
     157                 : 
     158                 : /************************************************************************/
     159                 : /* ==================================================================== */
     160                 : /*                         LAN4BitRasterBand                            */
     161                 : /* ==================================================================== */
     162                 : /************************************************************************/
     163                 : 
     164                 : /************************************************************************/
     165                 : /*                         LAN4BitRasterBand()                          */
     166                 : /************************************************************************/
     167                 : 
     168               1 : LAN4BitRasterBand::LAN4BitRasterBand( LANDataset *poDS, int nBandIn )
     169                 : 
     170                 : {
     171               1 :     this->poDS = poDS;
     172               1 :     this->nBand = nBandIn;
     173               1 :     this->eDataType = GDT_Byte;
     174                 : 
     175               1 :     nBlockXSize = poDS->GetRasterXSize();;
     176               1 :     nBlockYSize = 1;
     177                 : 
     178               1 :     poCT = NULL;
     179               1 :     eInterp = GCI_Undefined;
     180               1 : }
     181                 : 
     182                 : /************************************************************************/
     183                 : /*                         ~LAN4BitRasterBand()                         */
     184                 : /************************************************************************/
     185                 : 
     186               2 : LAN4BitRasterBand::~LAN4BitRasterBand()
     187                 : 
     188                 : {
     189               1 :     if( poCT )
     190               0 :         delete poCT;
     191               2 : }
     192                 : 
     193                 : /************************************************************************/
     194                 : /*                             IReadBlock()                             */
     195                 : /************************************************************************/
     196                 : 
     197               2 : CPLErr LAN4BitRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     198                 :                                       void * pImage )
     199                 : 
     200                 : {
     201               2 :     LANDataset *poLAN_DS = (LANDataset *) poDS;
     202                 :     CPLAssert( nBlockXOff == 0  );
     203                 :     
     204                 : /* -------------------------------------------------------------------- */
     205                 : /*      Seek to profile.                                                */
     206                 : /* -------------------------------------------------------------------- */
     207                 :     int nOffset;
     208                 : 
     209                 :     nOffset = 
     210                 :         ERD_HEADER_SIZE
     211                 :         + (nBlockYOff * nRasterXSize * poLAN_DS->GetRasterCount()) / 2
     212               2 :         + ((nBand - 1) * nRasterXSize) / 2;
     213                 : 
     214               2 :     if( VSIFSeekL( poLAN_DS->fpImage, nOffset, SEEK_SET ) != 0 )
     215                 :     {
     216                 :         CPLError( CE_Failure, CPLE_FileIO, 
     217               0 :                   "LAN Seek failed:%s", VSIStrerror( errno ) );
     218               0 :         return CE_Failure;
     219                 :     }
     220                 : 
     221                 : /* -------------------------------------------------------------------- */
     222                 : /*      Read the profile.                                               */
     223                 : /* -------------------------------------------------------------------- */
     224               2 :     if( VSIFReadL( pImage, 1, nRasterXSize/2, poLAN_DS->fpImage ) != 
     225                 :         (size_t) nRasterXSize / 2 )
     226                 :     {
     227                 :         CPLError( CE_Failure, CPLE_FileIO, 
     228               0 :                   "LAN Read failed:%s", VSIStrerror( errno ) );
     229               0 :         return CE_Failure;
     230                 :     }
     231                 : 
     232                 : /* -------------------------------------------------------------------- */
     233                 : /*      Convert 4bit to 8bit.                                           */
     234                 : /* -------------------------------------------------------------------- */
     235                 :     int i;
     236                 : 
     237               6 :     for( i = nRasterXSize-1; i >= 0; i-- )
     238                 :     {
     239               4 :         if( (i & 0x01) != 0 )
     240               2 :             ((GByte *) pImage)[i] = ((GByte *) pImage)[i/2] & 0x0f;
     241                 :         else
     242               2 :             ((GByte *) pImage)[i] = (((GByte *) pImage)[i/2] & 0xf0)/16;
     243                 :     }
     244                 : 
     245               2 :     return CE_None;
     246                 : }
     247                 : 
     248                 : /************************************************************************/
     249                 : /*                           SetColorTable()                            */
     250                 : /************************************************************************/
     251                 : 
     252               0 : CPLErr LAN4BitRasterBand::SetColorTable( GDALColorTable *poNewCT )
     253                 : 
     254                 : {
     255               0 :     if( poCT )
     256               0 :         delete poCT;
     257               0 :     if( poNewCT == NULL )
     258               0 :         poCT = NULL;
     259                 :     else
     260               0 :         poCT = poNewCT->Clone();
     261                 : 
     262               0 :     return CE_None;
     263                 : }
     264                 : 
     265                 : /************************************************************************/
     266                 : /*                           GetColorTable()                            */
     267                 : /************************************************************************/
     268                 : 
     269               0 : GDALColorTable *LAN4BitRasterBand::GetColorTable()
     270                 : 
     271                 : {
     272               0 :     if( poCT != NULL )
     273               0 :         return poCT;
     274                 :     else
     275               0 :         return GDALPamRasterBand::GetColorTable();
     276                 : }
     277                 : 
     278                 : /************************************************************************/
     279                 : /*                       SetColorInterpretation()                       */
     280                 : /************************************************************************/
     281                 : 
     282               0 : CPLErr LAN4BitRasterBand::SetColorInterpretation( GDALColorInterp eNewInterp )
     283                 : 
     284                 : {
     285               0 :     eInterp = eNewInterp;
     286                 : 
     287               0 :     return CE_None;
     288                 : }
     289                 : 
     290                 : /************************************************************************/
     291                 : /*                       GetColorInterpretation()                       */
     292                 : /************************************************************************/
     293                 : 
     294               0 : GDALColorInterp LAN4BitRasterBand::GetColorInterpretation()
     295                 : 
     296                 : {
     297               0 :     return eInterp;
     298                 : }
     299                 : 
     300                 : /************************************************************************/
     301                 : /* ==================================================================== */
     302                 : /*        LANDataset        */
     303                 : /* ==================================================================== */
     304                 : /************************************************************************/
     305                 : 
     306                 : /************************************************************************/
     307                 : /*                             LANDataset()                             */
     308                 : /************************************************************************/
     309                 : 
     310               2 : LANDataset::LANDataset()
     311                 : {
     312               2 :     fpImage = NULL;
     313               2 :     pszProjection = NULL;
     314               2 : }
     315                 : 
     316                 : /************************************************************************/
     317                 : /*                            ~LANDataset()                             */
     318                 : /************************************************************************/
     319                 : 
     320               4 : LANDataset::~LANDataset()
     321                 : 
     322                 : {
     323               2 :     FlushCache();
     324                 : 
     325               2 :     if( fpImage != NULL )
     326               2 :         VSIFCloseL( fpImage );
     327                 : 
     328               2 :     CPLFree( pszProjection );
     329               4 : }
     330                 : 
     331                 : /************************************************************************/
     332                 : /*                                Open()                                */
     333                 : /************************************************************************/
     334                 : 
     335            8523 : GDALDataset *LANDataset::Open( GDALOpenInfo * poOpenInfo )
     336                 : 
     337                 : {
     338                 : /* -------------------------------------------------------------------- */
     339                 : /*      We assume the user is pointing to the header (.pcb) file.       */
     340                 : /*      Does this appear to be a pcb file?                              */
     341                 : /* -------------------------------------------------------------------- */
     342            8523 :     if( poOpenInfo->nHeaderBytes < ERD_HEADER_SIZE || poOpenInfo->fp == NULL )
     343            8344 :         return NULL;
     344                 : 
     345             179 :     if( !EQUALN((const char *)poOpenInfo->pabyHeader,"HEADER",6)
     346                 :         && !EQUALN((const char *)poOpenInfo->pabyHeader,"HEAD74",6) )
     347             177 :         return NULL;
     348                 : 
     349                 : /* -------------------------------------------------------------------- */
     350                 : /*      Create a corresponding GDALDataset.                             */
     351                 : /* -------------------------------------------------------------------- */
     352                 :     LANDataset  *poDS;
     353                 : 
     354               2 :     poDS = new LANDataset();
     355                 : 
     356               2 :     poDS->eAccess = poOpenInfo->eAccess;
     357                 : 
     358                 : /* -------------------------------------------------------------------- */
     359                 : /*      Adopt the openinfo file pointer for use with this file.         */
     360                 : /* -------------------------------------------------------------------- */
     361               2 :     if( poOpenInfo->eAccess == GA_ReadOnly )
     362               2 :         poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
     363                 :     else
     364               0 :         poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
     365               2 :     if( poDS->fpImage == NULL )
     366               0 :         return NULL;
     367                 : 
     368                 : /* -------------------------------------------------------------------- */
     369                 : /*      Do we need to byte swap the headers to local machine order?     */
     370                 : /* -------------------------------------------------------------------- */
     371               2 :     int bBigEndian = poOpenInfo->pabyHeader[8] == 0;
     372                 :     int bNeedSwap;
     373                 : 
     374               2 :     memcpy( poDS->pachHeader, poOpenInfo->pabyHeader, ERD_HEADER_SIZE );
     375                 : 
     376                 : #ifdef CPL_LSB
     377               2 :     bNeedSwap = bBigEndian;
     378                 : #else
     379                 :     bNeedSwap = !bBigEndian;
     380                 : #endif
     381                 :         
     382               2 :     if( bNeedSwap )
     383                 :     {
     384               0 :         CPL_SWAP16PTR( poDS->pachHeader + 6 );
     385               0 :         CPL_SWAP16PTR( poDS->pachHeader + 8 );
     386                 : 
     387               0 :         CPL_SWAP32PTR( poDS->pachHeader + 16 );
     388               0 :         CPL_SWAP32PTR( poDS->pachHeader + 20 );
     389               0 :         CPL_SWAP32PTR( poDS->pachHeader + 24 );
     390               0 :         CPL_SWAP32PTR( poDS->pachHeader + 28 );
     391                 : 
     392               0 :         CPL_SWAP16PTR( poDS->pachHeader + 88 );
     393               0 :         CPL_SWAP16PTR( poDS->pachHeader + 90 );
     394                 : 
     395               0 :         CPL_SWAP16PTR( poDS->pachHeader + 106 );
     396               0 :         CPL_SWAP32PTR( poDS->pachHeader + 108 );
     397               0 :         CPL_SWAP32PTR( poDS->pachHeader + 112 );
     398               0 :         CPL_SWAP32PTR( poDS->pachHeader + 116 );
     399               0 :         CPL_SWAP32PTR( poDS->pachHeader + 120 );
     400               0 :         CPL_SWAP32PTR( poDS->pachHeader + 124 );
     401                 :     }
     402                 : 
     403                 : /* -------------------------------------------------------------------- */
     404                 : /*      Capture some information from the file that is of interest.     */
     405                 : /* -------------------------------------------------------------------- */
     406                 :     int  nBandCount, nPixelOffset;
     407                 :     GDALDataType eDataType;
     408                 : 
     409               2 :     if( EQUALN(poDS->pachHeader,"HEADER",7) )
     410                 :     {
     411               0 :         poDS->nRasterXSize = (int) *((float *) (poDS->pachHeader + 16));
     412               0 :         poDS->nRasterYSize = (int) *((float *) (poDS->pachHeader + 20));
     413                 :     }
     414                 :     else
     415                 :     {
     416               2 :         poDS->nRasterXSize = *((GInt32 *) (poDS->pachHeader + 16));
     417               2 :         poDS->nRasterYSize = *((GInt32 *) (poDS->pachHeader + 20));
     418                 :     }
     419                 : 
     420               2 :     if( *((GInt16 *) (poDS->pachHeader + 6)) == 0 )
     421                 :     {
     422               1 :         eDataType = GDT_Byte;
     423               1 :         nPixelOffset = 1;
     424                 :     }
     425               1 :     else if( *((GInt16 *) (poDS->pachHeader + 6)) == 1 ) /* 4bit! */
     426                 :     {
     427               1 :         eDataType = GDT_Byte;
     428               1 :         nPixelOffset = -1;
     429                 :     }
     430               0 :     else if( *((GInt16 *) (poDS->pachHeader + 6)) == 2 )
     431                 :     {
     432               0 :         nPixelOffset = 2;
     433               0 :         eDataType = GDT_Int16;
     434                 :     }
     435                 :     else
     436                 :     {
     437                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     438                 :                   "Unsupported pixel type (%d).", 
     439               0 :                   *((GInt16 *) (poDS->pachHeader + 6)) );
     440                 :                   
     441               0 :         delete poDS;
     442               0 :         return NULL;
     443                 :     }
     444                 : 
     445               2 :     nBandCount = *((GInt16 *) (poDS->pachHeader + 8));
     446                 : 
     447               2 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
     448                 :         !GDALCheckBandCount(nBandCount, FALSE))
     449                 :     {
     450               0 :         delete poDS;
     451               0 :         return NULL;
     452                 :     }
     453                 : 
     454                 : /* -------------------------------------------------------------------- */
     455                 : /*      Create band information object.                                 */
     456                 : /* -------------------------------------------------------------------- */
     457               4 :     for( int iBand = 1; iBand <= nBandCount; iBand++ )
     458                 :     {
     459               2 :         if( nPixelOffset == -1 ) /* 4 bit case */
     460                 :             poDS->SetBand( iBand, 
     461               1 :                            new LAN4BitRasterBand( poDS, iBand ) );
     462                 :         else
     463                 :             poDS->SetBand( 
     464                 :                 iBand, 
     465                 :                 new RawRasterBand( poDS, iBand, poDS->fpImage, 
     466                 :                                    ERD_HEADER_SIZE + (iBand-1) 
     467                 :                                    * nPixelOffset * poDS->nRasterXSize,
     468                 :                                    nPixelOffset, 
     469                 :                                    poDS->nRasterXSize*nPixelOffset*nBandCount,
     470               1 :                                    eDataType, !bNeedSwap, TRUE ));
     471                 :     }
     472                 : 
     473                 : /* -------------------------------------------------------------------- */
     474                 : /*      Initialize any PAM information.                                 */
     475                 : /* -------------------------------------------------------------------- */
     476               2 :     poDS->SetDescription( poOpenInfo->pszFilename );
     477               2 :     poDS->CheckForStatistics();
     478               2 :     poDS->TryLoadXML();
     479                 : 
     480                 : /* -------------------------------------------------------------------- */
     481                 : /*      Check for overviews.                                            */
     482                 : /* -------------------------------------------------------------------- */
     483               2 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     484                 : 
     485                 : /* -------------------------------------------------------------------- */
     486                 : /*      Try to interprete georeferencing.                               */
     487                 : /* -------------------------------------------------------------------- */
     488               2 :     poDS->adfGeoTransform[0] = *((float *) (poDS->pachHeader + 112));
     489               2 :     poDS->adfGeoTransform[1] = *((float *) (poDS->pachHeader + 120));
     490               2 :     poDS->adfGeoTransform[2] = 0.0;
     491               2 :     poDS->adfGeoTransform[3] = *((float *) (poDS->pachHeader + 116));
     492               2 :     poDS->adfGeoTransform[4] = 0.0;
     493               2 :     poDS->adfGeoTransform[5] = - *((float *) (poDS->pachHeader + 124));
     494                 : 
     495                 :     // adjust for center of pixel vs. top left corner of pixel.
     496               2 :     poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
     497               2 :     poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
     498                 : 
     499                 : /* -------------------------------------------------------------------- */
     500                 : /*      If we didn't get any georeferencing, try for a worldfile.       */
     501                 : /* -------------------------------------------------------------------- */
     502               4 :     if( poDS->adfGeoTransform[1] == 0.0
     503               2 :         || poDS->adfGeoTransform[5] == 0.0 )
     504                 :     {
     505               0 :         if( !GDALReadWorldFile( poOpenInfo->pszFilename, NULL, 
     506                 :                                 poDS->adfGeoTransform ) )
     507                 :             GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
     508               0 :                                poDS->adfGeoTransform );
     509                 :     }
     510                 : 
     511                 : /* -------------------------------------------------------------------- */
     512                 : /*      Try to come up with something for the coordinate system.        */
     513                 : /* -------------------------------------------------------------------- */
     514               2 :     int nCoordSys = *((GInt16 *) (poDS->pachHeader + 88));
     515                 : 
     516               2 :     if( nCoordSys == 0 )
     517                 :     {
     518               2 :         poDS->pszProjection = CPLStrdup(SRS_WKT_WGS84);
     519                 :             
     520                 :     }
     521               0 :     else if( nCoordSys == 1 )
     522                 :     {
     523                 :         poDS->pszProjection = 
     524               0 :             CPLStrdup("LOCAL_CS[\"UTM - Zone Unknown\",UNIT[\"Meter\",1]]");
     525                 :     }
     526               0 :     else if( nCoordSys == 2 )
     527                 :     {
     528               0 :         poDS->pszProjection = CPLStrdup("LOCAL_CS[\"State Plane - Zone Unknown\",UNIT[\"US survey foot\",0.3048006096012192]]");
     529                 :     }
     530                 :     else 
     531                 :     {
     532                 :         poDS->pszProjection = 
     533               0 :             CPLStrdup("LOCAL_CS[\"Unknown\",UNIT[\"Meter\",1]]");
     534                 :     }
     535                 : 
     536                 : /* -------------------------------------------------------------------- */
     537                 : /*      Check for a trailer file with a colormap in it.                 */
     538                 : /* -------------------------------------------------------------------- */
     539               2 :     char *pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
     540               2 :     char *pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename));
     541                 :     const char *pszTRLFilename = 
     542               2 :         CPLFormCIFilename( pszPath, pszBasename, "trl" );
     543                 :     FILE *fpTRL;
     544                 : 
     545               2 :     fpTRL = VSIFOpenL( pszTRLFilename, "rb" );
     546               2 :     if( fpTRL != NULL )
     547                 :     {
     548                 :         char szTRLData[896];
     549                 :         int iColor;
     550                 :         GDALColorTable *poCT;
     551                 : 
     552               0 :         VSIFReadL( szTRLData, 1, 896, fpTRL );
     553               0 :         VSIFCloseL( fpTRL );
     554                 :         
     555               0 :         poCT = new GDALColorTable();
     556               0 :         for( iColor = 0; iColor < 256; iColor++ )
     557                 :         {
     558                 :             GDALColorEntry sEntry;
     559                 : 
     560               0 :             sEntry.c2 = ((GByte *) szTRLData)[iColor+128];
     561               0 :             sEntry.c1 = ((GByte *) szTRLData)[iColor+128+256];
     562               0 :             sEntry.c3 = ((GByte *) szTRLData)[iColor+128+512];
     563               0 :             sEntry.c4 = 255;
     564               0 :             poCT->SetColorEntry( iColor, &sEntry );
     565                 : 
     566                 :             // only 16 colors in 4bit files.
     567               0 :             if( nPixelOffset == -1 && iColor == 15 )
     568               0 :                 break;
     569                 :         }
     570                 : 
     571               0 :         poDS->GetRasterBand(1)->SetColorTable( poCT );
     572               0 :         poDS->GetRasterBand(1)->SetColorInterpretation( GCI_PaletteIndex );
     573                 :         
     574               0 :         delete poCT;
     575                 :     }
     576                 : 
     577               2 :     CPLFree( pszPath );
     578               2 :     CPLFree( pszBasename );
     579                 : 
     580               2 :     return( poDS );
     581                 : }
     582                 : 
     583                 : /************************************************************************/
     584                 : /*                          GetGeoTransform()                           */
     585                 : /************************************************************************/
     586                 : 
     587               0 : CPLErr LANDataset::GetGeoTransform( double * padfTransform )
     588                 : 
     589                 : {
     590               0 :     if( adfGeoTransform[1] != 0.0 && adfGeoTransform[5] != 0.0 )
     591                 :     {
     592               0 :         memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
     593               0 :         return CE_None;
     594                 :     }
     595                 :     else
     596               0 :         return GDALPamDataset::GetGeoTransform( padfTransform );
     597                 : }
     598                 : 
     599                 : /************************************************************************/
     600                 : /*                          GetProjectionRef()                          */
     601                 : /*                                                                      */
     602                 : /*      Use PAM coordinate system if available in preference to the     */
     603                 : /*      generally poor value derived from the file itself.              */
     604                 : /************************************************************************/
     605                 : 
     606               0 : const char *LANDataset::GetProjectionRef()
     607                 : 
     608                 : {
     609               0 :     const char* pszPamPrj = GDALPamDataset::GetProjectionRef();
     610                 : 
     611               0 :     if( pszProjection != NULL && strlen(pszPamPrj) == 0 )
     612               0 :         return pszProjection;
     613                 :     else
     614               0 :         return pszPamPrj;
     615                 : }
     616                 : 
     617                 : /************************************************************************/
     618                 : /*                            GetFileList()                             */
     619                 : /************************************************************************/
     620                 : 
     621               0 : char **LANDataset::GetFileList()
     622                 : 
     623                 : {
     624               0 :     char **papszFileList = NULL;
     625                 : 
     626                 :     // Main data file, etc. 
     627               0 :     papszFileList = GDALPamDataset::GetFileList();
     628                 : 
     629               0 :     if( strlen(osSTAFilename) > 0 )
     630               0 :         papszFileList = CSLAddString( papszFileList, osSTAFilename );
     631                 : 
     632               0 :     return papszFileList;
     633                 : }
     634                 : 
     635                 : /************************************************************************/
     636                 : /*                         CheckForStatistics()                         */
     637                 : /************************************************************************/
     638                 : 
     639               2 : void LANDataset::CheckForStatistics()
     640                 : 
     641                 : {
     642                 : /* -------------------------------------------------------------------- */
     643                 : /*      Do we have a statistics file?                                   */
     644                 : /* -------------------------------------------------------------------- */
     645               2 :     osSTAFilename = CPLResetExtension(GetDescription(),"sta");
     646                 : 
     647               2 :     FILE *fpSTA = VSIFOpenL( osSTAFilename, "r" );
     648                 : 
     649                 : #ifndef WIN32
     650               2 :     if( fpSTA == NULL )
     651                 :     {
     652               2 :         osSTAFilename = CPLResetExtension(GetDescription(),"STA");
     653               2 :         fpSTA = VSIFOpenL( osSTAFilename, "r" );
     654                 :     }
     655                 : #endif
     656                 : 
     657               2 :     if( fpSTA == NULL )
     658                 :     {
     659               2 :         osSTAFilename = "";
     660               2 :         return;
     661                 :     }
     662                 : 
     663                 : /* -------------------------------------------------------------------- */
     664                 : /*      Read it one band at a time.                                     */
     665                 : /* -------------------------------------------------------------------- */
     666                 :     GByte abyBandInfo[1152];
     667                 :     int iBand;
     668                 : 
     669               0 :     for( iBand = 0; iBand < nBands; iBand++ )
     670                 :     {
     671               0 :         if( VSIFReadL( abyBandInfo, 1152, 1, fpSTA ) != 1 )
     672               0 :             break;
     673                 : 
     674               0 :         int nBandNumber = abyBandInfo[7];
     675               0 :         GDALRasterBand *poBand = GetRasterBand(nBandNumber);
     676               0 :         if( poBand == NULL )
     677               0 :             break;
     678                 : 
     679                 :         float fMean, fStdDev;
     680                 :         GInt16 nMin, nMax;
     681                 : 
     682               0 :         if( poBand->GetRasterDataType() != GDT_Byte )
     683                 :         {
     684               0 :             memcpy( &nMin, abyBandInfo + 28, 2 );
     685               0 :             memcpy( &nMax, abyBandInfo + 30, 2 );
     686                 :             CPL_LSBPTR16( &nMin );
     687                 :             CPL_LSBPTR16( &nMax );
     688                 :         }
     689                 :         else
     690                 :         {
     691               0 :             nMin = abyBandInfo[9];
     692               0 :             nMax = abyBandInfo[8];
     693                 :         }
     694                 :         
     695               0 :         memcpy( &fMean, abyBandInfo + 12, 4 );
     696               0 :         memcpy( &fStdDev, abyBandInfo + 24, 4 );
     697                 :         CPL_LSBPTR32( &fMean );
     698                 :         CPL_LSBPTR32( &fStdDev );
     699                 :         
     700               0 :         poBand->SetStatistics( nMin, nMax, fMean, fStdDev );
     701                 :     }
     702                 :     
     703               0 :     VSIFCloseL( fpSTA );
     704                 : }
     705                 : 
     706                 : /************************************************************************/
     707                 : /*                          GDALRegister_LAN()                          */
     708                 : /************************************************************************/
     709                 : 
     710             338 : void GDALRegister_LAN()
     711                 : 
     712                 : {
     713                 :     GDALDriver  *poDriver;
     714                 : 
     715             338 :     if( GDALGetDriverByName( "LAN" ) == NULL )
     716                 :     {
     717             336 :         poDriver = new GDALDriver();
     718                 :         
     719             336 :         poDriver->SetDescription( "LAN" );
     720                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     721             336 :                                    "Erdas .LAN/.GIS" );
     722                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     723             336 :                                    "frmt_various.html#LAN" );
     724                 :         
     725             336 :         poDriver->pfnOpen = LANDataset::Open;
     726                 : 
     727             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     728                 :     }
     729             338 : }
     730                 : 

Generated by: LCOV version 1.7