LCOV - code coverage report
Current view: top level - frmts/sdts - sdtsiref.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 66 118 55.9 %
Date: 2024-05-04 12:52:34 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SDTS Translator
       4             :  * Purpose:  Implementation of SDTS_IREF class for reading IREF module.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "sdts_al.h"
      30             : 
      31             : /************************************************************************/
      32             : /*                             SDTS_IREF()                              */
      33             : /************************************************************************/
      34             : 
      35          52 : SDTS_IREF::SDTS_IREF()
      36         104 :     : nDefaultSADRFormat(0), pszXAxisName(CPLStrdup("")),
      37         104 :       pszYAxisName(CPLStrdup("")), dfXScale(1.0), dfYScale(1.0), dfXOffset(0.0),
      38             :       dfYOffset(0.0), dfXRes(1.0), dfYRes(1.0),
      39          52 :       pszCoordinateFormat(CPLStrdup(""))
      40             : {
      41          52 : }
      42             : 
      43             : /************************************************************************/
      44             : /*                             ~SDTS_IREF()                             */
      45             : /************************************************************************/
      46             : 
      47         104 : SDTS_IREF::~SDTS_IREF()
      48             : {
      49          52 :     CPLFree(pszXAxisName);
      50          52 :     CPLFree(pszYAxisName);
      51          52 :     CPLFree(pszCoordinateFormat);
      52          52 : }
      53             : 
      54             : /************************************************************************/
      55             : /*                                Read()                                */
      56             : /*                                                                      */
      57             : /*      Read the named file to initialize this structure.               */
      58             : /************************************************************************/
      59             : 
      60           3 : int SDTS_IREF::Read(const char *pszFilename)
      61             : 
      62             : {
      63             :     /* -------------------------------------------------------------------- */
      64             :     /*      Open the file, and read the header.                             */
      65             :     /* -------------------------------------------------------------------- */
      66           6 :     DDFModule oIREFFile;
      67           3 :     if (!oIREFFile.Open(pszFilename))
      68           0 :         return FALSE;
      69             : 
      70             :     /* -------------------------------------------------------------------- */
      71             :     /*      Read the first record, and verify that this is an IREF record.  */
      72             :     /* -------------------------------------------------------------------- */
      73           3 :     DDFRecord *poRecord = oIREFFile.ReadRecord();
      74           3 :     if (poRecord == nullptr)
      75           0 :         return FALSE;
      76             : 
      77           3 :     if (poRecord->GetStringSubfield("IREF", 0, "MODN", 0) == nullptr)
      78           0 :         return FALSE;
      79             : 
      80             :     /* -------------------------------------------------------------------- */
      81             :     /*      Get the labels.                                                 */
      82             :     /* -------------------------------------------------------------------- */
      83           3 :     CPLFree(pszXAxisName);
      84           3 :     pszXAxisName = CPLStrdup(poRecord->GetStringSubfield("IREF", 0, "XLBL", 0));
      85           3 :     CPLFree(pszYAxisName);
      86           3 :     pszYAxisName = CPLStrdup(poRecord->GetStringSubfield("IREF", 0, "YLBL", 0));
      87             : 
      88             :     /* -------------------------------------------------------------------- */
      89             :     /*      Get the coordinate encoding.                                    */
      90             :     /* -------------------------------------------------------------------- */
      91           3 :     CPLFree(pszCoordinateFormat);
      92           3 :     pszCoordinateFormat =
      93           3 :         CPLStrdup(poRecord->GetStringSubfield("IREF", 0, "HFMT", 0));
      94             : 
      95             :     /* -------------------------------------------------------------------- */
      96             :     /*      Get the transformation information, and resolution.             */
      97             :     /* -------------------------------------------------------------------- */
      98           3 :     dfXScale = poRecord->GetFloatSubfield("IREF", 0, "SFAX", 0);
      99           3 :     dfYScale = poRecord->GetFloatSubfield("IREF", 0, "SFAY", 0);
     100             : 
     101           3 :     dfXOffset = poRecord->GetFloatSubfield("IREF", 0, "XORG", 0);
     102           3 :     dfYOffset = poRecord->GetFloatSubfield("IREF", 0, "YORG", 0);
     103             : 
     104           3 :     dfXRes = poRecord->GetFloatSubfield("IREF", 0, "XHRS", 0);
     105           3 :     dfYRes = poRecord->GetFloatSubfield("IREF", 0, "YHRS", 0);
     106             : 
     107           3 :     nDefaultSADRFormat = EQUAL(pszCoordinateFormat, "BI32");
     108             : 
     109           3 :     return TRUE;
     110             : }
     111             : 
     112             : /************************************************************************/
     113             : /*                            GetSADRCount()                            */
     114             : /*                                                                      */
     115             : /*      Return the number of SADR'es in the passed field.               */
     116             : /************************************************************************/
     117             : 
     118          55 : int SDTS_IREF::GetSADRCount(DDFField *poField) const
     119             : 
     120             : {
     121          55 :     if (nDefaultSADRFormat)
     122          55 :         return poField->GetDataSize() / SDTS_SIZEOF_SADR;
     123             : 
     124           0 :     return poField->GetRepeatCount();
     125             : }
     126             : 
     127             : /************************************************************************/
     128             : /*                              GetSADR()                               */
     129             : /************************************************************************/
     130             : 
     131         186 : int SDTS_IREF::GetSADR(DDFField *poField, int nVertices, double *padfX,
     132             :                        double *padfY, double *padfZ)
     133             : 
     134             : {
     135             :     /* -------------------------------------------------------------------- */
     136             :     /*      For the sake of efficiency we depend on our knowledge that      */
     137             :     /*      the SADR field is a series of bigendian int32's and decode      */
     138             :     /*      them directly.                                                  */
     139             :     /* -------------------------------------------------------------------- */
     140         186 :     if (nDefaultSADRFormat && poField->GetFieldDefn()->GetSubfieldCount() == 2)
     141             :     {
     142         184 :         if (poField->GetDataSize() < nVertices * SDTS_SIZEOF_SADR)
     143             :         {
     144           0 :             return FALSE;
     145             :         }
     146             : 
     147             :         GInt32 anXY[2];
     148         184 :         const char *pachRawData = poField->GetData();
     149             : 
     150        1222 :         for (int iVertex = 0; iVertex < nVertices; iVertex++)
     151             :         {
     152             :             // we copy to a temp buffer to ensure it is world aligned.
     153        1038 :             memcpy(anXY, pachRawData, 8);
     154        1038 :             pachRawData += 8;
     155             : 
     156             :             // possibly byte swap, and always apply scale factor
     157        1038 :             padfX[iVertex] =
     158        1038 :                 dfXOffset + dfXScale * static_cast<int>(CPL_MSBWORD32(anXY[0]));
     159        1038 :             padfY[iVertex] =
     160        1038 :                 dfYOffset + dfYScale * static_cast<int>(CPL_MSBWORD32(anXY[1]));
     161             : 
     162        1038 :             padfZ[iVertex] = 0.0;
     163             :         }
     164             :     }
     165             : 
     166             :     /* -------------------------------------------------------------------- */
     167             :     /*      This is the generic case.  We assume either two or three        */
     168             :     /*      subfields, and treat these as X, Y and Z regardless of          */
     169             :     /*      name.                                                           */
     170             :     /* -------------------------------------------------------------------- */
     171             :     else
     172             :     {
     173           2 :         DDFFieldDefn *poFieldDefn = poField->GetFieldDefn();
     174           2 :         int nBytesRemaining = poField->GetDataSize();
     175           2 :         const char *pachFieldData = poField->GetData();
     176             : 
     177           2 :         if (poFieldDefn->GetSubfieldCount() != 2 &&
     178           0 :             poFieldDefn->GetSubfieldCount() != 3)
     179             :         {
     180           0 :             return FALSE;
     181             :         }
     182             : 
     183           4 :         for (int iVertex = 0; iVertex < nVertices; iVertex++)
     184             :         {
     185           2 :             double adfXYZ[3] = {0.0, 0.0, 0.0};
     186             : 
     187          10 :             for (int iEntry = 0; nBytesRemaining > 0 &&
     188           4 :                                  iEntry < poFieldDefn->GetSubfieldCount();
     189             :                  iEntry++)
     190             :             {
     191           4 :                 int nBytesConsumed = 0;
     192           4 :                 DDFSubfieldDefn *poSF = poFieldDefn->GetSubfield(iEntry);
     193             : 
     194           4 :                 switch (poSF->GetType())
     195             :                 {
     196           0 :                     case DDFInt:
     197           0 :                         adfXYZ[iEntry] = poSF->ExtractIntData(
     198             :                             pachFieldData, nBytesRemaining, &nBytesConsumed);
     199           0 :                         break;
     200             : 
     201           4 :                     case DDFFloat:
     202           4 :                         adfXYZ[iEntry] = poSF->ExtractFloatData(
     203             :                             pachFieldData, nBytesRemaining, &nBytesConsumed);
     204           4 :                         break;
     205             : 
     206           0 :                     case DDFBinaryString:
     207             :                     {
     208             :                         GByte *pabyBString = reinterpret_cast<GByte *>(
     209           0 :                             const_cast<char *>(poSF->ExtractStringData(
     210             :                                 pachFieldData, nBytesRemaining,
     211             :                                 &nBytesConsumed)));
     212             : 
     213           0 :                         if (EQUAL(pszCoordinateFormat, "BI32"))
     214             :                         {
     215           0 :                             if (nBytesConsumed < 4)
     216           0 :                                 return FALSE;
     217             :                             GInt32 nValue;
     218           0 :                             memcpy(&nValue, pabyBString, 4);
     219           0 :                             adfXYZ[iEntry] =
     220           0 :                                 static_cast<int>(CPL_MSBWORD32(nValue));
     221             :                         }
     222           0 :                         else if (EQUAL(pszCoordinateFormat, "BI16"))
     223             :                         {
     224           0 :                             if (nBytesConsumed < 2)
     225           0 :                                 return FALSE;
     226             :                             GInt16 nValue;
     227           0 :                             memcpy(&nValue, pabyBString, 2);
     228           0 :                             adfXYZ[iEntry] =
     229           0 :                                 static_cast<int>(CPL_MSBWORD16(nValue));
     230             :                         }
     231           0 :                         else if (EQUAL(pszCoordinateFormat, "BU32"))
     232             :                         {
     233           0 :                             if (nBytesConsumed < 4)
     234           0 :                                 return FALSE;
     235             :                             GUInt32 nValue;
     236           0 :                             memcpy(&nValue, pabyBString, 4);
     237           0 :                             adfXYZ[iEntry] =
     238           0 :                                 static_cast<GUInt32>(CPL_MSBWORD32(nValue));
     239             :                         }
     240           0 :                         else if (EQUAL(pszCoordinateFormat, "BU16"))
     241             :                         {
     242           0 :                             if (nBytesConsumed < 2)
     243           0 :                                 return FALSE;
     244             :                             GUInt16 nValue;
     245           0 :                             memcpy(&nValue, pabyBString, 2);
     246           0 :                             adfXYZ[iEntry] =
     247           0 :                                 static_cast<GUInt16>(CPL_MSBWORD16(nValue));
     248             :                         }
     249           0 :                         else if (EQUAL(pszCoordinateFormat, "BFP32"))
     250             :                         {
     251           0 :                             if (nBytesConsumed < 4)
     252           0 :                                 return FALSE;
     253             :                             float fValue;
     254             : 
     255           0 :                             memcpy(&fValue, pabyBString, 4);
     256           0 :                             CPL_MSBPTR32(&fValue);
     257           0 :                             adfXYZ[iEntry] = fValue;
     258             :                         }
     259           0 :                         else if (EQUAL(pszCoordinateFormat, "BFP64"))
     260             :                         {
     261           0 :                             if (nBytesConsumed < 8)
     262           0 :                                 return FALSE;
     263             :                             double dfValue;
     264             : 
     265           0 :                             memcpy(&dfValue, pabyBString, 8);
     266           0 :                             CPL_MSBPTR64(&dfValue);
     267           0 :                             adfXYZ[iEntry] = dfValue;
     268             :                         }
     269             :                     }
     270           0 :                     break;
     271             : 
     272           0 :                     default:
     273           0 :                         adfXYZ[iEntry] = 0.0;
     274           0 :                         break;
     275             :                 }
     276             : 
     277           4 :                 pachFieldData += nBytesConsumed;
     278           4 :                 nBytesRemaining -= nBytesConsumed;
     279             :             } /* next iEntry */
     280             : 
     281           2 :             padfX[iVertex] = dfXOffset + adfXYZ[0] * dfXScale;
     282           2 :             padfY[iVertex] = dfYOffset + adfXYZ[1] * dfYScale;
     283           2 :             padfZ[iVertex] = adfXYZ[2];
     284             :         } /* next iVertex */
     285             :     }
     286             : 
     287         186 :     return TRUE;
     288             : }

Generated by: LCOV version 1.14