LCOV - code coverage report
Current view: top level - frmts/mrf - marfa.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 156 177 88.1 %
Date: 2024-11-21 22:18:42 Functions: 59 71 83.1 %

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

Generated by: LCOV version 1.14