LCOV - code coverage report
Current view: directory - frmts/northwood - grcdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 156 100 64.1 %
Date: 2012-04-28 Functions: 24 8 33.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: grcdataset.cpp 23059 2011-09-05 17:30:20Z rouault $
       3                 :  *
       4                 :  * Project:  GRC Reader
       5                 :  * Purpose:  GDAL driver for Northwood Classified Format
       6                 :  * Author:   Perry Casson
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Waypoint Information Technology
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_pam.h"
      31                 : #include "northwood.h"
      32                 : 
      33                 : #ifdef OGR_ENABLED
      34                 : #ifdef MSVC
      35                 : #include "..\..\ogr\ogrsf_frmts\mitab\mitab.h"
      36                 : #else
      37                 : #include "../../ogr/ogrsf_frmts/mitab/mitab.h"
      38                 : #endif
      39                 : #endif
      40                 : 
      41                 : 
      42                 : CPL_C_START void GDALRegister_NWT_GRC( void );
      43                 : CPL_C_END
      44                 : /************************************************************************/
      45                 : /* ==================================================================== */
      46                 : /*                             NWT_GRCDataset                           */
      47                 : /* ==================================================================== */
      48                 : /************************************************************************/
      49                 : class NWT_GRCRasterBand;
      50                 : 
      51                 : class NWT_GRCDataset : public GDALPamDataset
      52                 : {
      53                 :   friend class NWT_GRCRasterBand;
      54                 : 
      55                 :   private:
      56                 :     VSILFILE * fp;
      57                 :     GByte abyHeader[1024];
      58                 :     NWT_GRID *pGrd;
      59                 :     char **papszCategories;
      60                 :     char *pszProjection;
      61                 : 
      62                 :   protected:
      63                 :     GDALColorTable * poColorTable;
      64                 : 
      65                 :   public:
      66                 :     NWT_GRCDataset();
      67                 :     ~NWT_GRCDataset();
      68                 : 
      69                 :     static GDALDataset *Open( GDALOpenInfo * );
      70                 :     static int Identify( GDALOpenInfo * poOpenInfo );
      71                 : 
      72                 :     CPLErr GetGeoTransform( double *padfTransform );
      73                 :     const char *GetProjectionRef();
      74                 : };
      75                 : 
      76                 : /************************************************************************/
      77                 : /* ==================================================================== */
      78                 : /*                            NWT_GRCRasterBand                         */
      79                 : /* ==================================================================== */
      80                 : /************************************************************************/
      81                 : 
      82                 : class NWT_GRCRasterBand : public GDALPamRasterBand
      83                 : {
      84                 :   friend class NWT_GRCDataset;
      85                 :     int bHaveOffsetScale;
      86                 :     double dfOffset;
      87                 :     double dfScale;
      88                 : 
      89                 :   public:
      90                 : 
      91                 :     NWT_GRCRasterBand( NWT_GRCDataset *, int );
      92                 :     virtual ~NWT_GRCRasterBand();
      93                 : 
      94                 :     virtual CPLErr IReadBlock( int, int, void * );
      95                 :     virtual double GetNoDataValue( int *pbSuccess );
      96                 : 
      97                 :     virtual double GetOffset( int *pbSuccess = NULL );
      98                 :     virtual CPLErr SetOffset( double dfNewValue );
      99                 :     virtual double GetScale( int *pbSuccess = NULL );
     100                 :     virtual CPLErr SetScale( double dfNewValue );
     101                 : 
     102                 :     virtual GDALColorInterp GetColorInterpretation();
     103                 :     virtual char **GetCategoryNames();
     104                 :     virtual GDALColorTable *GetColorTable();
     105                 : };
     106                 : 
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                           NWT_GRCRasterBand()                        */
     110                 : /************************************************************************/
     111                 : 
     112               2 : NWT_GRCRasterBand::NWT_GRCRasterBand( NWT_GRCDataset * poDS, int nBand )
     113                 : {
     114               2 :     this->poDS = poDS;
     115               2 :     this->nBand = nBand;
     116               2 :     NWT_GRCDataset *poGDS =( NWT_GRCDataset * ) poDS;
     117                 : 
     118               2 :     bHaveOffsetScale = FALSE;
     119               2 :     dfOffset = 0;
     120               2 :     dfScale = 1.0;
     121               2 :     if( poGDS->pGrd->nBitsPerPixel == 8 )
     122               2 :         eDataType = GDT_Byte;
     123               0 :     else if( poGDS->pGrd->nBitsPerPixel == 16 )
     124               0 :         eDataType = GDT_UInt16;
     125               0 :     else if( poGDS->pGrd->nBitsPerPixel == 32 )
     126               0 :         eDataType = GDT_UInt32;        // this would be funny
     127                 : 
     128               2 :     nBlockXSize = poDS->GetRasterXSize();
     129               2 :     nBlockYSize = 1;
     130                 : 
     131                 :     // load the color table and might as well to the ClassNames
     132               2 :     poGDS->poColorTable = new GDALColorTable();
     133                 : 
     134                 :     GDALColorEntry oEntry;
     135                 :     // null value = 0 is transparent
     136               2 :     oEntry.c1 = 255;
     137               2 :     oEntry.c2 = 255;
     138               2 :     oEntry.c3 = 255;
     139               2 :     oEntry.c4 = 255;                // alpha 255 = transparent
     140                 : 
     141               2 :     poGDS->poColorTable->SetColorEntry( 0, &oEntry );
     142                 : 
     143                 :     int i;
     144               8 :     for( i=0; i < (int) poGDS->pGrd->stClassDict->nNumClassifiedItems; i++ )
     145                 :     {
     146               6 :         oEntry.c1 = poGDS->pGrd->stClassDict->stClassifedItem[i]->r;
     147               6 :         oEntry.c2 = poGDS->pGrd->stClassDict->stClassifedItem[i]->g;
     148               6 :         oEntry.c3 = poGDS->pGrd->stClassDict->stClassifedItem[i]->b;
     149               6 :         oEntry.c4 = 0;            // alpha 0 = solid
     150                 : 
     151                 :         poGDS->poColorTable->SetColorEntry( poDS->pGrd->
     152               6 :                                           stClassDict->stClassifedItem[i]->
     153               6 :                                           usPixVal, &oEntry );
     154                 :     }
     155                 : 
     156                 :     // find the max value used in the grc
     157               2 :     int maxValue = 0;
     158               8 :     for( i=0; i < (int) poDS->pGrd->stClassDict->nNumClassifiedItems; i++ )
     159                 :     {
     160               6 :         if( poDS->pGrd->stClassDict->stClassifedItem[i]->usPixVal > maxValue )
     161               6 :             maxValue = poDS->pGrd->stClassDict->stClassifedItem[i]->usPixVal;
     162                 :     }
     163                 : 
     164                 :     // load a value for the null value
     165               2 :     poGDS->papszCategories = CSLAddString( poGDS->papszCategories, "No Data" );
     166                 : 
     167                 :     // for the class names we need to load nulls string for all classes that
     168                 :     // are not defined
     169               8 :     for( int val = 1; val <= maxValue; val++ )
     170                 :     {
     171                 :         int i;
     172                 :         // loop throught the GRC dictionary to see if the value is defined
     173              12 :         for( i=0; i < (int) poDS->pGrd->stClassDict->nNumClassifiedItems; i++ )
     174                 :         {
     175              12 :             if( (int) poDS->pGrd->stClassDict->stClassifedItem[i]->usPixVal ==
     176                 :                 val )
     177                 :             {
     178                 :                 poGDS->papszCategories =
     179                 :                     CSLAddString( poGDS->papszCategories,
     180                 :                                     poDS->pGrd->stClassDict->
     181               6 :                                     stClassifedItem[i]->szClassName );
     182               6 :                 break;
     183                 :             }
     184                 :         }
     185               6 :         if( i >= (int) poDS->pGrd->stClassDict->nNumClassifiedItems )
     186               0 :             poGDS->papszCategories = CSLAddString( poGDS->papszCategories, "" );
     187                 : 
     188                 :     }
     189               2 : }
     190                 : 
     191               2 : NWT_GRCRasterBand::~NWT_GRCRasterBand()
     192                 : {
     193               2 : }
     194                 : 
     195               0 : double NWT_GRCRasterBand::GetNoDataValue( int *pbSuccess )
     196                 : {
     197               0 :     if( pbSuccess != NULL )
     198               0 :         *pbSuccess = TRUE;
     199                 : 
     200               0 :     return 0;                        //Northwood grid 0 is always null
     201                 : }
     202                 : 
     203                 : // return an array of null terminated strings for the class names
     204               0 : char **NWT_GRCRasterBand::GetCategoryNames()
     205                 : {
     206               0 :     NWT_GRCDataset *poGDS = (NWT_GRCDataset *) poDS;
     207                 : 
     208               0 :     return poGDS->papszCategories;
     209                 : }
     210                 : 
     211                 : // return the color table
     212               0 : GDALColorTable *NWT_GRCRasterBand::GetColorTable()
     213                 : {
     214               0 :     NWT_GRCDataset *poGDS = (NWT_GRCDataset *) poDS;
     215                 : 
     216               0 :     return poGDS->poColorTable;
     217                 : }
     218                 : 
     219               0 : GDALColorInterp NWT_GRCRasterBand::GetColorInterpretation()
     220                 : {
     221               0 :     if( nBand == 1 )
     222               0 :         return GCI_PaletteIndex;
     223                 :     else
     224               0 :         return GCI_Undefined;
     225                 : }
     226                 : 
     227                 : /************************************************************************/
     228                 : /*                             IReadBlock()                             */
     229                 : /************************************************************************/
     230             362 : CPLErr NWT_GRCRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     231                 :                                         void *pImage )
     232                 : {
     233             362 :     NWT_GRCDataset *poGDS =(NWT_GRCDataset *) poDS;
     234             362 :     int nRecordSize = nBlockXSize *( poGDS->pGrd->nBitsPerPixel / 8 );
     235                 : 
     236             362 :     if( nBand == 1 )
     237                 :     {                            //grc's are just one band of indices
     238             362 :         VSIFSeekL( poGDS->fp, 1024 + nRecordSize * nBlockYOff, SEEK_SET );
     239             362 :         VSIFReadL( pImage, 1, nRecordSize, poGDS->fp );
     240                 :     }
     241                 :     else
     242                 :     {
     243                 :         CPLError( CE_Failure, CPLE_IllegalArg,
     244                 :                   "No band number %d",
     245               0 :                   nBand );
     246               0 :         return CE_Failure;
     247                 :     }
     248             362 :     return CE_None;
     249                 : }
     250                 : 
     251                 : 
     252                 : /************************************************************************/
     253                 : /*                             GetOffset()                              */
     254                 : /************************************************************************/
     255               0 : double NWT_GRCRasterBand::GetOffset( int *pbSuccess )
     256                 : {
     257               0 :     if( pbSuccess )
     258               0 :         *pbSuccess = bHaveOffsetScale;
     259               0 :     return dfOffset;
     260                 : }
     261                 : 
     262                 : /************************************************************************/
     263                 : /*                             SetOffset()                              */
     264                 : /************************************************************************/
     265               0 : CPLErr NWT_GRCRasterBand::SetOffset( double dfNewValue )
     266                 : {
     267                 :     //poGDS->bMetadataChanged = TRUE;
     268                 : 
     269               0 :     bHaveOffsetScale = TRUE;
     270               0 :     dfOffset = dfNewValue;
     271               0 :     return CE_None;
     272                 : }
     273                 : 
     274                 : /************************************************************************/
     275                 : /*                              GetScale()                              */
     276                 : /************************************************************************/
     277               0 : double NWT_GRCRasterBand::GetScale( int *pbSuccess )
     278                 : {
     279               0 :     if( pbSuccess )
     280               0 :         *pbSuccess = bHaveOffsetScale;
     281               0 :     return dfScale;
     282                 : }
     283                 : 
     284                 : /************************************************************************/
     285                 : /*                              SetScale()                              */
     286                 : /************************************************************************/
     287               0 : CPLErr NWT_GRCRasterBand::SetScale( double dfNewValue )
     288                 : {
     289               0 :     bHaveOffsetScale = TRUE;
     290               0 :     dfScale = dfNewValue;
     291               0 :     return CE_None;
     292                 : }
     293                 : 
     294                 : /************************************************************************/
     295                 : /* ==================================================================== */
     296                 : /*                          NWT_GRCDataset                              */
     297                 : /* ==================================================================== */
     298                 : /************************************************************************/
     299               2 : NWT_GRCDataset::NWT_GRCDataset()
     300                 : {
     301               2 :     poColorTable = NULL;
     302               2 :     papszCategories = NULL;
     303               2 :     pszProjection = NULL;
     304               2 : }
     305                 : 
     306                 : 
     307                 : /************************************************************************/
     308                 : /*                            ~NWT_GRCDataset()                         */
     309                 : /************************************************************************/
     310               2 : NWT_GRCDataset::~NWT_GRCDataset()
     311                 : {
     312               2 :     delete poColorTable;
     313               2 :     CSLDestroy( papszCategories );
     314                 : 
     315               2 :     FlushCache();
     316               2 :     pGrd->fp = NULL;       // this prevents nwtCloseGrid from closing the fp
     317               2 :     nwtCloseGrid( pGrd );
     318                 : 
     319               2 :     if( fp != NULL )
     320               2 :         VSIFCloseL( fp );
     321                 : 
     322               2 :     CPLFree( pszProjection );
     323               2 : }
     324                 : 
     325                 : /************************************************************************/
     326                 : /*                          GetGeoTransform()                           */
     327                 : /************************************************************************/
     328               0 : CPLErr NWT_GRCDataset::GetGeoTransform( double *padfTransform )
     329                 : {
     330               0 :     padfTransform[0] = pGrd->dfMinX - ( pGrd->dfStepSize * 0.5 );
     331               0 :     padfTransform[3] = pGrd->dfMaxY + ( pGrd->dfStepSize * 0.5 );
     332               0 :     padfTransform[1] = pGrd->dfStepSize;
     333               0 :     padfTransform[2] = 0.0;
     334                 : 
     335               0 :     padfTransform[4] = 0.0;
     336               0 :     padfTransform[5] = -1 * pGrd->dfStepSize;
     337                 : 
     338               0 :     return CE_None;
     339                 : }
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                          GetProjectionRef()                          */
     343                 : /************************************************************************/
     344               0 : const char *NWT_GRCDataset::GetProjectionRef()
     345                 : {
     346                 : #ifdef OGR_ENABLED
     347               0 :     if (pszProjection == NULL)
     348                 :     {
     349                 :         OGRSpatialReference *poSpatialRef;
     350               0 :         poSpatialRef = MITABCoordSys2SpatialRef( pGrd->cMICoordSys );
     351               0 :         if (poSpatialRef)
     352                 :         {
     353               0 :             poSpatialRef->exportToWkt( &pszProjection );
     354               0 :             poSpatialRef->Release();
     355                 :         }
     356                 :     }
     357                 : #endif
     358               0 :     return ( (const char *) pszProjection );
     359                 : }
     360                 : 
     361                 : /************************************************************************/
     362                 : /*                              Identify()                              */
     363                 : /************************************************************************/
     364                 : 
     365           22234 : int NWT_GRCDataset::Identify( GDALOpenInfo * poOpenInfo )
     366                 : {
     367                 : /* -------------------------------------------------------------------- */
     368                 : /*  Look for the header                                                 */
     369                 : /* -------------------------------------------------------------------- */
     370           22234 :     if( poOpenInfo->nHeaderBytes < 50 )
     371           21244 :         return FALSE;
     372                 : 
     373            1040 :     if( poOpenInfo->pabyHeader[0] != 'H' ||
     374              44 :         poOpenInfo->pabyHeader[1] != 'G' ||
     375               2 :         poOpenInfo->pabyHeader[2] != 'P' ||
     376               2 :         poOpenInfo->pabyHeader[3] != 'C' ||
     377               2 :         poOpenInfo->pabyHeader[4] != '8' )
     378             988 :         return FALSE;
     379                 : 
     380               2 :     return TRUE;
     381                 : }
     382                 : 
     383                 : /************************************************************************/
     384                 : /*                                Open()                                */
     385                 : /************************************************************************/
     386                 : 
     387            3326 : GDALDataset *NWT_GRCDataset::Open( GDALOpenInfo * poOpenInfo )
     388                 : {
     389            3326 :     if( !Identify(poOpenInfo) )
     390            3324 :         return NULL;
     391                 : 
     392                 : /* -------------------------------------------------------------------- */
     393                 : /*      Create a corresponding GDALDataset.                             */
     394                 : /* -------------------------------------------------------------------- */
     395                 :     NWT_GRCDataset *poDS;
     396                 : 
     397               2 :     poDS = new NWT_GRCDataset();
     398                 : 
     399               2 :     poDS->fp = VSIFOpenL(poOpenInfo->pszFilename, "rb");
     400               2 :     if (poDS->fp == NULL)
     401                 :     {
     402               0 :         delete poDS;
     403               0 :         return NULL;
     404                 :     }
     405                 : 
     406                 : /* -------------------------------------------------------------------- */
     407                 : /*      Read the header.                                                */
     408                 : /* -------------------------------------------------------------------- */
     409               2 :     VSIFSeekL( poDS->fp, 0, SEEK_SET );
     410               2 :     VSIFReadL( poDS->abyHeader, 1, 1024, poDS->fp );
     411               2 :     poDS->pGrd = (NWT_GRID *) malloc( sizeof (NWT_GRID) );
     412                 : 
     413               2 :     poDS->pGrd->fp = poDS->fp;
     414                 : 
     415               2 :     if (!nwt_ParseHeader( poDS->pGrd, (char *) poDS->abyHeader ) ||
     416                 :         !GDALCheckDatasetDimensions(poDS->pGrd->nXSide, poDS->pGrd->nYSide) ||
     417                 :         poDS->pGrd->stClassDict == NULL)
     418                 :     {
     419               0 :         delete poDS;
     420               0 :         return NULL;
     421                 :     }
     422                 : 
     423               2 :     poDS->nRasterXSize = poDS->pGrd->nXSide;
     424               2 :     poDS->nRasterYSize = poDS->pGrd->nYSide;
     425                 : 
     426                 : /* -------------------------------------------------------------------- */
     427                 : /*      Create band information objects.                                */
     428                 : /* -------------------------------------------------------------------- */
     429               2 :     poDS->SetBand( 1, new NWT_GRCRasterBand( poDS, 1) );    //Class Indexes
     430                 : 
     431                 : /* -------------------------------------------------------------------- */
     432                 : /*      Initialize any PAM information.                                 */
     433                 : /* -------------------------------------------------------------------- */
     434               2 :     poDS->SetDescription( poOpenInfo->pszFilename );
     435               2 :     poDS->TryLoadXML();
     436                 : 
     437                 : /* -------------------------------------------------------------------- */
     438                 : /*      Check for external overviews.                                   */
     439                 : /* -------------------------------------------------------------------- */
     440               2 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles );
     441                 : 
     442               2 :     return (poDS);
     443                 : }
     444                 : 
     445                 : 
     446                 : /************************************************************************/
     447                 : /*                          GDALRegister_GRC()                          */
     448                 : /************************************************************************/
     449                 : 
     450                 : void
     451            1135 : GDALRegister_NWT_GRC()
     452                 : {
     453                 :     GDALDriver *poDriver;
     454                 : 
     455            1135 :     if( GDALGetDriverByName( "NWT_GRC" ) == NULL )
     456                 :     {
     457            1093 :         poDriver = new GDALDriver();
     458                 : 
     459            1093 :         poDriver->SetDescription( "NWT_GRC" );
     460                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
     461            1093 :                                  "Northwood Classified Grid Format .grc/.tab");
     462                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
     463            1093 :                                  "frmt_various.html#northwood_grc" );
     464            1093 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "grc" );
     465            1093 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     466                 : 
     467            1093 :         poDriver->pfnOpen = NWT_GRCDataset::Open;
     468            1093 :         poDriver->pfnIdentify = NWT_GRCDataset::Identify;
     469                 : 
     470            1093 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     471                 :     }
     472            1135 : }

Generated by: LCOV version 1.7