/****************************************************************************** * $Id$ * * Project: GDAL Core * Purpose: Declaration for Peristable Auxiliary Metadata classes. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2005, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #ifndef GDAL_PAM_H_INCLUDED #define GDAL_PAM_H_INCLUDED //! @cond Doxygen_Suppress #include "cpl_minixml.h" #include "gdal_priv.h" #include #include #include class GDALPamRasterBand; /* Clone Info Flags */ #define GCIF_GEOTRANSFORM 0x01 #define GCIF_PROJECTION 0x02 #define GCIF_METADATA 0x04 #define GCIF_GCPS 0x08 #define GCIF_NODATA 0x001000 #define GCIF_CATEGORYNAMES 0x002000 #define GCIF_MINMAX 0x004000 #define GCIF_SCALEOFFSET 0x008000 #define GCIF_UNITTYPE 0x010000 #define GCIF_COLORTABLE 0x020000 #define GCIF_COLORINTERP 0x020000 #define GCIF_BAND_METADATA 0x040000 #define GCIF_RAT 0x080000 #define GCIF_MASK 0x100000 #define GCIF_BAND_DESCRIPTION 0x200000 #define GCIF_ONLY_IF_MISSING 0x10000000 #define GCIF_PROCESS_BANDS 0x20000000 #define GCIF_PAM_DEFAULT \ (GCIF_GEOTRANSFORM | GCIF_PROJECTION | GCIF_METADATA | GCIF_GCPS | \ GCIF_NODATA | GCIF_CATEGORYNAMES | GCIF_MINMAX | GCIF_SCALEOFFSET | \ GCIF_UNITTYPE | GCIF_COLORTABLE | GCIF_COLORINTERP | GCIF_BAND_METADATA | \ GCIF_RAT | GCIF_MASK | GCIF_ONLY_IF_MISSING | GCIF_PROCESS_BANDS | \ GCIF_BAND_DESCRIPTION) /* GDAL PAM Flags */ /* ERO 2011/04/13 : GPF_AUXMODE seems to be unimplemented */ #define GPF_DIRTY 0x01 // .pam file needs to be written on close #define GPF_TRIED_READ_FAILED 0x02 // no need to keep trying to read .pam. #define GPF_DISABLED 0x04 // do not try any PAM stuff. #define GPF_AUXMODE 0x08 // store info in .aux (HFA) file. #define GPF_NOSAVE 0x10 // do not try to save pam info. /* ==================================================================== */ /* GDALDatasetPamInfo */ /* */ /* We make these things a separate structure of information */ /* primarily so we can modify it without altering the size of */ /* the GDALPamDataset. It is an effort to reduce ABI churn for */ /* driver plugins. */ /* ==================================================================== */ class GDALDatasetPamInfo { public: char *pszPamFilename = nullptr; std::vector m_apoOtherNodes{}; OGRSpatialReference *poSRS = nullptr; int bHaveGeoTransform = false; double adfGeoTransform[6]{0, 0, 0, 0, 0, 0}; int nGCPCount = 0; GDAL_GCP *pasGCPList = nullptr; OGRSpatialReference *poGCP_SRS = nullptr; CPLString osPhysicalFilename{}; CPLString osSubdatasetName{}; CPLString osAuxFilename{}; int bHasMetadata = false; }; //! @endcond /* ******************************************************************** */ /* GDALPamDataset */ /* ******************************************************************** */ /** PAM dataset */ class CPL_DLL GDALPamDataset : public GDALDataset { friend class GDALPamRasterBand; private: int IsPamFilenameAPotentialSiblingFile(); protected: GDALPamDataset(void); //! @cond Doxygen_Suppress int nPamFlags = 0; GDALDatasetPamInfo *psPam = nullptr; virtual CPLXMLNode *SerializeToXML(const char *); virtual CPLErr XMLInit(CPLXMLNode *, const char *); virtual CPLErr TryLoadXML(char **papszSiblingFiles = nullptr); virtual CPLErr TrySaveXML(); CPLErr TryLoadAux(char **papszSiblingFiles = nullptr); CPLErr TrySaveAux(); virtual const char *BuildPamFilename(); void PamInitialize(); void PamClear(); void SetPhysicalFilename(const char *); const char *GetPhysicalFilename(); void SetSubdatasetName(const char *); const char *GetSubdatasetName(); //! @endcond public: ~GDALPamDataset() override; void FlushCache(bool bAtClosing) override; const OGRSpatialReference *GetSpatialRef() const override; CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override; CPLErr GetGeoTransform(double *) override; CPLErr SetGeoTransform(double *) override; void DeleteGeoTransform(); int GetGCPCount() override; const OGRSpatialReference *GetGCPSpatialRef() const override; const GDAL_GCP *GetGCPs() override; using GDALDataset::SetGCPs; CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList, const OGRSpatialReference *poSRS) override; CPLErr SetMetadata(char **papszMetadata, const char *pszDomain = "") override; CPLErr SetMetadataItem(const char *pszName, const char *pszValue, const char *pszDomain = "") override; char **GetMetadata(const char *pszDomain = "") override; const char *GetMetadataItem(const char *pszName, const char *pszDomain = "") override; char **GetFileList(void) override; void ClearStatistics() override; //! @cond Doxygen_Suppress virtual CPLErr CloneInfo(GDALDataset *poSrcDS, int nCloneInfoFlags); CPLErr IBuildOverviews(const char *pszResampling, int nOverviews, const int *panOverviewList, int nListBands, const int *panBandList, GDALProgressFunc pfnProgress, void *pProgressData, CSLConstList papszOptions) override; // "semi private" methods. void MarkPamDirty() { nPamFlags |= GPF_DIRTY; } GDALDatasetPamInfo *GetPamInfo() { return psPam; } int GetPamFlags() { return nPamFlags; } void SetPamFlags(int nValue) { nPamFlags = nValue; } //! @endcond private: CPL_DISALLOW_COPY_ASSIGN(GDALPamDataset) }; //! @cond Doxygen_Suppress constexpr double GDAL_PAM_DEFAULT_NODATA_VALUE = 0; // Parenthesis for external code around std::numeric_limits<>::min/max, // for external Windows code that might have includes before // without defining NOMINMAX constexpr int64_t GDAL_PAM_DEFAULT_NODATA_VALUE_INT64 = (std::numeric_limits::min)(); constexpr uint64_t GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64 = (std::numeric_limits::max)(); /* ==================================================================== */ /* GDALRasterBandPamInfo */ /* */ /* We make these things a separate structure of information */ /* primarily so we can modify it without altering the size of */ /* the GDALPamDataset. It is an effort to reduce ABI churn for */ /* driver plugins. */ /* ==================================================================== */ struct GDALRasterBandPamInfo { GDALPamDataset *poParentDS = nullptr; bool bNoDataValueSet = false; bool bNoDataValueSetAsInt64 = false; bool bNoDataValueSetAsUInt64 = false; double dfNoDataValue = GDAL_PAM_DEFAULT_NODATA_VALUE; int64_t nNoDataValueInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_INT64; uint64_t nNoDataValueUInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64; GDALColorTable *poColorTable = nullptr; GDALColorInterp eColorInterp = GCI_Undefined; char *pszUnitType = nullptr; char **papszCategoryNames = nullptr; double dfOffset = 0.0; double dfScale = 1.0; int bHaveMinMax = FALSE; double dfMin = 0; double dfMax = 0; int bHaveStats = FALSE; double dfMean = 0; double dfStdDev = 0; CPLXMLNode *psSavedHistograms = nullptr; GDALRasterAttributeTable *poDefaultRAT = nullptr; bool bOffsetSet = false; bool bScaleSet = false; }; //! @endcond /* ******************************************************************** */ /* GDALPamRasterBand */ /* ******************************************************************** */ /** PAM raster band */ class CPL_DLL GDALPamRasterBand : public GDALRasterBand { friend class GDALPamDataset; protected: //! @cond Doxygen_Suppress virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath); virtual CPLErr XMLInit(CPLXMLNode *, const char *); void PamInitialize(); void PamClear(); void PamInitializeNoParent(); void MarkPamDirty(); GDALRasterBandPamInfo *psPam = nullptr; //! @endcond public: GDALPamRasterBand(); //! @cond Doxygen_Suppress explicit GDALPamRasterBand(int bForceCachedIO); //! @endcond ~GDALPamRasterBand() override; void SetDescription(const char *) override; CPLErr SetNoDataValue(double) override; CPLErr SetNoDataValueAsInt64(int64_t nNoData) override; CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override; double GetNoDataValue(int *pbSuccess = nullptr) override; int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override; uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override; CPLErr DeleteNoDataValue() override; CPLErr SetColorTable(GDALColorTable *) override; GDALColorTable *GetColorTable() override; CPLErr SetColorInterpretation(GDALColorInterp) override; GDALColorInterp GetColorInterpretation() override; const char *GetUnitType() override; CPLErr SetUnitType(const char *) override; char **GetCategoryNames() override; CPLErr SetCategoryNames(char **) override; double GetOffset(int *pbSuccess = nullptr) override; CPLErr SetOffset(double) override; double GetScale(int *pbSuccess = nullptr) override; CPLErr SetScale(double) override; CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc, void *pProgressData) override; CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets, GUIntBig **ppanHistogram, int bForce, GDALProgressFunc, void *pProgressData) override; CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram) override; CPLErr SetMetadata(char **papszMetadata, const char *pszDomain = "") override; CPLErr SetMetadataItem(const char *pszName, const char *pszValue, const char *pszDomain = "") override; GDALRasterAttributeTable *GetDefaultRAT() override; CPLErr SetDefaultRAT(const GDALRasterAttributeTable *) override; //! @cond Doxygen_Suppress // new in GDALPamRasterBand. virtual CPLErr CloneInfo(GDALRasterBand *poSrcBand, int nCloneInfoFlags); // "semi private" methods. GDALRasterBandPamInfo *GetPamInfo() { return psPam; } //! @endcond private: CPL_DISALLOW_COPY_ASSIGN(GDALPamRasterBand) void ResetNoDataValues(); }; //! @cond Doxygen_Suppress /* ******************************************************************** */ /* GDALPamMultiDim */ /* ******************************************************************** */ /** Class that serializes/deserializes metadata on multidimensional objects. * Currently SRS on GDALMDArray. */ class CPL_DLL GDALPamMultiDim { struct Private; std::unique_ptr d; void Load(); void Save(); public: explicit GDALPamMultiDim(const std::string &osFilename); virtual ~GDALPamMultiDim(); std::shared_ptr GetSpatialRef(const std::string &osArrayFullName); void SetSpatialRef(const std::string &osArrayFullName, const OGRSpatialReference *poSRS); CPLErr GetStatistics(const std::string &osArrayFullName, bool bApproxOK, double *pdfMin, double *pdfMax, double *pdfMean, double *pdfStdDev, GUInt64 *pnValidCount); void SetStatistics(const std::string &osArrayFullName, bool bApproxStats, double dfMin, double dfMax, double dfMean, double dfStdDev, GUInt64 nValidCount); void ClearStatistics(); void ClearStatistics(const std::string &osArrayFullName); }; /* ******************************************************************** */ /* GDALPamMDArray */ /* ******************************************************************** */ /** Class that relies on GDALPamMultiDim to serializes/deserializes metadata. */ class CPL_DLL GDALPamMDArray : public GDALMDArray { std::shared_ptr m_poPam; protected: GDALPamMDArray(const std::string &osParentName, const std::string &osName, const std::shared_ptr &poPam); bool SetStatistics(bool bApproxStats, double dfMin, double dfMax, double dfMean, double dfStdDev, GUInt64 nValidCount) override; public: const std::shared_ptr &GetPAM() const { return m_poPam; } CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin, double *pdfMax, double *pdfMean, double *padfStdDev, GUInt64 *pnValidCount, GDALProgressFunc pfnProgress, void *pProgressData) override; void ClearStatistics() override; bool SetSpatialRef(const OGRSpatialReference *poSRS) override; std::shared_ptr GetSpatialRef() const override; }; // These are mainly helper functions for internal use. int CPL_DLL PamParseHistogram(CPLXMLNode *psHistItem, double *pdfMin, double *pdfMax, int *pnBuckets, GUIntBig **ppanHistogram, int *pbIncludeOutOfRange, int *pbApproxOK); CPLXMLNode CPL_DLL *PamFindMatchingHistogram(CPLXMLNode *psSavedHistograms, double dfMin, double dfMax, int nBuckets, int bIncludeOutOfRange, int bApproxOK); CPLXMLNode CPL_DLL *PamHistogramToXMLTree(double dfMin, double dfMax, int nBuckets, GUIntBig *panHistogram, int bIncludeOutOfRange, int bApprox); // For managing the proxy file database. const char CPL_DLL *PamGetProxy(const char *); const char CPL_DLL *PamAllocateProxy(const char *); const char CPL_DLL *PamDeallocateProxy(const char *); void CPL_DLL PamCleanProxyDB(void); //! @endcond #endif /* ndef GDAL_PAM_H_INCLUDED */