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 : virtual ~MRFDataset();
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 : virtual CPLErr GetGeoTransform(GDALGeoTransform >) const override;
419 : virtual CPLErr SetGeoTransform(const GDALGeoTransform >) override;
420 :
421 : virtual 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 : virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
505 : GDALDataType, int, BANDMAP_TYPE, GSpacing,
506 : GSpacing, GSpacing,
507 : GDALRasterIOExtraArg *) override;
508 :
509 : virtual CPLErr IBuildOverviews(const char *, int, const int *, int,
510 : const int *, GDALProgressFunc, void *,
511 : CSLConstList papszOptions) override;
512 :
513 : virtual 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 : virtual ~MRFRasterBand();
651 : virtual CPLErr IReadBlock(int xblk, int yblk, void *buffer) override;
652 : virtual 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 : virtual 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 145 : virtual GDALColorInterp GetColorInterpretation() override
669 : {
670 145 : return img.ci;
671 : }
672 :
673 : // Get works within MRF or with PAM
674 : virtual double GetNoDataValue(int *) override;
675 : virtual CPLErr SetNoDataValue(double) override;
676 :
677 : // These get set with SetStatistics
678 : virtual double GetMinimum(int *) override;
679 : virtual 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 : virtual int GetOverviewCount() override;
785 : virtual 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 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
840 : virtual 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 98 : virtual ~JPEG_Band()
890 49 : {
891 98 : }
892 :
893 : protected:
894 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
895 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
896 :
897 : JPEG_Codec codec;
898 : };
899 :
900 : // A 2 or 4 band, with JPEG and/or PNG page encoding, optimized for size
901 : class JPNG_Band final : public MRFRasterBand
902 : {
903 : friend class MRFDataset;
904 :
905 : public:
906 : JPNG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
907 : virtual ~JPNG_Band();
908 :
909 : protected:
910 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
911 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
912 :
913 : CPLErr CompressJPNG(buf_mgr &dst, buf_mgr &src);
914 : CPLErr DecompressJPNG(buf_mgr &dst, buf_mgr &src);
915 : bool rgb, sameres, optimize, JFIF;
916 : };
917 :
918 : class Raw_Band final : public MRFRasterBand
919 : {
920 : friend class MRFDataset;
921 :
922 : public:
923 205 : Raw_Band(MRFDataset *pDS, const ILImage &image, int b, int level)
924 205 : : MRFRasterBand(pDS, image, b, int(level))
925 : {
926 205 : }
927 :
928 : protected:
929 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
930 :
931 215 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override
932 : {
933 215 : return Decompress(dst, src);
934 : }
935 : };
936 :
937 : class TIF_Band final : public MRFRasterBand
938 : {
939 : friend class MRFDataset;
940 :
941 : public:
942 : TIF_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
943 : virtual ~TIF_Band();
944 :
945 : protected:
946 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
947 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
948 :
949 : // Create options for TIF pages
950 : char **papszOptions;
951 : };
952 :
953 : #if defined(LERC)
954 : class LERC_Band final : public MRFRasterBand
955 : {
956 : friend class MRFDataset;
957 :
958 : public:
959 : LERC_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
960 : virtual ~LERC_Band();
961 :
962 : protected:
963 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
964 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
965 : double precision = 0;
966 : // L1 or L2
967 : int version = 0;
968 : // L2 version
969 : int l2ver = 0;
970 : // Build a MRF header for a single LERC tile
971 : static CPLXMLNode *GetMRFConfig(GDALOpenInfo *poOpenInfo);
972 :
973 : private:
974 1079 : static bool IsLerc1(const char *s)
975 : {
976 : static const char L1sig[] = "CntZImage ";
977 1079 : return !strncmp(s, L1sig, sizeof(L1sig) - 1);
978 : }
979 :
980 1614 : static bool IsLerc2(const char *s)
981 : {
982 : static const char L2sig[] = "Lerc2 ";
983 1614 : return !strncmp(s, L2sig, sizeof(L2sig) - 1);
984 : }
985 : };
986 : #endif
987 :
988 : #if defined(QB3_SUPPORT)
989 : class QB3_Band final : public MRFRasterBand
990 : {
991 : friend class MRFDataset;
992 :
993 : public:
994 : QB3_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
995 :
996 106 : virtual ~QB3_Band()
997 53 : {
998 106 : }
999 :
1000 : protected:
1001 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
1002 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
1003 :
1004 : std::vector<size_t> coreband;
1005 : };
1006 : #endif
1007 :
1008 : /*\brief band for level mrf
1009 : *
1010 : * Stand alone definition of a derived band, used in access to a specific level
1011 : * in an MRF
1012 : *
1013 : */
1014 : class MRFLRasterBand final : public GDALPamRasterBand
1015 : {
1016 : public:
1017 1 : explicit MRFLRasterBand(MRFRasterBand *b)
1018 1 : {
1019 1 : pBand = b;
1020 1 : eDataType = b->GetRasterDataType();
1021 1 : b->GetBlockSize(&nBlockXSize, &nBlockYSize);
1022 1 : eAccess = b->GetAccess();
1023 1 : nRasterXSize = b->GetXSize();
1024 1 : nRasterYSize = b->GetYSize();
1025 1 : }
1026 :
1027 : virtual CPLErr IReadBlock(int xblk, int yblk, void *buffer) override;
1028 :
1029 0 : virtual CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override
1030 : {
1031 0 : return pBand->IWriteBlock(xblk, yblk, buffer);
1032 : }
1033 :
1034 0 : virtual GDALColorTable *GetColorTable() override
1035 : {
1036 0 : return pBand->GetColorTable();
1037 : }
1038 :
1039 0 : virtual GDALColorInterp GetColorInterpretation() override
1040 : {
1041 0 : return pBand->GetColorInterpretation();
1042 : }
1043 :
1044 0 : virtual double GetNoDataValue(int *pbSuccess) override
1045 : {
1046 0 : return pBand->GetNoDataValue(pbSuccess);
1047 : }
1048 :
1049 0 : virtual double GetMinimum(int *b) override
1050 : {
1051 0 : return pBand->GetMinimum(b);
1052 : }
1053 :
1054 0 : virtual double GetMaximum(int *b) override
1055 : {
1056 0 : return pBand->GetMaximum(b);
1057 : }
1058 :
1059 : protected:
1060 0 : virtual int GetOverviewCount() override
1061 : {
1062 0 : return 0;
1063 : }
1064 :
1065 0 : virtual GDALRasterBand *GetOverview(int) override
1066 : {
1067 0 : return nullptr;
1068 : }
1069 :
1070 : MRFRasterBand *pBand;
1071 : };
1072 :
1073 : NAMESPACE_MRF_END
1074 :
1075 : #endif // GDAL_FRMTS_MRF_MARFA_H_INCLUDED
|