LCOV - code coverage report
Current view: directory - frmts/ingr - IntergraphBand.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 410 309 75.4 %
Date: 2013-03-30 Functions: 34 22 64.7 %

       1                 : /*****************************************************************************
       2                 :  * $Id: IntergraphBand.cpp 25785 2013-03-23 11:34:53Z rouault $
       3                 :  *
       4                 :  * Project:  Intergraph Raster Format support
       5                 :  * Purpose:  Read/Write Intergraph Raster Format, band 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                 : #include "math.h"
      38                 : 
      39                 : #include "IntergraphDataset.h"
      40                 : #include "IntergraphBand.h"
      41                 : #include "IngrTypes.h"
      42                 : 
      43                 : //  ----------------------------------------------------------------------------
      44                 : //                                  IntergraphRasterBand::IntergraphRasterBand()
      45                 : //  ----------------------------------------------------------------------------
      46                 : 
      47             114 : IntergraphRasterBand::IntergraphRasterBand( IntergraphDataset *poDS, 
      48                 :                                             int nBand,
      49                 :                                             int nBandOffset,
      50             114 :                                             GDALDataType eType )
      51                 : {
      52             114 :     this->poColorTable  = new GDALColorTable();
      53                 : 
      54             114 :     this->poDS          = poDS;
      55             114 :     this->nBand         = nBand != 0 ? nBand : poDS->nBands;
      56             114 :     this->nTiles        = 0;
      57             114 :     this->eDataType     = eType;
      58             114 :     this->pabyBlockBuf  = NULL;
      59             114 :     this->pahTiles      = NULL;
      60             114 :     this->nRGBIndex     = 0;
      61             114 :     this->nBandStart    = nBandOffset;
      62             114 :     this->bTiled        = FALSE;
      63                 : 
      64                 :     // -------------------------------------------------------------------- 
      65                 :     // Get Header Info
      66                 :     // -------------------------------------------------------------------- 
      67                 : 
      68             114 :     memcpy(&hHeaderOne, &poDS->hHeaderOne, sizeof(hHeaderOne));
      69             114 :     memcpy(&hHeaderTwo, &poDS->hHeaderTwo, sizeof(hHeaderTwo));
      70                 : 
      71                 :     // -------------------------------------------------------------------- 
      72                 :     // Get the image start from Words to Follow (WTF)
      73                 :     // -------------------------------------------------------------------- 
      74                 : 
      75             114 :     nDataOffset = nBandOffset + 2 + ( 2 * ( hHeaderOne.WordsToFollow + 1 ) );
      76                 : 
      77                 :     // -------------------------------------------------------------------- 
      78                 :     // Get Color Tabel from Color Table Type (CTV)
      79                 :     // -------------------------------------------------------------------- 
      80                 : 
      81             114 :     uint32 nEntries = hHeaderTwo.NumberOfCTEntries;
      82                 : 
      83             114 :     if( nEntries > 0 )
      84                 :     {
      85               8 :         switch ( hHeaderTwo.ColorTableType )
      86                 :         {
      87                 :         case EnvironVColorTable:
      88               6 :             INGR_GetEnvironVColors( poDS->fp, nBandOffset, nEntries, poColorTable );
      89               6 :             if (poColorTable->GetColorEntryCount() == 0)
      90               0 :                 return;
      91               6 :             break;
      92                 :         case IGDSColorTable:
      93               2 :             INGR_GetIGDSColors( poDS->fp, nBandOffset, nEntries, poColorTable );
      94               2 :             if (poColorTable->GetColorEntryCount() == 0)
      95               0 :                 return;
      96               2 :             break;
      97                 :         default:
      98                 :             CPLDebug( "INGR", "Wrong Color table type (%d), number of colors (%d)", 
      99               0 :                 hHeaderTwo.ColorTableType, nEntries );
     100                 :         }
     101                 :     }
     102                 : 
     103                 :     // -------------------------------------------------------------------- 
     104                 :     // Set Dimension
     105                 :     // -------------------------------------------------------------------- 
     106                 : 
     107             114 :     nRasterXSize  = hHeaderOne.PixelsPerLine;
     108             114 :     nRasterYSize  = hHeaderOne.NumberOfLines;
     109                 :     
     110             114 :     nBlockXSize   = nRasterXSize;
     111             114 :     nBlockYSize   = 1;
     112                 : 
     113                 :     // -------------------------------------------------------------------- 
     114                 :     // Get tile directory
     115                 :     // -------------------------------------------------------------------- 
     116                 : 
     117             114 :     this->eFormat = (INGR_Format) hHeaderOne.DataTypeCode;
     118                 : 
     119             114 :     this->bTiled = (hHeaderOne.DataTypeCode == TiledRasterData);
     120                 : 
     121             114 :     if( bTiled )
     122                 :     {
     123                 :         nTiles = INGR_GetTileDirectory( poDS->fp, 
     124                 :                                         nDataOffset, 
     125                 :                                         nRasterXSize, 
     126                 :                                         nRasterYSize,
     127                 :                                         &hTileDir, 
     128               5 :                                         &pahTiles );
     129               5 :         if (nTiles == 0)
     130               0 :             return;
     131                 : 
     132               5 :         eFormat = (INGR_Format) hTileDir.DataTypeCode;
     133                 : 
     134                 :         // ----------------------------------------------------------------
     135                 :         // Set blocks dimensions based on tiles
     136                 :         // ----------------------------------------------------------------
     137               5 :         nBlockXSize = hTileDir.TileSize;
     138               5 :         nBlockYSize = hTileDir.TileSize;
     139                 :     }
     140                 : 
     141             114 :     if (nBlockXSize <= 0 || nBlockYSize <= 0)
     142                 :     {
     143               0 :         pabyBlockBuf = NULL;
     144               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Invalid block dimensions");
     145               0 :         return;
     146                 :     }
     147                 : 
     148                 :     // -------------------------------------------------------------------- 
     149                 :     // Incomplete tiles have Block Offset greater than: 
     150                 :     // -------------------------------------------------------------------- 
     151                 : 
     152             114 :     nFullBlocksX  = ( nRasterXSize / nBlockXSize );
     153             114 :     nFullBlocksY  = ( nRasterYSize / nBlockYSize );
     154                 : 
     155                 :     // -------------------------------------------------------------------- 
     156                 :     // Get the Data Type from Format
     157                 :     // -------------------------------------------------------------------- 
     158                 : 
     159             114 :     this->eDataType = INGR_GetDataType( (uint16) eFormat );
     160                 : 
     161                 :     // -------------------------------------------------------------------- 
     162                 :     // Allocate buffer for a Block of data
     163                 :     // -------------------------------------------------------------------- 
     164                 : 
     165                 :     nBlockBufSize = nBlockXSize * nBlockYSize * 
     166             114 :                     GDALGetDataTypeSize( eDataType ) / 8;
     167                 : 
     168             114 :     if (eFormat == RunLengthEncoded)    
     169                 :     {
     170                 :         pabyBlockBuf = (GByte*) VSIMalloc3( nBlockXSize*4+2, nBlockYSize,
     171               7 :                                             GDALGetDataTypeSize( eDataType ) / 8);
     172                 :     }
     173                 :     else
     174                 :     {
     175                 :         pabyBlockBuf = (GByte*) VSIMalloc3( nBlockXSize, nBlockYSize,
     176             107 :                                             GDALGetDataTypeSize( eDataType ) / 8);
     177                 :     }
     178                 : 
     179             114 :     if (pabyBlockBuf == NULL)
     180                 :     {
     181               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize);
     182               0 :         return;
     183                 :     }
     184                 : 
     185                 :     // -------------------------------------------------------------------- 
     186                 :     // More Metadata Information
     187                 :     // -------------------------------------------------------------------- 
     188                 : 
     189                 :     SetMetadataItem( "FORMAT", INGR_GetFormatName( (uint16) eFormat ), 
     190             114 :         "IMAGE_STRUCTURE" );
     191                 : 
     192             114 :     if( bTiled )
     193                 :     {
     194                 :         SetMetadataItem( "TILESSIZE", CPLSPrintf ("%d", hTileDir.TileSize), 
     195               5 :             "IMAGE_STRUCTURE" );
     196                 :     }
     197                 :     else
     198                 :     {
     199             109 :         SetMetadataItem( "TILED", "NO", "IMAGE_STRUCTURE" ); 
     200                 :     }
     201                 : 
     202                 :     SetMetadataItem( "ORIENTATION", 
     203                 :         INGR_GetOrientation( hHeaderOne.ScanlineOrientation ),
     204             114 :         "IMAGE_STRUCTURE" );
     205                 : 
     206             114 :     if( eFormat == PackedBinary ||
     207                 :         eFormat == RunLengthEncoded ||
     208                 :         eFormat == CCITTGroup4 )
     209                 :     {
     210               8 :         SetMetadataItem( "NBITS", "1", "IMAGE_STRUCTURE" );
     211                 :     }
     212                 : 
     213             114 :     this->nRLEOffset = 0;
     214               0 : }
     215                 : 
     216                 : //  ----------------------------------------------------------------------------
     217                 : //                                 IntergraphRasterBand::~IntergraphRasterBand()
     218                 : //  ----------------------------------------------------------------------------
     219                 : 
     220             114 : IntergraphRasterBand::~IntergraphRasterBand()
     221                 : {
     222             114 :     if( pabyBlockBuf )
     223                 :     {
     224             114 :         CPLFree( pabyBlockBuf );
     225                 :     }
     226                 : 
     227             114 :     if( pahTiles )
     228                 :     {
     229               5 :         CPLFree( pahTiles );
     230                 :     }
     231                 : 
     232             114 :     if( poColorTable )
     233                 :     {
     234             114 :         delete poColorTable;
     235                 :     }
     236             114 : }
     237                 : 
     238                 : //  ----------------------------------------------------------------------------
     239                 : //                                            IntergraphRasterBand::GetMinimum()
     240                 : //  ----------------------------------------------------------------------------
     241                 : 
     242               0 : double IntergraphRasterBand::GetMinimum( int *pbSuccess )
     243                 : {
     244                 : 
     245               0 :     double dMinimum = INGR_GetMinMax( eDataType, hHeaderOne.Minimum ); 
     246               0 :     double dMaximum = INGR_GetMinMax( eDataType, hHeaderOne.Maximum ); 
     247                 : 
     248               0 :     if( pbSuccess )
     249                 :     {
     250               0 :         *pbSuccess = dMinimum == dMaximum ? FALSE : TRUE;
     251                 :     }
     252                 : 
     253               0 :     return dMinimum;
     254                 : }
     255                 : 
     256                 : //  ----------------------------------------------------------------------------
     257                 : //                                            IntergraphRasterBand::GetMaximum()
     258                 : //  ----------------------------------------------------------------------------
     259                 : 
     260               0 : double IntergraphRasterBand::GetMaximum( int *pbSuccess )
     261                 : {
     262               0 :     double dMinimum = INGR_GetMinMax( eDataType, hHeaderOne.Minimum ); 
     263               0 :     double dMaximum = INGR_GetMinMax( eDataType, hHeaderOne.Maximum ); 
     264                 : 
     265               0 :     if( pbSuccess )
     266                 :     {
     267               0 :         *pbSuccess = dMinimum == dMaximum ? FALSE : TRUE;
     268                 :     }
     269                 : 
     270               0 :     return dMaximum;
     271                 : }
     272                 : 
     273                 : //  ----------------------------------------------------------------------------
     274                 : //                                IntergraphRasterBand::GetColorInterpretation()
     275                 : //  ----------------------------------------------------------------------------
     276                 : 
     277               0 : GDALColorInterp IntergraphRasterBand::GetColorInterpretation()
     278                 : {
     279               0 :     if( eFormat == AdaptiveRGB ||
     280                 :         eFormat == Uncompressed24bit || 
     281                 :         eFormat == ContinuousTone )
     282                 :     {               
     283               0 :         switch( nRGBIndex )
     284                 :         {
     285                 :         case 1: 
     286               0 :             return GCI_RedBand;
     287                 :         case 2: 
     288               0 :             return GCI_GreenBand;
     289                 :         case 3: 
     290               0 :             return GCI_BlueBand;
     291                 :         }
     292               0 :         return GCI_GrayIndex;
     293                 :     }
     294                 :     else
     295                 :     {
     296               0 :         if( poColorTable->GetColorEntryCount() > 0 )
     297                 :         {
     298               0 :             return GCI_PaletteIndex;
     299                 :         }
     300                 :         else
     301                 :         {
     302               0 :             return GCI_GrayIndex;
     303                 :         }
     304                 :     }
     305                 : 
     306                 : }
     307                 : 
     308                 : //  ----------------------------------------------------------------------------
     309                 : //                                         IntergraphRasterBand::GetColorTable()
     310                 : //  ----------------------------------------------------------------------------
     311                 : 
     312               3 : GDALColorTable *IntergraphRasterBand::GetColorTable()
     313                 : {
     314               3 :     if( poColorTable->GetColorEntryCount() == 0 )
     315                 :     {
     316               1 :         return NULL;
     317                 :     }
     318                 :     else
     319                 :     {
     320               2 :         return poColorTable;
     321                 :     }
     322                 : }
     323                 : 
     324                 : //  ----------------------------------------------------------------------------
     325                 : //                                         IntergraphRasterBand::SetColorTable()
     326                 : //  ----------------------------------------------------------------------------
     327                 : 
     328              20 : CPLErr IntergraphRasterBand::SetColorTable( GDALColorTable *poColorTable )
     329                 : {      
     330              20 :     if( poColorTable == NULL )
     331                 :     {
     332              19 :         return CE_None;
     333                 :     }
     334                 : 
     335               1 :     delete this->poColorTable;
     336               1 :     this->poColorTable = poColorTable->Clone();
     337                 : 
     338               1 :     return CE_None;
     339                 : }
     340                 : 
     341                 : //  ----------------------------------------------------------------------------
     342                 : //                                         IntergraphRasterBand::SetStatistics()
     343                 : //  ----------------------------------------------------------------------------
     344                 : 
     345              21 : CPLErr IntergraphRasterBand::SetStatistics( double dfMin, 
     346                 :                                             double dfMax, 
     347                 :                                             double dfMean, 
     348                 :                                             double dfStdDev )
     349                 : {      
     350              21 :     hHeaderOne.Minimum = INGR_SetMinMax( eDataType, dfMin );
     351              21 :     hHeaderOne.Maximum = INGR_SetMinMax( eDataType, dfMax );
     352                 :     
     353              21 :     return GDALRasterBand::SetStatistics( dfMin, dfMax, dfMean, dfStdDev );
     354                 : }
     355                 : 
     356                 : //  ----------------------------------------------------------------------------
     357                 : //                                            IntergraphRasterBand::IReadBlock()
     358                 : //  ----------------------------------------------------------------------------
     359                 : 
     360            1360 : CPLErr IntergraphRasterBand::IReadBlock( int nBlockXOff, 
     361                 :                                          int nBlockYOff,
     362                 :                                          void *pImage )
     363                 : {
     364                 :     // --------------------------------------------------------------------
     365                 :     // Load Block Buffer
     366                 :     // --------------------------------------------------------------------
     367            1360 :     if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage ))
     368               0 :         return CE_None;
     369                 : 
     370            1360 :     uint32 nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf );
     371                 : 
     372            1360 :     if( nBytesRead == 0 )
     373                 :     {
     374                 :         memset( pImage, 0, nBlockXSize * nBlockYSize * 
     375               0 :                     GDALGetDataTypeSize( eDataType ) / 8 );
     376                 :         CPLError( CE_Failure, CPLE_FileIO, 
     377                 :             "Can't read (%s) tile with X offset %d and Y offset %d.\n", 
     378               0 :             ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff );
     379               0 :         return CE_Failure;
     380                 :     }
     381                 : 
     382                 :     // --------------------------------------------------------------------
     383                 :     // Reshape blocks if needed
     384                 :     // --------------------------------------------------------------------
     385                 : 
     386            1360 :     if( nBlockXOff == nFullBlocksX || 
     387                 :         nBlockYOff == nFullBlocksY )
     388                 :     {
     389               0 :         ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf );
     390                 :     }
     391                 : 
     392                 :     // --------------------------------------------------------------------
     393                 :     // Copy block buffer to image
     394                 :     // --------------------------------------------------------------------
     395                 : 
     396                 :     memcpy( pImage, pabyBlockBuf, nBlockXSize * nBlockYSize * 
     397            1360 :         GDALGetDataTypeSize( eDataType ) / 8 );
     398                 : 
     399                 : #ifdef CPL_MSB
     400                 :     if( eDataType == GDT_Int16 || eDataType == GDT_UInt16)
     401                 :         GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize, 2  );
     402                 :     else if( eDataType == GDT_Int32 || eDataType == GDT_UInt32 || eDataType == GDT_Float32  )
     403                 :         GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4  );
     404                 :     else if (eDataType == GDT_Float64  )
     405                 :         GDALSwapWords( pImage, 8, nBlockXSize * nBlockYSize, 8  );
     406                 : #endif
     407                 : 
     408            1360 :     return CE_None;
     409                 : }
     410                 : 
     411                 : //  ----------------------------------------------------------------------------
     412                 : //                                        IntergraphRasterBand::HandleUninstantiatedTile()
     413                 : //  ----------------------------------------------------------------------------
     414                 : 
     415            1379 : int IntergraphRasterBand::HandleUninstantiatedTile(int nBlockXOff, 
     416                 :                                                    int nBlockYOff,
     417                 :                                                    void* pImage)
     418                 : {
     419            1379 :     if( bTiled && pahTiles[nBlockXOff + nBlockYOff * nBlocksPerRow].Start == 0 ) 
     420                 :     {
     421                 :         // ------------------------------------------------------------
     422                 :         // Uninstantieted tile, unique value
     423                 :         // ------------------------------------------------------------
     424               0 :         int nColor = pahTiles[nBlockXOff + nBlockYOff * nBlocksPerRow].Used;
     425               0 :         switch( GetColorInterpretation() )
     426                 :         {
     427                 :             case GCI_RedBand: 
     428               0 :                 nColor >>= 16; break;
     429                 :             case GCI_GreenBand: 
     430               0 :                 nColor >>= 8; break;
     431                 :             default:
     432                 :                 break;
     433                 :         }
     434                 :         memset( pImage, nColor, nBlockXSize * nBlockYSize * 
     435               0 :                     GDALGetDataTypeSize( eDataType ) / 8 );
     436               0 :         return TRUE;
     437                 :     }
     438                 :     else
     439            1379 :         return FALSE;
     440                 : }
     441                 : 
     442                 : //  ----------------------------------------------------------------------------
     443                 : //                                        IntergraphRGBBand::IntergraphRGBBand()
     444                 : //  ----------------------------------------------------------------------------
     445                 : 
     446              18 : IntergraphRGBBand::IntergraphRGBBand( IntergraphDataset *poDS, 
     447                 :                                      int nBand,
     448                 :                                      int nBandOffset,
     449                 :                                      int nRGorB )
     450              18 :     : IntergraphRasterBand( poDS, nBand, nBandOffset )
     451                 : {
     452              18 :     if (pabyBlockBuf == NULL)
     453               0 :         return;
     454                 : 
     455              18 :     nRGBIndex     = (uint8) nRGorB;
     456                 : 
     457                 :     // -------------------------------------------------------------------- 
     458                 :     // Reallocate buffer for a block of RGB Data
     459                 :     // -------------------------------------------------------------------- 
     460                 : 
     461              18 :     nBlockBufSize *= 3;
     462              18 :     CPLFree( pabyBlockBuf );
     463              18 :     pabyBlockBuf = (GByte*) VSIMalloc( nBlockBufSize );
     464              18 :     if (pabyBlockBuf == NULL)
     465                 :     {
     466               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize);
     467                 :     }
     468               0 : }
     469                 : 
     470                 : //  ----------------------------------------------------------------------------
     471                 : //                                               IntergraphRGBBand::IReadBlock()
     472                 : //  ----------------------------------------------------------------------------
     473                 : 
     474             120 : CPLErr IntergraphRGBBand::IReadBlock( int nBlockXOff, 
     475                 :                                       int nBlockYOff,
     476                 :                                       void *pImage )
     477                 : {
     478             120 :     if( IntergraphRasterBand::IReadBlock( nBlockXOff, 
     479                 :                                           nBlockYOff, 
     480                 :                                           pImage ) != CE_None )
     481                 :     {
     482               0 :         return CE_Failure;
     483                 :     }
     484                 : 
     485                 :     // --------------------------------------------------------------------
     486                 :     // Extract the band of interest from the block buffer
     487                 :     // --------------------------------------------------------------------
     488                 : 
     489                 :     int i, j;
     490                 : 
     491           15520 :     for ( i = 0, j = ( nRGBIndex - 1 ); 
     492                 :           i < ( nBlockXSize * nBlockYSize ); 
     493                 :           i++, j += 3 )
     494                 :     {
     495           15400 :         ( (GByte*) pImage )[i] = pabyBlockBuf[j];
     496                 :     }
     497                 : 
     498             120 :     return CE_None;
     499                 : }
     500                 : 
     501                 : //  ----------------------------------------------------------------------------
     502                 : //                                        IntergraphRLEBand::IntergraphRLEBand()
     503                 : //  ----------------------------------------------------------------------------
     504                 : 
     505              11 : IntergraphRLEBand::IntergraphRLEBand( IntergraphDataset *poDS, 
     506                 :                                      int nBand,
     507                 :                                      int nBandOffset,
     508                 :                                      int nRGorB )
     509              11 :     : IntergraphRasterBand( poDS, nBand, nBandOffset )
     510                 : {
     511              11 :     nRLESize         = 0;
     512              11 :     nRGBIndex        = (uint8) nRGorB;
     513              11 :     bRLEBlockLoaded  = FALSE;
     514              11 :     pabyRLEBlock     = NULL;
     515              11 :     panRLELineOffset = NULL;
     516                 : 
     517              11 :     if (pabyBlockBuf == NULL)
     518               0 :         return;
     519                 : 
     520              11 :     if( ! this->bTiled )
     521                 :     {
     522                 :         // ------------------------------------------------------------
     523                 :         // Load all rows at once
     524                 :         // ------------------------------------------------------------
     525                 : 
     526              10 :         nFullBlocksX = 1;
     527                 : 
     528              16 :         if( eFormat == RunLengthEncodedC || eFormat == RunLengthEncoded )
     529                 :         {
     530               6 :             nBlockYSize = 1;
     531                 :             panRLELineOffset = (uint32 *) 
     532               6 :                 CPLCalloc(sizeof(uint32),nRasterYSize);
     533               6 :             nFullBlocksY = nRasterYSize;
     534                 :         }
     535                 :         else
     536                 :         {
     537               4 :             nBlockYSize  = nRasterYSize;
     538               4 :             nFullBlocksY = 1;
     539                 :         }
     540                 : 
     541                 :         nRLESize     = INGR_GetDataBlockSize( poDS->pszFilename, 
     542                 :                           hHeaderTwo.CatenatedFilePointer,
     543              10 :                           nDataOffset);
     544                 : 
     545              10 :         nBlockBufSize = nBlockXSize * nBlockYSize;
     546                 :     }
     547                 :     else
     548                 :     {
     549                 :         // ------------------------------------------------------------
     550                 :         // Find the biggest tile
     551                 :         // ------------------------------------------------------------
     552                 : 
     553                 :         uint32 iTiles;
     554               5 :         for( iTiles = 0; iTiles < nTiles; iTiles++)
     555                 :         {
     556               4 :             nRLESize = MAX( pahTiles[iTiles].Used, nRLESize );
     557                 :         }
     558                 :     }
     559                 : 
     560                 :     // ----------------------------------------------------------------
     561                 :     // Realocate the decompressed Buffer 
     562                 :     // ----------------------------------------------------------------
     563                 : 
     564              11 :     if( eFormat == AdaptiveRGB ||
     565                 :         eFormat == ContinuousTone )
     566                 :     {
     567               3 :         nBlockBufSize *= 3;
     568                 :     }
     569                 : 
     570              11 :     CPLFree( pabyBlockBuf );
     571              11 :     pabyBlockBuf = (GByte*) VSIMalloc( nBlockBufSize );
     572              11 :     if (pabyBlockBuf == NULL)
     573                 :     {
     574               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize);
     575                 :     }
     576                 : 
     577                 :     // ----------------------------------------------------------------
     578                 :     // Create a RLE buffer
     579                 :     // ----------------------------------------------------------------
     580                 : 
     581              11 :     pabyRLEBlock = (GByte*) VSIMalloc( nRLESize );
     582              11 :     if (pabyRLEBlock == NULL)
     583                 :     {
     584               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nRLESize);
     585                 :     }
     586                 : 
     587                 :     // ----------------------------------------------------------------
     588                 :     // Set a black and white Color Table
     589                 :     // ----------------------------------------------------------------
     590                 : 
     591              11 :     if( eFormat == RunLengthEncoded )
     592                 :     {
     593               6 :         BlackWhiteCT( true );
     594                 :     }
     595                 : 
     596               0 : }
     597                 : 
     598                 : //  ----------------------------------------------------------------------------
     599                 : //                                        IntergraphRLEBand::IntergraphRLEBand()
     600                 : //  ----------------------------------------------------------------------------
     601                 : 
     602              11 : IntergraphRLEBand::~IntergraphRLEBand()
     603                 : {
     604              11 :     CPLFree( pabyRLEBlock );
     605              11 :     CPLFree( panRLELineOffset );
     606              11 : }
     607                 : 
     608                 : //  ----------------------------------------------------------------------------
     609                 : //                                               IntergraphRLEBand::IReadBlock()
     610                 : //  ----------------------------------------------------------------------------
     611                 : 
     612             511 : CPLErr IntergraphRLEBand::IReadBlock( int nBlockXOff, 
     613                 :                                       int nBlockYOff,
     614                 :                                       void *pImage )
     615                 : {
     616                 :     // --------------------------------------------------------------------
     617                 :     // Load Block Buffer
     618                 :     // --------------------------------------------------------------------
     619                 : 
     620                 :     uint32 nBytesRead;
     621                 :     
     622             521 :     if( bTiled || !bRLEBlockLoaded )
     623                 :     {
     624              10 :         if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage ))
     625               0 :             return CE_None;
     626                 : 
     627              10 :         if (!bTiled)
     628                 :         {
     629                 :             // With RLE, we want to load all of the data.
     630                 :             // So load (0,0) since that's the only offset that will load everything.
     631               6 :             nBytesRead = LoadBlockBuf( 0, 0, nRLESize, pabyRLEBlock );
     632                 :         }
     633                 :         else
     634                 :         {
     635               4 :             nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nRLESize, pabyRLEBlock );
     636                 :         }
     637              10 :         bRLEBlockLoaded = TRUE;
     638                 :     }
     639                 :     else
     640             501 :         nBytesRead = nRLESize;
     641                 : 
     642             511 :     if( nBytesRead == 0 )
     643                 :     {
     644                 :         memset( pImage, 0, nBlockXSize * nBlockYSize * 
     645               0 :                     GDALGetDataTypeSize( eDataType ) / 8 );
     646                 :         CPLError( CE_Failure, CPLE_FileIO, 
     647                 :             "Can't read (%s) tile with X offset %d and Y offset %d.\n%s", 
     648                 :             ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff, 
     649               0 :             VSIStrerror( errno ) );
     650               0 :         return CE_Failure;
     651                 :     }
     652                 : 
     653                 :     // ----------------------------------------------------------------
     654                 :   // Calculate the resulting image dimmention
     655                 :     // ----------------------------------------------------------------
     656                 : 
     657             511 :     int nVirtualXSize = nBlockXSize;
     658             511 :     int nVirtualYSize = nBlockYSize; 
     659                 : 
     660             511 :     if( nBlockXOff == nFullBlocksX )
     661                 :     {
     662               2 :         nVirtualXSize = nRasterXSize % nBlockXSize;
     663                 :     }
     664                 : 
     665             511 :     if( nBlockYOff == nFullBlocksY )
     666                 :     {
     667               2 :         nVirtualYSize = nRasterYSize % nBlockYSize;
     668                 :     }
     669                 : 
     670                 :     // --------------------------------------------------------------------
     671                 :     // Decode Run Length
     672                 :     // --------------------------------------------------------------------
     673                 : 
     674             515 :     if( bTiled && eFormat == RunLengthEncoded )
     675                 :     {
     676                 :         nBytesRead = 
     677                 :             INGR_DecodeRunLengthBitonalTiled( pabyRLEBlock, pabyBlockBuf,  
     678               4 :                                               nRLESize, nBlockBufSize, NULL );
     679                 :     }
     680                 :     
     681             509 :     else if( bTiled || panRLELineOffset == NULL )
     682                 :     {
     683                 :         nBytesRead = INGR_Decode( eFormat, pabyRLEBlock, pabyBlockBuf,  
     684                 :                                   nRLESize, nBlockBufSize, 
     685               2 :                                   NULL );
     686                 :     }
     687                 : 
     688                 :     else
     689                 :     {
     690                 :         uint32 nBytesConsumed;
     691                 : 
     692                 :         // If we are missing the offset to this line, process all
     693                 :         // preceding lines that are not initialized.
     694             505 :         if( nBlockYOff > 0 && panRLELineOffset[nBlockYOff] == 0 )
     695                 :         {
     696               0 :             int iLine = nBlockYOff - 1;
     697                 :             // Find the last line that is initialized (or line 0).
     698               0 :             while ((iLine != 0) && (panRLELineOffset[iLine] == 0))
     699               0 :                 iLine--;
     700               0 :             for( ; iLine < nBlockYOff; iLine++ )
     701                 :             {
     702                 :                 // Pass NULL as destination so that no decompression 
     703                 :                 // actually takes place.
     704                 :                 INGR_Decode( eFormat,
     705               0 :                              pabyRLEBlock + panRLELineOffset[iLine], 
     706               0 :                              NULL,  nRLESize - panRLELineOffset[iLine], nBlockBufSize,
     707               0 :                              &nBytesConsumed );
     708                 : 
     709               0 :                 if( iLine < nRasterYSize-1 )
     710               0 :                     panRLELineOffset[iLine+1] = 
     711               0 :                         panRLELineOffset[iLine] + nBytesConsumed;
     712                 :             }
     713                 :         } 
     714                 :         
     715                 :         // Read the requested line.
     716                 :         nBytesRead = 
     717                 :             INGR_Decode( eFormat,
     718             505 :                          pabyRLEBlock + panRLELineOffset[nBlockYOff], 
     719             505 :                          pabyBlockBuf,  nRLESize - panRLELineOffset[nBlockYOff], nBlockBufSize,
     720            1515 :                          &nBytesConsumed );
     721                 :             
     722             505 :         if( nBlockYOff < nRasterYSize-1 )
     723             501 :             panRLELineOffset[nBlockYOff+1] = 
     724             501 :                 panRLELineOffset[nBlockYOff] + nBytesConsumed;
     725                 :     }
     726                 : 
     727                 :     // --------------------------------------------------------------------
     728                 :     // Reshape blocks if needed
     729                 :     // --------------------------------------------------------------------
     730                 : 
     731             511 :     if( nBlockXOff == nFullBlocksX || 
     732                 :         nBlockYOff == nFullBlocksY )
     733                 :     {
     734               3 :         ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf );
     735                 :     }
     736                 : 
     737                 :     // --------------------------------------------------------------------
     738                 :     // Extract the band of interest from the block buffer (BIL)
     739                 :     // --------------------------------------------------------------------
     740                 : 
     741             512 :     if( eFormat == AdaptiveRGB ||
     742                 :         eFormat == ContinuousTone )
     743                 :     {
     744                 :         int i, j;
     745               1 :         GByte *pabyImage = (GByte*) pImage;
     746               1 :         j = ( nRGBIndex - 1 ) * nVirtualXSize;
     747             101 :         for ( i = 0; i < nVirtualYSize; i++ )
     748                 :         {
     749             100 :             memcpy( &pabyImage[i * nBlockXSize], &pabyBlockBuf[j], nBlockXSize );
     750             100 :             j += ( 3 * nBlockXSize );
     751                 :         }
     752                 :     }
     753                 :     else
     754                 :     {
     755             510 :         memcpy( pImage, pabyBlockBuf, nBlockBufSize );
     756                 :     }
     757                 : 
     758             511 :     return CE_None;
     759                 : }
     760                 : 
     761                 : //  ----------------------------------------------------------------------------
     762                 : //                                  IntergraphBitmapBand::IntergraphBitmapBand()
     763                 : //  ----------------------------------------------------------------------------
     764                 : 
     765               5 : IntergraphBitmapBand::IntergraphBitmapBand( IntergraphDataset *poDS, 
     766                 :                                             int nBand,
     767                 :                                             int nBandOffset,
     768                 :                                             int nRGorB )
     769               5 :     : IntergraphRasterBand( poDS, nBand, nBandOffset, GDT_Byte )
     770                 : {
     771               5 :     nBMPSize    = 0;
     772               5 :     nRGBBand    = nRGorB;
     773               5 :     pabyBMPBlock = NULL;
     774                 : 
     775               5 :     if (pabyBlockBuf == NULL)
     776               0 :         return;
     777                 : 
     778                 : 
     779               5 :     if( ! this->bTiled )
     780                 :     {
     781                 :         // ------------------------------------------------------------
     782                 :         // Load all rows at once
     783                 :         // ------------------------------------------------------------
     784                 : 
     785               1 :         nBlockYSize = nRasterYSize;
     786                 :         nBMPSize    = INGR_GetDataBlockSize( poDS->pszFilename, 
     787                 :                                              hHeaderTwo.CatenatedFilePointer,
     788               1 :                                              nDataOffset);
     789                 :     }
     790                 :     else
     791                 :     {
     792                 :         // ------------------------------------------------------------
     793                 :         // Find the biggest tile
     794                 :         // ------------------------------------------------------------
     795                 : 
     796                 :         uint32 iTiles;
     797              20 :         for( iTiles = 0; iTiles < nTiles; iTiles++)
     798                 :         {
     799              16 :             nBMPSize = MAX( pahTiles[iTiles].Used, nBMPSize );
     800                 :         }
     801                 :     }
     802                 : 
     803                 :     // ----------------------------------------------------------------
     804                 :     // Create a Bitmap buffer
     805                 :     // ----------------------------------------------------------------
     806                 : 
     807               5 :     pabyBMPBlock = (GByte*) VSIMalloc( nBMPSize );
     808               5 :     if (pabyBMPBlock == NULL)
     809                 :     {
     810               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBMPSize);
     811                 :     }
     812                 : 
     813                 :     // ----------------------------------------------------------------
     814                 :     // Set a black and white Color Table
     815                 :     // ----------------------------------------------------------------
     816                 : 
     817               5 :   if( eFormat == CCITTGroup4 )
     818                 :   {
     819               1 :         BlackWhiteCT( true );
     820                 :   }
     821                 : 
     822                 :     // ----------------------------------------------------------------
     823                 :     // Read JPEG Quality from Application Data
     824                 :     // ----------------------------------------------------------------
     825                 : 
     826               5 :   if( eFormat == JPEGGRAY ||
     827                 :     eFormat == JPEGRGB  ||
     828                 :     eFormat == JPEGCYMK )
     829                 :   {
     830                 :         nQuality = INGR_ReadJpegQuality( poDS->fp, 
     831                 :             hHeaderTwo.ApplicationPacketPointer,
     832               4 :             nDataOffset );
     833                 :   }
     834               0 : }
     835                 : 
     836                 : //  ----------------------------------------------------------------------------
     837                 : //                                 IntergraphBitmapBand::~IntergraphBitmapBand()
     838                 : //  ----------------------------------------------------------------------------
     839                 : 
     840               5 : IntergraphBitmapBand::~IntergraphBitmapBand()
     841                 : {
     842               5 :     CPLFree( pabyBMPBlock );
     843               5 : }
     844                 : 
     845                 : //  ----------------------------------------------------------------------------
     846                 : //                                IntergraphBitmapBand::GetColorInterpretation()
     847                 : //  ----------------------------------------------------------------------------
     848                 : 
     849               0 : GDALColorInterp IntergraphBitmapBand::GetColorInterpretation()
     850                 : {
     851               0 :     if( eFormat == JPEGRGB)
     852                 :     {
     853               0 :         switch( nRGBBand )
     854                 :         {
     855                 :         case 1: 
     856               0 :             return GCI_RedBand;
     857                 :         case 2: 
     858               0 :             return GCI_GreenBand;
     859                 :         case 3: 
     860               0 :             return GCI_BlueBand;
     861                 :         }
     862               0 :         return GCI_GrayIndex;
     863                 :     }
     864                 :     else
     865                 :     {
     866               0 :         if( poColorTable->GetColorEntryCount() > 0 )
     867                 :         {
     868               0 :             return GCI_PaletteIndex;
     869                 :         }
     870                 :         else
     871                 :         {
     872               0 :             return GCI_GrayIndex;
     873                 :         }
     874                 :     }
     875                 : 
     876                 : }
     877                 : 
     878                 : //  ----------------------------------------------------------------------------
     879                 : //                                            IntergraphBitmapBand::IReadBlock()
     880                 : //  ----------------------------------------------------------------------------
     881                 : 
     882               9 : CPLErr IntergraphBitmapBand::IReadBlock( int nBlockXOff, 
     883                 :                                          int nBlockYOff,
     884                 :                                          void *pImage )
     885                 : {
     886               9 :     IntergraphDataset *poGDS = ( IntergraphDataset * ) poDS;
     887                 : 
     888                 :     // ----------------------------------------------------------------
     889                 :   // Load the block of a tile or a whole image
     890                 :     // ----------------------------------------------------------------
     891               9 :     if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage ))
     892               0 :         return CE_None;
     893                 : 
     894               9 :     uint32 nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nBMPSize, pabyBMPBlock );
     895                 : 
     896               9 :     if( nBytesRead == 0 )
     897                 :     {
     898                 :         memset( pImage, 0, nBlockXSize * nBlockYSize * 
     899               0 :                     GDALGetDataTypeSize( eDataType ) / 8 );
     900                 :         CPLError( CE_Failure, CPLE_FileIO, 
     901                 :             "Can't read (%s) tile with X offset %d and Y offset %d.\n%s", 
     902                 :             ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff, 
     903               0 :             VSIStrerror( errno ) );
     904               0 :         return CE_Failure;
     905                 :     }
     906                 : 
     907                 :     // ----------------------------------------------------------------
     908                 :   // Calculate the resulting image dimmention
     909                 :     // ----------------------------------------------------------------
     910                 : 
     911               9 :     int nVirtualXSize = nBlockXSize;
     912               9 :     int nVirtualYSize = nBlockYSize; 
     913                 : 
     914               9 :     if( nBlockXOff == nFullBlocksX )
     915                 :     {
     916               4 :         nVirtualXSize = nRasterXSize % nBlockXSize;
     917                 :     }
     918                 : 
     919               9 :     if( nBlockYOff == nFullBlocksY )
     920                 :     {
     921               4 :         nVirtualYSize = nRasterYSize % nBlockYSize;
     922                 :     }
     923                 : 
     924                 :     // ----------------------------------------------------------------
     925                 :   // Create an in memory small tiff file (~400K)
     926                 :     // ----------------------------------------------------------------
     927                 : 
     928                 :     poGDS->hVirtual = INGR_CreateVirtualFile( poGDS->pszFilename, 
     929                 :                                               eFormat,
     930                 :                                               nVirtualXSize,
     931                 :                                               nVirtualYSize,
     932                 :                                               hTileDir.TileSize,
     933                 :                                               nQuality,
     934                 :                                               pabyBMPBlock, 
     935                 :                                               nBytesRead, 
     936               9 :                                               nRGBBand );
     937                 : 
     938               9 :     if( poGDS->hVirtual.poDS == NULL )
     939                 :     {
     940                 :         memset( pImage, 0, nBlockXSize * nBlockYSize * 
     941               0 :                     GDALGetDataTypeSize( eDataType ) / 8 );
     942                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     943                 :       "Unable to open virtual file.\n"
     944               0 :       "Is the GTIFF and JPEG driver available?" );
     945               0 :         return CE_Failure;
     946                 :     }
     947                 : 
     948                 :     // ----------------------------------------------------------------
     949                 :   // Read the unique block from the in memory file and release it
     950                 :     // ----------------------------------------------------------------
     951                 : 
     952                 :     poGDS->hVirtual.poBand->RasterIO( GF_Read, 0, 0, 
     953                 :         nVirtualXSize, nVirtualYSize, pImage, 
     954               9 :         nVirtualXSize, nVirtualYSize, GDT_Byte, 0, 0 );
     955                 : 
     956                 :     // --------------------------------------------------------------------
     957                 :     // Reshape blocks if needed
     958                 :     // --------------------------------------------------------------------
     959                 : 
     960               9 :     if( nBlockXOff == nFullBlocksX || 
     961                 :         nBlockYOff == nFullBlocksY )
     962                 :     {
     963               6 :         ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, (GByte*) pImage );
     964                 :     }
     965                 : 
     966               9 :     INGR_ReleaseVirtual( &poGDS->hVirtual );
     967                 : 
     968               9 :     return CE_None;
     969                 : } 
     970                 : 
     971                 : //  ----------------------------------------------------------------------------
     972                 : //                                          IntergraphRasterBand::LoadBlockBuf()
     973                 : //  ----------------------------------------------------------------------------
     974                 : 
     975            1379 : int IntergraphRasterBand::LoadBlockBuf( int nBlockXOff, 
     976                 :                                         int nBlockYOff,
     977                 :                                         int nBlobkBytes,
     978                 :                                         GByte *pabyBlock )
     979                 : {
     980            1379 :     IntergraphDataset *poGDS = ( IntergraphDataset * ) poDS;
     981                 : 
     982            1379 :     uint32 nSeekOffset  = 0;
     983            1379 :     uint32 nReadSize    = 0;
     984            1379 :     uint32 nBlockId     = 0;
     985                 : 
     986                 :     // --------------------------------------------------------------------
     987                 :     // Read from tiles or read from strip
     988                 :     // --------------------------------------------------------------------
     989                 : 
     990            1379 :     if( bTiled )
     991                 :     {
     992              12 :         nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
     993                 : 
     994              12 :         if( pahTiles[nBlockId].Start == 0 ) 
     995                 :         {
     996               0 :             return 0;
     997                 :         }
     998                 : 
     999              12 :         nSeekOffset   = pahTiles[nBlockId].Start + nDataOffset;
    1000              12 :         nReadSize     = pahTiles[nBlockId].Used;
    1001                 : 
    1002              12 :         if( (int) nReadSize > nBlobkBytes ) 
    1003                 :         {
    1004                 :             CPLDebug( "INGR", 
    1005                 :                       "LoadBlockBuf(%d,%d) - trimmed tile size from %d to %d.", 
    1006                 :                       nBlockXOff, nBlockYOff,
    1007               0 :                       (int) nReadSize, (int) nBlobkBytes );
    1008               0 :             nReadSize = nBlobkBytes;
    1009                 :         }
    1010                 :     }
    1011                 :     else
    1012                 :     {
    1013            1367 :         nSeekOffset   = nDataOffset + ( nBlockBufSize * nBlockYOff );
    1014            1367 :         nReadSize     = nBlobkBytes;
    1015                 :     }
    1016                 : 
    1017            1379 :     if( VSIFSeekL( poGDS->fp, nSeekOffset, SEEK_SET ) < 0 )
    1018                 :     {
    1019               0 :         return 0;
    1020                 :     }
    1021                 : 
    1022            1379 :     return VSIFReadL( pabyBlock, 1, nReadSize, poGDS->fp );
    1023                 : }
    1024                 : 
    1025                 : //  ----------------------------------------------------------------------------
    1026                 : //                                   IntergraphRasterBand::ReshapeBlock()
    1027                 : //  ----------------------------------------------------------------------------
    1028                 : 
    1029                 : /**
    1030                 :  *  Complete Tile with zeroes to fill up a Block
    1031                 :  * 
    1032                 :  *         ###    ##000   ######    ###00
    1033                 :  *         ### => ##000 , 000000 or ###00
    1034                 :  *                ##000   000000    00000
    1035                 :  ***/
    1036                 : 
    1037               9 : void IntergraphRasterBand::ReshapeBlock( int nBlockXOff, 
    1038                 :                                          int nBlockYOff,
    1039                 :                                          int nBlockBytes,
    1040                 :                                          GByte *pabyBlock )
    1041                 : {
    1042               9 :     GByte *pabyTile = (GByte*) CPLCalloc( 1, nBlockBufSize );
    1043                 : 
    1044               9 :     memcpy( pabyTile, pabyBlock, nBlockBytes );
    1045               9 :     memset( pabyBlock, 0, nBlockBytes );
    1046                 : 
    1047               9 :     int nColSize   = nBlockXSize;
    1048               9 :     int nRowSize   = nBlockYSize;
    1049               9 :     int nCellBytes = GDALGetDataTypeSize( eDataType ) / 8;
    1050                 : 
    1051               9 :     if( nBlockXOff + 1 == nBlocksPerRow )
    1052                 :     {
    1053               6 :         nColSize = nRasterXSize % nBlockXSize;
    1054                 :     }
    1055                 : 
    1056               9 :     if( nBlockYOff + 1 == nBlocksPerColumn )
    1057                 :     {
    1058               6 :         nRowSize = nRasterYSize % nBlockYSize;
    1059                 :     }
    1060                 : 
    1061               9 :     if( nRGBIndex > 0 )
    1062                 :     {
    1063               0 :         nCellBytes = nCellBytes * 3;
    1064                 :     }
    1065                 : 
    1066             495 :     for( int iRow = 0; iRow < nRowSize; iRow++ )
    1067                 :     {
    1068                 :         memcpy( pabyBlock + ( iRow * nCellBytes * nBlockXSize ), 
    1069                 :                 pabyTile  + ( iRow * nCellBytes * nColSize ), 
    1070             486 :                 nCellBytes * nColSize);
    1071                 :     }
    1072                 : 
    1073               9 :     CPLFree( pabyTile );
    1074               9 : }
    1075                 : 
    1076                 : //  ----------------------------------------------------------------------------
    1077                 : //                                           IntergraphRasterBand::IWriteBlock()
    1078                 : //  ----------------------------------------------------------------------------
    1079                 : 
    1080             795 : CPLErr IntergraphRasterBand::IWriteBlock( int nBlockXOff, 
    1081                 :                                           int nBlockYOff,
    1082                 :                                           void *pImage )
    1083                 : {
    1084             795 :     uint32 nBlockSize = nBlockBufSize;
    1085             795 :     uint32 nBlockOffset = nBlockBufSize * nBlockYOff;
    1086                 : 
    1087             795 :     IntergraphDataset *poGDS = ( IntergraphDataset * ) poDS;
    1088                 : 
    1089             795 :     if( ( nBlockXOff == 0 ) && ( nBlockYOff == 0 ) )
    1090                 :     {
    1091              25 :         FlushBandHeader();
    1092                 :     }
    1093                 : 
    1094             795 :     if( nRGBIndex > 0 ) 
    1095                 :     {
    1096              30 :         if( nBand > 1 ) 
    1097                 :         {
    1098              20 :             VSIFSeekL( poGDS->fp, nDataOffset + ( nBlockBufSize * nBlockYOff ), SEEK_SET );
    1099              20 :             VSIFReadL( pabyBlockBuf, 1, nBlockBufSize, poGDS->fp );
    1100                 :         }
    1101                 :         int i, j;
    1102             330 :         for( i = 0, j = ( 3 - nRGBIndex ); i < nBlockXSize; i++, j += 3 )
    1103                 :         {
    1104             300 :             pabyBlockBuf[j] = ( ( GByte * ) pImage )[i];
    1105                 :         }
    1106                 :     }
    1107             765 :     else if (eFormat == RunLengthEncoded)
    1108                 :     {
    1109                 :         // Series of [OFF, ON,] OFF spans.
    1110             135 :         int nLastCount = 0;
    1111             135 :         GByte *pInput = ( GByte * ) pImage;
    1112             135 :         GInt16 *pOutput = ( GInt16 * ) pabyBlockBuf;
    1113                 : 
    1114             135 :         nBlockOffset = this->nRLEOffset * 2;
    1115             135 :         int nRLECount = 0;
    1116             135 :         GByte nValue = 0; // Start with OFF spans.
    1117                 : 
    1118           25650 :         for(uint32 i=0; i<nBlockBufSize; i++)
    1119                 :         {
    1120           47575 :             if (((nValue == 0) && (pInput[i] == 0)) || ((nValue == 1) && pInput[i]))
    1121                 :             {
    1122           22060 :                 nLastCount++;
    1123                 :             }
    1124                 :             else
    1125                 :             {
    1126                 :                 // Change of span type.
    1127            6910 :                 while(nLastCount>32767)
    1128                 :                 {
    1129               0 :                     pOutput[nRLECount++] = CPL_LSBWORD16(32767);
    1130               0 :                     pOutput[nRLECount++] = CPL_LSBWORD16(0);
    1131               0 :                     nLastCount -= 32767;
    1132                 :                 }
    1133            3455 :                 pOutput[nRLECount++] = CPL_LSBWORD16(nLastCount);
    1134            3455 :                 nLastCount = 1;
    1135            3455 :                 nValue ^= 1;
    1136                 :             }
    1137                 :         }
    1138                 : 
    1139                 :         // Output tail end of scanline
    1140             270 :         while(nLastCount>32767)
    1141                 :         {
    1142               0 :             pOutput[nRLECount++] = CPL_LSBWORD16(32767);
    1143               0 :             pOutput[nRLECount++] = CPL_LSBWORD16(0);
    1144               0 :             nLastCount -= 32767;
    1145                 :         }
    1146                 : 
    1147             135 :         if (nLastCount != 0)
    1148                 :         {
    1149             135 :             pOutput[nRLECount++] = CPL_LSBWORD16(nLastCount);
    1150             135 :             nLastCount = 0;
    1151             135 :             nValue ^= 1;
    1152                 :         }
    1153                 : 
    1154             135 :         if (nValue == 0)
    1155             127 :             pOutput[nRLECount++] = CPL_LSBWORD16(0);
    1156                 : 
    1157             135 :         this->nRLEOffset += nRLECount;
    1158             135 :         nBlockSize = nRLECount * 2;
    1159                 :     }
    1160                 :     else
    1161                 :     {
    1162             630 :         memcpy( pabyBlockBuf, pImage, nBlockBufSize );
    1163                 : #ifdef CPL_MSB
    1164                 :         if( eDataType == GDT_Int16 || eDataType == GDT_UInt16)
    1165                 :             GDALSwapWords( pabyBlockBuf, 2, nBlockXSize * nBlockYSize, 2  );
    1166                 :         else if( eDataType == GDT_Int32 || eDataType == GDT_UInt32 || eDataType == GDT_Float32  )
    1167                 :             GDALSwapWords( pabyBlockBuf, 4, nBlockXSize * nBlockYSize, 4  );
    1168                 :         else if (eDataType == GDT_Float64  )
    1169                 :             GDALSwapWords( pabyBlockBuf, 8, nBlockXSize * nBlockYSize, 8  );
    1170                 : #endif
    1171                 :     }
    1172                 : 
    1173             795 :     VSIFSeekL( poGDS->fp, nDataOffset + nBlockOffset, SEEK_SET );
    1174                 : 
    1175             795 :     if( ( uint32 ) VSIFWriteL( pabyBlockBuf, 1, nBlockSize, poGDS->fp ) < nBlockSize )
    1176                 :     {
    1177                 :         CPLError( CE_Failure, CPLE_FileIO, 
    1178                 :             "Can't write (%s) block with X offset %d and Y offset %d.\n%s", 
    1179               0 :             poGDS->pszFilename, nBlockXOff, nBlockYOff, VSIStrerror( errno ) );
    1180               0 :         return CE_Failure;
    1181                 :     }
    1182                 : 
    1183             795 :     return CE_None;
    1184                 : }
    1185                 : 
    1186                 : //  ----------------------------------------------------------------------------
    1187                 : //                                       IntergraphRasterBand::FlushBandHeader()
    1188                 : //  ----------------------------------------------------------------------------
    1189                 : 
    1190              25 : void IntergraphRasterBand::FlushBandHeader( void )
    1191                 : {
    1192              25 :     if( nRGBIndex > 1 )
    1193                 :     {
    1194               2 :         return;
    1195                 :     }
    1196                 : 
    1197              23 :     IntergraphDataset *poGDS = ( IntergraphDataset* ) poDS;
    1198                 : 
    1199                 :     INGR_ColorTable256 hCTab;
    1200                 : 
    1201              23 :     if( poColorTable->GetColorEntryCount() > 0 )
    1202                 :     {
    1203               1 :         hHeaderTwo.ColorTableType = IGDSColorTable;
    1204               1 :         hHeaderTwo.NumberOfCTEntries = poColorTable->GetColorEntryCount();
    1205               1 :         INGR_SetIGDSColors( poColorTable, &hCTab );
    1206                 :     }
    1207                 : 
    1208              23 :     if( nBand > poDS->GetRasterCount() )
    1209                 :     {
    1210                 :         hHeaderTwo.CatenatedFilePointer = nBand *
    1211               0 :             ( ( 3 * SIZEOF_HDR1 ) + ( nBlockBufSize * nRasterYSize ) );
    1212                 :     }
    1213                 : 
    1214              23 :     VSIFSeekL( poGDS->fp, nBandStart, SEEK_SET );
    1215                 : 
    1216                 :     GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_CTAB)];
    1217                 : 
    1218              23 :     INGR_HeaderOneMemToDisk( &hHeaderOne, abyBuf );
    1219                 : 
    1220              23 :     VSIFWriteL( abyBuf, 1, SIZEOF_HDR1, poGDS->fp );
    1221                 : 
    1222              23 :     INGR_HeaderTwoAMemToDisk( &hHeaderTwo, abyBuf );
    1223                 : 
    1224              23 :     VSIFWriteL( abyBuf, 1, SIZEOF_HDR2_A, poGDS->fp );
    1225                 : 
    1226              23 :     unsigned int i = 0;
    1227              23 :     unsigned int n = 0;
    1228                 : 
    1229            5911 :     for( i = 0; i < 256; i++ )
    1230                 :     {
    1231            5888 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_red );
    1232            5888 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_green );
    1233            5888 :         STRC2BUF( abyBuf, n, hCTab.Entry[i].v_blue );
    1234                 :     }
    1235                 : 
    1236              23 :     VSIFWriteL( abyBuf, 1, SIZEOF_CTAB, poGDS->fp );
    1237                 : }
    1238                 : 
    1239                 : //  ----------------------------------------------------------------------------
    1240                 : //                                          IntergraphRasterBand::BlackWhiteCT()
    1241                 : //  ----------------------------------------------------------------------------
    1242                 : 
    1243               7 : void IntergraphRasterBand::BlackWhiteCT( bool bReverse )
    1244                 : {
    1245                 :   GDALColorEntry oBlack;
    1246                 :   GDALColorEntry oWhite;
    1247                 : 
    1248               7 :     oWhite.c1 = (short) 255;
    1249               7 :   oWhite.c2 = (short) 255;
    1250               7 :   oWhite.c3 = (short) 255;
    1251               7 :   oWhite.c4 = (short) 255;
    1252                 : 
    1253               7 :   oBlack.c1 = (short) 0;
    1254               7 :   oBlack.c2 = (short) 0;
    1255               7 :   oBlack.c3 = (short) 0;
    1256               7 :   oBlack.c4 = (short) 255;
    1257                 : 
    1258               7 :     if( bReverse )
    1259                 :     {
    1260               7 :         poColorTable->SetColorEntry( 0, &oWhite );
    1261               7 :       poColorTable->SetColorEntry( 1, &oBlack );
    1262                 :     }
    1263                 :     else
    1264                 :     {
    1265               0 :         poColorTable->SetColorEntry( 0, &oBlack );
    1266               0 :       poColorTable->SetColorEntry( 1, &oWhite );
    1267                 :     }    
    1268               7 : }

Generated by: LCOV version 1.7