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-11-21 22:18:42 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             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "sdts_al.h"
      14             : 
      15             : /************************************************************************/
      16             : /*                             SDTS_IREF()                              */
      17             : /************************************************************************/
      18             : 
      19          52 : SDTS_IREF::SDTS_IREF()
      20         104 :     : nDefaultSADRFormat(0), pszXAxisName(CPLStrdup("")),
      21         104 :       pszYAxisName(CPLStrdup("")), dfXScale(1.0), dfYScale(1.0), dfXOffset(0.0),
      22             :       dfYOffset(0.0), dfXRes(1.0), dfYRes(1.0),
      23          52 :       pszCoordinateFormat(CPLStrdup(""))
      24             : {
      25          52 : }
      26             : 
      27             : /************************************************************************/
      28             : /*                             ~SDTS_IREF()                             */
      29             : /************************************************************************/
      30             : 
      31         104 : SDTS_IREF::~SDTS_IREF()
      32             : {
      33          52 :     CPLFree(pszXAxisName);
      34          52 :     CPLFree(pszYAxisName);
      35          52 :     CPLFree(pszCoordinateFormat);
      36          52 : }
      37             : 
      38             : /************************************************************************/
      39             : /*                                Read()                                */
      40             : /*                                                                      */
      41             : /*      Read the named file to initialize this structure.               */
      42             : /************************************************************************/
      43             : 
      44           3 : int SDTS_IREF::Read(const char *pszFilename)
      45             : 
      46             : {
      47             :     /* -------------------------------------------------------------------- */
      48             :     /*      Open the file, and read the header.                             */
      49             :     /* -------------------------------------------------------------------- */
      50           6 :     DDFModule oIREFFile;
      51           3 :     if (!oIREFFile.Open(pszFilename))
      52           0 :         return FALSE;
      53             : 
      54             :     /* -------------------------------------------------------------------- */
      55             :     /*      Read the first record, and verify that this is an IREF record.  */
      56             :     /* -------------------------------------------------------------------- */
      57           3 :     DDFRecord *poRecord = oIREFFile.ReadRecord();
      58           3 :     if (poRecord == nullptr)
      59           0 :         return FALSE;
      60             : 
      61           3 :     if (poRecord->GetStringSubfield("IREF", 0, "MODN", 0) == nullptr)
      62           0 :         return FALSE;
      63             : 
      64             :     /* -------------------------------------------------------------------- */
      65             :     /*      Get the labels.                                                 */
      66             :     /* -------------------------------------------------------------------- */
      67           3 :     CPLFree(pszXAxisName);
      68           3 :     pszXAxisName = CPLStrdup(poRecord->GetStringSubfield("IREF", 0, "XLBL", 0));
      69           3 :     CPLFree(pszYAxisName);
      70           3 :     pszYAxisName = CPLStrdup(poRecord->GetStringSubfield("IREF", 0, "YLBL", 0));
      71             : 
      72             :     /* -------------------------------------------------------------------- */
      73             :     /*      Get the coordinate encoding.                                    */
      74             :     /* -------------------------------------------------------------------- */
      75           3 :     CPLFree(pszCoordinateFormat);
      76           3 :     pszCoordinateFormat =
      77           3 :         CPLStrdup(poRecord->GetStringSubfield("IREF", 0, "HFMT", 0));
      78             : 
      79             :     /* -------------------------------------------------------------------- */
      80             :     /*      Get the transformation information, and resolution.             */
      81             :     /* -------------------------------------------------------------------- */
      82           3 :     dfXScale = poRecord->GetFloatSubfield("IREF", 0, "SFAX", 0);
      83           3 :     dfYScale = poRecord->GetFloatSubfield("IREF", 0, "SFAY", 0);
      84             : 
      85           3 :     dfXOffset = poRecord->GetFloatSubfield("IREF", 0, "XORG", 0);
      86           3 :     dfYOffset = poRecord->GetFloatSubfield("IREF", 0, "YORG", 0);
      87             : 
      88           3 :     dfXRes = poRecord->GetFloatSubfield("IREF", 0, "XHRS", 0);
      89           3 :     dfYRes = poRecord->GetFloatSubfield("IREF", 0, "YHRS", 0);
      90             : 
      91           3 :     nDefaultSADRFormat = EQUAL(pszCoordinateFormat, "BI32");
      92             : 
      93           3 :     return TRUE;
      94             : }
      95             : 
      96             : /************************************************************************/
      97             : /*                            GetSADRCount()                            */
      98             : /*                                                                      */
      99             : /*      Return the number of SADR'es in the passed field.               */
     100             : /************************************************************************/
     101             : 
     102          55 : int SDTS_IREF::GetSADRCount(DDFField *poField) const
     103             : 
     104             : {
     105          55 :     if (nDefaultSADRFormat)
     106          55 :         return poField->GetDataSize() / SDTS_SIZEOF_SADR;
     107             : 
     108           0 :     return poField->GetRepeatCount();
     109             : }
     110             : 
     111             : /************************************************************************/
     112             : /*                              GetSADR()                               */
     113             : /************************************************************************/
     114             : 
     115         186 : int SDTS_IREF::GetSADR(DDFField *poField, int nVertices, double *padfX,
     116             :                        double *padfY, double *padfZ)
     117             : 
     118             : {
     119             :     /* -------------------------------------------------------------------- */
     120             :     /*      For the sake of efficiency we depend on our knowledge that      */
     121             :     /*      the SADR field is a series of bigendian int32's and decode      */
     122             :     /*      them directly.                                                  */
     123             :     /* -------------------------------------------------------------------- */
     124         186 :     if (nDefaultSADRFormat && poField->GetFieldDefn()->GetSubfieldCount() == 2)
     125             :     {
     126         184 :         if (poField->GetDataSize() < nVertices * SDTS_SIZEOF_SADR)
     127             :         {
     128           0 :             return FALSE;
     129             :         }
     130             : 
     131             :         GInt32 anXY[2];
     132         184 :         const char *pachRawData = poField->GetData();
     133             : 
     134        1222 :         for (int iVertex = 0; iVertex < nVertices; iVertex++)
     135             :         {
     136             :             // we copy to a temp buffer to ensure it is world aligned.
     137        1038 :             memcpy(anXY, pachRawData, 8);
     138        1038 :             pachRawData += 8;
     139             : 
     140             :             // possibly byte swap, and always apply scale factor
     141        1038 :             padfX[iVertex] =
     142        1038 :                 dfXOffset + dfXScale * static_cast<int>(CPL_MSBWORD32(anXY[0]));
     143        1038 :             padfY[iVertex] =
     144        1038 :                 dfYOffset + dfYScale * static_cast<int>(CPL_MSBWORD32(anXY[1]));
     145             : 
     146        1038 :             padfZ[iVertex] = 0.0;
     147             :         }
     148             :     }
     149             : 
     150             :     /* -------------------------------------------------------------------- */
     151             :     /*      This is the generic case.  We assume either two or three        */
     152             :     /*      subfields, and treat these as X, Y and Z regardless of          */
     153             :     /*      name.                                                           */
     154             :     /* -------------------------------------------------------------------- */
     155             :     else
     156             :     {
     157           2 :         DDFFieldDefn *poFieldDefn = poField->GetFieldDefn();
     158           2 :         int nBytesRemaining = poField->GetDataSize();
     159           2 :         const char *pachFieldData = poField->GetData();
     160             : 
     161           2 :         if (poFieldDefn->GetSubfieldCount() != 2 &&
     162           0 :             poFieldDefn->GetSubfieldCount() != 3)
     163             :         {
     164           0 :             return FALSE;
     165             :         }
     166             : 
     167           4 :         for (int iVertex = 0; iVertex < nVertices; iVertex++)
     168             :         {
     169           2 :             double adfXYZ[3] = {0.0, 0.0, 0.0};
     170             : 
     171          10 :             for (int iEntry = 0; nBytesRemaining > 0 &&
     172           4 :                                  iEntry < poFieldDefn->GetSubfieldCount();
     173             :                  iEntry++)
     174             :             {
     175           4 :                 int nBytesConsumed = 0;
     176           4 :                 DDFSubfieldDefn *poSF = poFieldDefn->GetSubfield(iEntry);
     177             : 
     178           4 :                 switch (poSF->GetType())
     179             :                 {
     180           0 :                     case DDFInt:
     181           0 :                         adfXYZ[iEntry] = poSF->ExtractIntData(
     182             :                             pachFieldData, nBytesRemaining, &nBytesConsumed);
     183           0 :                         break;
     184             : 
     185           4 :                     case DDFFloat:
     186           4 :                         adfXYZ[iEntry] = poSF->ExtractFloatData(
     187             :                             pachFieldData, nBytesRemaining, &nBytesConsumed);
     188           4 :                         break;
     189             : 
     190           0 :                     case DDFBinaryString:
     191             :                     {
     192             :                         GByte *pabyBString = reinterpret_cast<GByte *>(
     193           0 :                             const_cast<char *>(poSF->ExtractStringData(
     194             :                                 pachFieldData, nBytesRemaining,
     195             :                                 &nBytesConsumed)));
     196             : 
     197           0 :                         if (EQUAL(pszCoordinateFormat, "BI32"))
     198             :                         {
     199           0 :                             if (nBytesConsumed < 4)
     200           0 :                                 return FALSE;
     201             :                             GInt32 nValue;
     202           0 :                             memcpy(&nValue, pabyBString, 4);
     203           0 :                             adfXYZ[iEntry] =
     204           0 :                                 static_cast<int>(CPL_MSBWORD32(nValue));
     205             :                         }
     206           0 :                         else if (EQUAL(pszCoordinateFormat, "BI16"))
     207             :                         {
     208           0 :                             if (nBytesConsumed < 2)
     209           0 :                                 return FALSE;
     210             :                             GInt16 nValue;
     211           0 :                             memcpy(&nValue, pabyBString, 2);
     212           0 :                             adfXYZ[iEntry] =
     213           0 :                                 static_cast<int>(CPL_MSBWORD16(nValue));
     214             :                         }
     215           0 :                         else if (EQUAL(pszCoordinateFormat, "BU32"))
     216             :                         {
     217           0 :                             if (nBytesConsumed < 4)
     218           0 :                                 return FALSE;
     219             :                             GUInt32 nValue;
     220           0 :                             memcpy(&nValue, pabyBString, 4);
     221           0 :                             adfXYZ[iEntry] =
     222           0 :                                 static_cast<GUInt32>(CPL_MSBWORD32(nValue));
     223             :                         }
     224           0 :                         else if (EQUAL(pszCoordinateFormat, "BU16"))
     225             :                         {
     226           0 :                             if (nBytesConsumed < 2)
     227           0 :                                 return FALSE;
     228             :                             GUInt16 nValue;
     229           0 :                             memcpy(&nValue, pabyBString, 2);
     230           0 :                             adfXYZ[iEntry] =
     231           0 :                                 static_cast<GUInt16>(CPL_MSBWORD16(nValue));
     232             :                         }
     233           0 :                         else if (EQUAL(pszCoordinateFormat, "BFP32"))
     234             :                         {
     235           0 :                             if (nBytesConsumed < 4)
     236           0 :                                 return FALSE;
     237             :                             float fValue;
     238             : 
     239           0 :                             memcpy(&fValue, pabyBString, 4);
     240           0 :                             CPL_MSBPTR32(&fValue);
     241           0 :                             adfXYZ[iEntry] = fValue;
     242             :                         }
     243           0 :                         else if (EQUAL(pszCoordinateFormat, "BFP64"))
     244             :                         {
     245           0 :                             if (nBytesConsumed < 8)
     246           0 :                                 return FALSE;
     247             :                             double dfValue;
     248             : 
     249           0 :                             memcpy(&dfValue, pabyBString, 8);
     250           0 :                             CPL_MSBPTR64(&dfValue);
     251           0 :                             adfXYZ[iEntry] = dfValue;
     252             :                         }
     253             :                     }
     254           0 :                     break;
     255             : 
     256           0 :                     default:
     257           0 :                         adfXYZ[iEntry] = 0.0;
     258           0 :                         break;
     259             :                 }
     260             : 
     261           4 :                 pachFieldData += nBytesConsumed;
     262           4 :                 nBytesRemaining -= nBytesConsumed;
     263             :             } /* next iEntry */
     264             : 
     265           2 :             padfX[iVertex] = dfXOffset + adfXYZ[0] * dfXScale;
     266           2 :             padfY[iVertex] = dfYOffset + adfXYZ[1] * dfYScale;
     267           2 :             padfZ[iVertex] = adfXYZ[2];
     268             :         } /* next iVertex */
     269             :     }
     270             : 
     271         186 :     return TRUE;
     272             : }

Generated by: LCOV version 1.14