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-01-18 12:42:00 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             :   public:
     165             :     HFABand(HFAInfo_t *, HFAEntry *);
     166             :     ~HFABand();
     167             : 
     168             :     HFAInfo_t *psInfo;
     169             : 
     170             :     VSILFILE *fpExternal;
     171             : 
     172             :     EPTType eDataType;
     173             :     HFAEntry *poNode;
     174             : 
     175             :     int nBlockXSize;
     176             :     int nBlockYSize;
     177             : 
     178             :     int nWidth;
     179             :     int nHeight;
     180             : 
     181             :     int nBlocksPerRow;
     182             :     int nBlocksPerColumn;
     183             : 
     184             :     bool bNoDataSet;
     185             :     double dfNoData;
     186             : 
     187             :     bool bOverviewsPending;
     188             :     int nOverviews;
     189             :     HFABand **papoOverviews;
     190             : 
     191             :     CPLErr GetRasterBlock(int nXBlock, int nYBlock, void *pData, int nDataSize);
     192             :     CPLErr SetRasterBlock(int nXBlock, int nYBlock, void *pData);
     193             : 
     194             :     const char *GetBandName();
     195             :     void SetBandName(const char *pszName);
     196             : 
     197             :     CPLErr SetNoDataValue(double dfValue);
     198             : 
     199             :     CPLErr GetPCT(int *, double **, double **, double **, double **, double **);
     200             :     CPLErr SetPCT(int, const double *, const double *, const double *,
     201             :                   const double *);
     202             : 
     203             :     int CreateOverview(int nOverviewLevel, const char *pszResampling);
     204             :     CPLErr CleanOverviews();
     205             : 
     206             :     CPLErr LoadOverviews();
     207             : };
     208             : 
     209             : /************************************************************************/
     210             : /*                               HFAEntry                               */
     211             : /*                                                                      */
     212             : /*      Base class for all entry types.  Most entry types do not        */
     213             : /*      have a subclass, and are just handled generically with this     */
     214             : /*      class.                                                          */
     215             : /************************************************************************/
     216             : class HFAEntry
     217             : {
     218             :     bool bDirty;
     219             :     GUInt32 nFilePos;
     220             : 
     221             :     HFAInfo_t *psHFA;
     222             :     HFAEntry *poParent;
     223             :     HFAEntry *poPrev;
     224             : 
     225             :     GUInt32 nNextPos;
     226             :     HFAEntry *poNext;
     227             : 
     228             :     GUInt32 nChildPos;
     229             :     HFAEntry *poChild;
     230             : 
     231             :     char szName[64];
     232             :     char szType[32];
     233             : 
     234             :     HFAType *poType;
     235             : 
     236             :     GUInt32 nDataPos;
     237             :     GUInt32 nDataSize;
     238             :     GByte *pabyData;
     239             : 
     240             :     void LoadData();
     241             : 
     242             :     bool GetFieldValue(const char *, char, void *, int *pnRemainingDataSize);
     243             :     CPLErr SetFieldValue(const char *, char, void *);
     244             : 
     245             :     bool bIsMIFObject;
     246             : 
     247             :     HFAEntry();
     248             :     HFAEntry(const char *pszDictionary, const char *pszTypeName,
     249             :              int nDataSizeIn, GByte *pabyDataIn);
     250             :     std::vector<HFAEntry *> FindChildren(const char *pszName,
     251             :                                          const char *pszType, int nRecLevel,
     252             :                                          int *pbErrorDetected);
     253             : 
     254             :   public:
     255             :     static HFAEntry *New(HFAInfo_t *psHFA, GUInt32 nPos, HFAEntry *poParent,
     256             :                          HFAEntry *poPrev) CPL_WARN_UNUSED_RESULT;
     257             : 
     258             :     HFAEntry(HFAInfo_t *psHFA, const char *pszNodeName, const char *pszTypeName,
     259             :              HFAEntry *poParent);
     260             : 
     261             :     static HFAEntry *New(HFAInfo_t *psHFA, const char *pszNodeName,
     262             :                          const char *pszTypeName,
     263             :                          HFAEntry *poParent) CPL_WARN_UNUSED_RESULT;
     264             : 
     265             :     virtual ~HFAEntry();
     266             : 
     267             :     static HFAEntry *BuildEntryFromMIFObject(HFAEntry *poContainer,
     268             :                                              const char *pszMIFObjectPath)
     269             :         CPL_WARN_UNUSED_RESULT;
     270             : 
     271             :     CPLErr RemoveAndDestroy();
     272             : 
     273         552 :     GUInt32 GetFilePos() const CPL_WARN_UNUSED_RESULT
     274             :     {
     275         552 :         return nFilePos;
     276             :     }
     277             : 
     278       69442 :     const char *GetName() const CPL_WARN_UNUSED_RESULT
     279             :     {
     280       69442 :         return szName;
     281             :     }
     282             : 
     283             :     void SetName(const char *pszNodeName);
     284             : 
     285        5698 :     const char *GetType() const CPL_WARN_UNUSED_RESULT
     286             :     {
     287        5698 :         return szType;
     288             :     }
     289             : 
     290             :     HFAType *GetTypeObject() CPL_WARN_UNUSED_RESULT;
     291             : 
     292         512 :     GByte *GetData() CPL_WARN_UNUSED_RESULT
     293             :     {
     294         512 :         LoadData();
     295         512 :         return pabyData;
     296             :     }
     297             : 
     298         385 :     GUInt32 GetDataPos() const CPL_WARN_UNUSED_RESULT
     299             :     {
     300         385 :         return nDataPos;
     301             :     }
     302             : 
     303         518 :     GUInt32 GetDataSize() const CPL_WARN_UNUSED_RESULT
     304             :     {
     305         518 :         return nDataSize;
     306             :     }
     307             : 
     308             :     HFAEntry *GetChild() CPL_WARN_UNUSED_RESULT;
     309             :     HFAEntry *GetNext() CPL_WARN_UNUSED_RESULT;
     310             :     HFAEntry *GetNamedChild(const char *) CPL_WARN_UNUSED_RESULT;
     311             :     std::vector<HFAEntry *>
     312             :     FindChildren(const char *pszName,
     313             :                  const char *pszType) CPL_WARN_UNUSED_RESULT;
     314             : 
     315             :     GInt32 GetIntField(const char *, CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     316             :     double GetDoubleField(const char *,
     317             :                           CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     318             :     const char *
     319             :     GetStringField(const char *, CPLErr * = nullptr,
     320             :                    int *pnRemainingDataSize = nullptr) CPL_WARN_UNUSED_RESULT;
     321             :     GIntBig GetBigIntField(const char *,
     322             :                            CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     323             :     int GetFieldCount(const char *, CPLErr * = nullptr) CPL_WARN_UNUSED_RESULT;
     324             : 
     325             :     CPLErr SetIntField(const char *, int);
     326             :     CPLErr SetDoubleField(const char *, double);
     327             :     CPLErr SetStringField(const char *, const char *);
     328             : 
     329             :     void DumpFieldValues(FILE *, const char * = nullptr);
     330             : 
     331             :     void SetPosition();
     332             :     CPLErr FlushToDisk();
     333             : 
     334             :     void MarkDirty();
     335             :     GByte *MakeData(int nSize = 0);
     336             : };
     337             : 
     338             : /************************************************************************/
     339             : /*                               HFAField                               */
     340             : /*                                                                      */
     341             : /*      A field in a HFAType in the dictionary.                         */
     342             : /************************************************************************/
     343             : 
     344             : class HFAField
     345             : {
     346             :   public:
     347             :     int nBytes;
     348             : 
     349             :     int nItemCount;
     350             :     // TODO(schwehr): Rename chPointer to something more meaningful.
     351             :     // It's not a pointer.
     352             :     char chPointer;   // '\0', '*' or 'p'
     353             :     char chItemType;  // 1|2|4|e|...
     354             : 
     355             :     char *pszItemObjectType;  // if chItemType == 'o'
     356             :     HFAType *poItemObjectType;
     357             : 
     358             :     char **papszEnumNames;  // Normally NULL if not an enum.
     359             : 
     360             :     char *pszFieldName;
     361             : 
     362             :     char szNumberString[36];  // Buffer used to return int as a string.
     363             : 
     364             :     HFAField();
     365             :     ~HFAField();
     366             : 
     367             :     const char *Initialize(const char *);
     368             : 
     369             :     bool CompleteDefn(HFADictionary *);
     370             : 
     371             :     void Dump(FILE *);
     372             : 
     373             :     bool ExtractInstValue(const char *pszField, int nIndexValue,
     374             :                           GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
     375             :                           char chReqType, void *pReqReturn,
     376             :                           int *pnRemainingDataSize = nullptr);
     377             : 
     378             :     CPLErr SetInstValue(const char *pszField, int nIndexValue, GByte *pabyData,
     379             :                         GUInt32 nDataOffset, int nDataSize, char chReqType,
     380             :                         void *pValue);
     381             : 
     382             :     void DumpInstValue(FILE *fpOut, GByte *pabyData, GUInt32 nDataOffset,
     383             :                        int nDataSize, const char *pszPrefix = nullptr);
     384             : 
     385             :     int GetInstBytes(GByte *, int, std::set<HFAField *> &oVisitedFields);
     386             :     int GetInstCount(GByte *pabyData, int nDataSize) const;
     387             : };
     388             : 
     389             : /************************************************************************/
     390             : /*                               HFAType                                */
     391             : /*                                                                      */
     392             : /*      A type in the dictionary.                                       */
     393             : /************************************************************************/
     394             : 
     395             : class HFAType
     396             : {
     397             :     bool bInCompleteDefn;
     398             : 
     399             :   public:
     400             :     int nBytes;
     401             : 
     402             :     std::vector<std::unique_ptr<HFAField>> apoFields;
     403             : 
     404             :     char *pszTypeName;
     405             : 
     406             :     HFAType();
     407             :     ~HFAType();
     408             : 
     409             :     const char *Initialize(const char *);
     410             : 
     411             :     bool CompleteDefn(HFADictionary *);
     412             : 
     413             :     void Dump(FILE *);
     414             : 
     415             :     int GetInstBytes(GByte *, int, std::set<HFAField *> &oVisitedFields) const;
     416             :     int GetInstCount(const char *pszField, GByte *pabyData, GUInt32 nDataOffset,
     417             :                      int nDataSize);
     418             :     bool ExtractInstValue(const char *pszField, GByte *pabyData,
     419             :                           GUInt32 nDataOffset, int nDataSize, char chReqType,
     420             :                           void *pReqReturn, int *pnRemainingDataSize);
     421             :     CPLErr SetInstValue(const char *pszField, GByte *pabyData,
     422             :                         GUInt32 nDataOffset, int nDataSize, char chReqType,
     423             :                         void *pValue);
     424             :     void DumpInstValue(FILE *fpOut, GByte *pabyData, GUInt32 nDataOffset,
     425             :                        int nDataSize, const char *pszPrefix = nullptr) const;
     426             : };
     427             : 
     428             : /************************************************************************/
     429             : /*                            HFADictionary                             */
     430             : /************************************************************************/
     431             : 
     432             : class HFADictionary
     433             : {
     434             :   public:
     435             :     explicit HFADictionary(const char *pszDict);
     436             :     ~HFADictionary();
     437             : 
     438             :     HFAType *FindType(const char *);
     439             :     void AddType(HFAType *);
     440             : 
     441             :     static int GetItemSize(char);
     442             : 
     443             :     void Dump(FILE *);
     444             : 
     445             :   private:
     446             :     int nTypes;
     447             :     int nTypesMax;
     448             :     HFAType **papoTypes;
     449             : 
     450             :   public:
     451             :     // TODO(schwehr): Make these members private.
     452             :     CPLString osDictionaryText;
     453             :     bool bDictionaryTextDirty;
     454             : };
     455             : 
     456             : /************************************************************************/
     457             : /*                             HFACompress                              */
     458             : /*                                                                      */
     459             : /*      Class that given a block of memory compresses the contents      */
     460             : /*      using run length encoding (RLE) as used by Imagine.             */
     461             : /************************************************************************/
     462             : 
     463             : class HFACompress
     464             : {
     465             :   public:
     466             :     HFACompress(void *pData, GUInt32 nBlockSize, EPTType eDataType);
     467             :     ~HFACompress();
     468             : 
     469             :     // This is the method that does the work.
     470             :     bool compressBlock();
     471             : 
     472             :     // Static method to allow us to query whether HFA type supported.
     473             :     static bool QueryDataTypeSupported(EPTType eHFADataType);
     474             : 
     475             :     // Get methods - only valid after compressBlock has been called.
     476          28 :     GByte *getCounts() const
     477             :     {
     478          28 :         return m_pCounts;
     479             :     }
     480             : 
     481          13 :     GUInt32 getCountSize() const
     482             :     {
     483          13 :         return m_nSizeCounts;
     484             :     }
     485             : 
     486          28 :     GByte *getValues() const
     487             :     {
     488          28 :         return m_pValues;
     489             :     }
     490             : 
     491          13 :     GUInt32 getValueSize() const
     492             :     {
     493          13 :         return m_nSizeValues;
     494             :     }
     495             : 
     496          13 :     GUInt32 getMin() const
     497             :     {
     498          13 :         return m_nMin;
     499             :     }
     500             : 
     501          13 :     GUInt32 getNumRuns() const
     502             :     {
     503          13 :         return m_nNumRuns;
     504             :     }
     505             : 
     506          13 :     GByte getNumBits() const
     507             :     {
     508          13 :         return m_nNumBits;
     509             :     }
     510             : 
     511             :   private:
     512             :     static void makeCount(GUInt32 count, GByte *pCounter, GUInt32 *pnSizeCount);
     513             :     GUInt32 findMin(GByte *pNumBits);
     514             :     GUInt32 valueAsUInt32(GUInt32 index);
     515             :     void encodeValue(GUInt32 val, GUInt32 repeat);
     516             : 
     517             :     void *m_pData;
     518             :     GUInt32 m_nBlockSize;
     519             :     GUInt32 m_nBlockCount;
     520             :     EPTType m_eDataType;
     521             :     // The number of bits the datatype we are trying to compress takes.
     522             :     int m_nDataTypeNumBits;
     523             : 
     524             :     GByte *m_pCounts;
     525             :     GByte *m_pCurrCount;
     526             :     GUInt32 m_nSizeCounts;
     527             : 
     528             :     GByte *m_pValues;
     529             :     GByte *m_pCurrValues;
     530             :     GUInt32 m_nSizeValues;
     531             : 
     532             :     GUInt32 m_nMin;
     533             :     GUInt32 m_nNumRuns;
     534             :     // The number of bits needed to compress the range of values in the block.
     535             :     GByte m_nNumBits;
     536             : };
     537             : 
     538             : #endif /* ndef HFA_P_H_INCLUDED */

Generated by: LCOV version 1.14