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