LCOV - code coverage report
Current view: directory - frmts/ingr - IntergraphDataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 324 276 85.2 %
Date: 2013-03-30 Functions: 12 9 75.0 %

       1                 : /*****************************************************************************
       2                 :  * $Id: IntergraphDataset.cpp 25785 2013-03-23 11:34:53Z rouault $
       3                 :  *
       4                 :  * Project:  Intergraph Raster Format support
       5                 :  * Purpose:  Read/Write Intergraph Raster Format, dataset support
       6                 :  * Author:   Ivan Lucena, ivan.lucena@pmldnet.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Ivan Lucena
      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_priv.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "cpl_csv.h"
      34                 : #include "ogr_spatialref.h"
      35                 : #include "gdal_pam.h"
      36                 : #include "gdal_alg.h"
      37                 : 
      38                 : #include "IntergraphDataset.h"
      39                 : #include "IntergraphBand.h"
      40                 : #include "IngrTypes.h"
      41                 : 
      42                 : //  ----------------------------------------------------------------------------
      43                 : //                                        IntergraphDataset::IntergraphDataset()
      44                 : //  ----------------------------------------------------------------------------
      45                 : 
      46              77 : IntergraphDataset::IntergraphDataset()
      47                 : {
      48              77 :     pszFilename = NULL;
      49              77 :     fp = NULL;
      50                 : 
      51              77 :     adfGeoTransform[0] = 0.0;
      52              77 :     adfGeoTransform[1] = 1.0;
      53              77 :     adfGeoTransform[2] = 0.0;
      54              77 :     adfGeoTransform[3] = 0.0;
      55              77 :     adfGeoTransform[4] = 0.0;
      56              77 :     adfGeoTransform[5] = 1.0;
      57                 : 
      58              77 :     hVirtual.poDS = NULL;
      59              77 :     hVirtual.poBand = NULL;
      60              77 :     hVirtual.pszFileName = NULL;
      61                 : 
      62              77 :     memset(&hHeaderOne, 0, sizeof(hHeaderOne));
      63              77 :     memset(&hHeaderTwo, 0, sizeof(hHeaderTwo));
      64              77 : }
      65                 : 
      66                 : //  ----------------------------------------------------------------------------
      67                 : //                                       IntergraphDataset::~IntergraphDataset()
      68                 : //  ----------------------------------------------------------------------------
      69                 : 
      70              77 : IntergraphDataset::~IntergraphDataset()
      71                 : {
      72              77 :     FlushCache();
      73                 : 
      74              77 :     CPLFree( pszFilename );
      75                 : 
      76              77 :     if( fp != NULL )
      77                 :     {
      78              77 :         VSIFCloseL( fp );
      79                 :     }
      80              77 : }
      81                 : 
      82                 : //  ----------------------------------------------------------------------------
      83                 : //                                                     IntergraphDataset::Open()
      84                 : //  ----------------------------------------------------------------------------
      85                 : 
      86           12613 : GDALDataset *IntergraphDataset::Open( GDALOpenInfo *poOpenInfo )
      87                 : {
      88           12613 :     if( poOpenInfo->nHeaderBytes < 1024 )
      89                 :     {
      90           11881 :         return NULL;
      91                 :     }
      92                 : 
      93                 :     // -------------------------------------------------------------------- 
      94                 :     // Assign Header Information
      95                 :     // -------------------------------------------------------------------- 
      96                 : 
      97                 :     INGR_HeaderOne hHeaderOne;
      98                 : 
      99             732 :     INGR_HeaderOneDiskToMem( &hHeaderOne, (GByte*) poOpenInfo->pabyHeader);
     100                 : 
     101                 :     // -------------------------------------------------------------------- 
     102                 :     // Check Header Type (HTC) Version
     103                 :     // -------------------------------------------------------------------- 
     104                 : 
     105             732 :     if( hHeaderOne.HeaderType.Version != INGR_HEADER_VERSION )
     106                 :     {
     107             629 :         return NULL;
     108                 :     }
     109                 : 
     110                 :     // -------------------------------------------------------------------- 
     111                 :     // Check Header Type (HTC) 2D / 3D Flag
     112                 :     // -------------------------------------------------------------------- 
     113                 : 
     114             103 :     if( ( hHeaderOne.HeaderType.Is2Dor3D != INGR_HEADER_2D ) && 
     115                 :         ( hHeaderOne.HeaderType.Is2Dor3D != INGR_HEADER_3D ) )
     116                 :     {
     117              26 :         return NULL;
     118                 :     }
     119                 : 
     120                 :     // -------------------------------------------------------------------- 
     121                 :     // Check Header Type (HTC) Type Flag
     122                 :     // -------------------------------------------------------------------- 
     123                 : 
     124              77 :     if( hHeaderOne.HeaderType.Type != INGR_HEADER_TYPE )
     125                 :     {
     126               0 :         return NULL;
     127                 :     }
     128                 : 
     129                 :     // -------------------------------------------------------------------- 
     130                 :     // Check Grid File Version (VER)
     131                 :     // -------------------------------------------------------------------- 
     132                 : 
     133              77 :     if( hHeaderOne.GridFileVersion != 1 &&
     134                 :         hHeaderOne.GridFileVersion != 2 &&
     135                 :         hHeaderOne.GridFileVersion != 3 )
     136                 :     {
     137               0 :         return NULL;
     138                 :     }
     139                 : 
     140                 :     // -------------------------------------------------------------------- 
     141                 :     // Check Words To Follow (WTC) Minimum Value
     142                 :     // -------------------------------------------------------------------- 
     143                 : 
     144              77 :     if( hHeaderOne.WordsToFollow < 254 )
     145                 :     {
     146               0 :         return NULL;
     147                 :     }
     148                 : 
     149                 :     // -------------------------------------------------------------------- 
     150                 :     // Check Words To Follow (WTC) Integrity
     151                 :     // -------------------------------------------------------------------- 
     152                 : 
     153              77 :     float fHeaderBlocks = (float) ( hHeaderOne.WordsToFollow + 2 ) / 256;
     154                 : 
     155              77 :     if( ( fHeaderBlocks - (int) fHeaderBlocks ) != 0.0 )
     156                 :     {
     157               0 :         return NULL;
     158                 :     }
     159                 : 
     160                 :     // -------------------------------------------------------------------- 
     161                 :     // Get Data Type Code (DTC) => Format Type
     162                 :     // -------------------------------------------------------------------- 
     163                 : 
     164              77 :     INGR_Format eFormat = (INGR_Format) hHeaderOne.DataTypeCode;
     165                 : 
     166                 :     // -------------------------------------------------------------------- 
     167                 :     // We need to scan around the file, so we open it now. 
     168                 :     // -------------------------------------------------------------------- 
     169                 : 
     170                 :     VSILFILE   *fp;
     171                 : 
     172              77 :     if( poOpenInfo->eAccess == GA_ReadOnly  )
     173                 :     {
     174              44 :         fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
     175                 :     } 
     176                 :     else 
     177                 :     {
     178              33 :         fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );
     179                 :     }
     180                 : 
     181              77 :     if( fp == NULL )
     182                 :     {
     183               0 :         CPLError( CE_Failure, CPLE_OpenFailed, "%s", VSIStrerror( errno ) );
     184               0 :         return NULL;
     185                 :     }
     186                 : 
     187                 :     // -------------------------------------------------------------------- 
     188                 :     // Get Format Type from the tile directory
     189                 :     // -------------------------------------------------------------------- 
     190                 : 
     191              77 :     if( hHeaderOne.DataTypeCode == TiledRasterData )
     192                 :     {
     193                 :         INGR_TileHeader hTileDir;
     194                 : 
     195               3 :         int nOffset = 2 + ( 2 * ( hHeaderOne.WordsToFollow + 1 ) );
     196                 : 
     197                 :         GByte abyBuffer[SIZEOF_TDIR];
     198                 : 
     199               3 :         if( (VSIFSeekL( fp, nOffset, SEEK_SET ) == -1 )  ||
     200                 :             (VSIFReadL( abyBuffer, 1, SIZEOF_TDIR, fp ) == 0) )
     201                 :         {
     202               0 :             VSIFCloseL( fp );
     203                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     204               0 :                 "Error reading tiles header" );
     205               0 :             return NULL;
     206                 :         }
     207                 : 
     208               3 :         INGR_TileHeaderDiskToMem( &hTileDir, abyBuffer );
     209                 : 
     210               3 :         if( !
     211                 :           ( hTileDir.ApplicationType     == 1 &&
     212                 :             hTileDir.SubTypeCode         == 7 &&
     213                 :             ( hTileDir.WordsToFollow % 4 ) == 0 &&
     214                 :             hTileDir.PacketVersion       == 1 &&
     215                 :             hTileDir.Identifier          == 1 ) )
     216                 :         {
     217                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     218               0 :                 "Cannot recognize tiles header info");
     219               0 :             VSIFCloseL( fp );
     220               0 :             return NULL;
     221                 :         }
     222                 :             
     223               3 :         eFormat = (INGR_Format) hTileDir.DataTypeCode;
     224                 :     }
     225                 : 
     226                 :     // -------------------------------------------------------------------- 
     227                 :     // Check Scannable Flag
     228                 :     // -------------------------------------------------------------------- 
     229                 : /*
     230                 :     if (hHeaderOne.ScannableFlag == HasLineHeader)
     231                 :     {
     232                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     233                 :             "Intergraph Raster Scannable Line Header not supported yet" );
     234                 :         VSIFCloseL( fp );
     235                 :         return NULL;
     236                 :     }
     237                 : */
     238                 :     // -------------------------------------------------------------------- 
     239                 :     // Check supported Format Type
     240                 :     // -------------------------------------------------------------------- 
     241                 : 
     242              77 :     if( eFormat != ByteInteger &&
     243                 :         eFormat != WordIntegers &&
     244                 :         eFormat != Integers32Bit &&
     245                 :         eFormat != FloatingPoint32Bit &&
     246                 :         eFormat != FloatingPoint64Bit &&
     247                 :         eFormat != RunLengthEncoded &&
     248                 :         eFormat != RunLengthEncodedC &&
     249                 :         eFormat != CCITTGroup4 &&
     250                 :         eFormat != AdaptiveRGB &&
     251                 :         eFormat != Uncompressed24bit &&
     252                 :         eFormat != AdaptiveGrayScale &&
     253                 :         eFormat != ContinuousTone &&
     254                 :         eFormat != JPEGGRAY &&
     255                 :         eFormat != JPEGRGB && 
     256                 :         eFormat != JPEGCYMK )
     257                 :     {
     258                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     259                 :             "Intergraph Raster Format %d ( \"%s\" ) not supported",
     260               0 :             hHeaderOne.DataTypeCode, INGR_GetFormatName( (uint16) eFormat ) );
     261               0 :         VSIFCloseL( fp );
     262               0 :         return NULL;
     263                 :     }
     264                 : 
     265                 :     // -----------------------------------------------------------------
     266                 :     // Create a corresponding GDALDataset
     267                 :     // -----------------------------------------------------------------
     268                 : 
     269                 :     IntergraphDataset *poDS;
     270                 : 
     271              77 :     poDS = new IntergraphDataset();
     272              77 :     poDS->eAccess = poOpenInfo->eAccess;
     273              77 :     poDS->pszFilename = CPLStrdup( poOpenInfo->pszFilename );
     274              77 :     poDS->fp = fp;
     275                 : 
     276                 :     // -------------------------------------------------------------------- 
     277                 :     // Get X Size from Pixels Per Line (PPL)
     278                 :     // -------------------------------------------------------------------- 
     279                 : 
     280              77 :     poDS->nRasterXSize = hHeaderOne.PixelsPerLine;
     281                 : 
     282                 :     // -------------------------------------------------------------------- 
     283                 :     // Get Y Size from Number of Lines (NOL)
     284                 :     // -------------------------------------------------------------------- 
     285                 : 
     286              77 :     poDS->nRasterYSize = hHeaderOne.NumberOfLines;
     287                 : 
     288             154 :     if (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0)
     289                 :     {
     290                 :         CPLError( CE_Failure, CPLE_AppDefined,
     291                 :                   "Invalid dimensions : %d x %d",
     292               0 :                   poDS->nRasterXSize, poDS->nRasterYSize);
     293               0 :         delete poDS;
     294               0 :         return NULL;
     295                 :     }
     296                 : 
     297                 :     // -------------------------------------------------------------------- 
     298                 :     // Get Geo Transformation from Homogeneous Transformation Matrix (TRN)
     299                 :     // -------------------------------------------------------------------- 
     300                 : 
     301              77 :     INGR_GetTransMatrix( &hHeaderOne, poDS->adfGeoTransform );
     302                 : 
     303                 :     // -------------------------------------------------------------------- 
     304                 :     // Set Metadata Information
     305                 :     // -------------------------------------------------------------------- 
     306                 : 
     307                 :     poDS->SetMetadataItem( "VERSION", 
     308              77 :         CPLSPrintf ( "%d", hHeaderOne.GridFileVersion ), "IMAGE_STRUCTURE" );
     309                 :     poDS->SetMetadataItem( "RESOLUTION",
     310              77 :         CPLSPrintf ( "%d", (hHeaderOne.DeviceResolution < 0)?-hHeaderOne.DeviceResolution:1) );
     311                 : 
     312                 :     // -------------------------------------------------------------------- 
     313                 :     // Create Band Information
     314                 :     // -------------------------------------------------------------------- 
     315                 : 
     316              77 :     int nBands = 0;
     317              77 :     int nBandOffset = 0;
     318                 : 
     319                 :     GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_HDR2_A)];
     320                 : 
     321              77 :     do
     322                 :     {
     323              77 :         VSIFSeekL( poDS->fp, nBandOffset, SEEK_SET );
     324                 : 
     325              77 :         VSIFReadL( abyBuf, 1, SIZEOF_HDR1, poDS->fp );
     326                 : 
     327              77 :         INGR_HeaderOneDiskToMem( &poDS->hHeaderOne, abyBuf );
     328                 : 
     329              77 :         VSIFReadL( abyBuf, 1, SIZEOF_HDR2_A, poDS->fp );
     330                 : 
     331              77 :         INGR_HeaderTwoADiskToMem( &poDS->hHeaderTwo, abyBuf );
     332                 : 
     333              77 :         switch( eFormat )
     334                 :         {
     335                 :         case JPEGRGB:
     336                 :         case JPEGCYMK:
     337                 :         {
     338                 :             IntergraphBitmapBand* poBand;
     339               1 :             nBands++;
     340                 :             poDS->SetBand( nBands, 
     341               1 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 1 ));
     342               1 :             if (poBand->pabyBMPBlock == NULL)
     343                 :             {
     344               0 :                 delete poDS;
     345               0 :                 return NULL;
     346                 :             }
     347               1 :             nBands++;
     348                 :             poDS->SetBand( nBands, 
     349               1 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 2 ));
     350               1 :             if (poBand->pabyBMPBlock == NULL)
     351                 :             {
     352               0 :                 delete poDS;
     353               0 :                 return NULL;
     354                 :             }
     355               1 :             nBands++;
     356                 :             poDS->SetBand( nBands, 
     357               1 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 3 ));
     358               1 :             if (poBand->pabyBMPBlock == NULL)
     359                 :             {
     360               0 :                 delete poDS;
     361               0 :                 return NULL;
     362                 :             }
     363               1 :             break;
     364                 :         }
     365                 :         case JPEGGRAY:
     366                 :         case CCITTGroup4:
     367                 :         {
     368                 :             IntergraphBitmapBand* poBand;
     369               2 :             nBands++;
     370                 :             poDS->SetBand( nBands, 
     371               2 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset ));
     372               2 :             if (poBand->pabyBMPBlock == NULL)
     373                 :             {
     374               0 :                 delete poDS;
     375               0 :                 return NULL;
     376                 :             }
     377               2 :             break;
     378                 :         }
     379                 :         case RunLengthEncoded:
     380                 :         case RunLengthEncodedC:
     381                 :         case AdaptiveGrayScale:
     382                 :         {
     383                 :             IntergraphRLEBand* poBand;
     384               8 :             nBands++;
     385                 :             poDS->SetBand( nBands, 
     386               8 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset ));
     387              16 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     388                 :             {
     389               0 :                 delete poDS;
     390               0 :                 return NULL;
     391                 :             }
     392               8 :             break;
     393                 :         }
     394                 :         case AdaptiveRGB:
     395                 :         case ContinuousTone:
     396                 :         {
     397                 :             IntergraphRLEBand* poBand;
     398               1 :             nBands++;
     399                 :             poDS->SetBand( nBands, 
     400               1 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 1 ));
     401               2 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     402                 :             {
     403               0 :                 delete poDS;
     404               0 :                 return NULL;
     405                 :             }
     406               1 :             nBands++;
     407                 :             poDS->SetBand( nBands, 
     408               1 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 2 ));
     409               2 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     410                 :             {
     411               0 :                 delete poDS;
     412               0 :                 return NULL;
     413                 :             }
     414               1 :             nBands++;
     415                 :             poDS->SetBand( nBands, 
     416               1 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 3 ));
     417               2 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     418                 :             {
     419               0 :                 delete poDS;
     420               0 :                 return NULL;
     421                 :             }
     422               1 :             break;
     423                 :         }
     424                 :         case Uncompressed24bit:
     425                 :         {
     426                 :             IntergraphRGBBand* poBand;
     427               5 :             nBands++;
     428                 :             poDS->SetBand( nBands, 
     429               5 :                 poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 1 ));
     430               5 :             if (poBand->pabyBlockBuf == NULL)
     431                 :             {
     432               0 :                 delete poDS;
     433               0 :                 return NULL;
     434                 :             }
     435               5 :             nBands++;
     436                 :             poDS->SetBand( nBands, 
     437               5 :                 poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 2 ));
     438               5 :             if (poBand->pabyBlockBuf == NULL)
     439                 :             {
     440               0 :                 delete poDS;
     441               0 :                 return NULL;
     442                 :             }
     443               5 :             nBands++;
     444                 :             poDS->SetBand( nBands, 
     445               5 :                 poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 3 ));
     446               5 :             if (poBand->pabyBlockBuf == NULL)
     447                 :             {
     448               0 :                 delete poDS;
     449               0 :                 return NULL;
     450                 :             }
     451               5 :             break;
     452                 :         }
     453                 :         default:
     454                 :         {
     455                 :             IntergraphRasterBand* poBand;
     456              60 :             nBands++;
     457                 :             poDS->SetBand( nBands, 
     458              60 :                 poBand = new IntergraphRasterBand( poDS, nBands, nBandOffset ));
     459              60 :             if (poBand->pabyBlockBuf == NULL)
     460                 :             {
     461               0 :                 delete poDS;
     462               0 :                 return NULL;
     463                 :             }
     464                 :         }
     465                 :         }
     466                 : 
     467                 :         // ----------------------------------------------------------------
     468                 :         // Get next band offset from Catenated File Pointer (CFP)
     469                 :         // ----------------------------------------------------------------
     470                 : 
     471              77 :         nBandOffset = poDS->hHeaderTwo.CatenatedFilePointer;
     472                 :     }
     473                 :     while( nBandOffset != 0 );
     474                 : 
     475              77 :     poDS->nBands = nBands;
     476                 : 
     477                 :     // -------------------------------------------------------------------- 
     478                 :     // Initialize any PAM information                                 
     479                 :     // -------------------------------------------------------------------- 
     480                 : 
     481              77 :     poDS->SetDescription( poOpenInfo->pszFilename );
     482              77 :     poDS->TryLoadXML();
     483                 : 
     484                 :     /* -------------------------------------------------------------------- */
     485                 :     /*      Check for external overviews.                                   */
     486                 :     /* -------------------------------------------------------------------- */
     487                 : 
     488              77 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     489                 : 
     490              77 :     return ( poDS );
     491                 : }
     492                 : 
     493                 : //  ----------------------------------------------------------------------------
     494                 : //                                                   IntergraphDataset::Create()
     495                 : //  ----------------------------------------------------------------------------
     496                 : 
     497              47 : GDALDataset *IntergraphDataset::Create( const char *pszFilename,
     498                 :                                         int nXSize, 
     499                 :                                         int nYSize, 
     500                 :                                         int nBands, 
     501                 :                                         GDALDataType eType,
     502                 :                                         char **papszOptions )
     503                 : {
     504              47 :     int nDeviceResolution = 1;
     505                 :     const char *pszValue;
     506              47 :     const char *pszCompression = NULL;
     507                 : 
     508              47 :     pszValue = CSLFetchNameValue(papszOptions, "RESOLUTION");
     509              47 :     if( pszValue != NULL )
     510               2 :         nDeviceResolution = -atoi( pszValue );
     511                 : 
     512              47 :     char *pszExtension = CPLStrlwr(CPLStrdup(CPLGetExtension(pszFilename)));
     513              47 :     if ( EQUAL( pszExtension, "rle" ) )
     514               1 :         pszCompression = INGR_GetFormatName(RunLengthEncoded);
     515              47 :     CPLFree(pszExtension);
     516                 :   
     517              47 :     if( eType != GDT_Byte &&
     518                 :         eType != GDT_Int16 && 
     519                 :         eType != GDT_Int32 && 
     520                 :         eType != GDT_UInt16 && 
     521                 :         eType != GDT_UInt32 && 
     522                 :         eType != GDT_Float32&& 
     523                 :         eType != GDT_Float64 )
     524                 :     {
     525                 :         CPLError( CE_Failure, CPLE_AppDefined, "Data type not supported (%s)",
     526              12 :             GDALGetDataTypeName( eType ) );
     527              12 :         return NULL;
     528                 :     }
     529                 : 
     530                 :     // -------------------------------------------------------------------- 
     531                 :     //  Fill headers with minimun information
     532                 :     // -------------------------------------------------------------------- 
     533                 : 
     534                 :     INGR_HeaderOne  hHdr1;
     535                 :     INGR_HeaderTwoA hHdr2;
     536                 :     INGR_ColorTable256 hCTab;
     537                 :     int             i;
     538                 :     
     539              35 :     memset(&hHdr1, 0, SIZEOF_HDR1);
     540              35 :     memset(&hHdr2, 0, SIZEOF_HDR2_A);
     541              35 :     memset(&hCTab, 0, SIZEOF_CTAB);
     542                 : 
     543              35 :     hHdr1.HeaderType.Version    = INGR_HEADER_VERSION;
     544              35 :     hHdr1.HeaderType.Type       = INGR_HEADER_TYPE;
     545              35 :     hHdr1.HeaderType.Is2Dor3D   = INGR_HEADER_2D;
     546              35 :     hHdr1.DataTypeCode          = (uint16) INGR_GetFormat( eType, (pszCompression!=NULL)?pszCompression:"None" );
     547              35 :     hHdr1.WordsToFollow         = ( ( SIZEOF_HDR1 * 3 ) / 2 ) - 2;
     548              35 :     hHdr1.ApplicationType       = GenericRasterImageFile;
     549              35 :     hHdr1.XViewOrigin           = 0.0;
     550              35 :     hHdr1.YViewOrigin           = 0.0;
     551              35 :     hHdr1.ZViewOrigin           = 0.0;
     552              35 :     hHdr1.XViewExtent           = 0.0;
     553              35 :     hHdr1.YViewExtent           = 0.0;
     554              35 :     hHdr1.ZViewExtent           = 0.0;
     555             560 :     for( i = 0; i < 15; i++ )
     556             525 :         hHdr1.TransformationMatrix[i]   = 0.0;
     557              35 :     hHdr1.TransformationMatrix[15]      = 1.0;
     558              35 :     hHdr1.PixelsPerLine         = nXSize;
     559              35 :     hHdr1.NumberOfLines         = nYSize;
     560              35 :     hHdr1.DeviceResolution      = nDeviceResolution;
     561              35 :     hHdr1.ScanlineOrientation   = UpperLeftHorizontal;
     562              35 :     hHdr1.ScannableFlag         = NoLineHeader;
     563              35 :     hHdr1.RotationAngle         = 0.0;
     564              35 :     hHdr1.SkewAngle             = 0.0;
     565              35 :     hHdr1.DataTypeModifier      = 0;
     566              35 :     hHdr1.DesignFileName[0]     = '\0';
     567              35 :     hHdr1.DataBaseFileName[0]   = '\0';
     568              35 :     hHdr1.ParentGridFileName[0] = '\0';
     569              35 :     hHdr1.FileDescription[0]    = '\0';
     570              35 :     hHdr1.Minimum               = INGR_SetMinMax( eType, 0.0 );
     571              35 :     hHdr1.Maximum               = INGR_SetMinMax( eType, 0.0 );
     572              35 :     hHdr1.GridFileVersion       = 3;
     573              35 :     hHdr1.Reserved[0]           = 0;
     574              35 :     hHdr1.Reserved[1]           = 0;
     575              35 :     hHdr1.Reserved[2]           = 0;
     576              35 :     hHdr2.Gain                  = 0;
     577              35 :     hHdr2.OffsetThreshold       = 0;
     578              35 :     hHdr2.View1                 = 0;
     579              35 :     hHdr2.View2                 = 0;
     580              35 :     hHdr2.ViewNumber            = 0;
     581              35 :     hHdr2.Reserved2             = 0;
     582              35 :     hHdr2.Reserved3             = 0;
     583              35 :     hHdr2.AspectRatio           = nXSize / nYSize;
     584              35 :     hHdr2.CatenatedFilePointer  = 0;
     585              35 :     hHdr2.ColorTableType        = NoColorTable;
     586              35 :     hHdr2.NumberOfCTEntries     = 0;
     587              35 :     hHdr2.Reserved8             = 0;
     588            3885 :     for( i = 0; i < 110; i++ )
     589            3850 :         hHdr2.Reserved[i]       = 0;
     590              35 :     hHdr2.ApplicationPacketLength   = 0;
     591              35 :     hHdr2.ApplicationPacketPointer  = 0;
     592                 : 
     593                 :     // -------------------------------------------------------------------- 
     594                 :     //  RGB Composite assumption
     595                 :     // -------------------------------------------------------------------- 
     596                 : 
     597              35 :     if( eType  == GDT_Byte  &&
     598                 :         nBands == 3 )
     599                 :     {
     600               2 :         hHdr1.DataTypeCode = Uncompressed24bit;
     601                 :     }
     602                 : 
     603                 :     // -------------------------------------------------------------------- 
     604                 :     //  Create output file with minimum header info
     605                 :     // -------------------------------------------------------------------- 
     606                 : 
     607              35 :     VSILFILE *fp = VSIFOpenL( pszFilename, "wb+" );
     608                 : 
     609              35 :     if( fp == NULL )
     610                 :     {
     611                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     612               2 :             "Attempt to create file %s' failed.\n", pszFilename );
     613               2 :         return NULL;
     614                 :     }
     615                 : 
     616                 :     GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_CTAB)];
     617                 : 
     618              33 :     INGR_HeaderOneMemToDisk( &hHdr1, abyBuf );
     619                 : 
     620              33 :     VSIFWriteL( abyBuf, 1, SIZEOF_HDR1, fp );
     621                 : 
     622              33 :     INGR_HeaderTwoAMemToDisk( &hHdr2, abyBuf );
     623                 : 
     624              33 :     VSIFWriteL( abyBuf, 1, SIZEOF_HDR2_A, fp );
     625                 : 
     626              33 :     unsigned int n = 0;
     627                 : 
     628            8481 :     for( i = 0; i < 256; i++ )
     629                 :     {
     630            8448 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_red );
     631            8448 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_green );
     632            8448 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_blue );
     633                 :     }
     634                 : 
     635              33 :     VSIFWriteL( abyBuf, 1, SIZEOF_CTAB, fp );
     636                 : 
     637              33 :     VSIFCloseL( fp );
     638                 : 
     639                 :     // -------------------------------------------------------------------- 
     640                 :     //  Returns a new IntergraphDataset from the created file
     641                 :     // -------------------------------------------------------------------- 
     642                 : 
     643              33 :     return ( IntergraphDataset * ) GDALOpen( pszFilename, GA_Update );
     644                 : }
     645                 : 
     646                 : //  ----------------------------------------------------------------------------
     647                 : //                                               IntergraphDataset::CreateCopy()
     648                 : //  ----------------------------------------------------------------------------
     649                 : 
     650              20 : GDALDataset *IntergraphDataset::CreateCopy( const char *pszFilename, 
     651                 :                                            GDALDataset *poSrcDS,
     652                 :                                            int bStrict,
     653                 :                                            char **papszOptions,
     654                 :                                            GDALProgressFunc pfnProgress, 
     655                 :                                            void *pProgressData )
     656                 : {
     657                 :     (void) bStrict;
     658                 : 
     659              20 :     int nBands = poSrcDS->GetRasterCount();
     660              20 :     if (nBands == 0)
     661                 :     {
     662                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     663               1 :                   "Intergraph driver does not support source dataset with zero band.\n");
     664               1 :         return NULL;
     665                 :     }
     666                 : 
     667              19 :     if( !pfnProgress( 0.0, NULL, pProgressData ) )
     668                 :     {
     669               0 :         return NULL;
     670                 :     }
     671                 : 
     672                 :     // -------------------------------------------------------------------- 
     673                 :     // Query GDAL Data Type 
     674                 :     // -------------------------------------------------------------------- 
     675                 : 
     676              19 :     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     677                 : 
     678                 :     // -------------------------------------------------------------------- 
     679                 :     // Copy metadata
     680                 :     // -------------------------------------------------------------------- 
     681                 : 
     682              19 :     char **papszCreateOptions = CSLDuplicate( papszOptions );
     683                 :     const char  *pszValue;
     684                 :   
     685              19 :     pszValue = CSLFetchNameValue(papszCreateOptions, "RESOLUTION");
     686              19 :     if( pszValue == NULL )
     687                 :     {
     688              19 :         const char *value = poSrcDS->GetMetadataItem("RESOLUTION");
     689              19 :         if (value)
     690                 :         {
     691                 :             papszCreateOptions = CSLSetNameValue( papszCreateOptions, "RESOLUTION", 
     692               2 :                 value );
     693                 :         }
     694                 :     }
     695                 : 
     696                 :     // -------------------------------------------------------------------- 
     697                 :     // Create IntergraphDataset
     698                 :     // -------------------------------------------------------------------- 
     699                 : 
     700                 :     IntergraphDataset *poDstDS;
     701                 : 
     702                 :     poDstDS = (IntergraphDataset*) IntergraphDataset::Create( pszFilename, 
     703                 :         poSrcDS->GetRasterXSize(), 
     704                 :         poSrcDS->GetRasterYSize(), 
     705                 :         poSrcDS->GetRasterCount(), 
     706                 :         eType, 
     707              19 :         papszCreateOptions );
     708                 : 
     709              19 :     CSLDestroy( papszCreateOptions );
     710                 : 
     711              19 :     if( poDstDS == NULL )
     712                 :     {
     713               6 :         return NULL;
     714                 :     }
     715                 : 
     716                 :     // -------------------------------------------------------------------- 
     717                 :     // Copy Transformation Matrix to the dataset
     718                 :     // -------------------------------------------------------------------- 
     719                 : 
     720                 :     double adfGeoTransform[6];
     721                 : 
     722              13 :     poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
     723              13 :     poSrcDS->GetGeoTransform( adfGeoTransform );
     724              13 :     poDstDS->SetGeoTransform( adfGeoTransform );
     725                 : 
     726                 :     // -------------------------------------------------------------------- 
     727                 :     // Copy information to the raster band
     728                 :     // -------------------------------------------------------------------- 
     729                 : 
     730                 :     GDALRasterBand *poSrcBand;
     731                 :     GDALRasterBand *poDstBand;
     732                 :     double dfMin;
     733                 :     double dfMax;
     734                 :     double dfMean;
     735              13 :     double dfStdDev = -1;
     736                 :     
     737              28 :     for( int i = 1; i <= poDstDS->nBands; i++)
     738                 :     {
     739              15 :         delete poDstDS->GetRasterBand(i);
     740                 :     }
     741              13 :     poDstDS->nBands = 0;
     742                 : 
     743              13 :     if( poDstDS->hHeaderOne.DataTypeCode == Uncompressed24bit )
     744                 :     {
     745               1 :         poDstDS->SetBand( 1, new IntergraphRGBBand( poDstDS, 1, 0, 3 ) );
     746               2 :         poDstDS->SetBand( 2, new IntergraphRGBBand( poDstDS, 2, 0, 2 ) );
     747               2 :         poDstDS->SetBand( 3, new IntergraphRGBBand( poDstDS, 3, 0, 1 ) );
     748               1 :         poDstDS->nBands = 3;
     749                 :     }
     750                 :     else
     751                 :     {
     752              64 :         for( int i = 1; i <= poSrcDS->GetRasterCount(); i++ )
     753                 :         {
     754              20 :             poSrcBand = poSrcDS->GetRasterBand(i);
     755              20 :             eType = poSrcDS->GetRasterBand(i)->GetRasterDataType();
     756                 : 
     757              20 :             poDstBand = new IntergraphRasterBand( poDstDS, i, 0, eType );
     758              20 :             poDstDS->SetBand( i, poDstBand );
     759                 : 
     760              20 :             poDstBand->SetCategoryNames( poSrcBand->GetCategoryNames() );
     761              20 :             poDstBand->SetColorTable( poSrcBand->GetColorTable() );
     762              20 :             poSrcBand->GetStatistics( false, true, &dfMin, &dfMax, &dfMean, &dfStdDev );
     763              20 :             poDstBand->SetStatistics( dfMin, dfMax, dfMean, dfStdDev );
     764                 :         }
     765                 :     }
     766                 : 
     767                 :     // -------------------------------------------------------------------- 
     768                 :     // Copy image data
     769                 :     // -------------------------------------------------------------------- 
     770                 : 
     771              13 :     int nXSize = poDstDS->GetRasterXSize();
     772              13 :     int nYSize = poDstDS->GetRasterYSize();
     773                 : 
     774                 :     int nBlockXSize;
     775                 :     int nBlockYSize;
     776                 : 
     777              13 :     CPLErr eErr = CE_None;
     778                 : 
     779              36 :     for( int iBand = 1; iBand <= poSrcDS->GetRasterCount(); iBand++ )
     780                 :     {
     781              23 :         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand );
     782              23 :         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand );
     783                 : 
     784                 :         // ------------------------------------------------------------
     785                 :         // Copy Untiled / Uncompressed
     786                 :         // ------------------------------------------------------------
     787                 : 
     788                 :         int   iYOffset, iXOffset;
     789                 :         void *pData;
     790                 : 
     791              23 :         poSrcBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
     792                 : 
     793              23 :         nBlockXSize = nXSize;
     794              23 :         nBlockYSize = 1;
     795                 : 
     796              23 :         pData = CPLMalloc( nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eType ) / 8 );
     797                 : 
     798             518 :         for( iYOffset = 0; iYOffset < nYSize; iYOffset += nBlockYSize )
     799                 :         {
     800             990 :             for( iXOffset = 0; iXOffset < nXSize; iXOffset += nBlockXSize )
     801                 :             {
     802                 :                 eErr = poSrcBand->RasterIO( GF_Read, 
     803                 :                     iXOffset, iYOffset, 
     804                 :                     nBlockXSize, nBlockYSize,
     805                 :                     pData, nBlockXSize, nBlockYSize,
     806             495 :                     eType, 0, 0 );
     807             495 :                 if( eErr != CE_None )
     808                 :                 {
     809               0 :                     return NULL;
     810                 :                 }
     811                 :                 eErr = poDstBand->RasterIO( GF_Write, 
     812                 :                     iXOffset, iYOffset, 
     813                 :                     nBlockXSize, nBlockYSize,
     814                 :                     pData, nBlockXSize, nBlockYSize,
     815             495 :                     eType, 0, 0 );
     816             495 :                 if( eErr != CE_None )
     817                 :                 {
     818               0 :                     return NULL;
     819                 :                 }
     820                 :             }
     821             495 :             if( ( eErr == CE_None ) && ( ! pfnProgress( 
     822                 :                 ( iYOffset + 1 ) / ( double ) nYSize, NULL, pProgressData ) ) )
     823                 :             {
     824               0 :                 eErr = CE_Failure;
     825               0 :                 CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" );
     826                 :             }
     827                 :         }
     828              23 :         CPLFree( pData );
     829                 :     }
     830                 : 
     831                 :     // -------------------------------------------------------------------- 
     832                 :     // Finalize
     833                 :     // -------------------------------------------------------------------- 
     834                 : 
     835              13 :     poDstDS->FlushCache();
     836                 : 
     837              13 :     return poDstDS;
     838                 : }
     839                 : 
     840                 : //  ----------------------------------------------------------------------------
     841                 : //                                          IntergraphDataset::GetGeoTransform()
     842                 : //  ----------------------------------------------------------------------------
     843                 : 
     844              21 : CPLErr  IntergraphDataset::GetGeoTransform( double *padfTransform )
     845                 : {
     846              21 :     if( GDALPamDataset::GetGeoTransform( padfTransform ) != CE_None )
     847                 :     {
     848               3 :         memcpy( padfTransform, adfGeoTransform, sizeof( double ) * 6 );
     849                 :     }
     850                 : 
     851              21 :     return CE_None;
     852                 : }
     853                 : 
     854                 : //  ----------------------------------------------------------------------------
     855                 : //                                          IntergraphDataset::SetGeoTransform()
     856                 : //  ----------------------------------------------------------------------------
     857                 : 
     858              31 : CPLErr IntergraphDataset::SetGeoTransform( double *padfTransform )
     859                 : {
     860              31 :     if( GDALPamDataset::SetGeoTransform( padfTransform ) != CE_None )
     861                 :     {
     862               0 :         memcpy( adfGeoTransform, padfTransform, sizeof( double ) * 6 );
     863                 :     }
     864                 : 
     865              31 :     INGR_SetTransMatrix( hHeaderOne.TransformationMatrix, padfTransform );
     866                 : 
     867              31 :     return CE_None;
     868                 : }
     869                 : 
     870                 : //  ----------------------------------------------------------------------------
     871                 : //                                            IntergraphDataset::SetProjection()
     872                 : //  ----------------------------------------------------------------------------
     873                 : 
     874              31 : CPLErr IntergraphDataset::SetProjection( const char *pszProjString )
     875                 : {   
     876                 :     (void) pszProjString;
     877                 : 
     878              31 :     return CE_None;
     879                 : }
     880                 : 
     881                 : //  ----------------------------------------------------------------------------
     882                 : //                                                           GDALRegister_INGR()
     883                 : //  ----------------------------------------------------------------------------
     884                 : 
     885             610 : void GDALRegister_INGR()
     886                 : {
     887                 :     GDALDriver  *poDriver;
     888                 : 
     889             610 :     if( GDALGetDriverByName( "INGR" ) == NULL )
     890                 :     {
     891             588 :         poDriver = new GDALDriver();
     892                 : 
     893             588 :         poDriver->SetDescription( "INGR" );
     894             588 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "Intergraph Raster" );
     895             588 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "frmt_IntergraphRaster.html" );
     896             588 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     897                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     898             588 :             "Byte Int16 Int32 Float32 Float64" );
     899             588 :         poDriver->pfnOpen = IntergraphDataset::Open;
     900             588 :         poDriver->pfnCreate    = IntergraphDataset::Create;
     901             588 :         poDriver->pfnCreateCopy = IntergraphDataset::CreateCopy;
     902             588 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     903                 :     }
     904             610 : }

Generated by: LCOV version 1.7