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-05-06 22:33:47 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #include "cpl_port.h"
      32             : #include "hfa_p.h"
      33             : 
      34             : #include <cstdio>
      35             : #include <cstring>
      36             : #include <string>
      37             : 
      38             : #include "cpl_conv.h"
      39             : #include "cpl_error.h"
      40             : #include "cpl_string.h"
      41             : #include "cpl_vsi.h"
      42             : 
      43             : static const char *const apszDefDefn[] = {
      44             :     "Edsc_Table",
      45             :     "{1:lnumrows,}Edsc_Table",
      46             : 
      47             :     "Edsc_Column",
      48             :     "{1:lnumRows,1:LcolumnDataPtr,1:e4:integer,real,complex,string,dataType,1:"
      49             :     "lmaxNumChars,}Edsc_Column",
      50             : 
      51             :     "Eprj_Size",
      52             :     "{1:dwidth,1:dheight,}Eprj_Size",
      53             : 
      54             :     "Eprj_Coordinate",
      55             :     "{1:dx,1:dy,}Eprj_Coordinate",
      56             : 
      57             :     "Eprj_MapInfo",
      58             :     "{0:pcproName,1:*oEprj_Coordinate,upperLeftCenter,1:*oEprj_Coordinate,"
      59             :     "lowerRightCenter,1:*oEprj_Size,pixelSize,0:pcunits,}Eprj_MapInfo",
      60             : 
      61             :     "Eimg_StatisticsParameters830",
      62             :     "{0:poEmif_String,LayerNames,1:*bExcludedValues,1:oEmif_String,AOIname,1:"
      63             :     "lSkipFactorX,1:lSkipFactorY,1:*oEdsc_BinFunction,BinFunction,}Eimg_"
      64             :     "StatisticsParameters830",
      65             : 
      66             :     "Esta_Statistics",
      67             :     "{1:dminimum,1:dmaximum,1:dmean,1:dmedian,1:dmode,1:dstddev,}Esta_"
      68             :     "Statistics",
      69             : 
      70             :     "Edsc_BinFunction",
      71             :     "{1:lnumBins,1:e4:direct,linear,logarithmic,explicit,binFunctionType,1:"
      72             :     "dminLimit,1:dmaxLimit,1:*bbinLimits,}Edsc_BinFunction",
      73             : 
      74             :     "Eimg_NonInitializedValue",
      75             :     "{1:*bvalueBD,}Eimg_NonInitializedValue",
      76             : 
      77             :     "Eprj_MapProjection842",
      78             :     "{1:x{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,"
      79             :     "MIFDictionary,0:pCMIFObject,}Emif_MIFObject,projection,1:x{0:pcstring,}"
      80             :     "Emif_String,title,}Eprj_MapProjection842",
      81             : 
      82             :     "Emif_MIFObject",
      83             :     "{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,"
      84             :     "MIFDictionary,0:pCMIFObject,}Emif_MIFObject",
      85             : 
      86             :     "Eprj_ProParameters",
      87             :     "{1:e2:EPRJ_INTERNAL,EPRJ_EXTERNAL,proType,1:lproNumber,0:pcproExeName,0:"
      88             :     "pcproName,1:lproZone,0:pdproParams,1:*oEprj_Spheroid,proSpheroid,}Eprj_"
      89             :     "ProParameters",
      90             : 
      91             :     "Eprj_Datum",
      92             :     "{0:pcdatumname,1:e3:EPRJ_DATUM_PARAMETRIC,EPRJ_DATUM_GRID,EPRJ_DATUM_"
      93             :     "REGRESSION,type,0:pdparams,0:pcgridname,}Eprj_Datum",
      94             : 
      95             :     "Eprj_Spheroid",
      96             :     "{0:pcsphereName,1:da,1:db,1:deSquared,1:dradius,}Eprj_Spheroid",
      97             : 
      98             :     nullptr,
      99             :     nullptr};
     100             : 
     101             : /************************************************************************/
     102             : /* ==================================================================== */
     103             : /*                             HFADictionary                            */
     104             : /* ==================================================================== */
     105             : /************************************************************************/
     106             : 
     107             : /************************************************************************/
     108             : /*                           HFADictionary()                            */
     109             : /************************************************************************/
     110             : 
     111         946 : HFADictionary::HFADictionary(const char *pszString)
     112             :     : nTypes(0), nTypesMax(0), papoTypes(nullptr), osDictionaryText(pszString),
     113         946 :       bDictionaryTextDirty(false)
     114             : {
     115             :     // Read all the types.
     116             :     // TODO(schwehr): Refactor this approach to be more obvious.
     117       28301 :     while (pszString != nullptr && *pszString != '.')
     118             :     {
     119       27355 :         HFAType *poNewType = new HFAType();
     120       27355 :         pszString = poNewType->Initialize(pszString);
     121             : 
     122       27355 :         if (pszString != nullptr)
     123       27354 :             AddType(poNewType);
     124             :         else
     125           1 :             delete poNewType;
     126             :     }
     127             : 
     128             :     // Complete the definitions.
     129       28300 :     for (int i = 0; i < nTypes; i++)
     130             :     {
     131       27354 :         papoTypes[i]->CompleteDefn(this);
     132             :     }
     133         946 : }
     134             : 
     135             : /************************************************************************/
     136             : /*                           ~HFADictionary()                           */
     137             : /************************************************************************/
     138             : 
     139         946 : HFADictionary::~HFADictionary()
     140             : 
     141             : {
     142       28305 :     for (int i = 0; i < nTypes; i++)
     143       27359 :         delete papoTypes[i];
     144             : 
     145         946 :     CPLFree(papoTypes);
     146         946 : }
     147             : 
     148             : /************************************************************************/
     149             : /*                              AddType()                               */
     150             : /************************************************************************/
     151             : 
     152       27359 : void HFADictionary::AddType(HFAType *poType)
     153             : 
     154             : {
     155       27359 :     if (nTypes == nTypesMax
     156             : #ifdef DEBUG
     157             :         // To please Coverity.
     158       24959 :         || papoTypes == nullptr
     159             : #endif
     160             :     )
     161             :     {
     162        2400 :         nTypesMax = nTypes * 2 + 10;
     163        2400 :         papoTypes = static_cast<HFAType **>(
     164        2400 :             CPLRealloc(papoTypes, sizeof(void *) * nTypesMax));
     165             :     }
     166             : 
     167       27359 :     papoTypes[nTypes++] = poType;
     168       27359 : }
     169             : 
     170             : /************************************************************************/
     171             : /*                              FindType()                              */
     172             : /************************************************************************/
     173             : 
     174       19983 : HFAType *HFADictionary::FindType(const char *pszName)
     175             : 
     176             : {
     177      332320 :     for (int i = 0; i < nTypes; i++)
     178             :     {
     179      332312 :         if (papoTypes[i]->pszTypeName != nullptr &&
     180      332312 :             strcmp(pszName, papoTypes[i]->pszTypeName) == 0)
     181       19975 :             return papoTypes[i];
     182             :     }
     183             : 
     184             :     // Check if this is a type have other knowledge of.  If so, add
     185             :     // it to the dictionary now.  I'm not sure how some files end
     186             :     // up being distributed using types not in the dictionary.
     187          47 :     for (int i = 0; apszDefDefn[i] != nullptr; i += 2)
     188             :     {
     189          45 :         if (strcmp(pszName, apszDefDefn[i]) == 0)
     190             :         {
     191           6 :             HFAType *poNewType = new HFAType();
     192             : 
     193           6 :             poNewType->Initialize(apszDefDefn[i + 1]);
     194           6 :             if (!poNewType->CompleteDefn(this))
     195             :             {
     196           1 :                 delete poNewType;
     197           1 :                 return nullptr;
     198             :             }
     199           5 :             AddType(poNewType);
     200             : 
     201           5 :             if (!osDictionaryText.empty())
     202           5 :                 osDictionaryText.erase(osDictionaryText.size() - 1, 1);
     203           5 :             osDictionaryText += apszDefDefn[i + 1];
     204           5 :             osDictionaryText += ",.";
     205             : 
     206           5 :             bDictionaryTextDirty = true;
     207             : 
     208           5 :             return poNewType;
     209             :         }
     210             :     }
     211             : 
     212           2 :     return nullptr;
     213             : }
     214             : 
     215             : /************************************************************************/
     216             : /*                            GetItemSize()                             */
     217             : /*                                                                      */
     218             : /*      Get the size of a basic (atomic) item.                          */
     219             : /************************************************************************/
     220             : 
     221      152465 : int HFADictionary::GetItemSize(char chType)
     222             : 
     223             : {
     224      152465 :     switch (chType)
     225             :     {
     226       71419 :         case '1':
     227             :         case '2':
     228             :         case '4':
     229             :         case 'c':
     230             :         case 'C':
     231       71419 :             return 1;
     232             : 
     233       15588 :         case 'e':
     234             :         case 's':
     235             :         case 'S':
     236       15588 :             return 2;
     237             : 
     238       41939 :         case 't':
     239             :         case 'l':
     240             :         case 'L':
     241             :         case 'f':
     242       41939 :             return 4;
     243             : 
     244       18889 :         case 'd':
     245             :         case 'm':
     246       18889 :             return 8;
     247             : 
     248           0 :         case 'M':
     249           0 :             return 16;
     250             : 
     251        4627 :         case 'b':
     252        4627 :             return -1;
     253             : 
     254           3 :         case 'o':
     255             :         case 'x':
     256           3 :             return 0;
     257             : 
     258           0 :         default:
     259           0 :             CPLAssert(false);
     260             :     }
     261             : 
     262             :     return 0;
     263             : }
     264             : 
     265             : /************************************************************************/
     266             : /*                                Dump()                                */
     267             : /************************************************************************/
     268             : 
     269           0 : void HFADictionary::Dump(FILE *fp)
     270             : 
     271             : {
     272           0 :     CPL_IGNORE_RET_VAL(VSIFPrintf(fp, "\nHFADictionary:\n"));
     273             : 
     274           0 :     for (int i = 0; i < nTypes; i++)
     275             :     {
     276           0 :         papoTypes[i]->Dump(fp);
     277             :     }
     278           0 : }

Generated by: LCOV version 1.14