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