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