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