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 : 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 : {
182 : return psPam;
183 : }
184 :
185 6555 : int GetPamFlags()
186 : {
187 6555 : return nPamFlags;
188 : }
189 :
190 6441 : void SetPamFlags(int nValue)
191 : {
192 6441 : nPamFlags = nValue;
193 6441 : }
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 : {
347 : return psPam;
348 : }
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 563 : const std::shared_ptr<GDALPamMultiDim> &GetPAM() const
425 : {
426 563 : return m_poPam;
427 : }
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 */
|