LTP GCOV extension - code coverage report
Current view: directory - frmts/elas - elasdataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 201
Code covered: 87.6 % Executed lines: 176

       1                 : /******************************************************************************
       2                 :  * $Id: elasdataset.cpp 16396 2009-02-22 20:49:52Z rouault $
       3                 :  *
       4                 :  * Project:  ELAS Translator
       5                 :  * Purpose:  Complete implementation of ELAS translator module for GDAL.
       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                 : 
      32                 : CPL_CVSID("$Id: elasdataset.cpp 16396 2009-02-22 20:49:52Z rouault $");
      33                 : 
      34                 : CPL_C_START
      35                 : void  GDALRegister_ELAS(void);
      36                 : CPL_C_END
      37                 : 
      38                 : typedef struct {
      39                 :     GInt32  NBIH; /* bytes in header, normaly 1024 */
      40                 :     GInt32      NBPR; /* bytes per data record (all bands of scanline) */
      41                 :     GInt32  IL; /* initial line - normally 1 */
      42                 :     GInt32  LL; /* last line */
      43                 :     GInt32  IE; /* initial element (pixel), normally 1 */
      44                 :     GInt32  LE; /* last element (pixel) */
      45                 :     GInt32  NC; /* number of channels (bands) */
      46                 :     GInt32  H4321;  /* header record identifier - always 4321. */
      47                 :     char  YLabel[4]; /* Should be "NOR" for UTM */
      48                 :     GInt32      YOffset;/* topleft pixel center northing */
      49                 :     char  XLabel[4]; /* Should be "EAS" for UTM */
      50                 :     GInt32      XOffset;/* topleft pixel center easting */
      51                 :     float YPixSize;/* height of pixel in georef units */
      52                 :     float XPixSize;/* width of pixel in georef units */
      53                 :     float Matrix[4]; /* 2x2 transformation matrix.  Should be
      54                 :                               1,0,0,1 for pixel/line, or
      55                 :                               1,0,0,-1 for UTM */
      56                 :     GByte IH19[4];/* data type, and size flags */
      57                 :     GInt32  IH20; /* number of secondary headers */
      58                 :     char  unused1[8];
      59                 :     GInt32  LABL; /* used by LABL module */
      60                 :     char  HEAD; /* used by HEAD module */
      61                 :     char  Comment1[64];
      62                 :     char  Comment2[64];
      63                 :     char  Comment3[64];
      64                 :     char  Comment4[64];
      65                 :     char  Comment5[64];
      66                 :     char  Comment6[64];
      67                 :     GUInt16 ColorTable[256];  /* RGB packed with 4 bits each */
      68                 :     char  unused2[32];
      69                 : } ELASHeader;
      70                 : 
      71                 : 
      72                 : /************************************************************************/
      73                 : /* ==================================================================== */
      74                 : /*        ELASDataset       */
      75                 : /* ==================================================================== */
      76                 : /************************************************************************/
      77                 : 
      78                 : class ELASRasterBand;
      79                 : 
      80                 : class ELASDataset : public GDALPamDataset
      81                 : {
      82                 :     friend class ELASRasterBand;
      83                 : 
      84                 :     FILE  *fp;
      85                 : 
      86                 :     ELASHeader  sHeader;
      87                 :     int   bHeaderModified;
      88                 : 
      89                 :     GDALDataType eRasterDataType;
      90                 : 
      91                 :     int   nLineOffset;
      92                 :     int   nBandOffset;     // within a line.
      93                 :     
      94                 :     double  adfGeoTransform[6];
      95                 : 
      96                 :   public:
      97                 :                  ELASDataset();
      98                 :                  ~ELASDataset();
      99                 : 
     100                 :     virtual CPLErr GetGeoTransform( double * );
     101                 :     virtual CPLErr SetGeoTransform( double * );
     102                 : 
     103                 :     static GDALDataset *Open( GDALOpenInfo * );
     104                 :     static GDALDataset *Create( const char * pszFilename,
     105                 :                                 int nXSize, int nYSize, int nBands,
     106                 :                                 GDALDataType eType, char ** papszParmList );
     107                 : 
     108                 :     virtual void FlushCache( void );
     109                 : };
     110                 : 
     111                 : /************************************************************************/
     112                 : /* ==================================================================== */
     113                 : /*                            ELASRasterBand                             */
     114                 : /* ==================================================================== */
     115                 : /************************************************************************/
     116                 : 
     117                 : class ELASRasterBand : public GDALPamRasterBand
     118              74 : {
     119                 :     friend class ELASDataset;
     120                 : 
     121                 :   public:
     122                 : 
     123                 :                    ELASRasterBand( ELASDataset *, int );
     124                 : 
     125                 :     // should override RasterIO eventually.
     126                 :     
     127                 :     virtual CPLErr IReadBlock( int, int, void * );
     128                 :     virtual CPLErr IWriteBlock( int, int, void * ); 
     129                 : };
     130                 : 
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                           ELASRasterBand()                            */
     134                 : /************************************************************************/
     135                 : 
     136              74 : ELASRasterBand::ELASRasterBand( ELASDataset *poDS, int nBand )
     137                 : 
     138                 : {
     139              74 :     this->poDS = poDS;
     140              74 :     this->nBand = nBand;
     141                 : 
     142              74 :     this->eAccess = poDS->eAccess;
     143                 : 
     144              74 :     eDataType = poDS->eRasterDataType;
     145                 : 
     146              74 :     nBlockXSize = poDS->GetRasterXSize();
     147              74 :     nBlockYSize = 1;
     148              74 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                             IReadBlock()                             */
     152                 : /************************************************************************/
     153                 : 
     154                 : CPLErr ELASRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     155             100 :                                    void * pImage )
     156                 : 
     157                 : {
     158             100 :     ELASDataset *poGDS = (ELASDataset *) poDS;
     159             100 :     CPLErr    eErr = CE_None;
     160                 :     long    nOffset;
     161                 :     int     nDataSize;
     162                 : 
     163             100 :     CPLAssert( nBlockXOff == 0 );
     164                 : 
     165             100 :     nDataSize = GDALGetDataTypeSize(eDataType) * poGDS->GetRasterXSize() / 8;
     166             100 :     nOffset = poGDS->nLineOffset * nBlockYOff + 1024 + (nBand-1) * nDataSize;
     167                 :     
     168                 : /* -------------------------------------------------------------------- */
     169                 : /*      If we can't seek to the data, we will assume this is a newly    */
     170                 : /*      created file, and that the file hasn't been extended yet.       */
     171                 : /*      Just read as zeros.                                             */
     172                 : /* -------------------------------------------------------------------- */
     173             100 :     if( VSIFSeek( poGDS->fp, nOffset, SEEK_SET ) != 0 
     174                 :         || VSIFRead( pImage, 1, nDataSize, poGDS->fp ) != (size_t) nDataSize )
     175                 :     {
     176                 :         CPLError( CE_Failure, CPLE_FileIO,
     177                 :                   "Seek or read of %d bytes at %ld failed.\n",
     178               0 :                   nDataSize, nOffset );
     179               0 :         eErr = CE_Failure;
     180                 :     }
     181                 : 
     182             100 :     return eErr;
     183                 : }
     184                 : 
     185                 : /************************************************************************/
     186                 : /*                            IWriteBlock()                             */
     187                 : /************************************************************************/
     188                 : 
     189                 : CPLErr ELASRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
     190             230 :                                      void * pImage )
     191                 : 
     192                 : {
     193             230 :     ELASDataset *poGDS = (ELASDataset *) poDS;
     194             230 :     CPLErr    eErr = CE_None;
     195                 :     long    nOffset;
     196                 :     int     nDataSize;
     197                 : 
     198             230 :     CPLAssert( nBlockXOff == 0 );
     199             230 :     CPLAssert( eAccess == GA_Update );
     200                 : 
     201             230 :     nDataSize = GDALGetDataTypeSize(eDataType) * poGDS->GetRasterXSize() / 8;
     202             230 :     nOffset = poGDS->nLineOffset * nBlockYOff + 1024 + (nBand-1) * nDataSize;
     203                 :     
     204             230 :     if( VSIFSeek( poGDS->fp, nOffset, SEEK_SET ) != 0
     205                 :         || VSIFWrite( pImage, 1, nDataSize, poGDS->fp ) != (size_t) nDataSize )
     206                 :     {
     207                 :         CPLError( CE_Failure, CPLE_FileIO,
     208                 :                   "Seek or write of %d bytes at %ld failed.\n",
     209               0 :                   nDataSize, nOffset );
     210               0 :         eErr = CE_Failure;
     211                 :     }
     212                 : 
     213             230 :     return eErr;
     214                 : }
     215                 : 
     216                 : /************************************************************************/
     217                 : /* ==================================================================== */
     218                 : /*      ELASDataset                                                     */
     219                 : /* ==================================================================== */
     220                 : /************************************************************************/
     221                 : 
     222                 : 
     223                 : /************************************************************************/
     224                 : /*                            ELASDataset()                             */
     225                 : /************************************************************************/
     226                 : 
     227              30 : ELASDataset::ELASDataset()
     228                 : 
     229                 : {
     230              30 :     fp = NULL;
     231                 : 
     232              30 :     adfGeoTransform[0] = 0.0;
     233              30 :     adfGeoTransform[1] = 1.0;
     234              30 :     adfGeoTransform[2] = 0.0;
     235              30 :     adfGeoTransform[3] = 0.0;
     236              30 :     adfGeoTransform[4] = 0.0;
     237              30 :     adfGeoTransform[5] = 1.0;
     238              30 : }
     239                 : 
     240                 : /************************************************************************/
     241                 : /*                            ~ELASDataset()                            */
     242                 : /************************************************************************/
     243                 : 
     244              30 : ELASDataset::~ELASDataset()
     245                 : 
     246                 : {
     247              30 :     FlushCache();
     248                 : 
     249              30 :     VSIFClose( fp );
     250              30 :     fp = NULL;
     251              30 : }
     252                 : 
     253                 : /************************************************************************/
     254                 : /*                             FlushCache()                             */
     255                 : /*                                                                      */
     256                 : /*      We also write out the header, if it is modified.                */
     257                 : /************************************************************************/
     258                 : 
     259              30 : void ELASDataset::FlushCache()
     260                 : 
     261                 : {
     262              30 :     GDALDataset::FlushCache();
     263                 : 
     264              30 :     if( bHeaderModified )
     265                 :     {
     266              16 :         VSIFSeek( fp, 0, SEEK_SET );
     267              16 :         VSIFWrite( &sHeader, 1024, 1, fp );
     268              16 :         bHeaderModified = FALSE;
     269                 :     }
     270              30 : }
     271                 : 
     272                 : 
     273                 : /************************************************************************/
     274                 : /*                                Open()                                */
     275                 : /************************************************************************/
     276                 : 
     277           11371 : GDALDataset *ELASDataset::Open( GDALOpenInfo * poOpenInfo )
     278                 : 
     279                 : {
     280                 : /* -------------------------------------------------------------------- */
     281                 : /*  First we check to see if the file has the expected header */
     282                 : /*  bytes.                */    
     283                 : /* -------------------------------------------------------------------- */
     284           11371 :     if( poOpenInfo->nHeaderBytes < 256 )
     285            9970 :         return NULL;
     286                 : 
     287            1401 :     if( CPL_MSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+0))) != 1024
     288                 :         || CPL_MSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+28))) != 4321 )
     289                 :     {
     290            1371 :         return NULL;
     291                 :     }
     292                 : 
     293                 : /* -------------------------------------------------------------------- */
     294                 : /*      Create a corresponding GDALDataset.                             */
     295                 : /* -------------------------------------------------------------------- */
     296                 :     ELASDataset   *poDS;
     297                 :     const char    *pszAccess;
     298                 : 
     299              30 :     if( poOpenInfo->eAccess == GA_Update )
     300              17 :         pszAccess = "r+b";
     301                 :     else
     302              13 :         pszAccess = "rb";
     303                 : 
     304              30 :     poDS = new ELASDataset();
     305                 : 
     306              30 :     poDS->fp = VSIFOpen( poOpenInfo->pszFilename, pszAccess );
     307              30 :     if( poDS->fp == NULL )
     308                 :     {
     309                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     310                 :                   "Attempt to open `%s' with acces `%s' failed.\n",
     311               0 :                   poOpenInfo->pszFilename, pszAccess );
     312               0 :         return NULL;
     313                 :     }
     314                 : 
     315              30 :     poDS->eAccess = poOpenInfo->eAccess;
     316                 : 
     317                 : /* -------------------------------------------------------------------- */
     318                 : /*      Read the header information.                                    */
     319                 : /* -------------------------------------------------------------------- */
     320              30 :     poDS->bHeaderModified = FALSE;
     321              30 :     if( VSIFRead( &(poDS->sHeader), 1024, 1, poDS->fp ) != 1 )
     322                 :     {
     323                 :         CPLError( CE_Failure, CPLE_FileIO,
     324                 :                   "Attempt to read 1024 byte header filed on file %s\n",
     325               0 :                   poOpenInfo->pszFilename );
     326               0 :         return NULL;
     327                 :     }
     328                 : 
     329                 : /* -------------------------------------------------------------------- */
     330                 : /*      Extract information of interest from the header.                */
     331                 : /* -------------------------------------------------------------------- */
     332                 :     int   nStart, nEnd, nELASDataType, nBytesPerSample;
     333                 :     
     334              30 :     poDS->nLineOffset = CPL_MSBWORD32( poDS->sHeader.NBPR );
     335                 : 
     336              30 :     nStart = CPL_MSBWORD32( poDS->sHeader.IL );
     337              30 :     nEnd = CPL_MSBWORD32( poDS->sHeader.LL );
     338              30 :     poDS->nRasterYSize = nEnd - nStart + 1;
     339                 : 
     340              30 :     nStart = CPL_MSBWORD32( poDS->sHeader.IE );
     341              30 :     nEnd = CPL_MSBWORD32( poDS->sHeader.LE );
     342              30 :     poDS->nRasterXSize = nEnd - nStart + 1;
     343                 : 
     344              30 :     poDS->nBands = CPL_MSBWORD32( poDS->sHeader.NC );
     345                 : 
     346              30 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
     347                 :         !GDALCheckBandCount(poDS->nBands, FALSE))
     348                 :     {
     349               0 :         delete poDS;
     350               0 :         return NULL;
     351                 :     }
     352                 : 
     353              30 :     nELASDataType = (poDS->sHeader.IH19[2] & 0x7e) >> 2;
     354              30 :     nBytesPerSample = poDS->sHeader.IH19[3];
     355                 :     
     356              30 :     if( nELASDataType == 0 && nBytesPerSample == 1 )
     357               0 :         poDS->eRasterDataType = GDT_Byte;
     358              50 :     else if( nELASDataType == 1 && nBytesPerSample == 1 )
     359              20 :         poDS->eRasterDataType = GDT_Byte;
     360              15 :     else if( nELASDataType == 16 && nBytesPerSample == 4 )
     361               5 :         poDS->eRasterDataType = GDT_Float32;
     362              10 :     else if( nELASDataType == 17 && nBytesPerSample == 8 )
     363               5 :         poDS->eRasterDataType = GDT_Float64;
     364                 :     else
     365                 :     {
     366               0 :         delete poDS;
     367                 :         CPLError( CE_Failure, CPLE_AppDefined,
     368                 :                   "Unrecognised image data type %d, with BytesPerSample=%d.\n",
     369               0 :                   nELASDataType, nBytesPerSample );
     370               0 :         return NULL;
     371                 :     }
     372                 :     
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*  Band offsets are always multiples of 256 within a multi-band  */
     375                 : /*  scanline of data.           */
     376                 : /* -------------------------------------------------------------------- */
     377                 :     poDS->nBandOffset =
     378              30 :         (poDS->nRasterXSize * GDALGetDataTypeSize(poDS->eRasterDataType)/8);
     379                 : 
     380              30 :     if( poDS->nBandOffset % 256 != 0 )
     381                 :     {
     382                 :         poDS->nBandOffset =
     383              30 :             poDS->nBandOffset - (poDS->nBandOffset % 256) + 256;
     384                 :     }
     385                 : 
     386                 : /* -------------------------------------------------------------------- */
     387                 : /*      Create band information objects.                                */
     388                 : /* -------------------------------------------------------------------- */
     389                 :     int   iBand;
     390                 : 
     391             208 :     for( iBand = 0; iBand < poDS->nBands; iBand++ )
     392                 :     {
     393              74 :         poDS->SetBand( iBand+1, new ELASRasterBand( poDS, iBand+1 ) );
     394                 :     }
     395                 : 
     396                 : /* -------------------------------------------------------------------- */
     397                 : /*  Extract the projection coordinates, if present.     */
     398                 : /* -------------------------------------------------------------------- */
     399              30 :     if( poDS->sHeader.XOffset != 0 )
     400                 :     {
     401              11 :         CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
     402              11 :         CPL_MSBPTR32(&(poDS->sHeader.YPixSize));
     403                 : 
     404                 :         poDS->adfGeoTransform[0] =
     405              11 :             (GInt32) CPL_MSBWORD32(poDS->sHeader.XOffset);
     406              11 :         poDS->adfGeoTransform[1] = poDS->sHeader.XPixSize;
     407              11 :         poDS->adfGeoTransform[2] = 0.0;
     408                 :         poDS->adfGeoTransform[3] =
     409              11 :             (GInt32) CPL_MSBWORD32(poDS->sHeader.YOffset);
     410              11 :         poDS->adfGeoTransform[4] = 0.0;
     411              11 :         poDS->adfGeoTransform[5] = -1.0 * ABS(poDS->sHeader.YPixSize);
     412                 : 
     413              11 :         CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
     414              11 :         CPL_MSBPTR32(&(poDS->sHeader.YPixSize));
     415                 : 
     416              11 :         poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
     417              11 :         poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
     418                 :     }
     419                 :     else
     420                 :     {
     421              19 :         poDS->adfGeoTransform[0] = 0.0;
     422              19 :         poDS->adfGeoTransform[1] = 1.0;
     423              19 :         poDS->adfGeoTransform[2] = 0.0;
     424              19 :         poDS->adfGeoTransform[3] = 0.0;
     425              19 :         poDS->adfGeoTransform[4] = 0.0;
     426              19 :         poDS->adfGeoTransform[5] = 1.0;
     427                 :     }
     428                 :     
     429                 : /* -------------------------------------------------------------------- */
     430                 : /*      Initialize any PAM information.                                 */
     431                 : /* -------------------------------------------------------------------- */
     432              30 :     poDS->SetDescription( poOpenInfo->pszFilename );
     433              30 :     poDS->TryLoadXML();
     434                 : 
     435              30 :     return( poDS );
     436                 : }
     437                 : 
     438                 : /************************************************************************/
     439                 : /*                               Create()                               */
     440                 : /*                                                                      */
     441                 : /*      Create a new GeoTIFF or TIFF file.                              */
     442                 : /************************************************************************/
     443                 : 
     444                 : GDALDataset *ELASDataset::Create( const char * pszFilename,
     445                 :                                   int nXSize, int nYSize, int nBands,
     446                 :                                   GDALDataType eType,
     447              42 :                                   char ** /* notdef: papszParmList */ )
     448                 : 
     449                 : {
     450                 :     int   nBandOffset;
     451                 :     
     452                 : /* -------------------------------------------------------------------- */
     453                 : /*      Verify input options.                                           */
     454                 : /* -------------------------------------------------------------------- */
     455              42 :     if (nBands <= 0)
     456                 :     {
     457                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     458               1 :                   "ELAS driver does not support %d bands.\n", nBands);
     459               1 :         return NULL;
     460                 :     }
     461                 : 
     462              41 :     if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_Float64 )
     463                 :     {
     464                 :         CPLError( CE_Failure, CPLE_AppDefined,
     465                 :                   "Attempt to create an ELAS dataset with an illegal\n"
     466                 :                   "data type (%d).\n",
     467              24 :                   eType );
     468                 : 
     469              24 :         return NULL;
     470                 :     }
     471                 : 
     472                 : /* -------------------------------------------------------------------- */
     473                 : /*      Try to create the file.                                         */
     474                 : /* -------------------------------------------------------------------- */
     475                 :     FILE  *fp;
     476                 : 
     477              17 :     fp = VSIFOpen( pszFilename, "w" );
     478                 : 
     479              17 :     if( fp == NULL )
     480                 :     {
     481                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     482                 :                   "Attempt to create file `%s' failed.\n",
     483               0 :                   pszFilename );
     484               0 :         return NULL;
     485                 :     }
     486                 :     
     487                 : /* -------------------------------------------------------------------- */
     488                 : /*  How long will each band of a scanline be?     */
     489                 : /* -------------------------------------------------------------------- */
     490              17 :     nBandOffset = nXSize * GDALGetDataTypeSize(eType)/8;
     491                 : 
     492              17 :     if( nBandOffset % 256 != 0 )
     493                 :     {
     494              17 :         nBandOffset = nBandOffset - (nBandOffset % 256) + 256;
     495                 :     }
     496                 : 
     497                 : /* -------------------------------------------------------------------- */
     498                 : /*      Setup header data block.                                        */
     499                 : /*                                                                      */
     500                 : /*      Note that CPL_MSBWORD32() will swap little endian words to      */
     501                 : /*      big endian on little endian platforms.                          */
     502                 : /* -------------------------------------------------------------------- */
     503                 :     ELASHeader  sHeader;
     504                 : 
     505              17 :     memset( &sHeader, 0, 1024 );
     506                 : 
     507              17 :     sHeader.NBIH = CPL_MSBWORD32(1024);
     508                 : 
     509              17 :     sHeader.NBPR = CPL_MSBWORD32(nBands * nBandOffset);
     510                 :     
     511              17 :     sHeader.IL = CPL_MSBWORD32(1);
     512              17 :     sHeader.LL = CPL_MSBWORD32(nYSize);
     513                 : 
     514              17 :     sHeader.IE = CPL_MSBWORD32(1);
     515              17 :     sHeader.LE = CPL_MSBWORD32(nXSize);
     516                 : 
     517              17 :     sHeader.NC = CPL_MSBWORD32(nBands);
     518                 : 
     519              17 :     sHeader.H4321 = CPL_MSBWORD32(4321);
     520                 : 
     521              17 :     sHeader.IH19[0] = 0x04;
     522              17 :     sHeader.IH19[1] = 0xd2;
     523              17 :     sHeader.IH19[3] = (GByte) (GDALGetDataTypeSize(eType) / 8);
     524                 : 
     525              17 :     if( eType == GDT_Byte )
     526              11 :         sHeader.IH19[2] = 1 << 2;
     527               6 :     else if( eType == GDT_Float32 )
     528               3 :         sHeader.IH19[2] = 16 << 2;
     529               3 :     else if( eType == GDT_Float64 )
     530               3 :         sHeader.IH19[2] = 17 << 2;
     531                 : 
     532                 : /* -------------------------------------------------------------------- */
     533                 : /*      Write the header data.                                          */
     534                 : /* -------------------------------------------------------------------- */
     535              17 :     VSIFWrite( &sHeader, 1024, 1, fp );
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      Now write out zero data for all the imagery.  This is           */
     539                 : /*      inefficient, but simplies the IReadBlock() / IWriteBlock() logic.*/
     540                 : /* -------------------------------------------------------------------- */
     541                 :     GByte *pabyLine;
     542                 : 
     543              17 :     pabyLine = (GByte *) CPLCalloc(nBandOffset,nBands);
     544            1007 :     for( int iLine = 0; iLine < nYSize; iLine++ )
     545                 :     {
     546             990 :         if( VSIFWrite( pabyLine, 1, nBandOffset, fp ) != (size_t) nBandOffset )
     547                 :         {
     548                 :             CPLError( CE_Failure, CPLE_FileIO,
     549                 :                       "Error writing ELAS image data ... likely insufficient"
     550               0 :                       " disk space.\n" );
     551               0 :             VSIFClose( fp );
     552               0 :             CPLFree( pabyLine );
     553               0 :             return NULL;
     554                 :         }
     555                 :     }
     556                 : 
     557              17 :     CPLFree( pabyLine );
     558                 :     
     559              17 :     VSIFClose( fp );
     560                 : 
     561                 : /* -------------------------------------------------------------------- */
     562                 : /*      Try to return a regular handle on the file.                     */
     563                 : /* -------------------------------------------------------------------- */
     564              17 :     return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
     565                 : }
     566                 : 
     567                 : /************************************************************************/
     568                 : /*                          GetGeoTransform()                           */
     569                 : /************************************************************************/
     570                 : 
     571               0 : CPLErr ELASDataset::GetGeoTransform( double * padfTransform )
     572                 : 
     573                 : {
     574               0 :     memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
     575                 : 
     576               0 :     return( CE_None );
     577                 : }
     578                 : 
     579                 : /************************************************************************/
     580                 : /*                          SetGeoTransform()                           */
     581                 : /************************************************************************/
     582                 : 
     583              16 : CPLErr ELASDataset::SetGeoTransform( double * padfTransform )
     584                 : 
     585                 : {
     586                 : /* -------------------------------------------------------------------- */
     587                 : /*      I don't think it supports rotation, but perhaps it is possible  */
     588                 : /*      for us to use the 2x2 transform matrix to accomplish some       */
     589                 : /*      sort of rotation.                                               */
     590                 : /* -------------------------------------------------------------------- */
     591              16 :     if( padfTransform[2] != 0.0 || padfTransform[4] != 0.0 )
     592                 :     {
     593                 :         CPLError( CE_Failure, CPLE_AppDefined,
     594                 :                   "Attempt to set rotated geotransform on ELAS file.\n"
     595               0 :                   "ELAS does not support rotation.\n" );
     596                 : 
     597               0 :         return CE_Failure;
     598                 :     }
     599                 :     
     600                 : /* -------------------------------------------------------------------- */
     601                 : /*      Remember the new transform, and update the header.              */
     602                 : /* -------------------------------------------------------------------- */
     603                 :     int   nXOff, nYOff;
     604                 :     
     605              16 :     memcpy( adfGeoTransform, padfTransform, sizeof(double)*6 );
     606                 : 
     607              16 :     bHeaderModified = TRUE;
     608                 : 
     609              16 :     nXOff = (int) (adfGeoTransform[0] + adfGeoTransform[1]*0.5);
     610              16 :     nYOff = (int) (adfGeoTransform[3] + adfGeoTransform[5]*0.5);
     611                 : 
     612              16 :     sHeader.XOffset = CPL_MSBWORD32(nXOff);
     613              16 :     sHeader.YOffset = CPL_MSBWORD32(nYOff);
     614                 : 
     615              16 :     sHeader.XPixSize = (float) ABS(adfGeoTransform[1]);
     616              16 :     sHeader.YPixSize = (float) ABS(adfGeoTransform[5]);
     617                 : 
     618              16 :     CPL_MSBPTR32(&(sHeader.XPixSize));
     619              16 :     CPL_MSBPTR32(&(sHeader.YPixSize));
     620                 : 
     621              16 :     strncpy( sHeader.YLabel, "NOR ", 4 );
     622              16 :     strncpy( sHeader.XLabel, "EAS ", 4 );
     623                 : 
     624              16 :     sHeader.Matrix[0] = 1.0;
     625              16 :     sHeader.Matrix[1] = 0.0;
     626              16 :     sHeader.Matrix[2] = 0.0;
     627              16 :     sHeader.Matrix[3] = -1.0;
     628                 :     
     629              16 :     CPL_MSBPTR32(&(sHeader.Matrix[0]));
     630              16 :     CPL_MSBPTR32(&(sHeader.Matrix[1]));
     631              16 :     CPL_MSBPTR32(&(sHeader.Matrix[2]));
     632              16 :     CPL_MSBPTR32(&(sHeader.Matrix[3]));
     633                 :     
     634              16 :     return( CE_None );
     635                 : }
     636                 : 
     637                 : 
     638                 : /************************************************************************/
     639                 : /*                          GDALRegister_ELAS()                        */
     640                 : /************************************************************************/
     641                 : 
     642             409 : void GDALRegister_ELAS()
     643                 : 
     644                 : {
     645                 :     GDALDriver  *poDriver;
     646                 : 
     647             409 :     if( GDALGetDriverByName( "ELAS" ) == NULL )
     648                 :     {
     649             392 :         poDriver = new GDALDriver();
     650                 :         
     651             392 :         poDriver->SetDescription( "ELAS" );
     652                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     653             392 :                                    "ELAS" );
     654                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     655             392 :                                    "Byte Float32 Float64" );
     656                 :         
     657             392 :         poDriver->pfnOpen = ELASDataset::Open;
     658             392 :         poDriver->pfnCreate = ELASDataset::Create;
     659                 : 
     660             392 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     661                 :     }
     662             409 : }

Generated by: LTP GCOV extension version 1.5