LCOV - code coverage report
Current view: top level - frmts/hfa - hfa_p.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 27 27 100.0 %
Date: 2025-08-19 18:03:11 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Erdas Imagine (.img) Translator
       4             :  * Purpose:  Private class declarations for the HFA classes used to read
       5             :  *           Erdas Imagine (.img) files.  Public (C callable) declarations
       6             :  *           are in hfa.h.
       7             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 1999, Intergraph Corporation
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef HFA_P_H_INCLUDED
      16             : #define HFA_P_H_INCLUDED
      17             : 
      18             : #include "cpl_port.h"
      19             : #include "hfa.h"
      20             : 
      21             : #include <cstdio>
      22             : #include <memory>
      23             : #include <vector>
      24             : #include <set>
      25             : 
      26             : #include "cpl_error.h"
      27             : #include "cpl_vsi.h"
      28             : #include "ogr_spatialref.h"
      29             : 
      30             : #ifdef CPL_LSB
      31             : #define HFAStandard(n, p)                                                      \
      32             :     {                                                                          \
      33             :     }
      34             : #else
      35             : void HFAStandard(int, void *);
      36             : #endif
      37             : 
      38             : #include "hfa.h"
      39             : 
      40             : class HFABand;
      41             : class HFADictionary;
      42             : class HFAEntry;
      43             : class HFASpillFile;
      44             : class HFAType;
      45             : 
      46             : /************************************************************************/
      47             : /*      Flag indicating read/write, or read-only access to data.        */
      48             : /************************************************************************/
      49             : typedef enum
      50             : {
      51             :     /*! Read only (no update) access */ HFA_ReadOnly = 0,
      52             :     /*! Read/write access. */ HFA_Update = 1
      53             : } HFAAccess;
      54             : 
      55             : /************************************************************************/
      56             : /*                              HFAInfo_t                               */
      57             : /*                                                                      */
      58             : /*      This is just a structure, and used hold info about the whole    */
      59             : /*      dataset within hfaopen.cpp                                      */
      60             : /************************************************************************/
      61             : struct hfainfo
      62             : {
      63             :     VSILFILE *fp;
      64             : 
      65             :     char *pszPath;
      66             :     char *pszFilename;     // Sans path.
      67             :     char *pszIGEFilename;  // Sans path.
      68             : 
      69             :     HFAAccess eAccess;
      70             : 
      71             :     GUInt32 nEndOfFile;
      72             :     GUInt32 nRootPos;
      73             :     GUInt32 nDictionaryPos;
      74             : 
      75             :     GInt16 nEntryHeaderLength;
      76             :     GInt32 nVersion;
      77             : 
      78             :     bool bTreeDirty;
      79             :     HFAEntry *poRoot;
      80             : 
      81             :     HFADictionary *poDictionary;
      82             :     char *pszDictionary;
      83             : 
      84             :     int nXSize;
      85             :     int nYSize;
      86             : 
      87             :     int nBands;
      88             :     HFABand **papoBand;
      89             : 
      90             :     void *pMapInfo;
      91             :     void *pDatum;
      92             :     void *pProParameters;
      93             : 
      94             :     struct hfainfo *psDependent;
      95             : };
      96             : 
      97             : typedef struct hfainfo HFAInfo_t;
      98             : 
      99             : GUInt32 HFAAllocateSpace(HFAInfo_t *, GUInt32);
     100             : CPLErr HFAParseBandInfo(HFAInfo_t *);
     101             : HFAInfo_t *HFAGetDependent(HFAInfo_t *, const char *);
     102             : HFAInfo_t *HFACreateDependent(HFAInfo_t *psBase);
     103             : bool HFACreateSpillStack(HFAInfo_t *, int nXSize, int nYSize, int nLayers,
     104             :                          int nBlockSize, EPTType eDataType,
     105             :                          GIntBig *pnValidFlagsOffset, GIntBig *pnDataOffset);
     106             : 
     107             : const char *const *GetHFAAuxMetaDataList();
     108             : 
     109             : double *HFAReadBFUniqueBins(HFAEntry *poBinFunc, int nPCTColors);
     110             : 
     111             : int CPL_DLL HFACreateLayer(HFAHandle psInfo, HFAEntry *poParent,
     112             :                            const char *pszLayerName, int bOverview,
     113             :                            int nBlockSize, int bCreateCompressed,
     114             :                            int bCreateLargeRaster, int bDependentLayer,
     115             :                            int nXSize, int nYSize, EPTType eDataType,
     116             :                            char **papszOptions,
     117             : 
     118             :                            // These are only related to external (large) files.
     119             :                            GIntBig nStackValidFlagsOffset,
     120             :                            GIntBig nStackDataOffset, int nStackCount,
     121             :                            int nStackIndex);
     122             : 
     123             : std::unique_ptr<OGRSpatialReference>
     124             : HFAPCSStructToOSR(const Eprj_Datum *psDatum, const Eprj_ProParameters *psPro,
     125             :                   const Eprj_MapInfo *psMapInfo, HFAEntry *poMapInformation);
     126             : 
     127             : const char *const *HFAGetDatumMap();
     128             : const char *const *HFAGetUnitMap();
     129             : 
     130             : /************************************************************************/
     131             : /*                               HFABand                                */
     132             : /************************************************************************/
     133             : 
     134             : class HFABand
     135             : {
     136             :     int nBlocks;
     137             : 
     138             :     // Used for single-file modification.
     139             :     vsi_l_offset *panBlockStart;
     140             :     int *panBlockSize;
     141             :     int *panBlockFlag;
     142             : 
     143             :     // Used for spill-file modification.
     144             :     vsi_l_offset nBlockStart;
     145             :     vsi_l_offset nBlockSize;
     146             :     int nLayerStackCount;
     147             :     int nLayerStackIndex;
     148             : 
     149             : #define BFLG_VALID 0x01
     150             : #define BFLG_COMPRESSED 0x02
     151             : 
     152             :     int nPCTColors;
     153             :     double *apadfPCT[4];
     154             :     double *padfPCTBins;
     155             : 
     156             :     CPLErr LoadBlockInfo();
     157             :     CPLErr LoadExternalBlockInfo();
     158             : 
     159             :     void ReAllocBlock(int iBlock, int nSize);
     160             :     void NullBlock(void *);
     161             : 
     162             :     CPLString osOverName;
     163             : 
     164             :     CPL_DISALLOW_COPY_ASSIGN(HFABand)
     165             : 
     166             :   public:
     167             :     HFABand(HFAInfo_t *, HFAEntry *);
     168             :     ~HFABand();
     169             : 
     170             :     HFAInfo_t *psInfo;
     171             : 
     172             :     VSILFILE *fpExternal;
     173             : 
     174             :     EPTType eDataType;
     175             :     HFAEntry *poNode;
     176             : 
     177             :     int nBlockXSize;
     178             :     int nBlockYSize;
     179             : 
     180             :     int nWidth;
     181             :     int nHeight;
     182             : 
     183             :     int nBlocksPerRow;
     184             :     int nBlocksPerColumn;
     185             : 
     186             :     bool bNoDataSet;
     187             :     double dfNoData;
     188             : 
     189             :     bool bOverviewsPending;
     190             :     int nOverviews;
     191             :     HFABand **papoOverviews;
     192             : 
     193             :     CPLErr GetRasterBlock(int nXBlock, int nYBlock, void *pData, int nDataSize);
     194             :     CPLErr SetRasterBlock(int nXBlock, int nYBlock, void *pData);
     195             : 
     196             :     const char *GetBandName();
     197             :     void SetBandName(const char *pszName);
     198             : 
     199             :     CPLErr SetNoDataValue(double dfValue);
     200             : 
     201             :     CPLErr GetPCT(int *, double **, double **, double **, double **, double **);
     202             :     CPLErr SetPCT(int, const double *, const double *, const double *,
     203             :                   const double *);
     204             : 
     205             :     int CreateOverview(int nOverviewLevel, const char *pszResampling);
     206             :     CPLErr CleanOverviews();
     207             : 
     208             :     CPLErr LoadOverviews();
     209             : };
     210             : 
     211             : /************************************************************************/
     212             : /*                               HFAEntry                               */
     213             : /*                                                                      */
     214             : /*      Base class for all entry types.  Most entry types do not        */
     215             : /*      have a subclass, and are just handled generically with this     */
     216             : /*      class.                                                          */
     217             : /************************************************************************/
     218             : class HFAEntry
     219             : {
     220             :     bool bDirty;
     221             :     GUInt32 nFilePos;
     222             : 
     223             :     HFAInfo_t *psHFA;
     224             :     HFAEntry *poParent;
     225             :     HFAEntry *poPrev;
     226             : 
     227             :     GUInt32 nNextPos;
     228             :     HFAEntry *poNext;
     229             : 
     230             :     GUInt32 nChildPos;
     231             :     HFAEntry *poChild;
     232             : 
     233             :     char szName[64];
     234             :     char szType[32];
     235             : 
     236             :     HFAType *poType;
     237             : 
     238             :     GUInt32 nDataPos;
     239             :     GUInt32 nDataSize;
     240             :     GByte *pabyData;
     241             : 
     242             :     void LoadData();
     243             : 
     244             :     bool GetFieldValue(const char *, char, void *, int *pnRemainingDataSize);
     245             :     CPLErr SetFieldValue(const char *, char, void *);
     246             : 
     247             :     bool bIsMIFObject;
     248             : 
     249             :     HFAEntry();
     250             :     HFAEntry(const char *pszDictionary, const char *pszTypeName,
     251             :              int nDataSizeIn, GByte *pabyDataIn);
     252             :     std::vector<HFAEntry *> FindChildren(const char *pszName,
     253             :                                          const char *pszType, int nRecLevel,
     254             :                                          int *pbErrorDetected);
     255             : 
     256             :     CPL_DISALLOW_COPY_ASSIGN(HFAEntry)
     257             : 
     258             :   public:
     259             :     static HFAEntry *New(HFAInfo_t *psHFA, GUInt32 nPos, HFAEntry *poParent,
     260             :                          HFAEntry *poPrev) CPL_WARN_UNUSED_RESULT;
     261             : 
     262             :     HFAEntry(HFAInfo_t *psHFA, const char *pszNodeName, const char *pszTypeName,
     263             :              HFAEntry *poParent);
     264             : 
     265             :     static HFAEntry *New(HFAInfo_t *psHFA, const char *pszNodeName,
     266             :                          const char *pszTypeName,
     267             :                          HFAEntry *poParent) CPL_WARN_UNUSED_RESULT;
     268             : 
     269             :     virtual ~HFAEntry();
     270             : 
     271             :     static HFAEntry *BuildEntryFromMIFObject(HFAEntry *poContainer,
     272             :                                              const char *pszMIFObjectPath)
     273             :         CPL_WARN_UNUSED_RESULT;
     274             : 
     275             :     CPLErr RemoveAndDestroy();
     276             : 
     277         576 :     GUInt32 GetFilePos() const CPL_WARN_UNUSED_RESULT
     278             :     {
     279         576 :         return nFilePos;
     280             :     }
     281             : 
     282       69863 :     const char *GetName() const CPL_WARN_UNUSED_RESULT
     283             :     {
     284       69863 :         return szName;
     285             :     }
     286             : 
     287             :     void SetName(const char *pszNodeName);
     288             : 
     289        5641 :     const char *GetType() const CPL_WARN_UNUSED_RESULT
     290             :     {
     291        5641 :         return szType;
     292             :     }
     293             : 
     294             :     HFAType *GetTypeObject() CPL_WARN_UNUSED_RESULT;
     295             : 
     296         533 :     GByte *GetData() CPL_WARN_UNUSED_RESULT
     297             :     {
     298         533 :         LoadData();
     299         533 :         return pabyData;
     300             :     }
     301             : 
     302         400 :     GUInt32 GetDataPos() const CPL_WARN_UNUSED_RESULT
     303             :     {
     304         400 :         return nDataPos;
     305             :     }
     306             : 
     307         539 :     GUInt32 GetDataSize() const CPL_WARN_UNUSED_RESULT
     308             :     {
     309         539 :         return nDataSize;
     310             :     }
     311             : 
     312             :     HFAEntry *GetChild() CPL_WARN_UNUSED_RESULT;
     313             :     HFAEntry *GetNext() CPL_WARN_UNUSED_RESULT;
     314             :     HFAEntry *GetNamedChild(const char *) CPL_WARN_UNUSED_RESULT;
     315             :     std::vector<HFAEntry *>
     316             :     FindChildren(const char *pszName,
     317             :                  const char *pszType) CPL_WARN_UNUSED_RESULT;
     318             : 
     319             :     GInt32 GetIntField(const char *, CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     320             :     double GetDoubleField(const char *,
     321             :                           CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     322             :     const char *
     323             :     GetStringField(const char *, CPLErr * = nullptr,
     324             :                    int *pnRemainingDataSize = nullptr) CPL_WARN_UNUSED_RESULT;
     325             :     GIntBig GetBigIntField(const char *,
     326             :                            CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     327             :     int GetFieldCount(const char *, CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     328             : 
     329             :     CPLErr SetIntField(const char *, int);
     330             :     CPLErr SetDoubleField(const char *, double);
     331             :     CPLErr SetStringField(const char *, const char *);
     332             : 
     333             :     void DumpFieldValues(FILE *, const char * = nullptr);
     334             : 
     335             :     void SetPosition();
     336             :     CPLErr FlushToDisk();
     337             : 
     338             :     void MarkDirty();
     339             :     GByte *MakeData(int nSize = 0);
     340             : };
     341             : 
     342             : /************************************************************************/
     343             : /*                               HFAField                               */
     344             : /*                                                                      */
     345             : /*      A field in a HFAType in the dictionary.                         */
     346             : /************************************************************************/
     347             : 
     348             : class HFAField
     349             : {
     350             :   public:
     351             :     int nBytes;
     352             : 
     353             :     int nItemCount;
     354             :     // TODO(schwehr): Rename chPointer to something more meaningful.
     355             :     // It's not a pointer.
     356             :     char chPointer;   // '\0', '*' or 'p'
     357             :     char chItemType;  // 1|2|4|e|...
     358             : 
     359             :     char *pszItemObjectType;  // if chItemType == 'o'
     360             :     HFAType *poItemObjectType;
     361             : 
     362             :     char **papszEnumNames;  // Normally NULL if not an enum.
     363             : 
     364             :     char *pszFieldName;
     365             : 
     366             :     char szNumberString[36];  // Buffer used to return int as a string.
     367             : 
     368             :     HFAField();
     369             :     ~HFAField();
     370             : 
     371             :     const char *Initialize(const char *);
     372             : 
     373             :     bool CompleteDefn(HFADictionary *);
     374             : 
     375             :     void Dump(FILE *);
     376             : 
     377             :     bool ExtractInstValue(const char *pszField, int nIndexValue,
     378             :                           GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
     379             :                           char chReqType, void *pReqReturn,
     380             :                           int *pnRemainingDataSize = nullptr);
     381             : 
     382             :     CPLErr SetInstValue(const char *pszField, int nIndexValue, GByte *pabyData,
     383             :                         GUInt32 nDataOffset, int nDataSize, char chReqType,
     384             :                         void *pValue);
     385             : 
     386             :     void DumpInstValue(FILE *fpOut, GByte *pabyData, GUInt32 nDataOffset,
     387             :                        int nDataSize, const char *pszPrefix = nullptr);
     388             : 
     389             :     int GetInstBytes(GByte *, int, std::set<HFAField *> &oVisitedFields);
     390             :     int GetInstCount(GByte *pabyData, int nDataSize) const;
     391             : };
     392             : 
     393             : /************************************************************************/
     394             : /*                               HFAType                                */
     395             : /*                                                                      */
     396             : /*      A type in the dictionary.                                       */
     397             : /************************************************************************/
     398             : 
     399             : class HFAType
     400             : {
     401             :     bool bInCompleteDefn;
     402             : 
     403             :   public:
     404             :     int nBytes;
     405             : 
     406             :     std::vector<std::unique_ptr<HFAField>> apoFields;
     407             : 
     408             :     char *pszTypeName;
     409             : 
     410             :     HFAType();
     411             :     ~HFAType();
     412             : 
     413             :     const char *Initialize(const char *);
     414             : 
     415             :     bool CompleteDefn(HFADictionary *);
     416             : 
     417             :     void Dump(FILE *);
     418             : 
     419             :     int GetInstBytes(GByte *, int, std::set<HFAField *> &oVisitedFields) const;
     420             :     int GetInstCount(const char *pszField, GByte *pabyData, GUInt32 nDataOffset,
     421             :                      int nDataSize);
     422             :     bool ExtractInstValue(const char *pszField, GByte *pabyData,
     423             :                           GUInt32 nDataOffset, int nDataSize, char chReqType,
     424             :                           void *pReqReturn, int *pnRemainingDataSize);
     425             :     CPLErr SetInstValue(const char *pszField, GByte *pabyData,
     426             :                         GUInt32 nDataOffset, int nDataSize, char chReqType,
     427             :                         void *pValue);
     428             :     void DumpInstValue(FILE *fpOut, GByte *pabyData, GUInt32 nDataOffset,
     429             :                        int nDataSize, const char *pszPrefix = nullptr) const;
     430             : };
     431             : 
     432             : /************************************************************************/
     433             : /*                            HFADictionary                             */
     434             : /************************************************************************/
     435             : 
     436             : class HFADictionary
     437             : {
     438             :   public:
     439             :     explicit HFADictionary(const char *pszDict);
     440             :     ~HFADictionary();
     441             : 
     442             :     HFAType *FindType(const char *);
     443             :     void AddType(HFAType *);
     444             : 
     445             :     static int GetItemSize(char);
     446             : 
     447             :     void Dump(FILE *);
     448             : 
     449             :   private:
     450             :     int nTypes;
     451             :     int nTypesMax;
     452             :     HFAType **papoTypes;
     453             : 
     454             :     CPL_DISALLOW_COPY_ASSIGN(HFADictionary)
     455             : 
     456             :   public:
     457             :     // TODO(schwehr): Make these members private.
     458             :     CPLString osDictionaryText;
     459             :     bool bDictionaryTextDirty;
     460             : };
     461             : 
     462             : /************************************************************************/
     463             : /*                             HFACompress                              */
     464             : /*                                                                      */
     465             : /*      Class that given a block of memory compresses the contents      */
     466             : /*      using run length encoding (RLE) as used by Imagine.             */
     467             : /************************************************************************/
     468             : 
     469             : class HFACompress
     470             : {
     471             :   public:
     472             :     HFACompress(void *pData, GUInt32 nBlockSize, EPTType eDataType);
     473             :     ~HFACompress();
     474             : 
     475             :     // This is the method that does the work.
     476             :     bool compressBlock();
     477             : 
     478             :     // Static method to allow us to query whether HFA type supported.
     479             :     static bool QueryDataTypeSupported(EPTType eHFADataType);
     480             : 
     481             :     // Get methods - only valid after compressBlock has been called.
     482          32 :     GByte *getCounts() const
     483             :     {
     484          32 :         return m_pCounts;
     485             :     }
     486             : 
     487          15 :     GUInt32 getCountSize() const
     488             :     {
     489          15 :         return m_nSizeCounts;
     490             :     }
     491             : 
     492          32 :     GByte *getValues() const
     493             :     {
     494          32 :         return m_pValues;
     495             :     }
     496             : 
     497          15 :     GUInt32 getValueSize() const
     498             :     {
     499          15 :         return m_nSizeValues;
     500             :     }
     501             : 
     502          15 :     GUInt32 getMin() const
     503             :     {
     504          15 :         return m_nMin;
     505             :     }
     506             : 
     507          15 :     GUInt32 getNumRuns() const
     508             :     {
     509          15 :         return m_nNumRuns;
     510             :     }
     511             : 
     512          15 :     GByte getNumBits() const
     513             :     {
     514          15 :         return m_nNumBits;
     515             :     }
     516             : 
     517             :   private:
     518             :     static void makeCount(GUInt32 count, GByte *pCounter, GUInt32 *pnSizeCount);
     519             :     GUInt32 findMin(GByte *pNumBits);
     520             :     GUInt32 valueAsUInt32(GUInt32 index);
     521             :     void encodeValue(GUInt32 val, GUInt32 repeat);
     522             : 
     523             :     void *m_pData;
     524             :     GUInt32 m_nBlockSize;
     525             :     GUInt32 m_nBlockCount;
     526             :     EPTType m_eDataType;
     527             :     // The number of bits the datatype we are trying to compress takes.
     528             :     int m_nDataTypeNumBits;
     529             : 
     530             :     GByte *m_pCounts;
     531             :     GByte *m_pCurrCount;
     532             :     GUInt32 m_nSizeCounts;
     533             : 
     534             :     GByte *m_pValues;
     535             :     GByte *m_pCurrValues;
     536             :     GUInt32 m_nSizeValues;
     537             : 
     538             :     GUInt32 m_nMin;
     539             :     GUInt32 m_nNumRuns;
     540             :     // The number of bits needed to compress the range of values in the block.
     541             :     GByte m_nNumBits;
     542             : };
     543             : 
     544             : #endif /* ndef HFA_P_H_INCLUDED */

Generated by: LCOV version 1.14