Coverage Report

Created: 2025-06-13 06:29

/src/gdal/gcore/gdal_pam.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  GDAL Core
4
 * Purpose:  Declaration for Peristable Auxiliary Metadata classes.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef GDAL_PAM_H_INCLUDED
14
#define GDAL_PAM_H_INCLUDED
15
16
//! @cond Doxygen_Suppress
17
18
#include "cpl_minixml.h"
19
#include "gdal_priv.h"
20
#include <array>
21
#include <limits>
22
#include <map>
23
#include <vector>
24
25
class GDALPamRasterBand;
26
27
/* Clone Info Flags */
28
29
0
#define GCIF_GEOTRANSFORM 0x01
30
0
#define GCIF_PROJECTION 0x02
31
0
#define GCIF_METADATA 0x04
32
0
#define GCIF_GCPS 0x08
33
34
0
#define GCIF_NODATA 0x001000
35
0
#define GCIF_CATEGORYNAMES 0x002000
36
0
#define GCIF_MINMAX 0x004000
37
0
#define GCIF_SCALEOFFSET 0x008000
38
0
#define GCIF_UNITTYPE 0x010000
39
0
#define GCIF_COLORTABLE 0x020000
40
/* Same value as GCIF_COLORTABLE */
41
0
#define GCIF_COLORINTERP 0x020000
42
0
#define GCIF_BAND_METADATA 0x040000
43
0
#define GCIF_RAT 0x080000
44
0
#define GCIF_MASK 0x100000
45
0
#define GCIF_BAND_DESCRIPTION 0x200000
46
47
0
#define GCIF_ONLY_IF_MISSING 0x10000000
48
0
#define GCIF_PROCESS_BANDS 0x20000000
49
50
#define GCIF_PAM_DEFAULT                                                       \
51
0
    (GCIF_GEOTRANSFORM | GCIF_PROJECTION | GCIF_METADATA | GCIF_GCPS |         \
52
0
     GCIF_NODATA | GCIF_CATEGORYNAMES | GCIF_MINMAX | GCIF_SCALEOFFSET |       \
53
0
     GCIF_UNITTYPE | GCIF_COLORTABLE | GCIF_BAND_METADATA | GCIF_RAT |         \
54
0
     GCIF_MASK | GCIF_ONLY_IF_MISSING | GCIF_PROCESS_BANDS |                   \
55
0
     GCIF_BAND_DESCRIPTION)
56
57
/* GDAL PAM Flags */
58
/* ERO 2011/04/13 : GPF_AUXMODE seems to be unimplemented */
59
0
#define GPF_DIRTY 0x01              // .pam file needs to be written on close
60
#define GPF_TRIED_READ_FAILED 0x02  // no need to keep trying to read .pam.
61
0
#define GPF_DISABLED 0x04           // do not try any PAM stuff.
62
0
#define GPF_AUXMODE 0x08            // store info in .aux (HFA) file.
63
0
#define GPF_NOSAVE 0x10             // do not try to save pam info.
64
65
/* ==================================================================== */
66
/*      GDALDatasetPamInfo                                              */
67
/*                                                                      */
68
/*      We make these things a separate structure of information        */
69
/*      primarily so we can modify it without altering the size of      */
70
/*      the GDALPamDataset.  It is an effort to reduce ABI churn for    */
71
/*      driver plugins.                                                 */
72
/* ==================================================================== */
73
class GDALDatasetPamInfo
74
{
75
  public:
76
    char *pszPamFilename = nullptr;
77
78
    std::vector<CPLXMLTreeCloser> m_apoOtherNodes{};
79
80
    OGRSpatialReference *poSRS = nullptr;
81
82
    int bHaveGeoTransform = false;
83
    std::array<double, 6> adfGeoTransform{};
84
85
    std::vector<gdal::GCP> asGCPs{};
86
    OGRSpatialReference *poGCP_SRS = nullptr;
87
88
    CPLString osPhysicalFilename{};
89
    CPLString osSubdatasetName{};
90
    CPLString osDerivedDatasetName{};
91
    CPLString osAuxFilename{};
92
93
    int bHasMetadata = false;
94
};
95
96
//! @endcond
97
98
/* ******************************************************************** */
99
/*                           GDALPamDataset                             */
100
/* ******************************************************************** */
101
102
/** PAM dataset */
103
class CPL_DLL GDALPamDataset : public GDALDataset
104
{
105
    friend class GDALPamRasterBand;
106
107
  private:
108
    int IsPamFilenameAPotentialSiblingFile();
109
110
  protected:
111
    GDALPamDataset(void);
112
    //! @cond Doxygen_Suppress
113
    int nPamFlags = 0;
114
    GDALDatasetPamInfo *psPam = nullptr;
115
116
    virtual CPLXMLNode *SerializeToXML(const char *);
117
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
118
119
    virtual CPLErr TryLoadXML(CSLConstList papszSiblingFiles = nullptr);
120
    virtual CPLErr TrySaveXML();
121
122
    CPLErr TryLoadAux(CSLConstList papszSiblingFiles = nullptr);
123
    CPLErr TrySaveAux();
124
125
    virtual const char *BuildPamFilename();
126
127
    void PamInitialize();
128
    void PamClear();
129
130
    void SetPhysicalFilename(const char *);
131
    const char *GetPhysicalFilename();
132
    void SetSubdatasetName(const char *);
133
    const char *GetSubdatasetName();
134
    void SetDerivedDatasetName(const char *);
135
    //! @endcond
136
137
  public:
138
    ~GDALPamDataset() override;
139
140
    CPLErr FlushCache(bool bAtClosing) override;
141
142
    const OGRSpatialReference *GetSpatialRef() const override;
143
    CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
144
145
    CPLErr GetGeoTransform(double *) override;
146
    CPLErr SetGeoTransform(double *) override;
147
    void DeleteGeoTransform();
148
149
    int GetGCPCount() override;
150
    const OGRSpatialReference *GetGCPSpatialRef() const override;
151
    const GDAL_GCP *GetGCPs() override;
152
    using GDALDataset::SetGCPs;
153
    CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
154
                   const OGRSpatialReference *poSRS) override;
155
156
    CPLErr SetMetadata(char **papszMetadata,
157
                       const char *pszDomain = "") override;
158
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
159
                           const char *pszDomain = "") override;
160
    char **GetMetadata(const char *pszDomain = "") override;
161
    const char *GetMetadataItem(const char *pszName,
162
                                const char *pszDomain = "") override;
163
164
    char **GetFileList(void) override;
165
166
    void ClearStatistics() override;
167
168
    //! @cond Doxygen_Suppress
169
    virtual CPLErr CloneInfo(GDALDataset *poSrcDS, int nCloneInfoFlags);
170
171
    CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
172
                           const int *panOverviewList, int nListBands,
173
                           const int *panBandList, GDALProgressFunc pfnProgress,
174
                           void *pProgressData,
175
                           CSLConstList papszOptions) override;
176
177
    // "semi private" methods.
178
    void MarkPamDirty();
179
180
    GDALDatasetPamInfo *GetPamInfo()
181
0
    {
182
0
        return psPam;
183
0
    }
184
185
    int GetPamFlags()
186
0
    {
187
0
        return nPamFlags;
188
0
    }
189
190
    void SetPamFlags(int nValue)
191
0
    {
192
0
        nPamFlags = nValue;
193
0
    }
194
195
    //! @endcond
196
197
  private:
198
    CPL_DISALLOW_COPY_ASSIGN(GDALPamDataset)
199
200
    // cached return of GetMetadataItem("OVERVIEW_FILE", "OVERVIEWS")
201
    std::string m_osOverviewFile{};
202
};
203
204
//! @cond Doxygen_Suppress
205
206
constexpr double GDAL_PAM_DEFAULT_NODATA_VALUE = 0;
207
// Parenthesis for external code around std::numeric_limits<>::min/max,
208
// for external Windows code that might have includes <windows.h> before
209
// without defining NOMINMAX
210
constexpr int64_t GDAL_PAM_DEFAULT_NODATA_VALUE_INT64 =
211
    (std::numeric_limits<int64_t>::min)();
212
constexpr uint64_t GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64 =
213
    (std::numeric_limits<uint64_t>::max)();
214
215
/* ==================================================================== */
216
/*      GDALRasterBandPamInfo                                           */
217
/*                                                                      */
218
/*      We make these things a separate structure of information        */
219
/*      primarily so we can modify it without altering the size of      */
220
/*      the GDALPamDataset.  It is an effort to reduce ABI churn for    */
221
/*      driver plugins.                                                 */
222
/* ==================================================================== */
223
struct GDALRasterBandPamInfo
224
{
225
    GDALPamDataset *poParentDS = nullptr;
226
227
    bool bNoDataValueSet = false;
228
    bool bNoDataValueSetAsInt64 = false;
229
    bool bNoDataValueSetAsUInt64 = false;
230
231
    double dfNoDataValue = GDAL_PAM_DEFAULT_NODATA_VALUE;
232
    int64_t nNoDataValueInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_INT64;
233
    uint64_t nNoDataValueUInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64;
234
235
    GDALColorTable *poColorTable = nullptr;
236
237
    GDALColorInterp eColorInterp = GCI_Undefined;
238
239
    char *pszUnitType = nullptr;
240
    char **papszCategoryNames = nullptr;
241
242
    double dfOffset = 0.0;
243
    double dfScale = 1.0;
244
245
    int bHaveMinMax = FALSE;
246
    double dfMin = 0;
247
    double dfMax = 0;
248
249
    int bHaveStats = FALSE;
250
    double dfMean = 0;
251
    double dfStdDev = 0;
252
253
    CPLXMLNode *psSavedHistograms = nullptr;
254
255
    GDALRasterAttributeTable *poDefaultRAT = nullptr;
256
257
    bool bOffsetSet = false;
258
    bool bScaleSet = false;
259
260
    void CopyFrom(const GDALRasterBandPamInfo &sOther);
261
};
262
263
//! @endcond
264
/* ******************************************************************** */
265
/*                          GDALPamRasterBand                           */
266
/* ******************************************************************** */
267
268
/** PAM raster band */
269
class CPL_DLL GDALPamRasterBand : public GDALRasterBand
270
{
271
    friend class GDALPamDataset;
272
273
  protected:
274
    //! @cond Doxygen_Suppress
275
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath);
276
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
277
278
    void PamInitialize();
279
    void PamClear();
280
    void PamInitializeNoParent();
281
    void MarkPamDirty();
282
283
    GDALRasterBandPamInfo *psPam = nullptr;
284
    //! @endcond
285
286
  public:
287
    GDALPamRasterBand();
288
    //! @cond Doxygen_Suppress
289
    explicit GDALPamRasterBand(int bForceCachedIO);
290
    //! @endcond
291
    ~GDALPamRasterBand() override;
292
293
    void SetDescription(const char *) override;
294
295
    CPLErr SetNoDataValue(double) override;
296
    CPLErr SetNoDataValueAsInt64(int64_t nNoData) override;
297
    CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override;
298
    double GetNoDataValue(int *pbSuccess = nullptr) override;
299
    int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override;
300
    uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override;
301
    CPLErr DeleteNoDataValue() override;
302
303
    CPLErr SetColorTable(GDALColorTable *) override;
304
    GDALColorTable *GetColorTable() override;
305
306
    CPLErr SetColorInterpretation(GDALColorInterp) override;
307
    GDALColorInterp GetColorInterpretation() override;
308
309
    const char *GetUnitType() override;
310
    CPLErr SetUnitType(const char *) override;
311
312
    char **GetCategoryNames() override;
313
    CPLErr SetCategoryNames(char **) override;
314
315
    double GetOffset(int *pbSuccess = nullptr) override;
316
    CPLErr SetOffset(double) override;
317
    double GetScale(int *pbSuccess = nullptr) override;
318
    CPLErr SetScale(double) override;
319
320
    CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
321
                        GUIntBig *panHistogram, int bIncludeOutOfRange,
322
                        int bApproxOK, GDALProgressFunc,
323
                        void *pProgressData) override;
324
325
    CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets,
326
                               GUIntBig **ppanHistogram, int bForce,
327
                               GDALProgressFunc, void *pProgressData) override;
328
329
    CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
330
                               GUIntBig *panHistogram) override;
331
332
    CPLErr SetMetadata(char **papszMetadata,
333
                       const char *pszDomain = "") override;
334
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
335
                           const char *pszDomain = "") override;
336
337
    GDALRasterAttributeTable *GetDefaultRAT() override;
338
    CPLErr SetDefaultRAT(const GDALRasterAttributeTable *) override;
339
340
    //! @cond Doxygen_Suppress
341
    // new in GDALPamRasterBand.
342
    virtual CPLErr CloneInfo(GDALRasterBand *poSrcBand, int nCloneInfoFlags);
343
344
    // "semi private" methods.
345
    GDALRasterBandPamInfo *GetPamInfo()
346
0
    {
347
0
        return psPam;
348
0
    }
349
350
    //! @endcond
351
  private:
352
    CPL_DISALLOW_COPY_ASSIGN(GDALPamRasterBand)
353
354
    void ResetNoDataValues();
355
};
356
357
//! @cond Doxygen_Suppress
358
359
/* ******************************************************************** */
360
/*                          GDALPamMultiDim                             */
361
/* ******************************************************************** */
362
363
/** Class that serializes/deserializes metadata on multidimensional objects.
364
 * Currently SRS on GDALMDArray.
365
 */
366
class CPL_DLL GDALPamMultiDim
367
{
368
    struct Private;
369
    std::unique_ptr<Private> d;
370
371
    void Load();
372
    void Save();
373
374
  public:
375
    explicit GDALPamMultiDim(const std::string &osFilename);
376
    virtual ~GDALPamMultiDim();
377
378
    std::shared_ptr<OGRSpatialReference>
379
    GetSpatialRef(const std::string &osArrayFullName,
380
                  const std::string &osContext);
381
382
    void SetSpatialRef(const std::string &osArrayFullName,
383
                       const std::string &osContext,
384
                       const OGRSpatialReference *poSRS);
385
386
    CPLErr GetStatistics(const std::string &osArrayFullName,
387
                         const std::string &osContext, bool bApproxOK,
388
                         double *pdfMin, double *pdfMax, double *pdfMean,
389
                         double *pdfStdDev, GUInt64 *pnValidCount);
390
391
    void SetStatistics(const std::string &osArrayFullName,
392
                       const std::string &osContext, bool bApproxStats,
393
                       double dfMin, double dfMax, double dfMean,
394
                       double dfStdDev, GUInt64 nValidCount);
395
396
    void ClearStatistics();
397
398
    void ClearStatistics(const std::string &osArrayFullName,
399
                         const std::string &osContext);
400
401
    static std::shared_ptr<GDALPamMultiDim>
402
    GetPAM(const std::shared_ptr<GDALMDArray> &poParent);
403
};
404
405
/* ******************************************************************** */
406
/*                          GDALPamMDArray                              */
407
/* ******************************************************************** */
408
409
/** Class that relies on GDALPamMultiDim to serializes/deserializes metadata. */
410
class CPL_DLL GDALPamMDArray : public GDALMDArray
411
{
412
    std::shared_ptr<GDALPamMultiDim> m_poPam;
413
414
  protected:
415
    GDALPamMDArray(const std::string &osParentName, const std::string &osName,
416
                   const std::shared_ptr<GDALPamMultiDim> &poPam,
417
                   const std::string &osContext = std::string());
418
419
    bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
420
                       double dfMean, double dfStdDev, GUInt64 nValidCount,
421
                       CSLConstList papszOptions) override;
422
423
  public:
424
    const std::shared_ptr<GDALPamMultiDim> &GetPAM() const
425
0
    {
426
0
        return m_poPam;
427
0
    }
428
429
    CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
430
                         double *pdfMax, double *pdfMean, double *padfStdDev,
431
                         GUInt64 *pnValidCount, GDALProgressFunc pfnProgress,
432
                         void *pProgressData) override;
433
434
    void ClearStatistics() override;
435
436
    bool SetSpatialRef(const OGRSpatialReference *poSRS) override;
437
438
    std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override;
439
};
440
441
// These are mainly helper functions for internal use.
442
int CPL_DLL PamParseHistogram(CPLXMLNode *psHistItem, double *pdfMin,
443
                              double *pdfMax, int *pnBuckets,
444
                              GUIntBig **ppanHistogram,
445
                              int *pbIncludeOutOfRange, int *pbApproxOK);
446
CPLXMLNode CPL_DLL *PamFindMatchingHistogram(CPLXMLNode *psSavedHistograms,
447
                                             double dfMin, double dfMax,
448
                                             int nBuckets,
449
                                             int bIncludeOutOfRange,
450
                                             int bApproxOK);
451
CPLXMLNode CPL_DLL *PamHistogramToXMLTree(double dfMin, double dfMax,
452
                                          int nBuckets, GUIntBig *panHistogram,
453
                                          int bIncludeOutOfRange, int bApprox);
454
455
// For managing the proxy file database.
456
const char CPL_DLL *PamGetProxy(const char *);
457
const char CPL_DLL *PamAllocateProxy(const char *);
458
const char CPL_DLL *PamDeallocateProxy(const char *);
459
void CPL_DLL PamCleanProxyDB(void);
460
461
//! @endcond
462
463
#endif /* ndef GDAL_PAM_H_INCLUDED */