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