Coverage Report

Created: 2025-11-16 06:25

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