Example #1
0
CPLErr HFABand::GetRasterBlock( int nXBlock, int nYBlock, void * pData )

{
    int		iBlock;

    if( LoadBlockInfo() != CE_None )
        return CE_Failure;

    iBlock = nXBlock + nYBlock * nBlocksPerRow;
    
/* -------------------------------------------------------------------- */
/*      If the block isn't valid, or is compressed we just return       */
/*      all zeros, and an indication of failure.                        */
/* -------------------------------------------------------------------- */
    if( !(panBlockFlag[iBlock] & (BFLG_VALID|BFLG_COMPRESSED)) )
    {
        int	nBytes;

        nBytes = HFAGetDataTypeBits(nDataType)*nBlockXSize*nBlockYSize/8;

        while( nBytes > 0 )
            ((GByte *) pData)[--nBytes] = 0;
        
        return( CE_Failure );
    }

/* -------------------------------------------------------------------- */
/*      Otherwise we really read the data.                              */
/* -------------------------------------------------------------------- */
    if( VSIFSeek( psInfo->fp, panBlockStart[iBlock], SEEK_SET ) != 0 )
        return CE_Failure;

    if( VSIFRead( pData, panBlockSize[iBlock], 1, psInfo->fp ) == 0 )
        return CE_Failure;

/* -------------------------------------------------------------------- */
/*      Byte swap to local byte order if required.  It appears that     */
/*      raster data is always stored in Intel byte order in Imagine     */
/*      files.                                                          */
/* -------------------------------------------------------------------- */

#ifdef CPL_MSB             
    if( HFAGetDataTypeBits(nDataType) == 16 )
    {
        int		ii;

        for( ii = 0; ii < nBlockXSize*nBlockYSize; ii++ )
        {
            unsigned char *pabyData = (unsigned char *) pData;
            int		nTemp;

            nTemp = pabyData[ii*2];
            pabyData[ii*2] = pabyData[ii*2+1];
            pabyData[ii*2+1] = nTemp;
        }
    }
#endif /* def CPL_MSB */

    return( CE_None );
}
Example #2
0
int HFAField::GetInstBytes( GByte *pabyData, int nDataSize )

{
    int		nCount;
    int		nInstBytes = 0;
    
    if( nBytes > -1 )
        return nBytes;

    if( chPointer != '\0' )
    {
        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );

        pabyData += 8;
        nInstBytes += 8;
    }
    else
        nCount = 1;

    if( chItemType == 'b' && nCount != 0 ) // BASEDATA
    {
        GInt32 nRows, nColumns;
        GInt16 nBaseItemType;
        
        memcpy( &nRows, pabyData, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+4, 4 );
        HFAStandard( 4, &nColumns );
        memcpy( &nBaseItemType, pabyData+8, 2 );
        HFAStandard( 2, &nBaseItemType );

        nInstBytes += 12;

        nInstBytes += 
            ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns;
    }
    else if( poItemObjectType == NULL )
    {
        nInstBytes += nCount * HFADictionary::GetItemSize(chItemType);
    }
    else
    {
        int		i;

        for( i = 0; i < nCount; i++ )
        {
            int	nThisBytes;

            nThisBytes =
                poItemObjectType->GetInstBytes( pabyData,
                                                nDataSize - nInstBytes );
            nInstBytes += nThisBytes;
            pabyData += nThisBytes;
        }
    }

    return( nInstBytes );
}
Example #3
0
HFACompress::HFACompress( void *pData, GUInt32 nBlockSize, int nDataType )
{
  m_pData       = pData;
  m_nDataType   = nDataType;
  m_nDataTypeNumBits    = HFAGetDataTypeBits( m_nDataType );
  m_nBlockSize  = nBlockSize;
  m_nBlockCount = (nBlockSize * 8) / m_nDataTypeNumBits;

  /* Allocate some memory for the count and values - probably too big */
  /* About right for worst case scenario tho */
  m_pCounts     = (GByte*)VSIMalloc( m_nBlockCount * sizeof(GUInt32) + sizeof(GUInt32) );
  m_nSizeCounts = 0;
  
  m_pValues     = (GByte*)VSIMalloc( m_nBlockCount * sizeof(GUInt32) + sizeof(GUInt32) );
  m_nSizeValues = 0;
  
  m_nMin        = 0;
  m_nNumRuns    = 0;
  m_nNumBits    = 0;
}
CPLErr
HFAField::SetInstValue( const char * pszField, int nIndexValue,
                        GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
                        char chReqType, void *pValue )

{
/* -------------------------------------------------------------------- */
/*	If this field contains a pointer, then we will adjust the	*/
/*	data offset relative to it.    					*/
/* -------------------------------------------------------------------- */
    if( chPointer != '\0' )
    {
        GUInt32		nCount;
        GUInt32		nOffset;

         /* set the count for fixed sized arrays */
        if( nBytes > -1 )
            nCount = nItemCount;

        // The count returned for BASEDATA's are the contents, 
        // but here we really want to mark it as one BASEDATA instance
        // (see #2144)
        if( chItemType == 'b' ) 
            nCount = 1;

        /* Set the size from string length */
        else if( chReqType == 's' && (chItemType == 'c' || chItemType == 'C'))
        {
            if( pValue == NULL )
                nCount = 0;
            else
                nCount = strlen((char *) pValue) + 1;
        }

        /* set size based on index ... assumes in-order setting of array */
        else
            nCount = nIndexValue+1;

        if( (int) nCount + 8 > nDataSize )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to extend field %s in node past end of data,\n"
                      "not currently supported.",
                      pszField );
            return CE_Failure;
        }

        // we will update the object count iff we are writing beyond the end
        memcpy( &nOffset, pabyData, 4 );
        HFAStandard( 4, &nOffset );
        if( nOffset < nCount )
        {
            nOffset = nCount;
            HFAStandard( 4, &nOffset );
            memcpy( pabyData, &nOffset, 4 );
        }

        if( pValue == NULL )
            nOffset = 0;
        else
            nOffset = nDataOffset + 8;
        HFAStandard( 4, &nOffset );
        memcpy( pabyData+4, &nOffset, 4 );

        pabyData += 8;

        nDataOffset += 8;
        nDataSize -= 8;
    }

/* -------------------------------------------------------------------- */
/*      pointers to char or uchar arrays requested as strings are       */
/*      handled as a special case.                                      */
/* -------------------------------------------------------------------- */
    if( (chItemType == 'c' || chItemType == 'C') && chReqType == 's' )
    {
        int	nBytesToCopy;
        
        if( nBytes == -1 )
        {
            if( pValue == NULL )
                nBytesToCopy = 0;
            else
                nBytesToCopy = strlen((char *) pValue) + 1;
        }
        else
            nBytesToCopy = nBytes;

        if( nBytesToCopy > nDataSize )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to extend field %s in node past end of data,\n"
                      "not currently supported.",
                      pszField );
            return CE_Failure;
        }

        memset( pabyData, 0, nBytesToCopy );

        if( pValue != NULL )
            strncpy( (char *) pabyData, (char *) pValue, nBytesToCopy );

        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Translate the passed type into different representations.       */
/* -------------------------------------------------------------------- */
    int		nIntValue;
    double      dfDoubleValue;

    if( chReqType == 's' )
    {
        nIntValue = atoi((char *) pValue);
        dfDoubleValue = atof((char *) pValue);
    }
    else if( chReqType == 'd' )
    {
        dfDoubleValue = *((double *) pValue);
        nIntValue = (int) dfDoubleValue;
    }
    else if( chReqType == 'i' )
    {
        dfDoubleValue = *((int *) pValue);
        nIntValue = *((int *) pValue);
    }
    else if( chReqType == 'p' )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
            "HFAField::SetInstValue() not supported yet for pointer values." );
        
        return CE_Failure;
    }
    else
    {
        CPLAssert( FALSE );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Handle by type.                                                 */
/* -------------------------------------------------------------------- */
    switch( chItemType )
    {
      case 'c':
      case 'C':
        if( nIndexValue + 1 > nDataSize )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to extend field %s in node past end of data,\n"
                      "not currently supported.",
                      pszField );
              return CE_Failure;
        }

        if( chReqType == 's' )
            pabyData[nIndexValue] = ((char *) pValue)[0];
        else
            pabyData[nIndexValue] = (char) nIntValue;
        break;

      case 'e':
      case 's':
      {
          if( chItemType == 'e' && chReqType == 's' )
          {
              nIntValue = CSLFindString( papszEnumNames, (char *) pValue );
              if( nIntValue == -1 )
              {
                  CPLError( CE_Failure, CPLE_AppDefined, 
                            "Attempt to set enumerated field with unknown"
                            " value `%s'.", 
                            (char *) pValue );
                  return CE_Failure;
              }
          }

          unsigned short nNumber = (unsigned short) nIntValue;

          if( nIndexValue*2 + 2 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 2, &nNumber );
          memcpy( pabyData + nIndexValue*2, &nNumber, 2 );
      }
      break;

      case 'S':
      {
          short nNumber;

          if( nIndexValue*2 + 2 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          nNumber = (short) nIntValue;
          HFAStandard( 2, &nNumber );
          memcpy( pabyData + nIndexValue*2, &nNumber, 2 );
      }
      break;
        
      case 't':
      case 'l':
      {
          GUInt32	nNumber = nIntValue;

          if( nIndexValue*4 + 4 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 4, &nNumber );
          memcpy( pabyData + nIndexValue*4, &nNumber, 4 );
      }
      break;
      
      case 'L':
      {
          GInt32	nNumber = nIntValue;
          
          if( nIndexValue*4 + 4 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 4, &nNumber );
          memcpy( pabyData + nIndexValue*4, &nNumber, 4 );
      }
      break;
      
      case 'f':
      {
          float		fNumber = (float) dfDoubleValue;
          
          if( nIndexValue*4 + 4 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 4, &fNumber );
          memcpy( pabyData + nIndexValue*4, &fNumber, 4 );
      }
      break;
        
      case 'd':
      {
          double	dfNumber = dfDoubleValue;
          
          if( nIndexValue*8 + 8 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 8, &dfNumber );
          memcpy( pabyData + nIndexValue*8, &dfNumber, 8 );
      }
      break;

    case 'b': 
    { 
        GInt32 nRows = 1; 
        GInt32 nColumns = 1; 
        GInt16 nBaseItemType;

        // Extract existing rows, columns, and datatype.
        memcpy( &nRows, pabyData, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+4, 4 );
        HFAStandard( 4, &nColumns );
        memcpy( &nBaseItemType, pabyData+8, 2 );
        HFAStandard( 2, &nBaseItemType );

        // Are we using special index values to update the rows, columnrs
        // or type?
        
        if( nIndexValue == -3 )
            nBaseItemType = nIntValue;
        else if( nIndexValue == -2 )
            nColumns = nIntValue;
        else if( nIndexValue == -1 )
            nRows = nIntValue;

        if( nIndexValue < -3 || nIndexValue >= nRows * nColumns ) 
            return CE_Failure; 

        // Write back the rows, columns and basedatatype.
        HFAStandard( 4, &nRows ); 
        memcpy( pabyData, &nRows, 4 ); 
        HFAStandard( 4, &nColumns ); 
        memcpy( pabyData+4, &nColumns, 4 ); 
        HFAStandard( 2, &nBaseItemType ); 
        memcpy ( pabyData + 8, &nBaseItemType, 2 ); 
        HFAStandard( 2, &nBaseItemType ); // swap back for our use.

        // We ignore the 2 byte objecttype value.  

        nDataSize -= 12; 

        if( nIndexValue >= 0 )
        { 
            if( (nIndexValue+1) * (HFAGetDataTypeBits(nBaseItemType)/8)
                > nDataSize ) 
            { 
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Attempt to extend field %s in node past end of data,\n" 
                          "not currently supported.", 
                          pszField ); 
                return CE_Failure; 
            } 

            if( nBaseItemType == EPT_f64 )
            {
                double dfNumber = dfDoubleValue; 

                HFAStandard( 8, &dfNumber ); 
                memcpy( pabyData + 12 + nIndexValue * 8, &dfNumber, 8 ); 
            }
            else
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Setting basedata field %s with type %s not currently supported.", 
                          pszField, HFAGetDataTypeName( nBaseItemType ) ); 
                return CE_Failure; 
            }
        } 
    } 
    break;               

      case 'o':
        if( poItemObjectType != NULL )
        {
            int		nExtraOffset = 0;
            int		iIndexCounter;

            if( poItemObjectType->nBytes > 0 )
            {
                if (nIndexValue != 0 && poItemObjectType->nBytes > INT_MAX / nIndexValue)
                    return CE_Failure;
                nExtraOffset = poItemObjectType->nBytes * nIndexValue;
            }
            else
            {
                for( iIndexCounter = 0;
                     iIndexCounter < nIndexValue && nExtraOffset < nDataSize;
                     iIndexCounter++ )
                {
                    int nInc = poItemObjectType->GetInstBytes(pabyData + nExtraOffset,
                                                              nDataSize - nExtraOffset);
                    if (nInc < 0 || nExtraOffset > INT_MAX - nInc)
                    {
                        CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
                        return CE_Failure;
                    }

                    nExtraOffset += nInc;
                }
            }

            if (nExtraOffset >= nDataSize)
                return CE_Failure;

            if( pszField != NULL && strlen(pszField) > 0 )
            {
                return( poItemObjectType->
                            SetInstValue( pszField, pabyData + nExtraOffset,
                                          nDataOffset + nExtraOffset,
                                          nDataSize - nExtraOffset,
                                          chReqType, pValue ) );
            }
            else
            {
                CPLAssert( FALSE );
                return CE_Failure;
            }
        }
        break;

      default:
        CPLAssert( FALSE );
        return CE_Failure;
        break;
    }

    return CE_None;
}
int HFAField::GetInstBytes( GByte *pabyData, int nDataSize )

{
    int		nCount;
    int		nInstBytes = 0;
    
    if( nBytes > -1 )
        return nBytes;

    if( chPointer != '\0' )
    {
        if (nDataSize < 4)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
            return -1;
        }

        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );

        pabyData += 8;
        nInstBytes += 8;
    }
    else
        nCount = 1;

    if( chItemType == 'b' && nCount != 0 ) // BASEDATA
    {
        if (nDataSize - nInstBytes < 4+4+2)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
            return -1;
        }

        GInt32 nRows, nColumns;
        GInt16 nBaseItemType;
        
        memcpy( &nRows, pabyData, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+4, 4 );
        HFAStandard( 4, &nColumns );
        memcpy( &nBaseItemType, pabyData+8, 2 );
        HFAStandard( 2, &nBaseItemType );

        nInstBytes += 12;
        
        if (nRows < 0 || nColumns < 0)
            return -1;
        if (nColumns != 0 && nRows > INT_MAX / nColumns)
            return -1;
        if (nColumns != 0 && ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows > INT_MAX / nColumns)
            return -1;
        if (((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns > INT_MAX - nInstBytes)
            return -1;

        nInstBytes += 
            ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns;
    }
    else if( poItemObjectType == NULL )
    {
        if (nCount != 0 && HFADictionary::GetItemSize(chItemType) > INT_MAX / nCount)
            return -1;
        nInstBytes += nCount * HFADictionary::GetItemSize(chItemType);
    }
    else
    {
        int		i;

        for( i = 0; i < nCount &&
                    nInstBytes < nDataSize &&
                    nInstBytes >= 0; i++ )
        {
            int	nThisBytes;

            nThisBytes =
                poItemObjectType->GetInstBytes( pabyData,
                                                nDataSize - nInstBytes );
            if (nThisBytes < 0 || nInstBytes > INT_MAX - nThisBytes)
            {
                CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
                return -1;
            }

            nInstBytes += nThisBytes;
            pabyData += nThisBytes;
        }
    }

    return( nInstBytes );
}