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 17420 : explicit ILSize(const int x_ = -1, const int y_ = -1, const int z_ = -1,
177 : const int c_ = -1, const int l_ = -1)
178 17420 : : x(x_), y(y_), z(z_), c(c_), l(l_)
179 : {
180 17420 : }
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 6910 : static inline int pcount(const int n, const int sz)
324 : {
325 6910 : 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 1671 : static inline const ILSize pcount(const ILSize &size, const ILSize &psz)
331 : {
332 1671 : ILSize pcnt;
333 1671 : pcnt.x = pcount(size.x, psz.x);
334 1671 : pcnt.y = pcount(size.y, psz.y);
335 1671 : pcnt.z = pcount(size.z, psz.z);
336 1671 : pcnt.c = pcount(size.c, psz.c);
337 1671 : auto xy = static_cast<GIntBig>(pcnt.x) * pcnt.y;
338 1671 : auto zc = static_cast<GIntBig>(pcnt.z) * pcnt.c;
339 1671 : 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 1671 : pcnt.l = xy * zc;
347 1671 : 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 433 : const GDALColorTable *GetColorTable()
430 : {
431 433 : 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 2020 : const CPLString GetFname()
440 : {
441 2020 : 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 300 : void SetPBufferSize(unsigned int sz)
455 : {
456 300 : pbsize = sz;
457 300 : }
458 :
459 5520 : unsigned int GetPBufferSize()
460 : {
461 5520 : 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 : void *pbuffer; // A place to keep an uncompressed block
598 : unsigned int pbsize;
599 : ILSize tile; // ID of tile present in buffer
600 : GUIntBig bdirty; // used in pixel interleaved (up to 64 bands)
601 :
602 : // GeoTransform support
603 : GDALGeoTransform m_gt{};
604 : mutable int bGeoTransformValid;
605 :
606 : // CRS
607 : OGRSpatialReference m_oSRS{};
608 :
609 : // Photometric interpretation
610 : CPLString photometric;
611 :
612 : GDALColorTable *poColorTable;
613 : int Quality;
614 :
615 : VF dfp; // Data file handle
616 : VF ifp; // Index file handle
617 :
618 : // statistical values
619 : std::vector<double> vNoData, vMin, vMax;
620 : // Sticky context for zstd compress and decompress
621 : void *pzscctx, *pzsdctx;
622 : #if defined(ZSTD_SUPPORT)
623 12 : ZSTD_CCtx *getzsc()
624 : {
625 12 : if (!pzscctx)
626 10 : pzscctx = ZSTD_createCCtx();
627 12 : return static_cast<ZSTD_CCtx *>(pzscctx);
628 : }
629 :
630 10 : ZSTD_DCtx *getzsd()
631 : {
632 10 : if (!pzsdctx)
633 10 : pzsdctx = ZSTD_createDCtx();
634 10 : return static_cast<ZSTD_DCtx *>(pzsdctx);
635 : }
636 : #endif
637 : // Time duration spend for decompression and compression
638 : std::chrono::nanoseconds read_timer, write_timer;
639 : };
640 :
641 : class MRFRasterBand CPL_NON_FINAL : public GDALPamRasterBand
642 : {
643 : friend class MRFDataset;
644 :
645 : public:
646 : MRFRasterBand(MRFDataset *, const ILImage &, int, int);
647 : ~MRFRasterBand() override;
648 : CPLErr IReadBlock(int xblk, int yblk, void *buffer) override;
649 : CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override;
650 :
651 : // Check that the respective block has data, without reading it
652 : virtual bool TestBlock(int xblk, int yblk);
653 :
654 11 : GDALColorTable *GetColorTable() override
655 : {
656 11 : return poMRFDS->poColorTable;
657 : }
658 :
659 433 : CPLErr SetColorInterpretation(GDALColorInterp ci) override
660 : {
661 433 : img.ci = ci;
662 433 : return CE_None;
663 : }
664 :
665 147 : GDALColorInterp GetColorInterpretation() override
666 : {
667 147 : return img.ci;
668 : }
669 :
670 : // Get works within MRF or with PAM
671 : double GetNoDataValue(int *) override;
672 : CPLErr SetNoDataValue(double) override;
673 :
674 : // These get set with SetStatistics
675 : double GetMinimum(int *) override;
676 : double GetMaximum(int *) override;
677 :
678 : // MRF specific, fetch is from a remote source
679 : CPLErr FetchBlock(int xblk, int yblk, void *buffer = nullptr);
680 : // Fetch a block from a cloned MRF
681 : CPLErr FetchClonedBlock(int xblk, int yblk, void *buffer = nullptr);
682 :
683 : // Block not stored on disk
684 : CPLErr FillBlock(void *buffer);
685 :
686 : // Same, for interleaved bands, current band goes in buffer
687 : CPLErr FillBlock(int xblk, int yblk, void *buffer);
688 :
689 : // de-interlace a buffer in pixel blocks
690 : CPLErr ReadInterleavedBlock(int xblk, int yblk, void *buffer);
691 :
692 : const char *GetOptionValue(const char *opt, const char *def) const;
693 :
694 505 : void SetAccess(GDALAccess eA)
695 : {
696 505 : eAccess = eA;
697 505 : }
698 :
699 26 : void SetDeflate(int v)
700 : {
701 26 : dodeflate = (v != 0);
702 26 : }
703 :
704 42 : void SetZstd(int v)
705 : {
706 42 : dozstd = (v != 0);
707 42 : }
708 :
709 : protected:
710 : // Pointer to the GDALMRFDataset
711 : MRFDataset *poMRFDS;
712 : // Deflate page requested, named to avoid conflict with libz deflate()
713 : int dodeflate;
714 : int deflate_flags;
715 : int dozstd;
716 : int zstd_level;
717 : // Level count of this band
718 : GInt32 m_l;
719 : // The info about the current image, to enable R-sets
720 : ILImage img;
721 : std::vector<MRFRasterBand *> overviews;
722 :
723 : VSILFILE *IdxFP()
724 : {
725 : return poMRFDS->IdxFP();
726 : }
727 :
728 4 : GDALRWFlag IdxMode()
729 : {
730 4 : return poMRFDS->IdxMode();
731 : }
732 :
733 1878 : VSILFILE *DataFP()
734 : {
735 1878 : return poMRFDS->DataFP();
736 : }
737 :
738 1 : GDALRWFlag DataMode()
739 : {
740 1 : return poMRFDS->DataMode();
741 : }
742 :
743 : // How many bytes are in a band block (not a page, a single band block)
744 : // Easiest is to calculate it from the pageSizeBytes
745 150 : GUInt32 blockSizeBytes()
746 : {
747 150 : return poMRFDS->current.pageSizeBytes / poMRFDS->current.pagesize.c;
748 : }
749 :
750 3031 : const CPLStringList &GetOptlist() const
751 : {
752 3031 : return poMRFDS->optlist;
753 : }
754 :
755 : // Compression and decompression functions. To be overwritten by specific
756 : // implementations
757 : virtual CPLErr Compress(buf_mgr &dst, buf_mgr &src) = 0;
758 : virtual CPLErr Decompress(buf_mgr &dst, buf_mgr &src) = 0;
759 :
760 : // Read the index record itself, can be overwritten
761 : // virtual CPLErr ReadTileIdx(const ILSize &, ILIdx &, GIntBig bias = 0);
762 :
763 27 : static GUInt64 bandbit(int b)
764 : {
765 27 : return ((GUInt64)1) << b;
766 : }
767 :
768 9 : GUInt64 bandbit()
769 : {
770 9 : return bandbit(nBand - 1);
771 : }
772 :
773 18 : GUInt64 AllBandMask()
774 : {
775 18 : return (~GUInt64(0)) >> (64 - poMRFDS->nBands);
776 : }
777 :
778 : // Overview Support
779 : // Inherited from GDALRasterBand
780 : // These are called only in the base level RasterBand
781 : int GetOverviewCount() override;
782 : GDALRasterBand *GetOverview(int n) override;
783 :
784 72 : void AddOverview(MRFRasterBand *b)
785 : {
786 72 : overviews.push_back(b);
787 72 : }
788 : };
789 :
790 : /**
791 : * Each type of compression needs to define at least two methods, a compress and
792 : * a decompress, which take as arguments a dest and a source buffer, plus an
793 : * image structure that holds the information about the compression type.
794 : * Filtering is needed, probably in the form of pack and unpack functions
795 : *
796 : */
797 :
798 : class PNG_Codec
799 : {
800 : public:
801 159 : explicit PNG_Codec(const ILImage &image)
802 159 : : img(image), PNGColors(nullptr), PNGAlpha(nullptr), PalSize(0),
803 159 : TransSize(0), deflate_flags(0)
804 : {
805 159 : }
806 :
807 159 : ~PNG_Codec()
808 159 : {
809 159 : CPLFree(PNGColors);
810 159 : CPLFree(PNGAlpha);
811 159 : }
812 :
813 : CPLErr CompressPNG(buf_mgr &dst, const buf_mgr &src);
814 : static CPLErr DecompressPNG(buf_mgr &dst, buf_mgr &src);
815 :
816 : const ILImage img;
817 :
818 : void *PNGColors;
819 : void *PNGAlpha;
820 : int PalSize, TransSize, deflate_flags;
821 :
822 : private:
823 : // not implemented. but suppress MSVC warning about 'assignment operator
824 : // could not be generated'
825 : PNG_Codec &operator=(const PNG_Codec &src);
826 : };
827 :
828 : class PNG_Band final : public MRFRasterBand
829 : {
830 : friend class MRFDataset;
831 :
832 : public:
833 : PNG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
834 :
835 : protected:
836 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
837 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
838 :
839 : PNG_Codec codec;
840 : };
841 :
842 : /*
843 : * The JPEG Codec can be used outside of the JPEG_Band
844 : */
845 :
846 : class JPEG_Codec
847 : {
848 : public:
849 49 : explicit JPEG_Codec(const ILImage &image)
850 49 : : img(image), sameres(FALSE), rgb(FALSE), optimize(false), JFIF(false)
851 : {
852 49 : }
853 :
854 : CPLErr CompressJPEG(buf_mgr &dst, buf_mgr &src);
855 : CPLErr DecompressJPEG(buf_mgr &dst, const buf_mgr &src);
856 :
857 : // Returns true for both JPEG and JPEG-XL (brunsli)
858 : static bool IsJPEG(const buf_mgr &src);
859 :
860 : #if defined(JPEG12_SUPPORTED) // Internal only
861 : CPLErr CompressJPEG12(buf_mgr &dst, buf_mgr &src);
862 : CPLErr DecompressJPEG12(buf_mgr &dst, const buf_mgr &src);
863 : #endif
864 :
865 : const ILImage img;
866 :
867 : // JPEG specific flags
868 : bool sameres; // No color space subsample
869 : bool rgb; // No conversion to YCbCr
870 : bool optimize; // Optimize Huffman tables
871 : bool JFIF; // Write JFIF only
872 :
873 : private:
874 : // not implemented. but suppress MSVC warning about 'assignment operator
875 : // could not be generated'
876 : JPEG_Codec &operator=(const JPEG_Codec &src);
877 : };
878 :
879 : class JPEG_Band final : public MRFRasterBand
880 : {
881 : friend class MRFDataset;
882 :
883 : public:
884 : JPEG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
885 :
886 : protected:
887 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
888 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
889 :
890 : JPEG_Codec codec;
891 : };
892 :
893 : // A 2 or 4 band, with JPEG and/or PNG page encoding, optimized for size
894 : class JPNG_Band final : public MRFRasterBand
895 : {
896 : friend class MRFDataset;
897 :
898 : public:
899 : JPNG_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
900 : ~JPNG_Band() override;
901 :
902 : protected:
903 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
904 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
905 :
906 : CPLErr CompressJPNG(buf_mgr &dst, buf_mgr &src);
907 : CPLErr DecompressJPNG(buf_mgr &dst, buf_mgr &src);
908 : bool rgb, sameres, optimize, JFIF;
909 : };
910 :
911 : class Raw_Band final : public MRFRasterBand
912 : {
913 : friend class MRFDataset;
914 :
915 : public:
916 205 : Raw_Band(MRFDataset *pDS, const ILImage &image, int b, int level)
917 205 : : MRFRasterBand(pDS, image, b, int(level))
918 : {
919 205 : }
920 :
921 : protected:
922 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
923 :
924 215 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override
925 : {
926 215 : return Decompress(dst, src);
927 : }
928 : };
929 :
930 : class TIF_Band final : public MRFRasterBand
931 : {
932 : friend class MRFDataset;
933 :
934 : public:
935 : TIF_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
936 : ~TIF_Band() override;
937 :
938 : protected:
939 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
940 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
941 :
942 : // Create options for TIF pages
943 : char **papszOptions;
944 : };
945 :
946 : #if defined(LERC)
947 : class LERC_Band final : public MRFRasterBand
948 : {
949 : friend class MRFDataset;
950 :
951 : public:
952 : LERC_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
953 : ~LERC_Band() override;
954 :
955 : protected:
956 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
957 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
958 : double precision = 0;
959 : // L1 or L2
960 : int version = 0;
961 : // L2 version
962 : int l2ver = 0;
963 : // Build a MRF header for a single LERC tile
964 : static CPLXMLNode *GetMRFConfig(GDALOpenInfo *poOpenInfo);
965 :
966 : private:
967 1082 : static bool IsLerc1(const char *s)
968 : {
969 : static const char L1sig[] = "CntZImage ";
970 1082 : return !strncmp(s, L1sig, sizeof(L1sig) - 1);
971 : }
972 :
973 1617 : static bool IsLerc2(const char *s)
974 : {
975 : static const char L2sig[] = "Lerc2 ";
976 1617 : return !strncmp(s, L2sig, sizeof(L2sig) - 1);
977 : }
978 : };
979 : #endif
980 :
981 : #if defined(QB3_SUPPORT)
982 : class QB3_Band final : public MRFRasterBand
983 : {
984 : friend class MRFDataset;
985 :
986 : public:
987 : QB3_Band(MRFDataset *pDS, const ILImage &image, int b, int level);
988 :
989 106 : virtual ~QB3_Band()
990 53 : {
991 106 : }
992 :
993 : protected:
994 : CPLErr Decompress(buf_mgr &dst, buf_mgr &src) override;
995 : CPLErr Compress(buf_mgr &dst, buf_mgr &src) override;
996 :
997 : std::vector<size_t> coreband;
998 : };
999 : #endif
1000 :
1001 : /*\brief band for level mrf
1002 : *
1003 : * Stand alone definition of a derived band, used in access to a specific level
1004 : * in an MRF
1005 : *
1006 : */
1007 : class MRFLRasterBand final : public GDALPamRasterBand
1008 : {
1009 : public:
1010 1 : explicit MRFLRasterBand(MRFRasterBand *b)
1011 1 : {
1012 1 : pBand = b;
1013 1 : eDataType = b->GetRasterDataType();
1014 1 : b->GetBlockSize(&nBlockXSize, &nBlockYSize);
1015 1 : eAccess = b->GetAccess();
1016 1 : nRasterXSize = b->GetXSize();
1017 1 : nRasterYSize = b->GetYSize();
1018 1 : }
1019 :
1020 : CPLErr IReadBlock(int xblk, int yblk, void *buffer) override;
1021 :
1022 0 : CPLErr IWriteBlock(int xblk, int yblk, void *buffer) override
1023 : {
1024 0 : return pBand->IWriteBlock(xblk, yblk, buffer);
1025 : }
1026 :
1027 0 : GDALColorTable *GetColorTable() override
1028 : {
1029 0 : return pBand->GetColorTable();
1030 : }
1031 :
1032 0 : GDALColorInterp GetColorInterpretation() override
1033 : {
1034 0 : return pBand->GetColorInterpretation();
1035 : }
1036 :
1037 0 : double GetNoDataValue(int *pbSuccess) override
1038 : {
1039 0 : return pBand->GetNoDataValue(pbSuccess);
1040 : }
1041 :
1042 0 : double GetMinimum(int *b) override
1043 : {
1044 0 : return pBand->GetMinimum(b);
1045 : }
1046 :
1047 0 : double GetMaximum(int *b) override
1048 : {
1049 0 : return pBand->GetMaximum(b);
1050 : }
1051 :
1052 : protected:
1053 0 : int GetOverviewCount() override
1054 : {
1055 0 : return 0;
1056 : }
1057 :
1058 0 : GDALRasterBand *GetOverview(int) override
1059 : {
1060 0 : return nullptr;
1061 : }
1062 :
1063 : MRFRasterBand *pBand;
1064 : };
1065 :
1066 : NAMESPACE_MRF_END
1067 :
1068 : #endif // GDAL_FRMTS_MRF_MARFA_H_INCLUDED
|