LCOV - code coverage report
Current view: top level - frmts/pds - pds4dataset.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 54 60 90.0 %
Date: 2024-11-21 22:18:42 Functions: 26 29 89.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PDS 4 Driver; Planetary Data System Format
       4             :  * Purpose:  Implementation of PDS4Dataset
       5             :  * Author:   Even Rouault, even.rouault at spatialys.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2019, Hobu Inc
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #pragma once
      14             : 
      15             : #include "cpl_string.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdal_proxy.h"
      18             : #include "ogreditablelayer.h"
      19             : #include "rawdataset.h"
      20             : #include "ogr_spatialref.h"
      21             : 
      22             : #include <vector>
      23             : 
      24             : class PDS4Dataset;
      25             : 
      26             : /************************************************************************/
      27             : /* ==================================================================== */
      28             : /*                        PDS4TableBaseLayer                            */
      29             : /* ==================================================================== */
      30             : /************************************************************************/
      31             : 
      32             : class PDS4TableBaseLayer CPL_NON_FINAL : public OGRLayer
      33             : {
      34             :   protected:
      35             :     PDS4Dataset *m_poDS = nullptr;
      36             :     OGRFeatureDefn *m_poRawFeatureDefn = nullptr;
      37             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
      38             :     CPLString m_osFilename{};
      39             :     int m_iLatField = -1;
      40             :     int m_iLongField = -1;
      41             :     int m_iAltField = -1;
      42             :     int m_iWKT = -1;
      43             :     bool m_bKeepGeomColmuns = false;
      44             :     bool m_bDirtyHeader = false;
      45             :     VSILFILE *m_fp = nullptr;
      46             :     GIntBig m_nFeatureCount = -1;
      47             :     GIntBig m_nFID = 1;
      48             :     vsi_l_offset m_nOffset = 0;
      49             :     CPLStringList m_aosLCO{};
      50             :     std::string m_osLineEnding{};
      51             : 
      52             :     void SetupGeomField();
      53             :     OGRFeature *AddGeometryFromFields(OGRFeature *poFeature);
      54             :     OGRFeature *AddFieldsFromGeometry(OGRFeature *poFeature);
      55             :     void MarkHeaderDirty();
      56             :     CPLXMLNode *RefreshFileAreaObservationalBeginningCommon(
      57             :         CPLXMLNode *psFAO, const CPLString &osPrefix,
      58             :         const char *pszTableEltName, CPLString &osDescription);
      59             :     void ParseLineEndingOption(CSLConstList papszOptions);
      60             : 
      61             :   public:
      62             :     PDS4TableBaseLayer(PDS4Dataset *poDS, const char *pszName,
      63             :                        const char *pszFilename);
      64             :     ~PDS4TableBaseLayer();
      65             : 
      66        2725 :     OGRFeatureDefn *GetLayerDefn() override
      67             :     {
      68        2725 :         return m_poFeatureDefn;
      69             :     }
      70             : 
      71             :     GIntBig GetFeatureCount(int bForce) override;
      72             : 
      73         136 :     const char *GetFileName() const
      74             :     {
      75         136 :         return m_osFilename.c_str();
      76             :     }
      77             : 
      78          72 :     bool IsDirtyHeader() const
      79             :     {
      80          72 :         return m_bDirtyHeader;
      81             :     }
      82             : 
      83          69 :     int GetRawFieldCount() const
      84             :     {
      85          69 :         return m_poRawFeatureDefn->GetFieldCount();
      86             :     }
      87             : 
      88             :     bool RenameFileTo(const char *pszNewName);
      89             :     virtual char **GetFileList() const;
      90             : 
      91             :     virtual void RefreshFileAreaObservational(CPLXMLNode *psFAO) = 0;
      92             : 
      93             :     GDALDataset *GetDataset() override;
      94             : };
      95             : 
      96             : /************************************************************************/
      97             : /* ==================================================================== */
      98             : /*                        PDS4FixedWidthTable                           */
      99             : /* ==================================================================== */
     100             : /************************************************************************/
     101             : 
     102             : template <class T> class PDS4EditableSynchronizer;
     103             : 
     104             : class PDS4FixedWidthTable CPL_NON_FINAL : public PDS4TableBaseLayer
     105             : {
     106             :     friend class PDS4EditableSynchronizer<PDS4FixedWidthTable>;
     107             : 
     108             :   protected:
     109             :     int m_nRecordSize = 0;
     110             :     CPLString m_osBuffer{};
     111             : 
     112             :     struct Field
     113             :     {
     114             :         int m_nOffset = 0;  // in XML 1-based, here 0-based
     115             :         int m_nLength = 0;
     116             :         CPLString m_osDataType{};
     117             :         CPLString m_osUnit{};
     118             :         CPLString m_osDescription{};
     119             :         CPLString m_osSpecialConstantsXML{};
     120             :     };
     121             : 
     122             :     std::vector<Field> m_aoFields{};
     123             : 
     124             :     virtual CPLString GetSubType() const = 0;
     125             : 
     126             :     virtual bool CreateFieldInternal(OGRFieldType eType,
     127             :                                      OGRFieldSubType eSubType, int nWidth,
     128             :                                      Field &f) = 0;
     129             : 
     130             :     bool ReadFields(const CPLXMLNode *psParent, int nBaseOffset,
     131             :                     const CPLString &osSuffixFieldName);
     132             : 
     133             :   public:
     134             :     PDS4FixedWidthTable(PDS4Dataset *poDS, const char *pszName,
     135             :                         const char *pszFilename);
     136             : 
     137             :     void ResetReading() override;
     138             :     OGRFeature *GetFeature(GIntBig nFID) override;
     139             :     OGRFeature *GetNextFeature() override;
     140             :     int TestCapability(const char *) override;
     141             :     OGRErr ISetFeature(OGRFeature *poFeature) override;
     142             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     143             :     OGRErr CreateField(const OGRFieldDefn *poFieldIn, int) override;
     144             : 
     145             :     bool ReadTableDef(const CPLXMLNode *psTable);
     146             : 
     147             :     bool InitializeNewLayer(const OGRSpatialReference *poSRS,
     148             :                             bool bForceGeographic, OGRwkbGeometryType eGType,
     149             :                             const char *const *papszOptions);
     150             : 
     151             :     virtual PDS4FixedWidthTable *NewLayer(PDS4Dataset *poDS,
     152             :                                           const char *pszName,
     153             :                                           const char *pszFilename) = 0;
     154             : 
     155             :     void RefreshFileAreaObservational(CPLXMLNode *psFAO) override;
     156             : };
     157             : 
     158             : /************************************************************************/
     159             : /* ==================================================================== */
     160             : /*                        PDS4TableCharacter                            */
     161             : /* ==================================================================== */
     162             : /************************************************************************/
     163             : 
     164             : class PDS4TableCharacter final : public PDS4FixedWidthTable
     165             : {
     166         565 :     CPLString GetSubType() const override
     167             :     {
     168         565 :         return "Character";
     169             :     }
     170             : 
     171             :     bool CreateFieldInternal(OGRFieldType eType, OGRFieldSubType eSubType,
     172             :                              int nWidth, Field &f) override;
     173             : 
     174             :   public:
     175             :     PDS4TableCharacter(PDS4Dataset *poDS, const char *pszName,
     176             :                        const char *pszFilename);
     177             : 
     178           2 :     PDS4FixedWidthTable *NewLayer(PDS4Dataset *poDS, const char *pszName,
     179             :                                   const char *pszFilename) override
     180             :     {
     181           2 :         return new PDS4TableCharacter(poDS, pszName, pszFilename);
     182             :     }
     183             : };
     184             : 
     185             : /************************************************************************/
     186             : /* ==================================================================== */
     187             : /*                        PDS4TableBinary                               */
     188             : /* ==================================================================== */
     189             : /************************************************************************/
     190             : 
     191             : class PDS4TableBinary final : public PDS4FixedWidthTable
     192             : {
     193        3258 :     CPLString GetSubType() const override
     194             :     {
     195        3258 :         return "Binary";
     196             :     }
     197             : 
     198             :     bool CreateFieldInternal(OGRFieldType eType, OGRFieldSubType eSubType,
     199             :                              int nWidth, Field &f) override;
     200             : 
     201             :   public:
     202             :     PDS4TableBinary(PDS4Dataset *poDS, const char *pszName,
     203             :                     const char *pszFilename);
     204             : 
     205           0 :     PDS4FixedWidthTable *NewLayer(PDS4Dataset *poDS, const char *pszName,
     206             :                                   const char *pszFilename) override
     207             :     {
     208           0 :         return new PDS4TableBinary(poDS, pszName, pszFilename);
     209             :     }
     210             : };
     211             : 
     212             : /************************************************************************/
     213             : /* ==================================================================== */
     214             : /*                        PDS4DelimitedTable                            */
     215             : /* ==================================================================== */
     216             : /************************************************************************/
     217             : 
     218             : class PDS4DelimitedTable CPL_NON_FINAL : public PDS4TableBaseLayer
     219             : {
     220             :     friend class PDS4EditableSynchronizer<PDS4DelimitedTable>;
     221             : 
     222             :   protected:
     223             :     bool m_bCreation = false;
     224             :     char m_chFieldDelimiter = ',';
     225             :     bool m_bAddWKTColumnPending = false;
     226             : 
     227             :     struct Field
     228             :     {
     229             :         CPLString m_osDataType{};
     230             :         CPLString m_osUnit{};
     231             :         CPLString m_osDescription{};
     232             :         CPLString m_osSpecialConstantsXML{};
     233             :         CPLString m_osMissingConstant{};  // included in above potentially
     234             :     };
     235             : 
     236             :     std::vector<Field> m_aoFields{};
     237             : 
     238             :     OGRFeature *GetNextFeatureRaw();
     239             :     CPLString QuoteIfNeeded(const char *pszVal);
     240             :     void GenerateVRT();
     241             : 
     242             :     bool ReadFields(const CPLXMLNode *psParent,
     243             :                     const CPLString &osSuffixFieldName);
     244             : 
     245             :   public:
     246             :     PDS4DelimitedTable(PDS4Dataset *poDS, const char *pszName,
     247             :                        const char *pszFilename);
     248             :     ~PDS4DelimitedTable() override;
     249             : 
     250             :     void ResetReading() override;
     251             :     OGRFeature *GetNextFeature() override;
     252             :     int TestCapability(const char *) override;
     253             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     254             :     OGRErr CreateField(const OGRFieldDefn *poFieldIn, int) override;
     255             : 
     256             :     bool ReadTableDef(const CPLXMLNode *psTable);
     257             : 
     258             :     bool InitializeNewLayer(const OGRSpatialReference *poSRS,
     259             :                             bool bForceGeographic, OGRwkbGeometryType eGType,
     260             :                             const char *const *papszOptions);
     261             : 
     262             :     void RefreshFileAreaObservational(CPLXMLNode *psFAO) override;
     263             :     char **GetFileList() const override;
     264             : 
     265           1 :     PDS4DelimitedTable *NewLayer(PDS4Dataset *poDS, const char *pszName,
     266             :                                  const char *pszFilename)
     267             :     {
     268           1 :         return new PDS4DelimitedTable(poDS, pszName, pszFilename);
     269             :     }
     270             : };
     271             : 
     272             : /************************************************************************/
     273             : /* ==================================================================== */
     274             : /*                         PDS4EditableLayer                            */
     275             : /* ==================================================================== */
     276             : /************************************************************************/
     277             : 
     278             : class PDS4EditableLayer final : public OGREditableLayer
     279             : {
     280             :     PDS4TableBaseLayer *GetBaseLayer() const;
     281             : 
     282             :   public:
     283             :     explicit PDS4EditableLayer(PDS4FixedWidthTable *poBaseLayer);
     284             :     explicit PDS4EditableLayer(PDS4DelimitedTable *poBaseLayer);
     285             : 
     286          69 :     void RefreshFileAreaObservational(CPLXMLNode *psFAO)
     287             :     {
     288          69 :         GetBaseLayer()->RefreshFileAreaObservational(psFAO);
     289          69 :     }
     290             : 
     291          69 :     const char *GetFileName() const
     292             :     {
     293          69 :         return GetBaseLayer()->GetFileName();
     294             :     }
     295             : 
     296          72 :     bool IsDirtyHeader() const
     297             :     {
     298          72 :         return GetBaseLayer()->IsDirtyHeader();
     299             :     }
     300             : 
     301          69 :     int GetRawFieldCount() const
     302             :     {
     303          69 :         return GetBaseLayer()->GetRawFieldCount();
     304             :     }
     305             : 
     306             :     void SetSpatialRef(OGRSpatialReference *poSRS);
     307             : 
     308          64 :     char **GetFileList() const
     309             :     {
     310          64 :         return GetBaseLayer()->GetFileList();
     311             :     }
     312             : };
     313             : 
     314             : /************************************************************************/
     315             : /*                            PDS4Dataset                               */
     316             : /************************************************************************/
     317             : 
     318             : class PDS4Dataset final : public RawDataset
     319             : {
     320             :     friend class PDS4RawRasterBand;
     321             :     friend class PDS4WrapperRasterBand;
     322             : 
     323             :     VSILFILE *m_fpImage = nullptr;
     324             :     vsi_l_offset m_nBaseOffset = 0;
     325             :     GDALDataset *m_poExternalDS = nullptr;  // external dataset (GeoTIFF)
     326             :     OGRSpatialReference m_oSRS{};
     327             :     bool m_bGotTransform = false;
     328             :     double m_adfGeoTransform[6];
     329             :     CPLString m_osXMLFilename{};
     330             :     CPLString m_osImageFilename{};
     331             :     CPLString m_osUnits{};
     332             :     bool m_bCreatedFromExistingBinaryFile = false;
     333             : 
     334             :     std::vector<std::unique_ptr<PDS4EditableLayer>> m_apoLayers{};
     335             : 
     336             :     // Write dedicated parameters
     337             :     bool m_bMustInitImageFile = false;
     338             :     bool m_bUseSrcLabel = true;
     339             :     bool m_bDirtyHeader = false;
     340             :     bool m_bCreateHeader = false;
     341             :     bool m_bStripFileAreaObservationalFromTemplate = false;
     342             :     bool m_bIsLSB = true;
     343             :     CPLString m_osHeaderParsingStandard{};
     344             :     CPLString m_osInterleave{};
     345             :     char **m_papszCreationOptions = nullptr;
     346             :     CPLString m_osXMLPDS4{};
     347             : 
     348             :     void CreateHeader(CPLXMLNode *psProduct, const char *pszCARTVersion);
     349             :     void WriteHeader();
     350             :     void WriteHeaderAppendCase();
     351             :     void WriteVectorLayers(CPLXMLNode *psProduct);
     352             :     void WriteArray(const CPLString &osPrefix, CPLXMLNode *psFAO,
     353             :                     const char *pszLocalIdentifier,
     354             :                     CPLXMLNode *psTemplateSpecialConstants);
     355             :     void WriteGeoreferencing(CPLXMLNode *psCart, const char *pszCARTVersion);
     356             :     void ReadGeoreferencing(CPLXMLNode *psProduct);
     357             :     bool InitImageFile();
     358             : 
     359             :     void SubstituteVariables(CPLXMLNode *psNode, char **papszDict);
     360             : 
     361             :     bool OpenTableCharacter(const char *pszFilename, const CPLXMLNode *psTable);
     362             : 
     363             :     bool OpenTableBinary(const char *pszFilename, const CPLXMLNode *psTable);
     364             : 
     365             :     bool OpenTableDelimited(const char *pszFilename, const CPLXMLNode *psTable);
     366             : 
     367             :     static PDS4Dataset *CreateInternal(const char *pszFilename,
     368             :                                        GDALDataset *poSrcDS, int nXSize,
     369             :                                        int nYSize, int nBands,
     370             :                                        GDALDataType eType,
     371             :                                        const char *const *papszOptions);
     372             : 
     373             :     CPLErr Close() override;
     374             : 
     375             :   public:
     376             :     PDS4Dataset();
     377             :     virtual ~PDS4Dataset();
     378             : 
     379             :     virtual int CloseDependentDatasets() override;
     380             : 
     381             :     const OGRSpatialReference *GetSpatialRef() const override;
     382             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
     383             :     virtual CPLErr GetGeoTransform(double *) override;
     384             :     virtual CPLErr SetGeoTransform(double *) override;
     385             :     virtual char **GetFileList() override;
     386             :     virtual CPLErr SetMetadata(char **papszMD,
     387             :                                const char *pszDomain = "") override;
     388             : 
     389        1009 :     int GetLayerCount() override
     390             :     {
     391        1009 :         return static_cast<int>(m_apoLayers.size());
     392             :     }
     393             : 
     394             :     OGRLayer *GetLayer(int) override;
     395             : 
     396             :     OGRLayer *ICreateLayer(const char *pszName,
     397             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     398             :                            CSLConstList papszOptions) override;
     399             : 
     400             :     int TestCapability(const char *pszCap) override;
     401             : 
     402             :     bool GetRawBinaryLayout(GDALDataset::RawBinaryLayout &) override;
     403             : 
     404             :     static PDS4Dataset *OpenInternal(GDALOpenInfo *);
     405             : 
     406         178 :     static GDALDataset *Open(GDALOpenInfo *poOpenInfo)
     407             :     {
     408         178 :         return OpenInternal(poOpenInfo);
     409             :     }
     410             : 
     411             :     static GDALDataset *Create(const char *pszFilename, int nXSize, int nYSize,
     412             :                                int nBands, GDALDataType eType,
     413             :                                char **papszOptions);
     414             :     static GDALDataset *CreateCopy(const char *pszFilename,
     415             :                                    GDALDataset *poSrcDS, int bStrict,
     416             :                                    char **papszOptions,
     417             :                                    GDALProgressFunc pfnProgress,
     418             :                                    void *pProgressData);
     419             :     static CPLErr Delete(const char *pszName);
     420             : 
     421         262 :     const char *const *GetOpenOptions() const
     422             :     {
     423         262 :         return papszOpenOptions;
     424             :     }
     425             : 
     426         338 :     void MarkHeaderDirty()
     427             :     {
     428         338 :         m_bDirtyHeader = true;
     429         338 :     }
     430             : };
     431             : 
     432             : /************************************************************************/
     433             : /* ==================================================================== */
     434             : /*                        PDS4RawRasterBand                            */
     435             : /* ==================================================================== */
     436             : /************************************************************************/
     437             : 
     438             : class PDS4RawRasterBand final : public RawRasterBand
     439             : {
     440             :     friend class PDS4Dataset;
     441             : 
     442             :     bool m_bHasOffset;
     443             :     bool m_bHasScale;
     444             :     bool m_bHasNoData;
     445             :     double m_dfOffset;
     446             :     double m_dfScale;
     447             :     double m_dfNoData;
     448             : 
     449             :   public:
     450             :     PDS4RawRasterBand(GDALDataset *l_poDS, int l_nBand, VSILFILE *l_fpRaw,
     451             :                       vsi_l_offset l_nImgOffset, int l_nPixelOffset,
     452             :                       int l_nLineOffset, GDALDataType l_eDataType,
     453             :                       RawRasterBand::ByteOrder eByteOrderIn);
     454             : 
     455         840 :     virtual ~PDS4RawRasterBand()
     456         420 :     {
     457         840 :     }
     458             : 
     459             :     virtual CPLErr IWriteBlock(int, int, void *) override;
     460             : 
     461             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     462             :                              GDALDataType, GSpacing nPixelSpace,
     463             :                              GSpacing nLineSpace,
     464             :                              GDALRasterIOExtraArg *psExtraArg) override;
     465             : 
     466             :     virtual double GetOffset(int *pbSuccess = nullptr) override;
     467             :     virtual double GetScale(int *pbSuccess = nullptr) override;
     468             :     virtual CPLErr SetOffset(double dfNewOffset) override;
     469             :     virtual CPLErr SetScale(double dfNewScale) override;
     470             :     virtual double GetNoDataValue(int *pbSuccess = nullptr) override;
     471             :     virtual CPLErr SetNoDataValue(double dfNewNoData) override;
     472             : 
     473         115 :     virtual const char *GetUnitType() override
     474             :     {
     475         115 :         return static_cast<PDS4Dataset *>(poDS)->m_osUnits.c_str();
     476             :     }
     477             : 
     478          66 :     virtual CPLErr SetUnitType(const char *pszUnits) override
     479             :     {
     480          66 :         static_cast<PDS4Dataset *>(poDS)->m_osUnits = pszUnits;
     481          66 :         return CE_None;
     482             :     }
     483             : 
     484             :     void SetMaskBand(GDALRasterBand *poMaskBand);
     485             : };
     486             : 
     487             : /************************************************************************/
     488             : /* ==================================================================== */
     489             : /*                         PDS4WrapperRasterBand                       */
     490             : /*                                                                      */
     491             : /*      proxy for bands stored in other formats.                        */
     492             : /* ==================================================================== */
     493             : /************************************************************************/
     494             : class PDS4WrapperRasterBand final : public GDALProxyRasterBand
     495             : {
     496             :     friend class PDS4Dataset;
     497             : 
     498             :     GDALRasterBand *m_poBaseBand;
     499             :     bool m_bHasOffset;
     500             :     bool m_bHasScale;
     501             :     bool m_bHasNoData;
     502             :     double m_dfOffset;
     503             :     double m_dfScale;
     504             :     double m_dfNoData;
     505             : 
     506             :   protected:
     507             :     virtual GDALRasterBand *
     508         150 :     RefUnderlyingRasterBand(bool /*bForceOpen*/) const override
     509             :     {
     510         150 :         return m_poBaseBand;
     511             :     }
     512             : 
     513             :   public:
     514             :     explicit PDS4WrapperRasterBand(GDALRasterBand *poBaseBandIn);
     515             : 
     516          34 :     ~PDS4WrapperRasterBand()
     517          17 :     {
     518          34 :     }
     519             : 
     520             :     virtual CPLErr Fill(double dfRealValue,
     521             :                         double dfImaginaryValue = 0) override;
     522             :     virtual CPLErr IWriteBlock(int, int, void *) override;
     523             : 
     524             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     525             :                              GDALDataType, GSpacing nPixelSpace,
     526             :                              GSpacing nLineSpace,
     527             :                              GDALRasterIOExtraArg *psExtraArg) override;
     528             : 
     529             :     virtual double GetOffset(int *pbSuccess = nullptr) override;
     530             :     virtual double GetScale(int *pbSuccess = nullptr) override;
     531             :     virtual CPLErr SetOffset(double dfNewOffset) override;
     532             :     virtual CPLErr SetScale(double dfNewScale) override;
     533             :     virtual double GetNoDataValue(int *pbSuccess = nullptr) override;
     534             :     virtual CPLErr SetNoDataValue(double dfNewNoData) override;
     535             : 
     536          11 :     virtual const char *GetUnitType() override
     537             :     {
     538          11 :         return static_cast<PDS4Dataset *>(poDS)->m_osUnits.c_str();
     539             :     }
     540             : 
     541          13 :     virtual CPLErr SetUnitType(const char *pszUnits) override
     542             :     {
     543          13 :         static_cast<PDS4Dataset *>(poDS)->m_osUnits = pszUnits;
     544          13 :         return CE_None;
     545             :     }
     546             : 
     547           0 :     int GetMaskFlags() override
     548             :     {
     549           0 :         return nMaskFlags;
     550             :     }
     551             : 
     552           0 :     GDALRasterBand *GetMaskBand() override
     553             :     {
     554           0 :         return poMask;
     555             :     }
     556             : 
     557             :     void SetMaskBand(GDALRasterBand *poMaskBand);
     558             : };
     559             : 
     560             : /************************************************************************/
     561             : /* ==================================================================== */
     562             : /*                             PDS4MaskBand                             */
     563             : /* ==================================================================== */
     564             : 
     565             : class PDS4MaskBand final : public GDALRasterBand
     566             : {
     567             :     GDALRasterBand *m_poBaseBand;
     568             :     void *m_pBuffer;
     569             :     std::vector<double> m_adfConstants;
     570             : 
     571             :   public:
     572             :     PDS4MaskBand(GDALRasterBand *poBaseBand,
     573             :                  const std::vector<double> &adfConstants);
     574             :     ~PDS4MaskBand();
     575             : 
     576             :     virtual CPLErr IReadBlock(int, int, void *) override;
     577             : };

Generated by: LCOV version 1.14