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 : #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 : #define GCIF_GEOTRANSFORM 0x01
46 : #define GCIF_PROJECTION 0x02
47 : #define GCIF_METADATA 0x04
48 : #define GCIF_GCPS 0x08
49 :
50 : #define GCIF_NODATA 0x001000
51 : #define GCIF_CATEGORYNAMES 0x002000
52 : #define GCIF_MINMAX 0x004000
53 : #define GCIF_SCALEOFFSET 0x008000
54 : #define GCIF_UNITTYPE 0x010000
55 : #define GCIF_COLORTABLE 0x020000
56 : /* Same value as GCIF_COLORTABLE */
57 : #define GCIF_COLORINTERP 0x020000
58 : #define GCIF_BAND_METADATA 0x040000
59 : #define GCIF_RAT 0x080000
60 : #define GCIF_MASK 0x100000
61 : #define GCIF_BAND_DESCRIPTION 0x200000
62 :
63 : #define GCIF_ONLY_IF_MISSING 0x10000000
64 : #define GCIF_PROCESS_BANDS 0x20000000
65 :
66 : #define GCIF_PAM_DEFAULT \
67 : (GCIF_GEOTRANSFORM | GCIF_PROJECTION | GCIF_METADATA | GCIF_GCPS | \
68 : GCIF_NODATA | GCIF_CATEGORYNAMES | GCIF_MINMAX | GCIF_SCALEOFFSET | \
69 : GCIF_UNITTYPE | GCIF_COLORTABLE | GCIF_BAND_METADATA | GCIF_RAT | \
70 : GCIF_MASK | GCIF_ONLY_IF_MISSING | GCIF_PROCESS_BANDS | \
71 : GCIF_BAND_DESCRIPTION)
72 :
73 : /* GDAL PAM Flags */
74 : /* ERO 2011/04/13 : GPF_AUXMODE seems to be unimplemented */
75 : #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 : #define GPF_DISABLED 0x04 // do not try any PAM stuff.
78 : #define GPF_AUXMODE 0x08 // store info in .aux (HFA) file.
79 : #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 : {
201 : return psPam;
202 : }
203 :
204 7451 : int GetPamFlags()
205 : {
206 7451 : return nPamFlags;
207 : }
208 :
209 7351 : void SetPamFlags(int nValue)
210 : {
211 7351 : nPamFlags = nValue;
212 7351 : }
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 : {
366 : return psPam;
367 : }
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 */
|