LCOV - code coverage report
Current view: directory - frmts/ingr - IntergraphDataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 307 259 84.4 %
Date: 2012-12-26 Functions: 12 9 75.0 %

       1                 : /*****************************************************************************
       2                 :  * $Id: IntergraphDataset.cpp 20996 2010-10-28 18:38:15Z 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              73 : IntergraphDataset::IntergraphDataset()
      47                 : {
      48              73 :     pszFilename = NULL;
      49              73 :     fp = NULL;
      50                 : 
      51              73 :     adfGeoTransform[0] = 0.0;
      52              73 :     adfGeoTransform[1] = 1.0;
      53              73 :     adfGeoTransform[2] = 0.0;
      54              73 :     adfGeoTransform[3] = 0.0;
      55              73 :     adfGeoTransform[4] = 0.0;
      56              73 :     adfGeoTransform[5] = 1.0;
      57                 : 
      58              73 :     hVirtual.poDS = NULL;
      59              73 :     hVirtual.poBand = NULL;
      60              73 :     hVirtual.pszFileName = NULL;
      61                 : 
      62              73 :     memset(&hHeaderOne, 0, sizeof(hHeaderOne));
      63              73 :     memset(&hHeaderTwo, 0, sizeof(hHeaderTwo));
      64              73 : }
      65                 : 
      66                 : //  ----------------------------------------------------------------------------
      67                 : //                                       IntergraphDataset::~IntergraphDataset()
      68                 : //  ----------------------------------------------------------------------------
      69                 : 
      70              73 : IntergraphDataset::~IntergraphDataset()
      71                 : {
      72              73 :     FlushCache();
      73                 : 
      74              73 :     CPLFree( pszFilename );
      75                 : 
      76              73 :     if( fp != NULL )
      77                 :     {
      78              73 :         VSIFCloseL( fp );
      79                 :     }
      80              73 : }
      81                 : 
      82                 : //  ----------------------------------------------------------------------------
      83                 : //                                                     IntergraphDataset::Open()
      84                 : //  ----------------------------------------------------------------------------
      85                 : 
      86           12563 : GDALDataset *IntergraphDataset::Open( GDALOpenInfo *poOpenInfo )
      87                 : {
      88           12563 :     if( poOpenInfo->nHeaderBytes < 1024 )
      89                 :     {
      90           11836 :         return NULL;
      91                 :     }
      92                 : 
      93                 :     // -------------------------------------------------------------------- 
      94                 :     // Assign Header Information
      95                 :     // -------------------------------------------------------------------- 
      96                 : 
      97                 :     INGR_HeaderOne hHeaderOne;
      98                 : 
      99             727 :     INGR_HeaderOneDiskToMem( &hHeaderOne, (GByte*) poOpenInfo->pabyHeader);
     100                 : 
     101                 :     // -------------------------------------------------------------------- 
     102                 :     // Check Header Type (HTC) Version
     103                 :     // -------------------------------------------------------------------- 
     104                 : 
     105             727 :     if( hHeaderOne.HeaderType.Version != INGR_HEADER_VERSION )
     106                 :     {
     107             628 :         return NULL;
     108                 :     }
     109                 : 
     110                 :     // -------------------------------------------------------------------- 
     111                 :     // Check Header Type (HTC) 2D / 3D Flag
     112                 :     // -------------------------------------------------------------------- 
     113                 : 
     114              99 :     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              73 :     if( hHeaderOne.HeaderType.Type != INGR_HEADER_TYPE )
     125                 :     {
     126               0 :         return NULL;
     127                 :     }
     128                 : 
     129                 :     // -------------------------------------------------------------------- 
     130                 :     // Check Grid File Version (VER)
     131                 :     // -------------------------------------------------------------------- 
     132                 : 
     133              73 :     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              73 :     if( hHeaderOne.WordsToFollow < 254 )
     145                 :     {
     146               0 :         return NULL;
     147                 :     }
     148                 : 
     149                 :     // -------------------------------------------------------------------- 
     150                 :     // Check Words To Follow (WTC) Integrity
     151                 :     // -------------------------------------------------------------------- 
     152                 : 
     153              73 :     float fHeaderBlocks = (float) ( hHeaderOne.WordsToFollow + 2 ) / 256;
     154                 : 
     155              73 :     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              73 :     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              73 :     if( poOpenInfo->eAccess == GA_ReadOnly  )
     173                 :     {
     174              41 :         fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
     175                 :     } 
     176                 :     else 
     177                 :     {
     178              32 :         fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );
     179                 :     }
     180                 : 
     181              73 :     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              73 :     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              73 :     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              73 :     poDS = new IntergraphDataset();
     272              73 :     poDS->eAccess = poOpenInfo->eAccess;
     273              73 :     poDS->pszFilename = CPLStrdup( poOpenInfo->pszFilename );
     274              73 :     poDS->fp = fp;
     275                 : 
     276                 :     // -------------------------------------------------------------------- 
     277                 :     // Get X Size from Pixels Per Line (PPL)
     278                 :     // -------------------------------------------------------------------- 
     279                 : 
     280              73 :     poDS->nRasterXSize = hHeaderOne.PixelsPerLine;
     281                 : 
     282                 :     // -------------------------------------------------------------------- 
     283                 :     // Get Y Size from Number of Lines (NOL)
     284                 :     // -------------------------------------------------------------------- 
     285                 : 
     286              73 :     poDS->nRasterYSize = hHeaderOne.NumberOfLines;
     287                 : 
     288             146 :     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              73 :     INGR_GetTransMatrix( &hHeaderOne, poDS->adfGeoTransform );
     302                 : 
     303                 :     // -------------------------------------------------------------------- 
     304                 :     // Set Metadata Information
     305                 :     // -------------------------------------------------------------------- 
     306                 : 
     307                 :     poDS->SetMetadataItem( "VERSION", 
     308              73 :         CPLSPrintf ( "%d", hHeaderOne.GridFileVersion ), "IMAGE_STRUCTURE" );
     309                 : 
     310                 :     // -------------------------------------------------------------------- 
     311                 :     // Create Band Information
     312                 :     // -------------------------------------------------------------------- 
     313                 : 
     314              73 :     int nBands = 0;
     315              73 :     int nBandOffset = 0;
     316                 : 
     317                 :     GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_HDR2_A)];
     318                 : 
     319              73 :     do
     320                 :     {
     321              73 :         VSIFSeekL( poDS->fp, nBandOffset, SEEK_SET );
     322                 : 
     323              73 :         VSIFReadL( abyBuf, 1, SIZEOF_HDR1, poDS->fp );
     324                 : 
     325              73 :         INGR_HeaderOneDiskToMem( &poDS->hHeaderOne, abyBuf );
     326                 : 
     327              73 :         VSIFReadL( abyBuf, 1, SIZEOF_HDR2_A, poDS->fp );
     328                 : 
     329              73 :         INGR_HeaderTwoADiskToMem( &poDS->hHeaderTwo, abyBuf );
     330                 : 
     331              73 :         switch( eFormat )
     332                 :         {
     333                 :         case JPEGRGB:
     334                 :         case JPEGCYMK:
     335                 :         {
     336                 :             IntergraphBitmapBand* poBand;
     337               1 :             nBands++;
     338                 :             poDS->SetBand( nBands, 
     339               1 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 1 ));
     340               1 :             if (poBand->pabyBMPBlock == NULL)
     341                 :             {
     342               0 :                 delete poDS;
     343               0 :                 return NULL;
     344                 :             }
     345               1 :             nBands++;
     346                 :             poDS->SetBand( nBands, 
     347               1 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 2 ));
     348               1 :             if (poBand->pabyBMPBlock == NULL)
     349                 :             {
     350               0 :                 delete poDS;
     351               0 :                 return NULL;
     352                 :             }
     353               1 :             nBands++;
     354                 :             poDS->SetBand( nBands, 
     355               1 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 3 ));
     356               1 :             if (poBand->pabyBMPBlock == NULL)
     357                 :             {
     358               0 :                 delete poDS;
     359               0 :                 return NULL;
     360                 :             }
     361               1 :             break;
     362                 :         }
     363                 :         case JPEGGRAY:
     364                 :         case CCITTGroup4:
     365                 :         {
     366                 :             IntergraphBitmapBand* poBand;
     367               2 :             nBands++;
     368                 :             poDS->SetBand( nBands, 
     369               2 :                 poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset ));
     370               2 :             if (poBand->pabyBMPBlock == NULL)
     371                 :             {
     372               0 :                 delete poDS;
     373               0 :                 return NULL;
     374                 :             }
     375               2 :             break;
     376                 :         }
     377                 :         case RunLengthEncoded:
     378                 :         case RunLengthEncodedC:
     379                 :         case AdaptiveGrayScale:
     380                 :         {
     381                 :             IntergraphRLEBand* poBand;
     382               4 :             nBands++;
     383                 :             poDS->SetBand( nBands, 
     384               4 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset ));
     385               8 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     386                 :             {
     387               0 :                 delete poDS;
     388               0 :                 return NULL;
     389                 :             }
     390               4 :             break;
     391                 :         }
     392                 :         case AdaptiveRGB:
     393                 :         case ContinuousTone:
     394                 :         {
     395                 :             IntergraphRLEBand* poBand;
     396               1 :             nBands++;
     397                 :             poDS->SetBand( nBands, 
     398               1 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 1 ));
     399               2 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     400                 :             {
     401               0 :                 delete poDS;
     402               0 :                 return NULL;
     403                 :             }
     404               1 :             nBands++;
     405                 :             poDS->SetBand( nBands, 
     406               1 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 2 ));
     407               2 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     408                 :             {
     409               0 :                 delete poDS;
     410               0 :                 return NULL;
     411                 :             }
     412               1 :             nBands++;
     413                 :             poDS->SetBand( nBands, 
     414               1 :                 poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 3 ));
     415               2 :             if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL)
     416                 :             {
     417               0 :                 delete poDS;
     418               0 :                 return NULL;
     419                 :             }
     420               1 :             break;
     421                 :         }
     422                 :         case Uncompressed24bit:
     423                 :         {
     424                 :             IntergraphRGBBand* poBand;
     425               5 :             nBands++;
     426                 :             poDS->SetBand( nBands, 
     427               5 :                 poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 1 ));
     428               5 :             if (poBand->pabyBlockBuf == NULL)
     429                 :             {
     430               0 :                 delete poDS;
     431               0 :                 return NULL;
     432                 :             }
     433               5 :             nBands++;
     434                 :             poDS->SetBand( nBands, 
     435               5 :                 poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 2 ));
     436               5 :             if (poBand->pabyBlockBuf == NULL)
     437                 :             {
     438               0 :                 delete poDS;
     439               0 :                 return NULL;
     440                 :             }
     441               5 :             nBands++;
     442                 :             poDS->SetBand( nBands, 
     443               5 :                 poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 3 ));
     444               5 :             if (poBand->pabyBlockBuf == NULL)
     445                 :             {
     446               0 :                 delete poDS;
     447               0 :                 return NULL;
     448                 :             }
     449               5 :             break;
     450                 :         }
     451                 :         default:
     452                 :         {
     453                 :             IntergraphRasterBand* poBand;
     454              60 :             nBands++;
     455                 :             poDS->SetBand( nBands, 
     456              60 :                 poBand = new IntergraphRasterBand( poDS, nBands, nBandOffset ));
     457              60 :             if (poBand->pabyBlockBuf == NULL)
     458                 :             {
     459               0 :                 delete poDS;
     460               0 :                 return NULL;
     461                 :             }
     462                 :         }
     463                 :         }
     464                 : 
     465                 :         // ----------------------------------------------------------------
     466                 :         // Get next band offset from Catenated File Pointer (CFP)
     467                 :         // ----------------------------------------------------------------
     468                 : 
     469              73 :         nBandOffset = poDS->hHeaderTwo.CatenatedFilePointer;
     470                 :     }
     471                 :     while( nBandOffset != 0 );
     472                 : 
     473              73 :     poDS->nBands = nBands;
     474                 : 
     475                 :     // -------------------------------------------------------------------- 
     476                 :     // Initialize any PAM information                                 
     477                 :     // -------------------------------------------------------------------- 
     478                 : 
     479              73 :     poDS->SetDescription( poOpenInfo->pszFilename );
     480              73 :     poDS->TryLoadXML();
     481                 : 
     482                 :     /* -------------------------------------------------------------------- */
     483                 :     /*      Check for external overviews.                                   */
     484                 :     /* -------------------------------------------------------------------- */
     485                 : 
     486              73 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     487                 : 
     488              73 :     return ( poDS );
     489                 : }
     490                 : 
     491                 : //  ----------------------------------------------------------------------------
     492                 : //                                                   IntergraphDataset::Create()
     493                 : //  ----------------------------------------------------------------------------
     494                 : 
     495              46 : GDALDataset *IntergraphDataset::Create( const char *pszFilename,
     496                 :                                         int nXSize, 
     497                 :                                         int nYSize, 
     498                 :                                         int nBands, 
     499                 :                                         GDALDataType eType,
     500                 :                                         char **papszOptions )
     501                 : {
     502                 :     (void) papszOptions;
     503                 : 
     504              46 :     if( eType != GDT_Byte &&
     505                 :         eType != GDT_Int16 && 
     506                 :         eType != GDT_Int32 && 
     507                 :         eType != GDT_UInt16 && 
     508                 :         eType != GDT_UInt32 && 
     509                 :         eType != GDT_Float32&& 
     510                 :         eType != GDT_Float64 )
     511                 :     {
     512                 :         CPLError( CE_Failure, CPLE_AppDefined, "Data type not supported (%s)",
     513              12 :             GDALGetDataTypeName( eType ) );
     514              12 :         return NULL;
     515                 :     }
     516                 : 
     517                 :     // -------------------------------------------------------------------- 
     518                 :     //  Fill headers with minimun information
     519                 :     // -------------------------------------------------------------------- 
     520                 : 
     521                 :     INGR_HeaderOne  hHdr1;
     522                 :     INGR_HeaderTwoA hHdr2;
     523                 :     INGR_ColorTable256 hCTab;
     524                 :     int             i;
     525                 :     
     526              34 :     memset(&hHdr1, 0, SIZEOF_HDR1);
     527              34 :     memset(&hHdr2, 0, SIZEOF_HDR2_A);
     528              34 :     memset(&hCTab, 0, SIZEOF_CTAB);
     529                 : 
     530              34 :     hHdr1.HeaderType.Version    = INGR_HEADER_VERSION;
     531              34 :     hHdr1.HeaderType.Type       = INGR_HEADER_TYPE;
     532              34 :     hHdr1.HeaderType.Is2Dor3D   = INGR_HEADER_2D;
     533              34 :     hHdr1.DataTypeCode          = (uint16) INGR_GetFormat( eType, "None" );
     534              34 :     hHdr1.WordsToFollow         = ( ( SIZEOF_HDR1 * 3 ) / 2 ) - 2;
     535              34 :     hHdr1.ApplicationType       = GenericRasterImageFile;
     536              34 :     hHdr1.XViewOrigin           = 0.0;
     537              34 :     hHdr1.YViewOrigin           = 0.0;
     538              34 :     hHdr1.ZViewOrigin           = 0.0;
     539              34 :     hHdr1.XViewExtent           = 0.0;
     540              34 :     hHdr1.YViewExtent           = 0.0;
     541              34 :     hHdr1.ZViewExtent           = 0.0;
     542             544 :     for( i = 0; i < 15; i++ )
     543             510 :         hHdr1.TransformationMatrix[i]   = 0.0;
     544              34 :     hHdr1.TransformationMatrix[15]      = 1.0;
     545              34 :     hHdr1.PixelsPerLine         = nXSize;
     546              34 :     hHdr1.NumberOfLines         = nYSize;
     547              34 :     hHdr1.DeviceResolution      = 1;
     548              34 :     hHdr1.ScanlineOrientation   = UpperLeftHorizontal;
     549              34 :     hHdr1.ScannableFlag         = NoLineHeader;
     550              34 :     hHdr1.RotationAngle         = 0.0;
     551              34 :     hHdr1.SkewAngle             = 0.0;
     552              34 :     hHdr1.DataTypeModifier      = 0;
     553              34 :     hHdr1.DesignFileName[0]     = '\0';
     554              34 :     hHdr1.DataBaseFileName[0]   = '\0';
     555              34 :     hHdr1.ParentGridFileName[0] = '\0';
     556              34 :     hHdr1.FileDescription[0]    = '\0';
     557              34 :     hHdr1.Minimum               = INGR_SetMinMax( eType, 0.0 );
     558              34 :     hHdr1.Maximum               = INGR_SetMinMax( eType, 0.0 );
     559              34 :     hHdr1.GridFileVersion       = 3;
     560              34 :     hHdr1.Reserved[0]           = 0;
     561              34 :     hHdr1.Reserved[1]           = 0;
     562              34 :     hHdr1.Reserved[2]           = 0;
     563              34 :     hHdr2.Gain                  = 0;
     564              34 :     hHdr2.OffsetThreshold       = 0;
     565              34 :     hHdr2.View1                 = 0;
     566              34 :     hHdr2.View2                 = 0;
     567              34 :     hHdr2.ViewNumber            = 0;
     568              34 :     hHdr2.Reserved2             = 0;
     569              34 :     hHdr2.Reserved3             = 0;
     570              34 :     hHdr2.AspectRatio           = nXSize / nYSize;
     571              34 :     hHdr2.CatenatedFilePointer  = 0;
     572              34 :     hHdr2.ColorTableType        = NoColorTable;
     573              34 :     hHdr2.NumberOfCTEntries     = 0;
     574              34 :     hHdr2.Reserved8             = 0;
     575            3774 :     for( i = 0; i < 110; i++ )
     576            3740 :         hHdr2.Reserved[i]       = 0;
     577              34 :     hHdr2.ApplicationPacketLength   = 0;
     578              34 :     hHdr2.ApplicationPacketPointer  = 0;
     579                 : 
     580                 :     // -------------------------------------------------------------------- 
     581                 :     //  RGB Composite assumption
     582                 :     // -------------------------------------------------------------------- 
     583                 : 
     584              34 :     if( eType  == GDT_Byte  &&
     585                 :         nBands == 3 )
     586                 :     {
     587               2 :         hHdr1.DataTypeCode = Uncompressed24bit;
     588                 :     }
     589                 : 
     590                 :     // -------------------------------------------------------------------- 
     591                 :     //  Create output file with minimum header info
     592                 :     // -------------------------------------------------------------------- 
     593                 : 
     594              34 :     VSILFILE *fp = VSIFOpenL( pszFilename, "wb+" );
     595                 : 
     596              34 :     if( fp == NULL )
     597                 :     {
     598                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     599               2 :             "Attempt to create file %s' failed.\n", pszFilename );
     600               2 :         return NULL;
     601                 :     }
     602                 : 
     603                 :     GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_CTAB)];
     604                 : 
     605              32 :     INGR_HeaderOneMemToDisk( &hHdr1, abyBuf );
     606                 : 
     607              32 :     VSIFWriteL( abyBuf, 1, SIZEOF_HDR1, fp );
     608                 : 
     609              32 :     INGR_HeaderTwoAMemToDisk( &hHdr2, abyBuf );
     610                 : 
     611              32 :     VSIFWriteL( abyBuf, 1, SIZEOF_HDR2_A, fp );
     612                 : 
     613              32 :     unsigned int n = 0;
     614                 : 
     615            8224 :     for( i = 0; i < 256; i++ )
     616                 :     {
     617            8192 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_red );
     618            8192 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_green );
     619            8192 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_blue );
     620                 :     }
     621                 : 
     622              32 :     VSIFWriteL( abyBuf, 1, SIZEOF_CTAB, fp );
     623                 : 
     624              32 :     VSIFCloseL( fp );
     625                 : 
     626                 :     // -------------------------------------------------------------------- 
     627                 :     //  Returns a new IntergraphDataset from the created file
     628                 :     // -------------------------------------------------------------------- 
     629                 : 
     630              32 :     return ( IntergraphDataset * ) GDALOpen( pszFilename, GA_Update );
     631                 : }
     632                 : 
     633                 : //  ----------------------------------------------------------------------------
     634                 : //                                               IntergraphDataset::CreateCopy()
     635                 : //  ----------------------------------------------------------------------------
     636                 : 
     637              19 : GDALDataset *IntergraphDataset::CreateCopy( const char *pszFilename, 
     638                 :                                            GDALDataset *poSrcDS,
     639                 :                                            int bStrict,
     640                 :                                            char **papszOptions,
     641                 :                                            GDALProgressFunc pfnProgress, 
     642                 :                                            void *pProgressData )
     643                 : {
     644                 :     (void) bStrict;
     645                 : 
     646              19 :     int nBands = poSrcDS->GetRasterCount();
     647              19 :     if (nBands == 0)
     648                 :     {
     649                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     650               1 :                   "Intergraph driver does not support source dataset with zero band.\n");
     651               1 :         return NULL;
     652                 :     }
     653                 : 
     654              18 :     if( !pfnProgress( 0.0, NULL, pProgressData ) )
     655                 :     {
     656               0 :         return NULL;
     657                 :     }
     658                 : 
     659                 :     // -------------------------------------------------------------------- 
     660                 :     // Query GDAL Data Type 
     661                 :     // -------------------------------------------------------------------- 
     662                 : 
     663              18 :     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     664                 : 
     665                 :     // -------------------------------------------------------------------- 
     666                 :     // Create IntergraphDataset
     667                 :     // -------------------------------------------------------------------- 
     668                 : 
     669                 :     IntergraphDataset *poDstDS;
     670                 : 
     671                 :     poDstDS = (IntergraphDataset*) IntergraphDataset::Create( pszFilename, 
     672                 :         poSrcDS->GetRasterXSize(), 
     673                 :         poSrcDS->GetRasterYSize(), 
     674                 :         poSrcDS->GetRasterCount(), 
     675                 :         eType, 
     676              18 :         papszOptions );
     677                 : 
     678              18 :     if( poDstDS == NULL )
     679                 :     {
     680               6 :         return NULL;
     681                 :     }
     682                 : 
     683                 :     // -------------------------------------------------------------------- 
     684                 :     // Copy Transformation Matrix to the dataset
     685                 :     // -------------------------------------------------------------------- 
     686                 : 
     687                 :     double adfGeoTransform[6];
     688                 : 
     689              12 :     poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
     690              12 :     poSrcDS->GetGeoTransform( adfGeoTransform );
     691              12 :     poDstDS->SetGeoTransform( adfGeoTransform );
     692                 : 
     693                 :     // -------------------------------------------------------------------- 
     694                 :     // Copy information to the raster band
     695                 :     // -------------------------------------------------------------------- 
     696                 : 
     697                 :     GDALRasterBand *poSrcBand;
     698                 :     GDALRasterBand *poDstBand;
     699                 :     double dfMin;
     700                 :     double dfMax;
     701                 :     double dfMean;
     702              12 :     double dfStdDev = -1;
     703                 :     
     704              26 :     for( int i = 1; i <= poDstDS->nBands; i++)
     705                 :     {
     706              14 :         delete poDstDS->GetRasterBand(i);
     707                 :     }
     708              12 :     poDstDS->nBands = 0;
     709                 : 
     710              12 :     if( poDstDS->hHeaderOne.DataTypeCode == Uncompressed24bit )
     711                 :     {
     712               1 :         poDstDS->SetBand( 1, new IntergraphRGBBand( poDstDS, 1, 0, 3 ) );
     713               2 :         poDstDS->SetBand( 2, new IntergraphRGBBand( poDstDS, 2, 0, 2 ) );
     714               2 :         poDstDS->SetBand( 3, new IntergraphRGBBand( poDstDS, 3, 0, 1 ) );
     715               1 :         poDstDS->nBands = 3;
     716                 :     }
     717                 :     else
     718                 :     {
     719              60 :         for( int i = 1; i <= poSrcDS->GetRasterCount(); i++ )
     720                 :         {
     721              19 :             poSrcBand = poSrcDS->GetRasterBand(i);
     722              19 :             eType = poSrcDS->GetRasterBand(i)->GetRasterDataType();
     723                 : 
     724              19 :             poDstBand = new IntergraphRasterBand( poDstDS, i, 0, eType );
     725              19 :             poDstDS->SetBand( i, poDstBand );
     726                 : 
     727              19 :             poDstBand->SetCategoryNames( poSrcBand->GetCategoryNames() );
     728              19 :             poDstBand->SetColorTable( poSrcBand->GetColorTable() );
     729              19 :             poSrcBand->GetStatistics( false, true, &dfMin, &dfMax, &dfMean, &dfStdDev );
     730              19 :             poDstBand->SetStatistics( dfMin, dfMax, dfMean, dfStdDev );
     731                 :         }
     732                 :     }
     733                 : 
     734                 :     // -------------------------------------------------------------------- 
     735                 :     // Copy image data
     736                 :     // -------------------------------------------------------------------- 
     737                 : 
     738              12 :     int nXSize = poDstDS->GetRasterXSize();
     739              12 :     int nYSize = poDstDS->GetRasterYSize();
     740                 : 
     741                 :     int nBlockXSize;
     742                 :     int nBlockYSize;
     743                 : 
     744              12 :     CPLErr eErr = CE_None;
     745                 : 
     746              34 :     for( int iBand = 1; iBand <= poSrcDS->GetRasterCount(); iBand++ )
     747                 :     {
     748              22 :         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand );
     749              22 :         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand );
     750                 : 
     751                 :         // ------------------------------------------------------------
     752                 :         // Copy Untiled / Uncompressed
     753                 :         // ------------------------------------------------------------
     754                 : 
     755                 :         int   iYOffset, iXOffset;
     756                 :         void *pData;
     757                 : 
     758              22 :         poSrcBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
     759                 : 
     760              22 :         nBlockXSize = nXSize;
     761              22 :         nBlockYSize = 1;
     762                 : 
     763              22 :         pData = CPLMalloc( nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eType ) / 8 );
     764                 : 
     765             382 :         for( iYOffset = 0; iYOffset < nYSize; iYOffset += nBlockYSize )
     766                 :         {
     767             720 :             for( iXOffset = 0; iXOffset < nXSize; iXOffset += nBlockXSize )
     768                 :             {
     769                 :                 eErr = poSrcBand->RasterIO( GF_Read, 
     770                 :                     iXOffset, iYOffset, 
     771                 :                     nBlockXSize, nBlockYSize,
     772                 :                     pData, nBlockXSize, nBlockYSize,
     773             360 :                     eType, 0, 0 );
     774             360 :                 if( eErr != CE_None )
     775                 :                 {
     776               0 :                     return NULL;
     777                 :                 }
     778                 :                 eErr = poDstBand->RasterIO( GF_Write, 
     779                 :                     iXOffset, iYOffset, 
     780                 :                     nBlockXSize, nBlockYSize,
     781                 :                     pData, nBlockXSize, nBlockYSize,
     782             360 :                     eType, 0, 0 );
     783             360 :                 if( eErr != CE_None )
     784                 :                 {
     785               0 :                     return NULL;
     786                 :                 }
     787                 :             }
     788             360 :             if( ( eErr == CE_None ) && ( ! pfnProgress( 
     789                 :                 ( iYOffset + 1 ) / ( double ) nYSize, NULL, pProgressData ) ) )
     790                 :             {
     791               0 :                 eErr = CE_Failure;
     792               0 :                 CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" );
     793                 :             }
     794                 :         }
     795              22 :         CPLFree( pData );
     796                 :     }
     797                 : 
     798                 :     // -------------------------------------------------------------------- 
     799                 :     // Finalize
     800                 :     // -------------------------------------------------------------------- 
     801                 : 
     802              12 :     poDstDS->FlushCache();
     803                 : 
     804              12 :     return poDstDS;
     805                 : }
     806                 : 
     807                 : //  ----------------------------------------------------------------------------
     808                 : //                                          IntergraphDataset::GetGeoTransform()
     809                 : //  ----------------------------------------------------------------------------
     810                 : 
     811              20 : CPLErr  IntergraphDataset::GetGeoTransform( double *padfTransform )
     812                 : {
     813              20 :     if( GDALPamDataset::GetGeoTransform( padfTransform ) != CE_None )
     814                 :     {
     815               2 :         memcpy( padfTransform, adfGeoTransform, sizeof( double ) * 6 );
     816                 :     }
     817                 : 
     818              20 :     return CE_None;
     819                 : }
     820                 : 
     821                 : //  ----------------------------------------------------------------------------
     822                 : //                                          IntergraphDataset::SetGeoTransform()
     823                 : //  ----------------------------------------------------------------------------
     824                 : 
     825              30 : CPLErr IntergraphDataset::SetGeoTransform( double *padfTransform )
     826                 : {
     827              30 :     if( GDALPamDataset::SetGeoTransform( padfTransform ) != CE_None )
     828                 :     {
     829               0 :         memcpy( adfGeoTransform, padfTransform, sizeof( double ) * 6 );
     830                 :     }
     831                 : 
     832              30 :     INGR_SetTransMatrix( hHeaderOne.TransformationMatrix, padfTransform );
     833                 : 
     834              30 :     return CE_None;
     835                 : }
     836                 : 
     837                 : //  ----------------------------------------------------------------------------
     838                 : //                                            IntergraphDataset::SetProjection()
     839                 : //  ----------------------------------------------------------------------------
     840                 : 
     841              30 : CPLErr IntergraphDataset::SetProjection( const char *pszProjString )
     842                 : {   
     843                 :     (void) pszProjString;
     844                 : 
     845              30 :     return CE_None;
     846                 : }
     847                 : 
     848                 : //  ----------------------------------------------------------------------------
     849                 : //                                                           GDALRegister_INGR()
     850                 : //  ----------------------------------------------------------------------------
     851                 : 
     852             582 : void GDALRegister_INGR()
     853                 : {
     854                 :     GDALDriver  *poDriver;
     855                 : 
     856             582 :     if( GDALGetDriverByName( "INGR" ) == NULL )
     857                 :     {
     858             561 :         poDriver = new GDALDriver();
     859                 : 
     860             561 :         poDriver->SetDescription( "INGR" );
     861             561 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "Intergraph Raster" );
     862             561 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "frmt_IntergraphRaster.html" );
     863             561 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     864                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     865             561 :             "Byte Int16 Int32 Float32 Float64" );
     866             561 :         poDriver->pfnOpen = IntergraphDataset::Open;
     867             561 :         poDriver->pfnCreate    = IntergraphDataset::Create;
     868             561 :         poDriver->pfnCreateCopy = IntergraphDataset::CreateCopy;
     869             561 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     870                 :     }
     871             582 : }

Generated by: LCOV version 1.7