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