LCOV - code coverage report
Current view: top level - frmts/mrf - marfa.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 143 163 87.7 %
Date: 2026-03-26 04:14:48 Functions: 53 64 82.8 %

          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 &gt) const override;
     420             :     CPLErr SetGeoTransform(const GDALGeoTransform &gt) 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

Generated by: LCOV version 1.14