Changeset 14731

Show
Ignore:
Timestamp:
06/20/08 14:20:44 (6 months ago)
Author:
warmerdam
Message:

Read invalid blocks as nodata value if available. Create new files with
all blocks marked invalid. Support writing to invalid blocks as long as
there is already a pointer to valid data. (#2427)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/frmts/hfa/hfa_p.h

    r14711 r14731  
    142142     
    143143    void ReAllocBlock( int iBlock, int nSize ); 
     144    void NullBlock( void * ); 
    144145 
    145146  public: 
  • trunk/gdal/frmts/hfa/hfaband.cpp

    r14709 r14731  
    827827} 
    828828 
     829/************************************************************************/ 
     830/*                             NullBlock()                              */ 
     831/*                                                                      */ 
     832/*      Set the block buffer to zero or the nodata value as             */ 
     833/*      appropriate.                                                    */ 
     834/************************************************************************/ 
     835 
     836void HFABand::NullBlock( void *pData ) 
     837 
     838{ 
     839    if( !bNoDataSet ) 
     840        memset( pData, 0,  
     841                HFAGetDataTypeBits(nDataType)*nBlockXSize*nBlockYSize/8 ); 
     842    else 
     843             
     844    { 
     845        double adfND[2]; 
     846        int nChunkSize = MAX(1,HFAGetDataTypeBits(nDataType)/8); 
     847        int nWords = nBlockXSize * nBlockYSize; 
     848        int i; 
     849 
     850        switch( nDataType ) 
     851        { 
     852          case EPT_u1: 
     853          { 
     854              nWords = (nWords + 7)/8; 
     855              if( dfNoData != 0.0 ) 
     856                  ((unsigned char *) &adfND)[0] = 0xff; 
     857              else 
     858                  ((unsigned char *) &adfND)[0] = 0x00; 
     859          } 
     860          break; 
     861 
     862          case EPT_u2: 
     863          { 
     864              nWords = (nWords + 3)/4; 
     865              if( dfNoData == 0.0 ) 
     866                  ((unsigned char *) &adfND)[0] = 0x00; 
     867              else if( dfNoData == 1.0 ) 
     868                  ((unsigned char *) &adfND)[0] = 0x55; 
     869              else if( dfNoData == 2.0 ) 
     870                  ((unsigned char *) &adfND)[0] = 0xaa; 
     871              else 
     872                  ((unsigned char *) &adfND)[0] = 0xff; 
     873          } 
     874          break; 
     875 
     876          case EPT_u4: 
     877          { 
     878              unsigned char byVal =  
     879                  (unsigned char) MAX(0,MIN(15,(int)dfNoData)); 
     880 
     881              nWords = (nWords + 1)/2; 
     882                   
     883              ((unsigned char *) &adfND)[0] = byVal + (byVal << 4); 
     884          } 
     885          break; 
     886 
     887          case EPT_u8: 
     888            ((unsigned char *) &adfND)[0] =  
     889                (unsigned char) MAX(0,MIN(255,(int)dfNoData)); 
     890            break; 
     891 
     892          case EPT_s8: 
     893            ((signed char *) &adfND)[0] =  
     894                (signed char) MAX(-128,MIN(127,(int)dfNoData)); 
     895            break; 
     896 
     897          case EPT_u16: 
     898            ((GUInt16 *) &adfND)[0] = (GUInt16) dfNoData; 
     899            break; 
     900 
     901          case EPT_s16: 
     902            ((GInt16 *) &adfND)[0] = (GInt16) dfNoData; 
     903            break; 
     904 
     905          case EPT_u32: 
     906            ((GUInt32 *) &adfND)[0] = (GUInt32) dfNoData; 
     907            break; 
     908 
     909          case EPT_s32: 
     910            ((GInt32 *) &adfND)[0] = (GInt32) dfNoData; 
     911            break; 
     912 
     913          case EPT_f32: 
     914            ((float *) &adfND)[0] = (float) dfNoData; 
     915            break; 
     916 
     917          case EPT_f64: 
     918            ((double *) &adfND)[0] = dfNoData; 
     919            break; 
     920 
     921          case EPT_c64: 
     922            ((float *) &adfND)[0] = dfNoData; 
     923            ((float *) &adfND)[1] = 0; 
     924            break; 
     925 
     926          case EPT_c128: 
     927            ((double *) &adfND)[0] = dfNoData; 
     928            ((double *) &adfND)[1] = 0; 
     929            break; 
     930        } 
     931             
     932        for( i = 0; i < nWords; i++ ) 
     933            memcpy( ((GByte *) pData) + nChunkSize * i,  
     934                    &adfND[0], nChunkSize ); 
     935    } 
     936 
     937} 
    829938 
    830939/************************************************************************/ 
     
    849958    if( !panBlockFlag[iBlock] & BFLG_VALID ) 
    850959    { 
    851         memset( pData, 0,  
    852                 HFAGetDataTypeBits(nDataType)*nBlockXSize*nBlockYSize/8 ); 
    853  
     960        NullBlock( pData ); 
    854961        return( CE_None ); 
    855962    } 
     
    10591166/* -------------------------------------------------------------------- */ 
    10601167    if( (panBlockFlag[iBlock] & BFLG_VALID) == 0 
    1061         && !(panBlockFlag[iBlock] & BFLG_COMPRESSED) ) 
     1168        && !(panBlockFlag[iBlock] & BFLG_COMPRESSED)  
     1169        && panBlockStart[iBlock] == 0 ) 
    10621170    { 
    10631171        CPLError( CE_Failure, CPLE_AppDefined,  
     
    12661374            return CE_Failure; 
    12671375        } 
     1376 
     1377/* -------------------------------------------------------------------- */ 
     1378/*      If the block was previously invalid, mark it as valid now.      */ 
     1379/* -------------------------------------------------------------------- */ 
     1380        if( (panBlockFlag[iBlock] & BFLG_VALID) == 0 ) 
     1381        { 
     1382            char        szVarName[64]; 
     1383            HFAEntry    *poDMS = poNode->GetNamedChild( "RasterDMS" ); 
     1384 
     1385            sprintf( szVarName, "blockinfo[%d].logvalid", iBlock ); 
     1386            poDMS->SetStringField( szVarName, "true" ); 
     1387 
     1388            panBlockFlag[iBlock] |= BFLG_VALID; 
     1389        } 
    12681390    } 
    12691391/* -------------------------------------------------------------------- */ 
  • trunk/gdal/frmts/hfa/hfaopen.cpp

    r13687 r14731  
    20322032            memcpy( pabyData + nOffset + 6, &nValue, 4 ); 
    20332033 
    2034             /* logValid (true/false) */ 
    2035             if( bCreateCompressed ) 
    2036                 nValue16 = 0; 
    2037             else 
    2038                 nValue16 = 1; 
     2034            /* logValid (false) */ 
     2035            nValue16 = 0; 
    20392036            HFAStandard( 2, &nValue16 ); 
    20402037            memcpy( pabyData + nOffset + 10, &nValue16, 2 );