EVOLUTION-MANAGER
Edit File: marfa.h
/* * Copyright (c) 2002-2012, California Institute of Technology. * All rights reserved. Based on Government Sponsored Research under contracts NAS7-1407 and/or NAS7-03001. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * 3. Neither the name of the California Institute of Technology (Caltech), its operating division the Jet Propulsion Laboratory (JPL), * the National Aeronautics and Space Administration (NASA), nor the names of its contributors may be used to * endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2014-2015 Esri * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /****************************************************************************** * $Id: marfa.h 37669 2017-03-09 23:35:51Z lplesea $ * * Project: Meta Raster Format * Purpose: MRF structures * Author: Lucian Plesea * ****************************************************************************** * * * ****************************************************************************/ #ifndef GDAL_FRMTS_MRF_MARFA_H_INCLUDED #define GDAL_FRMTS_MRF_MARFA_H_INCLUDED #include <gdal_pam.h> #include <ogr_srs_api.h> #include <ogr_spatialref.h> // For printing values #include <ostream> #include <iostream> #include <sstream> #define NAMESPACE_MRF_START namespace GDAL_MRF { #define NAMESPACE_MRF_END } #define USING_NAMESPACE_MRF using namespace GDAL_MRF; NAMESPACE_MRF_START // ZLIB Bit flag fields // 0:3 - level, 4 - GZip, 5 RAW zlib, 6:9 strategy #define ZFLAG_LMASK 0xF // GZ and RAW are mutually exclusive, GZ has higher priority // If neither is set, use zlib stream format #define ZFLAG_GZ 0x10 #define ZFLAG_RAW 0x20 // Mask for zlib strategy, valid values are 0 to 4 shifted six bits, see zlib for meaning // Can use one of: // Z_DEFAULT : whatever zlib decides // Z_FILTERED : optimized for delta encoding // Z_HUFFMAN_ONLY : Only huffman encoding (adaptive) // Z_RLE : Only next character matches // Z_FIXED : Static huffman, faster decoder // #define ZFLAG_SMASK 0x1c0 // Force LERC to be included, normally off, detected in the makefile // #define LERC // These are a pain to maintain in sync. They should be replaced with // C++11 uniform initializers. The externs reside in util.cpp enum ILCompression { IL_PNG = 0, IL_PPNG, IL_JPEG, IL_JPNG, IL_NONE, IL_ZLIB, IL_TIF, #if defined(LERC) IL_LERC, #endif IL_ERR_COMP }; // Sequential is not supported by GDAL enum ILOrder { IL_Interleaved = 0, IL_Separate, IL_Sequential, IL_ERR_ORD }; extern char const * const * ILComp_Name; extern char const * const * ILComp_Ext; extern char const * const * ILOrder_Name; class GDALMRFDataset; class GDALMRFRasterBand; typedef struct { char *buffer; size_t size; } buf_mgr; // A tile index record, 16 bytes, big endian typedef struct { GIntBig offset; GIntBig size; } ILIdx; // Size of an image, also used as a tile or pixel location struct ILSize { GInt32 x, y, z, c; GIntBig l; // Dual use, sometimes it holds the number of pages ILSize(const int x_ = -1, const int y_ = -1, const int z_ = -1, const int c_ = -1, const int l_ = -1) { x = x_; y = y_; z = z_; c = c_; l = l_; } bool operator==(const ILSize& other) { return ((x == other.x) && (y == other.y) && (z == other.z) && (c == other.c) && (l == other.l)); } bool operator!=(const ILSize& other) { return !(*this == other); } }; std::ostream& operator<<(std::ostream &out, const ILSize& sz); std::ostream& operator<<(std::ostream &out, const ILIdx& t); bool is_Endianess_Dependent(GDALDataType dt, ILCompression comp); // Debugging support // #define PPMW #ifdef PPMW void ppmWrite(const char *fname, const char *data, const ILSize &sz); #endif /** * Collects information pertaining to a single raster * This structure is being shallow copied, no pointers allowed * */ typedef struct ILImage { ILImage(); GIntBig dataoffset; GIntBig idxoffset; GInt32 quality; GInt32 pageSizeBytes; ILSize size; ILSize pagesize; ILSize pagecount; ILCompression comp; ILOrder order; int nbo; int hasNoData; double NoDataValue; CPLString datfname; CPLString idxfname; GDALDataType dt; GDALColorInterp ci; } ILImage; // Delarations of utility functions /** * *\brief Converters between endianness * Call netXX() to guarantee big endian * */ static inline unsigned short int swab16(const unsigned short int val) { return (val << 8) | (val >> 8); } static inline unsigned int swab32(unsigned int val) { return (unsigned int)(swab16((unsigned short int) val)) << 16 | swab16((unsigned short int) (val >> 16)); } static inline unsigned long long int swab64(const unsigned long long int val) { return (unsigned long long int) (swab32((unsigned int)val)) << 32 | swab32((unsigned int)(val >> 32)); } // NET_ORDER is true if machine is BE, false otherwise // Call netxx() if network (big) order is needed #ifdef CPL_MSB #define NET_ORDER true // These could be macros, but for the side effects related to type static inline unsigned short net16(const unsigned short x) { return (x); } static inline unsigned int net32(const unsigned int x) { return (x); } static inline unsigned long long net64(const unsigned long long x) { return (x); } #else #define NET_ORDER false #define net16(x) swab16(x) #define net32(x) swab32(x) #define net64(x) swab64(x) #endif const char *CompName(ILCompression comp); const char *OrderName(ILOrder val); ILCompression CompToken(const char *, ILCompression def = IL_ERR_COMP); ILOrder OrderToken(const char *, ILOrder def = IL_ERR_ORD); CPLString getFname(CPLXMLNode *, const char *, const CPLString &, const char *); CPLString getFname(const CPLString &, const char *); double getXMLNum(CPLXMLNode *, const char *, double); GIntBig IdxOffset(const ILSize &, const ILImage &); double logbase(double val, double base); int IsPower(double value, double base); CPLXMLNode *SearchXMLSiblings(CPLXMLNode *psRoot, const char *pszElement); CPLString PrintDouble(double d, const char *frmt = "%12.8f"); void XMLSetAttributeVal(CPLXMLNode *parent, const char* pszName, const double val, const char *frmt = "%12.8f"); CPLXMLNode *XMLSetAttributeVal(CPLXMLNode *parent, const char*pszName, const ILSize &sz, const char *frmt = NULL); void XMLSetAttributeVal(CPLXMLNode *parent, const char*pszName, std::vector<double> const &values); // // Extension to CSL, set an entry only if it doesn't already exist // char **CSLAddIfMissing(char **papszList, const char *pszName, const char *pszValue); GDALColorEntry GetXMLColorEntry(CPLXMLNode *p); GIntBig IdxSize(const ILImage &full, const int scale = 0); // Similar to uncompress() from zlib, accepts the ZFLAG_RAW // Return true if it worked int ZUnPack(const buf_mgr &src, buf_mgr &dst, int flags); // Similar to compress2() but with flags to control zlib features // Returns true if it worked int ZPack(const buf_mgr &src, buf_mgr &dst, int flags); // checks that the file exists and is at least sz, if access is update it extends it int CheckFileSize(const char *fname, GIntBig sz, GDALAccess eAccess); // Number of pages of size psz needed to hold n elements static inline int pcount(const int n, const int sz) { return 1 + (n - 1) / sz; } // Returns a pagecount per dimension, .l will have the total number static inline const ILSize pcount(const ILSize &size, const ILSize &psz) { ILSize pcnt; pcnt.x = pcount(size.x, psz.x); pcnt.y = pcount(size.y, psz.y); pcnt.z = pcount(size.z, psz.z); pcnt.c = pcount(size.c, psz.c); pcnt.l = static_cast<GIntBig>(pcnt.x) * pcnt.y * pcnt.z * pcnt.c; return pcnt; } // Wrapper around the VISFile, remembers how the file was opened typedef struct { VSILFILE *FP; GDALRWFlag acc; } VF; // Offset of index, pos is in pages GIntBig IdxOffset(const ILSize &pos, const ILImage &img); enum { SAMPLING_ERR, SAMPLING_Avg, SAMPLING_Near }; GDALMRFRasterBand *newMRFRasterBand(GDALMRFDataset *, const ILImage &, int, int level = 0); class GDALMRFDataset : public GDALPamDataset { friend class GDALMRFRasterBand; friend GDALMRFRasterBand *newMRFRasterBand(GDALMRFDataset *, const ILImage &, int, int level); public: GDALMRFDataset(); virtual ~GDALMRFDataset(); static GDALDataset *Open(GDALOpenInfo *); static int Identify(GDALOpenInfo *); void Crystalize(); static GDALDataset *CreateCopy(const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData); static GDALDataset *Create(const char * pszName, int nXSize, int nYSize, int nBands, GDALDataType eType, char ** papszOptions); // Stub for delete, GDAL should only overwrite the XML static CPLErr Delete(const char *) { return CE_None; } virtual const char *GetProjectionRef() override { return projection; } virtual CPLErr SetProjection(const char *proj) override { projection = proj; return CE_None; } virtual CPLString const &GetPhotometricInterpretation() { return photometric; } virtual CPLErr SetPhotometricInterpretation(const char *photo) { photometric = photo; return CE_None; } virtual CPLErr GetGeoTransform(double *gt) override; virtual CPLErr SetGeoTransform(double *gt) override; virtual char **GetFileList() override; void SetColorTable(GDALColorTable *pct) { poColorTable = pct; }; const GDALColorTable *GetColorTable() { return poColorTable; }; void SetNoDataValue(const char*); void SetMinValue(const char*); void SetMaxValue(const char*); CPLErr SetVersion(int version); const CPLString GetFname() { return fname; }; // Patches a region of all the next overview, argument counts are in blocks virtual CPLErr PatchOverview(int BlockX, int BlockY, int Width, int Height, int srcLevel = 0, int recursive = false, int sampling_mode = SAMPLING_Avg); // Creates an XML tree from the current MRF. If written to a file it becomes an MRF CPLXMLNode *BuildConfig(); void SetPBufferSize(unsigned int sz) { pbsize = sz; } unsigned int GetPBufferSize() { return pbsize; } protected: CPLErr LevelInit(const int l); // Reads the XML metadata and returns the XML CPLXMLNode *ReadConfig() const; // Apply create options to the current dataset void ProcessCreateOptions(char **papszOptions); // Writes the XML tree as MRF. It does not check the content int WriteConfig(CPLXMLNode *); // Initializes the dataset from an MRF metadata XML CPLErr Initialize(CPLXMLNode *); // Do nothing, this is not possible in an MRF CPLErr CleanOverviews() { return CE_None; } bool IsSingleTile(); // Add uniform scale overlays, returns the new size of the index file GIntBig AddOverviews(int scale); // Late allocation buffer bool SetPBuffer(unsigned int sz); void *GetPBuffer() { if (!pbuffer && pbsize) SetPBuffer(pbsize); return pbuffer; } #if GDAL_VERSION_MAJOR >= 2 virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType, int, int *, GSpacing, GSpacing, GSpacing, GDALRasterIOExtraArg*) override; #else virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType, int, int *, int, int, int); #endif virtual CPLErr IBuildOverviews(const char*, int, int*, int, int*, GDALProgressFunc, void*) override; virtual int CloseDependentDatasets() override; // Write a tile, the infooffset is the relative position in the index file virtual CPLErr WriteTile(void *buff, GUIntBig infooffset, GUIntBig size = 0); // For versioned MRFs, add a version CPLErr AddVersion(); // Read the index record itself CPLErr ReadTileIdx(ILIdx &tinfo, const ILSize &pos, const ILImage &img, const GIntBig bias = 0); VSILFILE *IdxFP(); VSILFILE *DataFP(); GDALRWFlag IdxMode() { if (!ifp.FP) IdxFP(); return ifp.acc; }; GDALRWFlag DataMode() { if (!dfp.FP) DataFP(); return dfp.acc; }; GDALDataset *GetSrcDS(); /* * There are two images defined to allow for morphing on use, in the future * For example storing a multispectral image and opening it as RGB * * Support for this feature is not yet implemented. * */ // What the image is on disk ILImage full; // How we use it currently ILImage current; // The third dimension slice in use int zslice; // MRF file name CPLString fname; // The source to be cached in this MRF CPLString source; GIntBig idxSize; // The size of each version index, or the size of the cloned index int clonedSource; // Is it a cloned source int bypass_cache; // Do we alter disk cache int mp_safe; // Not thread safe, only multiple writers int hasVersions; // Does it support versions int verCount; // The last version int bCrystalized; // Unset only during the create process int spacing; // How many spare bytes before each tile data // Freeform sticky dataset options, as a list of key-value pairs CPLStringList optlist; // If caching data, the parent dataset GDALDataset *poSrcDS; // Level picked, or -1 for native int level; // Child dataset, if picking a specific level GDALMRFDataset *cds; // A small int actually due to GDAL limitations double scale; // A place to keep an uncompressed block, to keep from allocating it all the time void *pbuffer; unsigned int pbsize; ILSize tile; // ID of tile present in buffer GIntBig bdirty; // Holds bits, to be used in pixel interleaved (up to 64 bands) // GeoTransform support double GeoTransform[6]; int bGeoTransformValid; // Projection string, WKT CPLString projection; // Photometric interpretation CPLString photometric; GDALColorTable *poColorTable; int Quality; VF dfp; // Data file handle VF ifp; // Index file handle // statistical values std::vector<double> vNoData, vMin, vMax; }; class GDALMRFRasterBand : public GDALPamRasterBand { friend class GDALMRFDataset; public: GDALMRFRasterBand(GDALMRFDataset *, const ILImage &, int, int); virtual ~GDALMRFRasterBand(); virtual CPLErr IReadBlock(int xblk, int yblk, void *buffer) override; virtual CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override; virtual GDALColorTable *GetColorTable() override { return poDS->poColorTable; } CPLErr SetColorInterpretation(GDALColorInterp ci) override { img.ci = ci; return CE_None; } virtual GDALColorInterp GetColorInterpretation() override { return img.ci; } // Get works within MRF or with PAM virtual double GetNoDataValue(int *) override; virtual CPLErr SetNoDataValue(double) override; // These get set with SetStatistics virtual double GetMinimum(int *) override; virtual double GetMaximum(int *) override; // MRF specific, fetch is from a remote source CPLErr FetchBlock(int xblk, int yblk, void *buffer = NULL); // Fetch a block from a cloned MRF CPLErr FetchClonedBlock(int xblk, int yblk, void *buffer = NULL); // Block not stored on disk CPLErr FillBlock(void *buffer); // de-interlace a buffer in pixel blocks CPLErr RB(int xblk, int yblk, buf_mgr src, void *buffer); const char *GetOptionValue(const char *opt, const char *def) const; void SetAccess(GDALAccess eA) { eAccess = eA; } void SetDeflate(int v) { deflatep = (v != 0); } protected: // Pointer to the GDALMRFDataset GDALMRFDataset *poDS; // Deflate page requested, named to avoid conflict with libz deflate() int deflatep; int deflate_flags; // Level count of this band GInt32 m_l; // The info about the current image, to enable R-sets ILImage img; std::vector<GDALMRFRasterBand *> overviews; int overview; VSILFILE *IdxFP() { return poDS->IdxFP(); } GDALRWFlag IdxMode() { return poDS->IdxMode(); } VSILFILE *DataFP() { return poDS->DataFP(); } GDALRWFlag DataMode() { return poDS->DataMode(); } // How many bytes are in a band block (not a page, a single band block) // Easiest is to calculate it from the pageSizeBytes GUInt32 blockSizeBytes() { return poDS->current.pageSizeBytes / poDS->current.pagesize.c; } const CPLStringList & GetOptlist() const { return poDS->optlist; } // Compression and decompression functions. To be overwritten by specific implementations virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) = 0; virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) = 0; // Read the index record itself, can be overwritten // virtual CPLErr ReadTileIdx(const ILSize &, ILIdx &, GIntBig bias = 0); GIntBig bandbit(int b) { return ((GIntBig)1) << b; } GIntBig bandbit() { return bandbit(nBand - 1); } GIntBig AllBandMask() { return bandbit(poDS->nBands) - 1; } // Overview Support // Inherited from GDALRasterBand // These are called only in the base level RasterBand virtual int GetOverviewCount() override; virtual GDALRasterBand *GetOverview(int n) override; void AddOverview(GDALMRFRasterBand *b) { overviews.push_back(b); } }; /** * Each type of compression needs to define at least two methods, a compress and a * decompress, which take as arguments a dest and a source buffer, plus an image structure * that holds the information about the compression type. * Filtering is needed, probably in the form of pack and unpack functions * */ class PNG_Codec { public: explicit PNG_Codec(const ILImage &image) : img(image), PNGColors(NULL), PNGAlpha(NULL), PalSize(0), TransSize(0), deflate_flags(0) {}; virtual ~PNG_Codec() { CPLFree(PNGColors); CPLFree(PNGAlpha); } CPLErr CompressPNG(buf_mgr &dst, buf_mgr &src); static CPLErr DecompressPNG(buf_mgr &dst, buf_mgr &src); const ILImage img; void *PNGColors; void *PNGAlpha; int PalSize, TransSize, deflate_flags; private: PNG_Codec& operator= (const PNG_Codec& src); // not implemented. but suppress MSVC warning about 'assignment operator could not be generated' }; class PNG_Band : public GDALMRFRasterBand { friend class GDALMRFDataset; public: PNG_Band(GDALMRFDataset *pDS, const ILImage &image, int b, int level); protected: virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override; virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override; PNG_Codec codec; }; /* * The JPEG Codec can be used outside of the JPEG_Band */ class JPEG_Codec { public: explicit JPEG_Codec(const ILImage &image) : img(image), sameres(FALSE), rgb(FALSE), optimize(false) {}; CPLErr CompressJPEG(buf_mgr &dst, buf_mgr &src); CPLErr DecompressJPEG(buf_mgr &dst, buf_mgr &src); #if defined(JPEG12_SUPPORTED) // Internal only #define LIBJPEG_12_H "../jpeg/libjpeg12/jpeglib.h" CPLErr CompressJPEG12(buf_mgr &dst, buf_mgr &src); CPLErr DecompressJPEG12(buf_mgr &dst, buf_mgr &src); #endif const ILImage img; // JPEG specific flags bool sameres; bool rgb; bool optimize; private: JPEG_Codec& operator= (const JPEG_Codec& src); // not implemented. but suppress MSVC warning about 'assignment operator could not be generated' }; class JPEG_Band : public GDALMRFRasterBand { friend class GDALMRFDataset; public: JPEG_Band(GDALMRFDataset *pDS, const ILImage &image, int b, int level); virtual ~JPEG_Band() {}; protected: virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override; virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override; JPEG_Codec codec; }; // A 2 or 4 band, with JPEG and/or PNG page encoding, optimized for size class JPNG_Band : public GDALMRFRasterBand { friend class GDALMRFDataset; public: JPNG_Band(GDALMRFDataset *pDS, const ILImage &image, int b, int level); virtual ~JPNG_Band(); protected: virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override; virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override; CPLErr CompressJPNG(buf_mgr &dst, buf_mgr &src); CPLErr DecompressJPNG(buf_mgr &dst, buf_mgr &src); bool rgb, sameres, optimize; }; class Raw_Band : public GDALMRFRasterBand { friend class GDALMRFDataset; public: Raw_Band(GDALMRFDataset *pDS, const ILImage &image, int b, int level) : GDALMRFRasterBand(pDS, image, b, int(level)) {}; virtual ~Raw_Band() {}; protected: virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override; virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override; }; class TIF_Band : public GDALMRFRasterBand { friend class GDALMRFDataset; public: TIF_Band(GDALMRFDataset *pDS, const ILImage &image, int b, int level); virtual ~TIF_Band(); protected: virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override; virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override; // Create options for TIF pages char **papszOptions; }; #if defined(LERC) class LERC_Band : public GDALMRFRasterBand { friend class GDALMRFDataset; public: LERC_Band(GDALMRFDataset *pDS, const ILImage &image, int b, int level); virtual ~LERC_Band(); protected: virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override; virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override; double precision; int version; static bool IsLerc(CPLString &s) { return (STARTS_WITH(s, "Lerc2 ") || STARTS_WITH(s, "CntZImage ")); } // Build a MRF header for a single LERC tile static CPLXMLNode *GetMRFConfig(GDALOpenInfo *poOpenInfo); }; #endif /*\brief band for level mrf * * Stand alone definition of a derived band, used in access to a specific level in an MRF * */ class GDALMRFLRasterBand : public GDALPamRasterBand { public: explicit GDALMRFLRasterBand(GDALMRFRasterBand *b) { pBand = b; eDataType = b->GetRasterDataType(); b->GetBlockSize(&nBlockXSize, &nBlockYSize); eAccess = b->GetAccess(); nRasterXSize = b->GetXSize(); nRasterYSize = b->GetYSize(); } virtual CPLErr IReadBlock(int xblk, int yblk, void *buffer) override { return pBand->IReadBlock(xblk, yblk, buffer); } virtual CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override { return pBand->IWriteBlock(xblk, yblk, buffer); } virtual GDALColorTable *GetColorTable() override { return pBand->GetColorTable(); } virtual GDALColorInterp GetColorInterpretation() override { return pBand->GetColorInterpretation(); } virtual double GetNoDataValue(int * pbSuccess) override { return pBand->GetNoDataValue(pbSuccess); } virtual double GetMinimum(int *b) override { return pBand->GetMinimum(b); } virtual double GetMaximum(int *b) override { return pBand->GetMaximum(b); } protected: virtual int GetOverviewCount() override { return 0; } virtual GDALRasterBand *GetOverview(int ) override { return NULL; } GDALMRFRasterBand *pBand; }; NAMESPACE_MRF_END #endif // GDAL_FRMTS_MRF_MARFA_H_INCLUDED