LCOV - code coverage report
Current view: top level - frmts/mrf - marfa.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 146 166 88.0 %
Date: 2025-07-03 09:54:33 Functions: 55 66 83.3 %

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

Generated by: LCOV version 1.14