LTP GCOV extension - code coverage report
Current view: directory - frmts/gff - gff_dataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 110
Code covered: 81.8 % Executed lines: 90

       1                 : /******************************************************************************
       2                 :  * $Id: gff_dataset.cpp 18244 2009-12-10 17:08:59Z warmerdam $
       3                 :  *
       4                 :  * Project:  Ground-based SAR Applitcations Testbed File Format driver
       5                 :  * Purpose:  Support in GDAL for Sandia National Laboratory's GFF format
       6                 :  *       blame Tisham for putting me up to this
       7                 :  * Author:   Philippe Vachon <philippe@cowpig.ca>
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2007, Philippe Vachon
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "gdal_priv.h"
      32                 : #include "gdal_pam.h"
      33                 : #include "cpl_port.h"
      34                 : #include "cpl_conv.h"
      35                 : #include "cpl_vsi.h"
      36                 : #include "cpl_string.h"
      37                 : 
      38                 : CPL_CVSID("$Id: gff_dataset.cpp 18244 2009-12-10 17:08:59Z warmerdam $");
      39                 : 
      40                 : /*******************************************************************
      41                 :  * Declaration of the GFFDataset class                             *
      42                 :  *******************************************************************/
      43                 : 
      44                 : class GFFRasterBand;
      45                 : 
      46                 : class GFFDataset : public GDALPamDataset 
      47                 : {
      48                 :     friend class GFFRasterBand;
      49                 :     FILE *fp;
      50                 :     GDALDataType eDataType;
      51                 :     unsigned int nEndianess;
      52                 :     /* Some relevant headers */
      53                 :     unsigned short nVersionMajor;
      54                 :     unsigned short nVersionMinor;
      55                 :     unsigned int nLength;
      56                 :     char *pszCreator;
      57                 :     /* I am taking this at face value (are they freakin' insane?) */
      58                 :     float fBPP;
      59                 :     unsigned int nBPP;
      60                 : 
      61                 :     /* Good information to know */
      62                 :     unsigned int nFrameCnt;
      63                 :     unsigned int nImageType;
      64                 :     unsigned int nRowMajor;
      65                 :     unsigned int nRgCnt;
      66                 :     unsigned int nAzCnt;
      67                 :     long nScaleExponent;
      68                 :     long nScaleMantissa;
      69                 :     long nOffsetExponent;
      70                 :     long nOffsetMantissa;
      71                 : public:
      72                 :     GFFDataset();
      73                 :     ~GFFDataset();
      74                 : 
      75                 :     static GDALDataset *Open( GDALOpenInfo * );
      76                 :     static int Identify( GDALOpenInfo * poOpenInfo );
      77                 : };
      78                 : 
      79               1 : GFFDataset::GFFDataset()
      80                 : {
      81               1 :     fp = NULL;
      82               1 : }
      83                 : 
      84               1 : GFFDataset::~GFFDataset()
      85                 : {
      86               1 :     if (fp != NULL)
      87               1 :         VSIFCloseL(fp);
      88               1 : }
      89                 : 
      90                 : /*********************************************************************
      91                 :  * Declaration and implementation of the GFFRasterBand Class         *
      92                 :  *********************************************************************/
      93                 : 
      94               1 : class GFFRasterBand : public GDALPamRasterBand {
      95                 :     long nRasterBandMemory;
      96                 :     int nSampleSize;
      97                 : public:
      98                 :     GFFRasterBand( GFFDataset *, int, GDALDataType );
      99                 :     virtual CPLErr IReadBlock( int, int, void * );
     100                 : };
     101                 : 
     102                 : /************************************************************************/
     103                 : /*                           GFFRasterBand()                            */
     104                 : /************************************************************************/
     105                 : GFFRasterBand::GFFRasterBand( GFFDataset *poDS, int nBand,
     106               1 :   GDALDataType eDataType ) 
     107                 : {
     108                 :     unsigned long nBytes;
     109               1 :     this->poDS = poDS;
     110               1 :     this->nBand = nBand;
     111                 : 
     112               1 :     this->eDataType = eDataType;
     113                 : 
     114               1 :     nBlockXSize = poDS->GetRasterXSize();
     115               1 :     nBlockYSize = 1;
     116                 : 
     117                 :     /* Determine the number of bytes per sample */
     118               1 :     switch (eDataType) {
     119                 :       case GDT_CInt16:
     120               0 :         nBytes = 4;
     121               0 :         break;
     122                 :       case GDT_CInt32:
     123                 :       case GDT_CFloat32:
     124               1 :         nBytes = 8;
     125               1 :         break;
     126                 :       default:
     127               0 :         nBytes = 1;
     128                 :     }
     129                 : 
     130               1 :     nRasterBandMemory = nBytes * poDS->GetRasterXSize();
     131               1 :     nSampleSize = nBytes;
     132                 : 
     133               1 : }
     134                 : 
     135                 : /************************************************************************/
     136                 : /*                             IReadBlock()                             */
     137                 : /************************************************************************/
     138                 : 
     139                 : CPLErr GFFRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     140               2 :         void *pImage ) 
     141                 : {
     142               2 :     GFFDataset *poGDS = (GFFDataset *)poDS;
     143               2 :     long nOffset = poGDS->nLength;
     144                 : 
     145               2 :     VSIFSeekL(poGDS->fp, nOffset + (poGDS->GetRasterXSize() * nBlockYOff * (nSampleSize)),SEEK_SET);
     146                 : 
     147                 :     /* Ingest entire range line */
     148               2 :     if (VSIFReadL(pImage,nRasterBandMemory,1,poGDS->fp) != 1)
     149               1 :         return CE_Failure;
     150                 : 
     151                 : #if defined(CPL_MSB)
     152                 :     if( GDALDataTypeIsComplex( eDataType ) )
     153                 :     {
     154                 :         int nWordSize;
     155                 : 
     156                 :         nWordSize = GDALGetDataTypeSize(eDataType)/16;
     157                 :         GDALSwapWords( pImage, nWordSize, nBlockXSize, 2*nWordSize );
     158                 :         GDALSwapWords( ((GByte *) pImage)+nWordSize, 
     159                 :                         nWordSize, nBlockXSize, 2*nWordSize );
     160                 :     }
     161                 : #endif
     162                 : 
     163               1 :     return CE_None;
     164                 :   
     165                 : }
     166                 : 
     167                 : /********************************************************************
     168                 :  * ================================================================ *
     169                 :  * Implementation of the GFFDataset Class                           *
     170                 :  * ================================================================ *
     171                 :  ********************************************************************/
     172                 : 
     173                 : /************************************************************************/
     174                 : /*                              Identify()                              */
     175                 : /************************************************************************/
     176           11372 : int GFFDataset::Identify( GDALOpenInfo *poOpenInfo )
     177                 : {
     178           11372 :     if(poOpenInfo->nHeaderBytes < 7) 
     179            9835 :         return 0;
     180                 : 
     181            1537 :     if (EQUALN((char *)poOpenInfo->pabyHeader,"GSATIMG",7)) 
     182               1 :         return 1;
     183                 : 
     184            1536 :     return 0;
     185                 : }
     186                 : 
     187                 : /************************************************************************/
     188                 : /*                                Open()                                */
     189                 : /************************************************************************/
     190                 : 
     191           11372 : GDALDataset *GFFDataset::Open( GDALOpenInfo *poOpenInfo ) 
     192                 : {
     193           11372 :     unsigned short nCreatorLength = 0;
     194                 : 
     195                 :     /* Check that the dataset is indeed a GSAT File Format (GFF) file */
     196           11372 :     if (!GFFDataset::Identify(poOpenInfo)) 
     197           11371 :         return NULL;
     198                 : 
     199                 : /* -------------------------------------------------------------------- */
     200                 : /*      Confirm the requested access is supported.                      */
     201                 : /* -------------------------------------------------------------------- */
     202               1 :     if( poOpenInfo->eAccess == GA_Update )
     203                 :     {
     204                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     205                 :                   "The GFF driver does not support update access to existing"
     206               0 :                   " datasets.\n" );
     207               0 :         return NULL;
     208                 :     }
     209                 :     
     210                 :     GFFDataset *poDS;
     211               1 :     poDS = new GFFDataset();
     212                 : 
     213               1 :     poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r" );
     214               1 :     if( poDS->fp == NULL )
     215                 :     {
     216               0 :         delete poDS;
     217               0 :         return NULL;
     218                 :     }
     219                 : 
     220                 :     /* Check the endianess of the file */
     221               1 :     VSIFSeekL(poDS->fp,54,SEEK_SET);
     222               1 :     VSIFReadL(&(poDS->nEndianess),2,1,poDS->fp);
     223                 : 
     224                 : #if defined(CPL_LSB)
     225               1 :     int bSwap = 0;
     226                 : #else
     227                 :     int bSwap = 1;
     228                 : #endif
     229                 : 
     230               1 :     VSIFSeekL(poDS->fp,8,SEEK_SET);
     231               1 :     VSIFReadL(&poDS->nVersionMinor,2,1,poDS->fp);
     232               1 :     if (bSwap) CPL_SWAP16PTR(&poDS->nVersionMinor);
     233               1 :     VSIFReadL(&poDS->nVersionMajor,2,1,poDS->fp);
     234               1 :     if (bSwap) CPL_SWAP16PTR(&poDS->nVersionMajor);
     235               1 :     VSIFReadL(&poDS->nLength,4,1,poDS->fp);
     236               1 :     if (bSwap) CPL_SWAP32PTR(&poDS->nLength);
     237               1 :     VSIFReadL(&nCreatorLength,2,1,poDS->fp);
     238               1 :     if (bSwap) CPL_SWAP16PTR(&nCreatorLength);
     239                 :     /* Hack for now... I should properly load the date metadata, for
     240                 :      * example
     241                 :      */
     242               1 :     VSIFSeekL(poDS->fp,56,SEEK_SET);
     243                 : 
     244                 :     /* By looking at the Matlab code, one should write something like the following test */
     245                 :     /* but the results don't seem to be the ones really expected */
     246                 :     /*if ((poDS->nVersionMajor == 1 && poDS->nVersionMinor > 7) || (poDS->nVersionMajor > 1))
     247                 :     {
     248                 :         float fBPP;
     249                 :         VSIFRead(&fBPP,4,1,poDS->fp);
     250                 :         poDS->nBPP = fBPP;
     251                 :     }
     252                 :     else*/
     253                 :     {
     254               1 :         VSIFReadL(&poDS->nBPP,4,1,poDS->fp);
     255               1 :         if (bSwap) CPL_SWAP32PTR(&poDS->nBPP);
     256                 :     }
     257               1 :     VSIFReadL(&poDS->nFrameCnt,4,1,poDS->fp);
     258               1 :     if (bSwap) CPL_SWAP32PTR(&poDS->nFrameCnt);
     259               1 :     VSIFReadL(&poDS->nImageType,4,1,poDS->fp);
     260               1 :     if (bSwap) CPL_SWAP32PTR(&poDS->nImageType);
     261               1 :     VSIFReadL(&poDS->nRowMajor,4,1,poDS->fp);
     262               1 :     if (bSwap) CPL_SWAP32PTR(&poDS->nRowMajor);
     263               1 :     VSIFReadL(&poDS->nRgCnt,4,1,poDS->fp);
     264               1 :     if (bSwap) CPL_SWAP32PTR(&poDS->nRgCnt);
     265               1 :     VSIFReadL(&poDS->nAzCnt,4,1,poDS->fp);
     266               1 :     if (bSwap) CPL_SWAP32PTR(&poDS->nAzCnt);
     267                 : 
     268                 :     /* We now have enough information to determine the number format */
     269               1 :     switch (poDS->nImageType) {
     270                 :       case 0:
     271               0 :         poDS->eDataType = GDT_Byte;
     272               0 :         break;
     273                 : 
     274                 :       case 1:
     275               1 :         if (poDS->nBPP == 4)
     276               0 :             poDS->eDataType = GDT_CInt16;
     277                 :         else
     278               1 :             poDS->eDataType = GDT_CInt32;
     279               1 :         break;
     280                 : 
     281                 :       case 2:
     282               0 :         poDS->eDataType = GDT_CFloat32;
     283               0 :         break;
     284                 : 
     285                 :       default:
     286               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Unknown image type found!");
     287               0 :         delete poDS;
     288               0 :         return NULL;
     289                 :     }
     290                 : 
     291                 :     /* Set raster width/height 
     292                 :      * Note that the images that are complex are listed as having twice the
     293                 :      * number of X-direction values than there are actual pixels. This is 
     294                 :      * because whoever came up with the format was crazy (actually, my
     295                 :      * hunch is that they designed it very much for Matlab)
     296                 :      * */
     297               1 :     if (poDS->nRowMajor) {
     298               0 :         poDS->nRasterXSize = poDS->nRgCnt/(poDS->nImageType == 0 ? 1 : 2);
     299               0 :         poDS->nRasterYSize = poDS->nAzCnt;
     300                 :     }
     301                 :     else {
     302               1 :         poDS->nRasterXSize = poDS->nAzCnt/(poDS->nImageType == 0 ? 1 : 2);
     303               1 :         poDS->nRasterYSize = poDS->nRgCnt;
     304                 :     }
     305                 : 
     306               1 :     if (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0)
     307                 :     {
     308                 :         CPLError(CE_Failure, CPLE_AppDefined, "Invalid raster dimensions : %d x %d",
     309               0 :                  poDS->nRasterXSize, poDS->nRasterYSize);
     310               0 :         delete poDS;
     311               0 :         return NULL;
     312                 :     }
     313                 : 
     314               1 :     poDS->SetBand(1, new GFFRasterBand(poDS, 1, poDS->eDataType));
     315                 : 
     316                 : /* -------------------------------------------------------------------- */
     317                 : /*      Initialize any PAM information.                                 */
     318                 : /* -------------------------------------------------------------------- */
     319               1 :     poDS->SetDescription( poOpenInfo->pszFilename );
     320               1 :     poDS->TryLoadXML();
     321                 : 
     322                 : /* -------------------------------------------------------------------- */
     323                 : /*      Support overviews.                                              */
     324                 : /* -------------------------------------------------------------------- */
     325               1 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     326                 : 
     327               1 :     return poDS;
     328                 : }
     329                 : 
     330                 : /************************************************************************/
     331                 : /*                          GDALRegister_GFF()                          */
     332                 : /************************************************************************/
     333                 : 
     334             409 : void GDALRegister_GFF(void) 
     335                 : {
     336                 :     GDALDriver *poDriver;
     337             409 :     if ( GDALGetDriverByName("GFF") == NULL ) {
     338             392 :         poDriver = new GDALDriver();
     339             392 :         poDriver->SetDescription("GFF");
     340                 :         poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, 
     341             392 :                                   "Ground-based SAR Applications Testbed File Format (.gff)");
     342             392 :         poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "frmt_various.html#GFF");
     343             392 :         poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "gff");
     344             392 :         poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     345             392 :         poDriver->pfnOpen = GFFDataset::Open;
     346             392 :         GetGDALDriverManager()->RegisterDriver(poDriver);
     347                 :     }
     348             409 : }

Generated by: LTP GCOV extension version 1.5