Line data Source code
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 : #define GCIF_GEOTRANSFORM 0x01
30 : #define GCIF_PROJECTION 0x02
31 : #define GCIF_METADATA 0x04
32 : #define GCIF_GCPS 0x08
33 :
34 : #define GCIF_NODATA 0x001000
35 : #define GCIF_CATEGORYNAMES 0x002000
36 : #define GCIF_MINMAX 0x004000
37 : #define GCIF_SCALEOFFSET 0x008000
38 : #define GCIF_UNITTYPE 0x010000
39 : #define GCIF_COLORTABLE 0x020000
40 : /* Same value as GCIF_COLORTABLE */
41 : #define GCIF_COLORINTERP 0x020000
42 : #define GCIF_BAND_METADATA 0x040000
43 : #define GCIF_RAT 0x080000
44 : #define GCIF_MASK 0x100000
45 : #define GCIF_BAND_DESCRIPTION 0x200000
46 :
47 : #define GCIF_ONLY_IF_MISSING 0x10000000
48 : #define GCIF_PROCESS_BANDS 0x20000000
49 :
50 : #define GCIF_PAM_DEFAULT \
51 : (GCIF_GEOTRANSFORM | GCIF_PROJECTION | GCIF_METADATA | GCIF_GCPS | \
52 : GCIF_NODATA | GCIF_CATEGORYNAMES | GCIF_MINMAX | GCIF_SCALEOFFSET | \
53 : GCIF_UNITTYPE | GCIF_COLORTABLE | GCIF_BAND_METADATA | GCIF_RAT | \
54 : GCIF_MASK | GCIF_ONLY_IF_MISSING | GCIF_PROCESS_BANDS | \
55 : GCIF_BAND_DESCRIPTION)
56 :
57 : /* GDAL PAM Flags */
58 : /* ERO 2011/04/13 : GPF_AUXMODE seems to be unimplemented */
59 : #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 : #define GPF_DISABLED 0x04 // do not try any PAM stuff.
62 : #define GPF_AUXMODE 0x08 // store info in .aux (HFA) file.
63 : #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 : bool bHaveGeoTransform = false;
83 : GDALGeoTransform gt{};
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 Close() override;
141 :
142 : CPLErr FlushCache(bool bAtClosing) override;
143 :
144 : const OGRSpatialReference *GetSpatialRef() const override;
145 : const OGRSpatialReference *GetSpatialRefRasterOnly() const override;
146 : CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
147 :
148 : CPLErr GetGeoTransform(GDALGeoTransform &) const override;
149 : CPLErr SetGeoTransform(const GDALGeoTransform &) override;
150 : void DeleteGeoTransform();
151 :
152 : int GetGCPCount() override;
153 : const OGRSpatialReference *GetGCPSpatialRef() const override;
154 : const GDAL_GCP *GetGCPs() override;
155 : using GDALDataset::SetGCPs;
156 : CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
157 : const OGRSpatialReference *poSRS) override;
158 :
159 : CPLErr SetMetadata(char **papszMetadata,
160 : const char *pszDomain = "") override;
161 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
162 : const char *pszDomain = "") override;
163 : char **GetMetadata(const char *pszDomain = "") override;
164 : const char *GetMetadataItem(const char *pszName,
165 : const char *pszDomain = "") override;
166 :
167 : char **GetFileList(void) override;
168 :
169 : void ClearStatistics() override;
170 :
171 : //! @cond Doxygen_Suppress
172 : virtual CPLErr CloneInfo(GDALDataset *poSrcDS, int nCloneInfoFlags);
173 :
174 : CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
175 : const int *panOverviewList, int nListBands,
176 : const int *panBandList, GDALProgressFunc pfnProgress,
177 : void *pProgressData,
178 : CSLConstList papszOptions) override;
179 :
180 : // "semi private" methods.
181 : void MarkPamDirty();
182 :
183 : GDALDatasetPamInfo *GetPamInfo()
184 : {
185 : return psPam;
186 : }
187 :
188 7395 : int GetPamFlags()
189 : {
190 7395 : return nPamFlags;
191 : }
192 :
193 7291 : void SetPamFlags(int nValue)
194 : {
195 7291 : nPamFlags = nValue;
196 7291 : }
197 :
198 : //! @endcond
199 :
200 : private:
201 : CPL_DISALLOW_COPY_ASSIGN(GDALPamDataset)
202 :
203 : // cached return of GetMetadataItem("OVERVIEW_FILE", "OVERVIEWS")
204 : std::string m_osOverviewFile{};
205 : };
206 :
207 : //! @cond Doxygen_Suppress
208 :
209 : constexpr double GDAL_PAM_DEFAULT_NODATA_VALUE = 0;
210 : // Parenthesis for external code around std::numeric_limits<>::min/max,
211 : // for external Windows code that might have includes <windows.h> before
212 : // without defining NOMINMAX
213 : constexpr int64_t GDAL_PAM_DEFAULT_NODATA_VALUE_INT64 =
214 : (std::numeric_limits<int64_t>::min)();
215 : constexpr uint64_t GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64 =
216 : (std::numeric_limits<uint64_t>::max)();
217 :
218 : /* ==================================================================== */
219 : /* GDALRasterBandPamInfo */
220 : /* */
221 : /* We make these things a separate structure of information */
222 : /* primarily so we can modify it without altering the size of */
223 : /* the GDALPamDataset. It is an effort to reduce ABI churn for */
224 : /* driver plugins. */
225 : /* ==================================================================== */
226 : struct GDALRasterBandPamInfo
227 : {
228 : GDALPamDataset *poParentDS = nullptr;
229 :
230 : bool bNoDataValueSet = false;
231 : bool bNoDataValueSetAsInt64 = false;
232 : bool bNoDataValueSetAsUInt64 = false;
233 :
234 : double dfNoDataValue = GDAL_PAM_DEFAULT_NODATA_VALUE;
235 : int64_t nNoDataValueInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_INT64;
236 : uint64_t nNoDataValueUInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64;
237 :
238 : GDALColorTable *poColorTable = nullptr;
239 :
240 : GDALColorInterp eColorInterp = GCI_Undefined;
241 :
242 : char *pszUnitType = nullptr;
243 : char **papszCategoryNames = nullptr;
244 :
245 : double dfOffset = 0.0;
246 : double dfScale = 1.0;
247 :
248 : int bHaveMinMax = FALSE;
249 : double dfMin = 0;
250 : double dfMax = 0;
251 :
252 : int bHaveStats = FALSE;
253 : double dfMean = 0;
254 : double dfStdDev = 0;
255 :
256 : CPLXMLNode *psSavedHistograms = nullptr;
257 :
258 : GDALRasterAttributeTable *poDefaultRAT = nullptr;
259 :
260 : bool bOffsetSet = false;
261 : bool bScaleSet = false;
262 :
263 : void CopyFrom(const GDALRasterBandPamInfo &sOther);
264 : };
265 :
266 : //! @endcond
267 : /* ******************************************************************** */
268 : /* GDALPamRasterBand */
269 : /* ******************************************************************** */
270 :
271 : /** PAM raster band */
272 : class CPL_DLL GDALPamRasterBand : public GDALRasterBand
273 : {
274 : friend class GDALPamDataset;
275 :
276 : protected:
277 : //! @cond Doxygen_Suppress
278 : virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath);
279 : virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
280 :
281 : void PamInitialize();
282 : void PamClear();
283 : void PamInitializeNoParent();
284 : void MarkPamDirty();
285 :
286 : GDALRasterBandPamInfo *psPam = nullptr;
287 : //! @endcond
288 :
289 : public:
290 : GDALPamRasterBand();
291 : //! @cond Doxygen_Suppress
292 : explicit GDALPamRasterBand(int bForceCachedIO);
293 : //! @endcond
294 : ~GDALPamRasterBand() override;
295 :
296 : void SetDescription(const char *) override;
297 :
298 : CPLErr SetNoDataValue(double) override;
299 : CPLErr SetNoDataValueAsInt64(int64_t nNoData) override;
300 : CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override;
301 : double GetNoDataValue(int *pbSuccess = nullptr) override;
302 : int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override;
303 : uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override;
304 : CPLErr DeleteNoDataValue() override;
305 :
306 : CPLErr SetColorTable(GDALColorTable *) override;
307 : GDALColorTable *GetColorTable() override;
308 :
309 : CPLErr SetColorInterpretation(GDALColorInterp) override;
310 : GDALColorInterp GetColorInterpretation() override;
311 :
312 : const char *GetUnitType() override;
313 : CPLErr SetUnitType(const char *) override;
314 :
315 : char **GetCategoryNames() override;
316 : CPLErr SetCategoryNames(char **) override;
317 :
318 : double GetOffset(int *pbSuccess = nullptr) override;
319 : CPLErr SetOffset(double) override;
320 : double GetScale(int *pbSuccess = nullptr) override;
321 : CPLErr SetScale(double) override;
322 :
323 : CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
324 : GUIntBig *panHistogram, int bIncludeOutOfRange,
325 : int bApproxOK, GDALProgressFunc,
326 : void *pProgressData) override;
327 :
328 : CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets,
329 : GUIntBig **ppanHistogram, int bForce,
330 : GDALProgressFunc, void *pProgressData) override;
331 :
332 : CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
333 : GUIntBig *panHistogram) override;
334 :
335 : CPLErr SetMetadata(char **papszMetadata,
336 : const char *pszDomain = "") override;
337 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
338 : const char *pszDomain = "") override;
339 :
340 : GDALRasterAttributeTable *GetDefaultRAT() override;
341 : CPLErr SetDefaultRAT(const GDALRasterAttributeTable *) override;
342 :
343 : //! @cond Doxygen_Suppress
344 : // new in GDALPamRasterBand.
345 : virtual CPLErr CloneInfo(GDALRasterBand *poSrcBand, int nCloneInfoFlags);
346 :
347 : // "semi private" methods.
348 : GDALRasterBandPamInfo *GetPamInfo()
349 : {
350 : return psPam;
351 : }
352 :
353 : //! @endcond
354 : private:
355 : CPL_DISALLOW_COPY_ASSIGN(GDALPamRasterBand)
356 :
357 : void ResetNoDataValues();
358 : };
359 :
360 : //! @cond Doxygen_Suppress
361 :
362 : /* ******************************************************************** */
363 : /* GDALPamMultiDim */
364 : /* ******************************************************************** */
365 :
366 : /** Class that serializes/deserializes metadata on multidimensional objects.
367 : * Currently SRS on GDALMDArray.
368 : */
369 : class CPL_DLL GDALPamMultiDim final
370 : {
371 : struct Private;
372 : std::unique_ptr<Private> d;
373 :
374 : void Load();
375 : void Save();
376 :
377 : public:
378 : explicit GDALPamMultiDim(const std::string &osFilename);
379 : ~GDALPamMultiDim();
380 :
381 : std::shared_ptr<OGRSpatialReference>
382 : GetSpatialRef(const std::string &osArrayFullName,
383 : const std::string &osContext);
384 :
385 : void SetSpatialRef(const std::string &osArrayFullName,
386 : const std::string &osContext,
387 : const OGRSpatialReference *poSRS);
388 :
389 : CPLErr GetStatistics(const std::string &osArrayFullName,
390 : const std::string &osContext, bool bApproxOK,
391 : double *pdfMin, double *pdfMax, double *pdfMean,
392 : double *pdfStdDev, GUInt64 *pnValidCount);
393 :
394 : void SetStatistics(const std::string &osArrayFullName,
395 : const std::string &osContext, bool bApproxStats,
396 : double dfMin, double dfMax, double dfMean,
397 : double dfStdDev, GUInt64 nValidCount);
398 :
399 : void ClearStatistics();
400 :
401 : void ClearStatistics(const std::string &osArrayFullName,
402 : const std::string &osContext);
403 :
404 : static std::shared_ptr<GDALPamMultiDim>
405 : GetPAM(const std::shared_ptr<GDALMDArray> &poParent);
406 : };
407 :
408 : /* ******************************************************************** */
409 : /* GDALPamMDArray */
410 : /* ******************************************************************** */
411 :
412 : /** Class that relies on GDALPamMultiDim to serializes/deserializes metadata. */
413 : class CPL_DLL GDALPamMDArray : public GDALMDArray
414 : {
415 : std::shared_ptr<GDALPamMultiDim> m_poPam;
416 :
417 : protected:
418 : GDALPamMDArray(const std::string &osParentName, const std::string &osName,
419 : const std::shared_ptr<GDALPamMultiDim> &poPam,
420 : const std::string &osContext = std::string());
421 :
422 : bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
423 : double dfMean, double dfStdDev, GUInt64 nValidCount,
424 : CSLConstList papszOptions) override;
425 :
426 : public:
427 567 : const std::shared_ptr<GDALPamMultiDim> &GetPAM() const
428 : {
429 567 : return m_poPam;
430 : }
431 :
432 : CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
433 : double *pdfMax, double *pdfMean, double *padfStdDev,
434 : GUInt64 *pnValidCount, GDALProgressFunc pfnProgress,
435 : void *pProgressData) override;
436 :
437 : void ClearStatistics() override;
438 :
439 : bool SetSpatialRef(const OGRSpatialReference *poSRS) override;
440 :
441 : std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override;
442 : };
443 :
444 : // These are mainly helper functions for internal use.
445 : int CPL_DLL PamParseHistogram(CPLXMLNode *psHistItem, double *pdfMin,
446 : double *pdfMax, int *pnBuckets,
447 : GUIntBig **ppanHistogram,
448 : int *pbIncludeOutOfRange, int *pbApproxOK);
449 : CPLXMLNode CPL_DLL *PamFindMatchingHistogram(CPLXMLNode *psSavedHistograms,
450 : double dfMin, double dfMax,
451 : int nBuckets,
452 : int bIncludeOutOfRange,
453 : int bApproxOK);
454 : CPLXMLNode CPL_DLL *PamHistogramToXMLTree(double dfMin, double dfMax,
455 : int nBuckets, GUIntBig *panHistogram,
456 : int bIncludeOutOfRange, int bApprox);
457 :
458 : // For managing the proxy file database.
459 : const char CPL_DLL *PamGetProxy(const char *);
460 : const char CPL_DLL *PamAllocateProxy(const char *);
461 : const char CPL_DLL *PamDeallocateProxy(const char *);
462 : void CPL_DLL PamCleanProxyDB(void);
463 :
464 : //! @endcond
465 :
466 : #endif /* ndef GDAL_PAM_H_INCLUDED */
|