1 /*
2 * Copyright (c) 2002-2012, California Institute of Technology.
3 * All rights reserved.  Based on Government Sponsored Research under contracts NAS7-1407 and/or NAS7-03001.
4 *
5 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 *   1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 *   2. Redistributions in binary form must reproduce the above copyright notice,
8 *      this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 *   3. Neither the name of the California Institute of Technology (Caltech), its operating division the Jet Propulsion Laboratory (JPL),
10 *      the National Aeronautics and Space Administration (NASA), nor the names of its contributors may be used to
11 *      endorse or promote products derived from this software without specific prior written permission.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
14 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15 * IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
19 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * Copyright 2014-2021 Esri
22 *
23 * Licensed under the Apache License, Version 2.0 (the "License");
24 * you may not use this file except in compliance with the License.
25 * You may obtain a copy of the License at
26 *
27 * http://www.apache.org/licenses/LICENSE-2.0
28 *
29 * Unless required by applicable law or agreed to in writing, software
30 * distributed under the License is distributed on an "AS IS" BASIS,
31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35 
36 /******************************************************************************
37  *
38  * Project:  Meta Raster Format
39  * Purpose:  MRF structures
40  * Author:   Lucian Plesea
41  *
42  ******************************************************************************
43  *
44  *
45  *
46  ****************************************************************************/
47 
48 #ifndef GDAL_FRMTS_MRF_MARFA_H_INCLUDED
49 #define GDAL_FRMTS_MRF_MARFA_H_INCLUDED
50 
51 #include <gdal_pam.h>
52 #include <ogr_srs_api.h>
53 #include <ogr_spatialref.h>
54 
55 #include <limits>
56 // For printing values
57 #include <ostream>
58 #include <iostream>
59 #include <sstream>
60 
61 #define NAMESPACE_MRF_START namespace GDAL_MRF {
62 #define NAMESPACE_MRF_END   }
63 #define USING_NAMESPACE_MRF using namespace GDAL_MRF;
64 
65 NAMESPACE_MRF_START
66 
67 // ZLIB Bit flag fields
68 // 0:3 - level, 4 - GZip, 5 RAW zlib, 6:9 strategy
69 #define ZFLAG_LMASK 0xF
70 // GZ and RAW are mutually exclusive, GZ has higher priority
71 // If neither is set, use zlib stream format
72 #define ZFLAG_GZ 0x10
73 #define ZFLAG_RAW 0x20
74 
75 // Mask for zlib strategy, valid values are 0 to 4 shifted six bits, see zlib for meaning
76 // Can use one of:
77 // Z_DEFAULT : whatever zlib decides
78 // Z_FILTERED : optimized for delta encoding
79 // Z_HUFFMAN_ONLY : Only huffman encoding (adaptive)
80 // Z_RLE : Only next character matches
81 // Z_FIXED : Static huffman, faster decoder
82 //
83 #define ZFLAG_SMASK 0x1c0
84 
85 #define PADDING_BYTES 3
86 
87 // Force LERC to be included, normally off, detected in the makefile
88 // #define LERC
89 
90 // These are a pain to maintain in sync.  They should be replaced with
91 // C++11 uniform initializers.  The externs reside in util.cpp
92 enum ILCompression {
93     IL_PNG = 0, IL_PPNG, IL_JPEG, IL_JPNG, IL_NONE, IL_ZLIB, IL_TIF,
94 #if defined(LERC)
95     IL_LERC,
96 #endif
97     IL_ERR_COMP
98 };
99 
100 // Sequential is not supported by GDAL
101 enum ILOrder { IL_Interleaved = 0, IL_Separate, IL_Sequential, IL_ERR_ORD };
102 extern char const * const * ILComp_Name;
103 extern char const * const * ILComp_Ext;
104 extern char const * const * ILOrder_Name;
105 
106 class MRFDataset;
107 class MRFRasterBand;
108 
109 typedef struct {
110     char   *buffer;
111     size_t size;
112 } buf_mgr;
113 
114 // A tile index record, 16 bytes, big endian
115 typedef struct {
116     GIntBig offset;
117     GIntBig size;
118 } ILIdx;
119 
120 // Size of an image, also used as a tile or pixel location
121 struct ILSize {
122     GInt32 x, y, z, c;
123     GIntBig l; // Dual use, sometimes it holds the number of pages
124     ILSize(const int x_ = -1, const int y_ = -1, const int z_ = -1,
125         const int c_ = -1, const int l_ = -1):
xILSize126         x(x_), y(y_), z(z_), c(c_), l(l_)
127     {}
128 
129     bool operator==(const ILSize& other) const {
130         return ((x == other.x) && (y == other.y) && (z == other.z) &&
131             (c == other.c) && (l == other.l));
132     }
133 
134     bool operator!=(const ILSize& other) const { return !(*this == other); }
135 };
136 
137 std::ostream& operator<<(std::ostream &out, const ILSize& sz);
138 std::ostream& operator<<(std::ostream &out, const ILIdx& t);
139 
140 bool is_Endianess_Dependent(GDALDataType dt, ILCompression comp);
141 
142 // Debugging support
143 // #define PPMW
144 #ifdef PPMW
145 void ppmWrite(const char *fname, const char *data, const ILSize &sz);
146 #endif
147 
148 /**
149  * Collects information pertaining to a single raster
150  * This structure is being shallow copied, no pointers allowed
151  *
152  */
153 
154 typedef struct ILImage {
155     ILImage();
156     GIntBig dataoffset;
157     GIntBig idxoffset;
158     GInt32 quality;
159     GInt32 pageSizeBytes;
160     ILSize size;
161     ILSize pagesize;
162     ILSize pagecount;
163     ILCompression comp;
164     ILOrder order;
165     bool nbo;
166     int hasNoData;
167     double NoDataValue;
168     CPLString datfname;
169     CPLString idxfname;
170     GDALDataType dt;
171     GDALColorInterp ci;
172 } ILImage;
173 
174 // Declarations of utility functions
175 
176 /**
177  *
178  *\brief  Converters between endianness
179  *  Call netXX() to guarantee big endian
180  *
181  */
swab16(const unsigned short int val)182 static inline unsigned short int swab16(const unsigned short int val) {
183     return (val << 8) | (val >> 8);
184 }
185 
swab32(unsigned int val)186 static inline unsigned int swab32(unsigned int val) {
187     return (unsigned int)(swab16((unsigned short int) val)) << 16
188         | swab16((unsigned short int) (val >> 16));
189 }
190 
swab64(const unsigned long long int val)191 static inline unsigned long long int swab64(const unsigned long long int val) {
192     return (unsigned long long int) (swab32((unsigned int)val)) << 32
193         | swab32((unsigned int)(val >> 32));
194 }
195 
196 // NET_ORDER is true if machine is BE, false otherwise
197 // Call netxx() if network (big) order is needed
198 
199 #ifdef CPL_MSB
200 #define NET_ORDER true
201 // These could be macros, but for the side effects related to type
net16(const unsigned short x)202 static inline unsigned short net16(const unsigned short x) {
203     return (x);
204 }
net32(const unsigned int x)205 static inline unsigned int net32(const unsigned int x) {
206     return (x);
207 }
208 
net64(const unsigned long long x)209 static inline unsigned long long net64(const unsigned long long x) {
210     return (x);
211 }
212 
213 #else
214 #define NET_ORDER false
215 #define net16(x) swab16(x)
216 #define net32(x) swab32(x)
217 #define net64(x) swab64(x)
218 #endif
219 
220 // Count the values in a buffer that match a specific value
MatchCount(T * buff,int sz,T val)221 template<typename T> static int MatchCount(T *buff, int sz, T val) {
222     int ncount = 0;
223     for (int i = 0; i < sz; i++)
224         if (buff[i] == val)
225             ncount++;
226     return ncount;
227 }
228 
229 const char *CompName(ILCompression comp);
230 const char *OrderName(ILOrder val);
231 ILCompression CompToken(const char *, ILCompression def = IL_ERR_COMP);
232 ILOrder OrderToken(const char *, ILOrder def = IL_ERR_ORD);
233 CPLString getFname(CPLXMLNode *, const char *, const CPLString &, const char *);
234 CPLString getFname(const CPLString &, const char *);
235 double getXMLNum(CPLXMLNode *, const char *, double);
236 GIntBig IdxOffset(const ILSize &, const ILImage &);
237 double logbase(double val, double base);
238 int IsPower(double value, double base);
239 CPLXMLNode *SearchXMLSiblings(CPLXMLNode *psRoot, const char *pszElement);
240 CPLString PrintDouble(double d, const char *frmt = "%12.8f");
241 void XMLSetAttributeVal(CPLXMLNode* parent, const char* pszName, const char* pszValue);
242 void XMLSetAttributeVal(CPLXMLNode *parent, const char* pszName,
243     const double val, const char *frmt = "%12.8f");
244 CPLXMLNode *XMLSetAttributeVal(CPLXMLNode *parent,
245     const char*pszName, const ILSize &sz, const char *frmt = nullptr);
246 void XMLSetAttributeVal(CPLXMLNode *parent,
247     const char*pszName, std::vector<double> const &values);
248 //
249 // Extension to CSL, set an entry only if it doesn't already exist
250 //
251 char **CSLAddIfMissing(char **papszList,
252     const char *pszName, const char *pszValue);
253 
254 GDALColorEntry GetXMLColorEntry(CPLXMLNode *p);
255 GIntBig IdxSize(const ILImage &full, const int scale = 0);
256 // Similar to uncompress() from zlib, accepts the ZFLAG_RAW
257 // Return true if it worked
258 int ZUnPack(const buf_mgr &src, buf_mgr &dst, int flags);
259 // Similar to compress2() but with flags to control zlib features
260 // Returns true if it worked
261 int ZPack(const buf_mgr &src, buf_mgr &dst, int flags);
262 // checks that the file exists and is at least sz, if access is update it extends it
263 int CheckFileSize(const char *fname, GIntBig sz, GDALAccess eAccess);
264 
265 // Number of pages of size psz needed to hold n elements
pcount(const int n,const int sz)266 static inline int pcount(const int n, const int sz) {
267     return 1 + (n - 1) / sz;
268 }
269 
270 // Returns a pagecount per dimension, .l will have the total number
271 // or -1 in case of error
pcount(const ILSize & size,const ILSize & psz)272 static inline const ILSize pcount(const ILSize &size, const ILSize &psz) {
273     ILSize pcnt;
274     pcnt.x = pcount(size.x, psz.x);
275     pcnt.y = pcount(size.y, psz.y);
276     pcnt.z = pcount(size.z, psz.z);
277     pcnt.c = pcount(size.c, psz.c);
278     auto xy = static_cast<GIntBig>(pcnt.x) * pcnt.y;
279     auto zc = static_cast<GIntBig>(pcnt.z) * pcnt.c;
280     if( zc != 0 && xy > std::numeric_limits<GIntBig>::max() / zc ) {
281         CPLError(CE_Failure, CPLE_AppDefined,
282                  "Integer overflow in page count computation");
283         pcnt.l = -1;
284         return pcnt;
285     }
286     pcnt.l = xy * zc;
287     return pcnt;
288 }
289 
290 // Wrapper around the VISFile, remembers how the file was opened
291 typedef struct {
292     VSILFILE *FP;
293     GDALRWFlag acc;
294 } VF;
295 
296 // Offset of index, pos is in pages
297 GIntBig IdxOffset(const ILSize &pos, const ILImage &img);
298 
299 enum { SAMPLING_ERR, SAMPLING_Avg, SAMPLING_Near };
300 
301 MRFRasterBand *newMRFRasterBand(MRFDataset *, const ILImage &, int, int level = 0);
302 
303 class MRFDataset final: public GDALPamDataset {
304     friend class MRFRasterBand;
305     friend MRFRasterBand *newMRFRasterBand(MRFDataset *, const ILImage &, int, int level);
306 
307 public:
308     MRFDataset();
309     virtual ~MRFDataset();
310 
311     static GDALDataset *Open(GDALOpenInfo *);
312     static int Identify(GDALOpenInfo *);
313 
314     static GDALDataset *CreateCopy(const char *pszFilename, GDALDataset *poSrcDS,
315         int bStrict, char **papszOptions, GDALProgressFunc pfnProgress,
316         void *pProgressData);
317 
318     static GDALDataset *Create(const char * pszName,
319         int nXSize, int nYSize, int nBands,
320         GDALDataType eType, char ** papszOptions);
321 
322     // Stub for delete, GDAL should only overwrite the XML
Delete(const char *)323     static CPLErr Delete(const char *) { return CE_None; }
324 
_GetProjectionRef()325     virtual const char *_GetProjectionRef() override { return projection; }
_SetProjection(const char * proj)326     virtual CPLErr _SetProjection(const char *proj) override {
327         projection = proj;
328         return CE_None;
329     }
GetSpatialRef()330     const OGRSpatialReference* GetSpatialRef() const override {
331         return GetSpatialRefFromOldGetProjectionRef();
332     }
SetSpatialRef(const OGRSpatialReference * poSRS)333     CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override {
334         return OldSetProjectionFromSetSpatialRef(poSRS);
335     }
336 
GetPhotometricInterpretation()337     virtual CPLString const &GetPhotometricInterpretation() { return photometric; }
SetPhotometricInterpretation(const char * photo)338     virtual CPLErr SetPhotometricInterpretation(const char *photo) {
339         photometric = photo;
340         return CE_None;
341     }
342 
343     virtual CPLErr GetGeoTransform(double *gt) override;
344     virtual CPLErr SetGeoTransform(double *gt) override;
345 
346     virtual char **GetFileList() override;
347 
SetColorTable(GDALColorTable * pct)348     void SetColorTable(GDALColorTable *pct) { poColorTable = pct; }
GetColorTable()349     const GDALColorTable *GetColorTable() { return poColorTable; }
350     void SetNoDataValue(const char*);
351     void SetMinValue(const char*);
352     void SetMaxValue(const char*);
353     CPLErr SetVersion(int version);
354 
GetFname()355     const CPLString GetFname() { return fname; }
356     // Patches a region of all the next overview, argument counts are in blocks
357     virtual CPLErr PatchOverview(int BlockX, int BlockY, int Width, int Height,
358         int srcLevel = 0, int recursive = false, int sampling_mode = SAMPLING_Avg);
359 
360     // Creates an XML tree from the current MRF.  If written to a file it becomes an MRF
361     CPLXMLNode *BuildConfig();
362 
SetPBufferSize(unsigned int sz)363     void SetPBufferSize(unsigned int sz) { pbsize = sz; }
GetPBufferSize()364     unsigned int GetPBufferSize() { return pbsize; }
365 
366 protected:
367     // False if it failed
368     int Crystalize();
369 
370     CPLErr LevelInit(const int l);
371 
372     // Reads the XML metadata and returns the XML
373     CPLXMLNode *ReadConfig() const;
374 
375     // Apply create options to the current dataset
376     void ProcessCreateOptions(char **papszOptions);
377 
378     // Called once before the parsing of the XML, should just capture the options in dataset variables
379     void ProcessOpenOptions(char **papszOptions);
380 
381     // Writes the XML tree as MRF.  It does not check the content
382     int WriteConfig(CPLXMLNode *);
383 
384     // Initializes the dataset from an MRF metadata XML
385     // Options should be papszOpenOptions, but the dataset already has a member with that name
386     CPLErr Initialize(CPLXMLNode *);
387 
388     // Do nothing, this is not possible in an MRF
CleanOverviews()389     CPLErr CleanOverviews() { return CE_None; }
390 
391     bool IsSingleTile();
392 
393     // Add uniform scale overlays, returns the new size of the index file
394     GIntBig AddOverviews(int scale);
395 
396     // Late allocation buffer
397     bool SetPBuffer(unsigned int sz);
GetPBuffer()398     void *GetPBuffer() {
399         if (!pbuffer && pbsize)
400             SetPBuffer(pbsize);
401         return pbuffer;
402     }
403 
404     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int,
405         void *, int, int, GDALDataType,
406         int, int *, GSpacing, GSpacing, GSpacing, GDALRasterIOExtraArg*) override;
407 
408     virtual CPLErr IBuildOverviews(const char*, int, int*, int, int*,
409         GDALProgressFunc, void*) override;
410 
411     virtual int CloseDependentDatasets() override;
412 
413     // Write a tile, the infooffset is the relative position in the index file
414     virtual CPLErr WriteTile(void *buff, GUIntBig infooffset, GUIntBig size = 0);
415 
416     // Custom CopyWholeRaster for Zen JPEG
417     CPLErr ZenCopy(GDALDataset *poSrc, GDALProgressFunc pfnProgress, void * pProgressData);
418 
419     // For versioned MRFs, add a version
420     CPLErr AddVersion();
421 
422     // Read the index record itself
423     CPLErr ReadTileIdx(ILIdx &tinfo, const ILSize &pos, const ILImage &img, const GIntBig bias = 0);
424 
425     VSILFILE *IdxFP();
426     VSILFILE *DataFP();
IdxMode()427     GDALRWFlag IdxMode() {
428         if (!ifp.FP) IdxFP();
429         return ifp.acc;
430     }
DataMode()431     GDALRWFlag DataMode() {
432         if (!dfp.FP) DataFP();
433         return dfp.acc;
434     }
435     GDALDataset *GetSrcDS();
436 
437     /*
438      *  There are two images defined to allow for morphing on use, in the future
439      *  For example storing a multispectral image and opening it as RGB
440      *
441      *  Support for this feature is not yet implemented.
442      *
443      */
444 
445     // What the image is on disk
446     ILImage full;
447     // How we use it currently
448     ILImage current;
449     // The third dimension slice in use
450     int zslice;
451 
452     // MRF file name
453     CPLString fname;
454 
455     // The source to be cached in this MRF
456     CPLString source;
457     GIntBig idxSize; // The size of each version index, or the size of the cloned index
458 
459     int clonedSource; // Is it a cloned source
460     int nocopy;       // Set when initializing a caching MRF
461     int bypass_cache; // Do we alter disk cache
462     int mp_safe;      // Not thread safe, only multiple writers
463     int hasVersions;  // Does it support versions
464     int verCount;     // The last version
465     int bCrystalized; // Unset only during the create process
466     int spacing;      // How many spare bytes before each tile data
467     int no_errors;    // Ignore read errors
468     int missing;      // set if no_errors is set and data is missing
469 
470     // Freeform sticky dataset options, as a list of key-value pairs
471     CPLStringList optlist;
472 
473     // If caching data, the parent dataset
474     GDALDataset *poSrcDS;
475 
476     // Level picked, or -1 for native
477     int level;
478 
479     // Child dataset, if picking a specific level
480     MRFDataset *cds;
481     // A small int actually due to GDAL limitations
482     double scale;
483 
484     // A place to keep an uncompressed block, to keep from allocating it all the time
485     void *pbuffer;
486     unsigned int pbsize;
487     ILSize tile; // ID of tile present in buffer
488     GIntBig bdirty;    // Holds bits, to be used in pixel interleaved (up to 64 bands)
489 
490     // GeoTransform support
491     double GeoTransform[6];
492     int bGeoTransformValid;
493 
494     // Projection string, WKT
495     CPLString projection;
496 
497     // Photometric interpretation
498     CPLString photometric;
499 
500     GDALColorTable *poColorTable;
501     int Quality;
502 
503     VF dfp;  // Data file handle
504     VF ifp;  // Index file handle
505 
506     // statistical values
507     std::vector<double> vNoData, vMin, vMax;
508 };
509 
510 class MRFRasterBand CPL_NON_FINAL: public GDALPamRasterBand {
511     friend class MRFDataset;
512 public:
513     MRFRasterBand(MRFDataset *, const ILImage &, int, int);
514     virtual ~MRFRasterBand();
515     virtual CPLErr IReadBlock(int xblk, int yblk, void *buffer) override;
516     virtual CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override;
517 
518     // Check that the respective block has data, without reading it
519     virtual bool TestBlock(int xblk, int yblk);
520 
GetColorTable()521     virtual GDALColorTable *GetColorTable() override { return poDS->poColorTable; }
522 
SetColorInterpretation(GDALColorInterp ci)523     CPLErr SetColorInterpretation(GDALColorInterp ci) override { img.ci = ci; return CE_None; }
GetColorInterpretation()524     virtual GDALColorInterp GetColorInterpretation() override { return img.ci; }
525 
526     // Get works within MRF or with PAM
527     virtual double  GetNoDataValue(int *) override;
528     virtual CPLErr  SetNoDataValue(double) override;
529 
530     // These get set with SetStatistics
531     virtual double  GetMinimum(int *) override;
532     virtual double  GetMaximum(int *) override;
533 
534     // MRF specific, fetch is from a remote source
535     CPLErr FetchBlock(int xblk, int yblk, void *buffer = nullptr);
536     // Fetch a block from a cloned MRF
537     CPLErr FetchClonedBlock(int xblk, int yblk, void *buffer = nullptr);
538 
539     // Block not stored on disk
540     CPLErr FillBlock(void *buffer);
541 
542     // Same, for interleaved bands, current band goes in buffer
543     CPLErr FillBlock(int xblk, int yblk, void *buffer);
544 
545     // de-interlace a buffer in pixel blocks
546     CPLErr ReadInterleavedBlock(int xblk, int yblk, void *buffer);
547 
548     const char *GetOptionValue(const char *opt, const char *def) const;
SetAccess(GDALAccess eA)549     void SetAccess(GDALAccess eA) { eAccess = eA; }
SetDeflate(int v)550     void SetDeflate(int v) { dodeflate = (v != 0); }
551 
552 protected:
553     // Pointer to the GDALMRFDataset
554     MRFDataset *poDS;
555     // Deflate page requested, named to avoid conflict with libz deflate()
556     int dodeflate;
557     int deflate_flags;
558     // Level count of this band
559     GInt32 m_l;
560     // The info about the current image, to enable R-sets
561     ILImage img;
562     std::vector<MRFRasterBand *> overviews;
563 
IdxFP()564     VSILFILE *IdxFP() { return poDS->IdxFP(); }
IdxMode()565     GDALRWFlag IdxMode() { return poDS->IdxMode(); }
DataFP()566     VSILFILE *DataFP() { return poDS->DataFP(); }
DataMode()567     GDALRWFlag DataMode() { return poDS->DataMode(); }
568 
569     // How many bytes are in a band block (not a page, a single band block)
570     // Easiest is to calculate it from the pageSizeBytes
blockSizeBytes()571     GUInt32 blockSizeBytes() {
572         return poDS->current.pageSizeBytes / poDS->current.pagesize.c;
573     }
574 
GetOptlist()575     const CPLStringList & GetOptlist() const { return poDS->optlist; }
576 
577     // Compression and decompression functions.  To be overwritten by specific implementations
578     virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) = 0;
579     virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) = 0;
580 
581     // Read the index record itself, can be overwritten
582     //    virtual CPLErr ReadTileIdx(const ILSize &, ILIdx &, GIntBig bias = 0);
583 
bandbit(int b)584     GIntBig bandbit(int b) { return ((GIntBig)1) << b; }
bandbit()585     GIntBig bandbit() { return bandbit(nBand - 1); }
AllBandMask()586     GIntBig AllBandMask() { return bandbit(poDS->nBands) - 1; }
587 
588     // Overview Support
589     // Inherited from GDALRasterBand
590     // These are called only in the base level RasterBand
591     virtual int GetOverviewCount() override;
592     virtual GDALRasterBand *GetOverview(int n) override;
AddOverview(MRFRasterBand * b)593     void AddOverview(MRFRasterBand *b) { overviews.push_back(b); }
594 };
595 
596 /**
597  * Each type of compression needs to define at least two methods, a compress and a
598  * decompress, which take as arguments a dest and a source buffer, plus an image structure
599  * that holds the information about the compression type.
600  * Filtering is needed, probably in the form of pack and unpack functions
601  *
602  */
603 
604 class PNG_Codec {
605 public:
PNG_Codec(const ILImage & image)606     explicit PNG_Codec(const ILImage &image) : img(image),
607         PNGColors(nullptr), PNGAlpha(nullptr), PalSize(0), TransSize(0), deflate_flags(0) {}
608 
~PNG_Codec()609     virtual ~PNG_Codec() {
610         CPLFree(PNGColors);
611         CPLFree(PNGAlpha);
612     }
613 
614     CPLErr CompressPNG(buf_mgr &dst, buf_mgr &src);
615     static CPLErr DecompressPNG(buf_mgr &dst, buf_mgr &src);
616 
617     const ILImage img;
618 
619     void *PNGColors;
620     void *PNGAlpha;
621     int PalSize, TransSize, deflate_flags;
622 
623 private:
624     // not implemented. but suppress MSVC warning about 'assignment operator could not be generated'
625     PNG_Codec& operator= (const PNG_Codec& src);
626 };
627 
628 class PNG_Band final: public MRFRasterBand {
629     friend class MRFDataset;
630 public:
631     PNG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
632 
633 protected:
634     virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
635     virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
636 
637     PNG_Codec codec;
638 };
639 
640 /*
641  * The JPEG Codec can be used outside of the JPEG_Band
642 */
643 
644 class JPEG_Codec {
645 public:
JPEG_Codec(const ILImage & image)646     explicit JPEG_Codec(const ILImage &image) : img(image), sameres(FALSE), rgb(FALSE), optimize(false) {}
647 
648     CPLErr CompressJPEG(buf_mgr &dst, buf_mgr &src);
649     CPLErr DecompressJPEG(buf_mgr &dst, buf_mgr &src);
650 
651 #if defined(JPEG12_SUPPORTED) // Internal only
652 #define LIBJPEG_12_H "../jpeg/libjpeg12/jpeglib.h"
653     CPLErr CompressJPEG12(buf_mgr &dst, buf_mgr &src);
654     CPLErr DecompressJPEG12(buf_mgr &dst, buf_mgr &src);
655 #endif
656 
657     const ILImage img;
658 
659     // JPEG specific flags
660     bool sameres;
661     bool rgb;
662     bool optimize;
663 
664 private:
665     JPEG_Codec& operator= (const JPEG_Codec& src); // not implemented. but suppress MSVC warning about 'assignment operator could not be generated'
666 };
667 
668 class JPEG_Band final: public MRFRasterBand {
669     friend class MRFDataset;
670 public:
671     JPEG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
~JPEG_Band()672     virtual ~JPEG_Band() {}
673 
674 protected:
675     virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
676     virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
677 
678     JPEG_Codec codec;
679 };
680 
681 // A 2 or 4 band, with JPEG and/or PNG page encoding, optimized for size
682 class JPNG_Band final: public MRFRasterBand {
683     friend class MRFDataset;
684 public:
685     JPNG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
686     virtual ~JPNG_Band();
687 protected:
688     virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
689     virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
690 
691     CPLErr CompressJPNG(buf_mgr &dst, buf_mgr &src);
692     CPLErr DecompressJPNG(buf_mgr &dst, buf_mgr &src);
693     bool rgb, sameres, optimize;
694 };
695 
696 class Raw_Band final: public MRFRasterBand {
697     friend class MRFDataset;
698 public:
Raw_Band(MRFDataset * pDS,const ILImage & image,int b,int level)699     Raw_Band(MRFDataset *pDS, const ILImage &image, int b, int level) :
700         MRFRasterBand(pDS, image, b, int(level)) {}
~Raw_Band()701     virtual ~Raw_Band() {}
702 protected:
Decompress(buf_mgr & dst,buf_mgr & src)703     virtual CPLErr Decompress(buf_mgr& dst, buf_mgr& src) override {
704         if (src.size > dst.size)
705             return CE_Failure;
706         memcpy(dst.buffer, src.buffer, src.size);
707         dst.size = src.size;
708         return CE_None;
709     }
Compress(buf_mgr & dst,buf_mgr & src)710     virtual CPLErr Compress(buf_mgr& dst, buf_mgr& src) override {
711         return Decompress(dst, src);
712     }
713 };
714 
715 class TIF_Band final: public MRFRasterBand {
716     friend class MRFDataset;
717 public:
718     TIF_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
719     virtual ~TIF_Band();
720 protected:
721     virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
722     virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
723 
724     // Create options for TIF pages
725     char **papszOptions;
726 };
727 
728 #if defined(LERC)
729 class LERC_Band final: public MRFRasterBand {
730     friend class MRFDataset;
731 public:
732     LERC_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
733     virtual ~LERC_Band();
734 protected:
735     virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
736     virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
737     double precision;
738     int version;
IsLerc(CPLString & s)739     static bool IsLerc(CPLString &s) {
740         return (STARTS_WITH(s, "Lerc2 ") || STARTS_WITH(s, "CntZImage "));
741     }
742 
743     // Build a MRF header for a single LERC tile
744     static CPLXMLNode *GetMRFConfig(GDALOpenInfo *poOpenInfo);
745 };
746 #endif
747 
748 /*\brief band for level mrf
749  *
750  * Stand alone definition of a derived band, used in access to a specific level in an MRF
751  *
752  */
753 class MRFLRasterBand final: public GDALPamRasterBand {
754 public:
MRFLRasterBand(MRFRasterBand * b)755     explicit MRFLRasterBand(MRFRasterBand *b) {
756         pBand = b;
757         eDataType = b->GetRasterDataType();
758         b->GetBlockSize(&nBlockXSize, &nBlockYSize);
759         eAccess = b->GetAccess();
760         nRasterXSize = b->GetXSize();
761         nRasterYSize = b->GetYSize();
762     }
IReadBlock(int xblk,int yblk,void * buffer)763     virtual CPLErr IReadBlock(int xblk, int yblk, void *buffer) override {
764         return pBand->IReadBlock(xblk, yblk, buffer);
765     }
IWriteBlock(int xblk,int yblk,void * buffer)766     virtual CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override {
767         return pBand->IWriteBlock(xblk, yblk, buffer);
768     }
GetColorTable()769     virtual GDALColorTable *GetColorTable() override {
770         return pBand->GetColorTable();
771     }
GetColorInterpretation()772     virtual GDALColorInterp GetColorInterpretation() override {
773         return pBand->GetColorInterpretation();
774     }
GetNoDataValue(int * pbSuccess)775     virtual double  GetNoDataValue(int * pbSuccess) override {
776         return pBand->GetNoDataValue(pbSuccess);
777     }
GetMinimum(int * b)778     virtual double  GetMinimum(int *b) override {
779         return pBand->GetMinimum(b);
780     }
GetMaximum(int * b)781     virtual double  GetMaximum(int *b) override {
782         return pBand->GetMaximum(b);
783     }
784 
785 protected:
GetOverviewCount()786     virtual int GetOverviewCount() override { return 0; }
GetOverview(int)787     virtual GDALRasterBand *GetOverview(int ) override { return nullptr; }
788 
789     MRFRasterBand *pBand;
790 };
791 
792 NAMESPACE_MRF_END
793 
794 #endif // GDAL_FRMTS_MRF_MARFA_H_INCLUDED
795