LCOV - code coverage report
Current view: top level - frmts/hfa - hfadictionary.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 58 67 86.6 %
Date: 2024-11-21 22:18:42 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Erdas Imagine (.img) Translator
       4             :  * Purpose:  Implementation of the HFADictionary class for managing the
       5             :  *           dictionary read from the HFA file.  Most work done by the
       6             :  *           HFAType, and HFAField classes.
       7             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 1999, Intergraph Corporation
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "cpl_port.h"
      16             : #include "hfa_p.h"
      17             : 
      18             : #include <cstdio>
      19             : #include <cstring>
      20             : #include <string>
      21             : 
      22             : #include "cpl_conv.h"
      23             : #include "cpl_error.h"
      24             : #include "cpl_string.h"
      25             : #include "cpl_vsi.h"
      26             : 
      27             : static const char *const apszDefDefn[] = {
      28             :     "Edsc_Table",
      29             :     "{1:lnumrows,}Edsc_Table",
      30             : 
      31             :     "Edsc_Column",
      32             :     "{1:lnumRows,1:LcolumnDataPtr,1:e4:integer,real,complex,string,dataType,1:"
      33             :     "lmaxNumChars,}Edsc_Column",
      34             : 
      35             :     "Eprj_Size",
      36             :     "{1:dwidth,1:dheight,}Eprj_Size",
      37             : 
      38             :     "Eprj_Coordinate",
      39             :     "{1:dx,1:dy,}Eprj_Coordinate",
      40             : 
      41             :     "Eprj_MapInfo",
      42             :     "{0:pcproName,1:*oEprj_Coordinate,upperLeftCenter,1:*oEprj_Coordinate,"
      43             :     "lowerRightCenter,1:*oEprj_Size,pixelSize,0:pcunits,}Eprj_MapInfo",
      44             : 
      45             :     "Eimg_StatisticsParameters830",
      46             :     "{0:poEmif_String,LayerNames,1:*bExcludedValues,1:oEmif_String,AOIname,1:"
      47             :     "lSkipFactorX,1:lSkipFactorY,1:*oEdsc_BinFunction,BinFunction,}Eimg_"
      48             :     "StatisticsParameters830",
      49             : 
      50             :     "Esta_Statistics",
      51             :     "{1:dminimum,1:dmaximum,1:dmean,1:dmedian,1:dmode,1:dstddev,}Esta_"
      52             :     "Statistics",
      53             : 
      54             :     "Edsc_BinFunction",
      55             :     "{1:lnumBins,1:e4:direct,linear,logarithmic,explicit,binFunctionType,1:"
      56             :     "dminLimit,1:dmaxLimit,1:*bbinLimits,}Edsc_BinFunction",
      57             : 
      58             :     "Eimg_NonInitializedValue",
      59             :     "{1:*bvalueBD,}Eimg_NonInitializedValue",
      60             : 
      61             :     "Eprj_MapProjection842",
      62             :     "{1:x{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,"
      63             :     "MIFDictionary,0:pCMIFObject,}Emif_MIFObject,projection,1:x{0:pcstring,}"
      64             :     "Emif_String,title,}Eprj_MapProjection842",
      65             : 
      66             :     "Emif_MIFObject",
      67             :     "{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,"
      68             :     "MIFDictionary,0:pCMIFObject,}Emif_MIFObject",
      69             : 
      70             :     "Eprj_ProParameters",
      71             :     "{1:e2:EPRJ_INTERNAL,EPRJ_EXTERNAL,proType,1:lproNumber,0:pcproExeName,0:"
      72             :     "pcproName,1:lproZone,0:pdproParams,1:*oEprj_Spheroid,proSpheroid,}Eprj_"
      73             :     "ProParameters",
      74             : 
      75             :     "Eprj_Datum",
      76             :     "{0:pcdatumname,1:e3:EPRJ_DATUM_PARAMETRIC,EPRJ_DATUM_GRID,EPRJ_DATUM_"
      77             :     "REGRESSION,type,0:pdparams,0:pcgridname,}Eprj_Datum",
      78             : 
      79             :     "Eprj_Spheroid",
      80             :     "{0:pcsphereName,1:da,1:db,1:deSquared,1:dradius,}Eprj_Spheroid",
      81             : 
      82             :     nullptr,
      83             :     nullptr};
      84             : 
      85             : /************************************************************************/
      86             : /* ==================================================================== */
      87             : /*                             HFADictionary                            */
      88             : /* ==================================================================== */
      89             : /************************************************************************/
      90             : 
      91             : /************************************************************************/
      92             : /*                           HFADictionary()                            */
      93             : /************************************************************************/
      94             : 
      95         948 : HFADictionary::HFADictionary(const char *pszString)
      96             :     : nTypes(0), nTypesMax(0), papoTypes(nullptr), osDictionaryText(pszString),
      97         948 :       bDictionaryTextDirty(false)
      98             : {
      99             :     // Read all the types.
     100             :     // TODO(schwehr): Refactor this approach to be more obvious.
     101       28338 :     while (pszString != nullptr && *pszString != '.')
     102             :     {
     103       27390 :         HFAType *poNewType = new HFAType();
     104       27390 :         pszString = poNewType->Initialize(pszString);
     105             : 
     106       27390 :         if (pszString != nullptr)
     107       27389 :             AddType(poNewType);
     108             :         else
     109           1 :             delete poNewType;
     110             :     }
     111             : 
     112             :     // Complete the definitions.
     113       28337 :     for (int i = 0; i < nTypes; i++)
     114             :     {
     115       27389 :         papoTypes[i]->CompleteDefn(this);
     116             :     }
     117         948 : }
     118             : 
     119             : /************************************************************************/
     120             : /*                           ~HFADictionary()                           */
     121             : /************************************************************************/
     122             : 
     123         948 : HFADictionary::~HFADictionary()
     124             : 
     125             : {
     126       28342 :     for (int i = 0; i < nTypes; i++)
     127       27394 :         delete papoTypes[i];
     128             : 
     129         948 :     CPLFree(papoTypes);
     130         948 : }
     131             : 
     132             : /************************************************************************/
     133             : /*                              AddType()                               */
     134             : /************************************************************************/
     135             : 
     136       27394 : void HFADictionary::AddType(HFAType *poType)
     137             : 
     138             : {
     139       27394 :     if (nTypes == nTypesMax
     140             : #ifdef DEBUG
     141             :         // To please Coverity.
     142       24990 :         || papoTypes == nullptr
     143             : #endif
     144             :     )
     145             :     {
     146        2404 :         nTypesMax = nTypes * 2 + 10;
     147        2404 :         papoTypes = static_cast<HFAType **>(
     148        2404 :             CPLRealloc(papoTypes, sizeof(void *) * nTypesMax));
     149             :     }
     150             : 
     151       27394 :     papoTypes[nTypes++] = poType;
     152       27394 : }
     153             : 
     154             : /************************************************************************/
     155             : /*                              FindType()                              */
     156             : /************************************************************************/
     157             : 
     158       19965 : HFAType *HFADictionary::FindType(const char *pszName)
     159             : 
     160             : {
     161      331142 :     for (int i = 0; i < nTypes; i++)
     162             :     {
     163      331134 :         if (papoTypes[i]->pszTypeName != nullptr &&
     164      331134 :             strcmp(pszName, papoTypes[i]->pszTypeName) == 0)
     165       19957 :             return papoTypes[i];
     166             :     }
     167             : 
     168             :     // Check if this is a type have other knowledge of.  If so, add
     169             :     // it to the dictionary now.  I'm not sure how some files end
     170             :     // up being distributed using types not in the dictionary.
     171          47 :     for (int i = 0; apszDefDefn[i] != nullptr; i += 2)
     172             :     {
     173          45 :         if (strcmp(pszName, apszDefDefn[i]) == 0)
     174             :         {
     175           6 :             HFAType *poNewType = new HFAType();
     176             : 
     177           6 :             poNewType->Initialize(apszDefDefn[i + 1]);
     178           6 :             if (!poNewType->CompleteDefn(this))
     179             :             {
     180           1 :                 delete poNewType;
     181           1 :                 return nullptr;
     182             :             }
     183           5 :             AddType(poNewType);
     184             : 
     185           5 :             if (!osDictionaryText.empty())
     186           5 :                 osDictionaryText.erase(osDictionaryText.size() - 1, 1);
     187           5 :             osDictionaryText += apszDefDefn[i + 1];
     188           5 :             osDictionaryText += ",.";
     189             : 
     190           5 :             bDictionaryTextDirty = true;
     191             : 
     192           5 :             return poNewType;
     193             :         }
     194             :     }
     195             : 
     196           2 :     return nullptr;
     197             : }
     198             : 
     199             : /************************************************************************/
     200             : /*                            GetItemSize()                             */
     201             : /*                                                                      */
     202             : /*      Get the size of a basic (atomic) item.                          */
     203             : /************************************************************************/
     204             : 
     205      152633 : int HFADictionary::GetItemSize(char chType)
     206             : 
     207             : {
     208      152633 :     switch (chType)
     209             :     {
     210       71499 :         case '1':
     211             :         case '2':
     212             :         case '4':
     213             :         case 'c':
     214             :         case 'C':
     215       71499 :             return 1;
     216             : 
     217       15604 :         case 'e':
     218             :         case 's':
     219             :         case 'S':
     220       15604 :             return 2;
     221             : 
     222       41996 :         case 't':
     223             :         case 'l':
     224             :         case 'L':
     225             :         case 'f':
     226       41996 :             return 4;
     227             : 
     228       18899 :         case 'd':
     229             :         case 'm':
     230       18899 :             return 8;
     231             : 
     232           0 :         case 'M':
     233           0 :             return 16;
     234             : 
     235        4632 :         case 'b':
     236        4632 :             return -1;
     237             : 
     238           3 :         case 'o':
     239             :         case 'x':
     240           3 :             return 0;
     241             : 
     242           0 :         default:
     243           0 :             CPLAssert(false);
     244             :     }
     245             : 
     246             :     return 0;
     247             : }
     248             : 
     249             : /************************************************************************/
     250             : /*                                Dump()                                */
     251             : /************************************************************************/
     252             : 
     253           0 : void HFADictionary::Dump(FILE *fp)
     254             : 
     255             : {
     256           0 :     CPL_IGNORE_RET_VAL(VSIFPrintf(fp, "\nHFADictionary:\n"));
     257             : 
     258           0 :     for (int i = 0; i < nTypes; i++)
     259             :     {
     260           0 :         papoTypes[i]->Dump(fp);
     261             :     }
     262           0 : }

Generated by: LCOV version 1.14