LCOV - code coverage report
Current view: directory - frmts/raw - dipxdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 100 68 68.0 %
Date: 2010-01-09 Functions: 7 5 71.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: dipxdataset.cpp 16396 2009-02-22 20:49:52Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL
       5                 :  * Purpose:  Implementation for ELAS DIPEx format variant.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2006, 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_spatialref.h"
      33                 : 
      34                 : CPL_CVSID("$Id: dipxdataset.cpp 16396 2009-02-22 20:49:52Z rouault $");
      35                 : 
      36                 : CPL_C_START
      37                 : void  GDALRegister_DIPEx(void);
      38                 : CPL_C_END
      39                 : 
      40                 : typedef struct {
      41                 :     GInt32  NBIH; /* bytes in header, normaly 1024 */
      42                 :     GInt32      NBPR; /* bytes per data record (all bands of scanline) */
      43                 :     GInt32  IL; /* initial line - normally 1 */
      44                 :     GInt32  LL; /* last line */
      45                 :     GInt32  IE; /* initial element (pixel), normally 1 */
      46                 :     GInt32  LE; /* last element (pixel) */
      47                 :     GInt32  NC; /* number of channels (bands) */
      48                 :     GInt32  H4322;  /* header record identifier - always 4322. */
      49                 :     char        unused1[40]; 
      50                 :     GByte IH19[4];/* data type, and size flags */
      51                 :     GInt32  IH20; /* number of secondary headers */
      52                 :     GInt32  SRID; 
      53                 :     char        unused2[12];
      54                 :     double      YOffset;
      55                 :     double      XOffset; 
      56                 :     double      YPixSize;
      57                 :     double      XPixSize;
      58                 :     double      Matrix[4];
      59                 :     char        unused3[344];
      60                 :     GUInt16 ColorTable[256];  /* RGB packed with 4 bits each */
      61                 :     char  unused4[32];
      62                 : } DIPExHeader;
      63                 : 
      64                 : /************************************************************************/
      65                 : /* ==================================================================== */
      66                 : /*        DIPExDataset        */
      67                 : /* ==================================================================== */
      68                 : /************************************************************************/
      69                 : 
      70                 : class DIPExRasterBand;
      71                 : 
      72                 : class DIPExDataset : public GDALPamDataset
      73                 : {
      74                 :     friend class DIPExRasterBand;
      75                 : 
      76                 :     FILE  *fp;
      77                 :     CPLString    osSRS;
      78                 : 
      79                 :     DIPExHeader  sHeader;
      80                 : 
      81                 :     GDALDataType eRasterDataType;
      82                 : 
      83                 :     double  adfGeoTransform[6];
      84                 : 
      85                 :   public:
      86                 :                  DIPExDataset();
      87                 :                  ~DIPExDataset();
      88                 : 
      89                 :     virtual CPLErr GetGeoTransform( double * );
      90                 : 
      91                 :     virtual const char *GetProjectionRef( void );
      92                 :     static GDALDataset *Open( GDALOpenInfo * );
      93                 : };
      94                 : 
      95                 : /************************************************************************/
      96                 : /* ==================================================================== */
      97                 : /*                             DIPExDataset                              */
      98                 : /* ==================================================================== */
      99                 : /************************************************************************/
     100                 : 
     101                 : 
     102                 : /************************************************************************/
     103                 : /*                            DIPExDataset()                             */
     104                 : /************************************************************************/
     105                 : 
     106               1 : DIPExDataset::DIPExDataset()
     107                 : 
     108                 : {
     109               1 :     fp = NULL;
     110                 : 
     111               1 :     adfGeoTransform[0] = 0.0;
     112               1 :     adfGeoTransform[1] = 1.0;
     113               1 :     adfGeoTransform[2] = 0.0;
     114               1 :     adfGeoTransform[3] = 0.0;
     115               1 :     adfGeoTransform[4] = 0.0;
     116               1 :     adfGeoTransform[5] = 1.0;
     117               1 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                            ~DIPExDataset()                            */
     121                 : /************************************************************************/
     122                 : 
     123               2 : DIPExDataset::~DIPExDataset()
     124                 : 
     125                 : {
     126               1 :     if (fp)
     127               1 :         VSIFCloseL( fp );
     128               1 :     fp = NULL;
     129               2 : }
     130                 : 
     131                 : /************************************************************************/
     132                 : /*                                Open()                                */
     133                 : /************************************************************************/
     134                 : 
     135            8494 : GDALDataset *DIPExDataset::Open( GDALOpenInfo * poOpenInfo )
     136                 : 
     137                 : {
     138                 : /* -------------------------------------------------------------------- */
     139                 : /*  First we check to see if the file has the expected header */
     140                 : /*  bytes.                */    
     141                 : /* -------------------------------------------------------------------- */
     142            8494 :     if( poOpenInfo->nHeaderBytes < 256 )
     143            8316 :         return NULL;
     144                 : 
     145             178 :     if( CPL_LSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+0))) != 1024 )
     146             177 :         return NULL;
     147                 : 
     148               1 :     if( CPL_LSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+28))) != 4322 )
     149               0 :         return NULL;
     150                 : 
     151                 : /* -------------------------------------------------------------------- */
     152                 : /*      Create a corresponding GDALDataset.                             */
     153                 : /* -------------------------------------------------------------------- */
     154                 :     DIPExDataset  *poDS;
     155                 :     const char    *pszAccess;
     156                 : 
     157               1 :     if( poOpenInfo->eAccess == GA_Update )
     158               0 :         pszAccess = "r+b";
     159                 :     else
     160               1 :         pszAccess = "rb";
     161                 : 
     162               1 :     poDS = new DIPExDataset();
     163                 : 
     164               1 :     poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, pszAccess );
     165               1 :     if( poDS->fp == NULL )
     166                 :     {
     167                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     168                 :                   "Attempt to open `%s' with acces `%s' failed.\n",
     169               0 :                   poOpenInfo->pszFilename, pszAccess );
     170               0 :         delete poDS;
     171               0 :         return NULL;
     172                 :     }
     173                 : 
     174               1 :     poDS->eAccess = poOpenInfo->eAccess;
     175                 : 
     176                 : /* -------------------------------------------------------------------- */
     177                 : /*      Read the header information.                                    */
     178                 : /* -------------------------------------------------------------------- */
     179               1 :     if( VSIFReadL( &(poDS->sHeader), 1024, 1, poDS->fp ) != 1 )
     180                 :     {
     181                 :         CPLError( CE_Failure, CPLE_FileIO,
     182                 :                   "Attempt to read 1024 byte header filed on file %s\n",
     183               0 :                   poOpenInfo->pszFilename );
     184               0 :         delete poDS;
     185               0 :         return NULL;
     186                 :     }
     187                 : 
     188                 : /* -------------------------------------------------------------------- */
     189                 : /*      Extract information of interest from the header.                */
     190                 : /* -------------------------------------------------------------------- */
     191                 :     int   nStart, nEnd, nDIPExDataType, nBytesPerSample;
     192                 :     int         nLineOffset;
     193                 :     
     194               1 :     nLineOffset = CPL_LSBWORD32( poDS->sHeader.NBPR );
     195                 : 
     196               1 :     nStart = CPL_LSBWORD32( poDS->sHeader.IL );
     197               1 :     nEnd = CPL_LSBWORD32( poDS->sHeader.LL );
     198               1 :     poDS->nRasterYSize = nEnd - nStart + 1;
     199                 : 
     200               1 :     nStart = CPL_LSBWORD32( poDS->sHeader.IE );
     201               1 :     nEnd = CPL_LSBWORD32( poDS->sHeader.LE );
     202               1 :     poDS->nRasterXSize = nEnd - nStart + 1;
     203                 : 
     204               1 :     poDS->nBands = CPL_LSBWORD32( poDS->sHeader.NC );
     205                 : 
     206               1 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
     207                 :         !GDALCheckBandCount(poDS->nBands, FALSE))
     208                 :     {
     209               0 :         delete poDS;
     210               0 :         return NULL;
     211                 :     }
     212                 : 
     213               1 :     nDIPExDataType = (poDS->sHeader.IH19[1] & 0x7e) >> 2;
     214               1 :     nBytesPerSample = poDS->sHeader.IH19[0];
     215                 :     
     216               2 :     if( nDIPExDataType == 0 && nBytesPerSample == 1 )
     217               1 :         poDS->eRasterDataType = GDT_Byte;
     218               0 :     else if( nDIPExDataType == 1 && nBytesPerSample == 1 )
     219               0 :         poDS->eRasterDataType = GDT_Byte;
     220               0 :     else if( nDIPExDataType == 16 && nBytesPerSample == 4 )
     221               0 :         poDS->eRasterDataType = GDT_Float32;
     222               0 :     else if( nDIPExDataType == 17 && nBytesPerSample == 8 )
     223               0 :         poDS->eRasterDataType = GDT_Float64;
     224                 :     else
     225                 :     {
     226               0 :         delete poDS;
     227                 :         CPLError( CE_Failure, CPLE_AppDefined,
     228                 :                   "Unrecognised image data type %d, with BytesPerSample=%d.\n",
     229               0 :                   nDIPExDataType, nBytesPerSample );
     230               0 :         return NULL;
     231                 :     }
     232                 :     
     233                 : /* -------------------------------------------------------------------- */
     234                 : /*      Create band information objects.                                */
     235                 : /* -------------------------------------------------------------------- */
     236                 :     int   iBand;
     237                 : 
     238               4 :     for( iBand = 0; iBand < poDS->nBands; iBand++ )
     239                 :     {
     240                 :         poDS->SetBand( iBand+1, 
     241                 :                        new RawRasterBand( poDS, iBand+1, poDS->fp, 
     242                 :                                           1024 + iBand * nLineOffset, 
     243                 :                                           nBytesPerSample, 
     244                 :                                           nLineOffset * poDS->nBands,
     245                 :                                           poDS->eRasterDataType, 
     246               1 :                                           CPL_IS_LSB, TRUE ) );
     247                 :     }
     248                 : 
     249                 : /* -------------------------------------------------------------------- */
     250                 : /*  Extract the projection coordinates, if present.     */
     251                 : /* -------------------------------------------------------------------- */
     252                 :     CPL_LSBPTR64(&(poDS->sHeader.XPixSize));
     253                 :     CPL_LSBPTR64(&(poDS->sHeader.YPixSize));
     254                 :     CPL_LSBPTR64(&(poDS->sHeader.XOffset));
     255                 :     CPL_LSBPTR64(&(poDS->sHeader.YOffset));
     256                 : 
     257               1 :     if( poDS->sHeader.XOffset != 0 )
     258                 :     {
     259               0 :         poDS->adfGeoTransform[0] = poDS->sHeader.XOffset;
     260               0 :         poDS->adfGeoTransform[1] = poDS->sHeader.XPixSize;
     261               0 :         poDS->adfGeoTransform[2] = 0.0;
     262               0 :         poDS->adfGeoTransform[3] = poDS->sHeader.YOffset;
     263               0 :         poDS->adfGeoTransform[4] = 0.0;
     264               0 :         poDS->adfGeoTransform[5] = -1.0 * ABS(poDS->sHeader.YPixSize);
     265                 : 
     266               0 :         poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
     267               0 :         poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
     268                 :     }
     269                 :     else
     270                 :     {
     271               1 :         poDS->adfGeoTransform[0] = 0.0;
     272               1 :         poDS->adfGeoTransform[1] = 1.0;
     273               1 :         poDS->adfGeoTransform[2] = 0.0;
     274               1 :         poDS->adfGeoTransform[3] = 0.0;
     275               1 :         poDS->adfGeoTransform[4] = 0.0;
     276               1 :         poDS->adfGeoTransform[5] = 1.0;
     277                 :     }
     278                 :     
     279                 : /* -------------------------------------------------------------------- */
     280                 : /*      Look for SRID.                                                  */
     281                 : /* -------------------------------------------------------------------- */
     282                 :     CPL_LSBPTR32( &(poDS->sHeader.SRID) );
     283                 :     
     284               1 :     if( poDS->sHeader.SRID > 0 && poDS->sHeader.SRID < 33000 )
     285                 :     {
     286               1 :         OGRSpatialReference oSR;
     287                 : 
     288               1 :         if( oSR.importFromEPSG( poDS->sHeader.SRID ) == OGRERR_NONE )
     289                 :         {
     290               1 :             char *pszWKT = NULL;
     291               1 :             oSR.exportToWkt( &pszWKT );
     292               1 :             poDS->osSRS = pszWKT;
     293               1 :             CPLFree( pszWKT );
     294               1 :         }
     295                 :     }
     296                 : 
     297                 : /* -------------------------------------------------------------------- */
     298                 : /*      Initialize any PAM information.                                 */
     299                 : /* -------------------------------------------------------------------- */
     300               1 :     poDS->SetDescription( poOpenInfo->pszFilename );
     301               1 :     poDS->TryLoadXML();
     302                 : 
     303               1 :     return( poDS );
     304                 : }
     305                 : 
     306                 : /************************************************************************/
     307                 : /*                          GetProjectionRef()                          */
     308                 : /************************************************************************/
     309                 : 
     310               0 : const char *DIPExDataset::GetProjectionRef()
     311                 : 
     312                 : {
     313               0 :     return osSRS.c_str();
     314                 : }
     315                 : 
     316                 : /************************************************************************/
     317                 : /*                          GetGeoTransform()                           */
     318                 : /************************************************************************/
     319                 : 
     320               0 : CPLErr DIPExDataset::GetGeoTransform( double * padfTransform )
     321                 : 
     322                 : {
     323               0 :     memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
     324                 : 
     325               0 :     return( CE_None );
     326                 : }
     327                 : 
     328                 : /************************************************************************/
     329                 : /*                          GDALRegister_DIPEx()                        */
     330                 : /************************************************************************/
     331                 : 
     332             338 : void GDALRegister_DIPEx()
     333                 : 
     334                 : {
     335                 :     GDALDriver  *poDriver;
     336                 : 
     337             338 :     if( GDALGetDriverByName( "DIPEx" ) == NULL )
     338                 :     {
     339             336 :         poDriver = new GDALDriver();
     340                 :         
     341             336 :         poDriver->SetDescription( "DIPEx" );
     342                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     343             336 :                                    "DIPEx" );
     344                 :         
     345             336 :         poDriver->pfnOpen = DIPExDataset::Open;
     346                 : 
     347             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     348                 :     }
     349             338 : }

Generated by: LCOV version 1.7