LCOV - code coverage report
Current view: top level - frmts/mrf/LERCV1 - Lerc1Image.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 62 62 100.0 %
Date: 2024-11-21 22:18:42 Functions: 22 22 100.0 %

          Line data    Source code
       1             : /*
       2             : Copyright 2015 - 2024 Esri
       3             : Licensed under the Apache License, Version 2.0 (the "License");
       4             : you may not use this file except in compliance with the License.
       5             : You may obtain a copy of the License at
       6             : http://www.apache.org/licenses/LICENSE-2.0
       7             : Unless required by applicable law or agreed to in writing, software
       8             : distributed under the License is distributed on an "AS IS" BASIS,
       9             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      10             : See the License for the specific language governing permissions and
      11             : limitations under the License.
      12             : A local copy of the license and additional notices are located with the
      13             : source distribution at:
      14             : http://github.com/Esri/lerc/
      15             : Contributors:  Thomas Maurer
      16             :                Lucian Plesea
      17             : */
      18             : 
      19             : #ifndef LERC1IMAGE_H
      20             : #define LERC1IMAGE_H
      21             : 
      22             : #include <cstring>
      23             : #include <vector>
      24             : 
      25             : #ifndef NAMESPACE_LERC1_START
      26             : #define NAMESPACE_LERC1_START                                                  \
      27             :     namespace Lerc1NS                                                          \
      28             :     {
      29             : #define NAMESPACE_LERC1_END }
      30             : #define USING_NAMESPACE_LERC1 using namespace Lerc1NS;
      31             : #endif
      32             : 
      33             : NAMESPACE_LERC1_START
      34             : static_assert(sizeof(float) == 4, "lerc requires float to be exactly 4 bytes");
      35             : 
      36             : typedef unsigned char Byte;
      37             : 
      38             : /** BitMaskV1 - Convenient and fast access to binary mask bits
      39             :  * includes RLE compression and decompression
      40             :  *
      41             :  */
      42             : 
      43             : class BitMaskV1
      44             : {
      45             :   public:
      46          24 :     BitMaskV1() : m_nRows(0), m_nCols(0)
      47             :     {
      48          24 :     }
      49             : 
      50          68 :     int size() const
      51             :     {
      52          68 :         return 1 + (m_nCols * m_nRows - 1) / 8;
      53             :     }
      54             : 
      55     3145730 :     void Set(int k, bool v)
      56             :     {
      57     3145730 :         if (v)
      58      259297 :             SetValid(k);
      59             :         else
      60     2886430 :             SetInvalid(k);
      61     3145730 :     }
      62             : 
      63    20517500 :     Byte IsValid(int k) const
      64             :     {
      65    20517500 :         return (bits[k >> 3] & Bit(k)) != 0;
      66             :     }
      67             : 
      68          28 :     void resize(int nCols, int nRows)
      69             :     {
      70          28 :         m_nRows = nRows;
      71          28 :         m_nCols = nCols;
      72          28 :         bits.resize(size());
      73          28 :     }
      74             : 
      75             :     // max RLE compressed size is n + 4 + 2 * (n - 1) / 32767
      76             :     // Returns encoded size
      77             :     int RLEcompress(Byte *aRLE) const;
      78             :     // Encoded size, without doing the work
      79             :     int RLEsize() const;
      80             :     // Decompress a RLE bitmask, bitmask size should be already set
      81             :     // Returns false if input seems wrong
      82             :     bool RLEdecompress(const Byte *src, size_t sz);
      83             : 
      84             :   private:
      85             :     int m_nRows, m_nCols;
      86             :     std::vector<Byte> bits;
      87             : 
      88    23663200 :     static Byte Bit(int k)
      89             :     {
      90    23663200 :         return static_cast<Byte>(0x80 >> (k & 7));
      91             :     }
      92             : 
      93      259297 :     void SetValid(int k)
      94             :     {
      95      259297 :         bits[k >> 3] |= Bit(k);
      96      259297 :     }
      97             : 
      98     2886430 :     void SetInvalid(int k)
      99             :     {
     100     2886430 :         bits[k >> 3] &= ~Bit(k);
     101     2886430 :     }
     102             : };
     103             : 
     104             : template <typename T> class TImage
     105             : {
     106             :   public:
     107          24 :     TImage() : width_(0), height_(0)
     108             :     {
     109          24 :     }
     110             : 
     111          24 :     ~TImage()
     112             :     {
     113          24 :     }
     114             : 
     115          28 :     bool setsize(int width, int height)
     116             :     {
     117          28 :         width_ = width;
     118          28 :         height_ = height;
     119          28 :         values.resize(getSize());
     120          28 :         return true;
     121             :     }
     122             : 
     123    23913600 :     int getWidth() const
     124             :     {
     125    23913600 :         return width_;
     126             :     }
     127             : 
     128       76919 :     int getHeight() const
     129             :     {
     130       76919 :         return height_;
     131             :     }
     132             : 
     133        1540 :     int getSize() const
     134             :     {
     135        1540 :         return width_ * height_;
     136             :     }
     137             : 
     138     1253600 :     const T &operator()(int row, int col) const
     139             :     {
     140     1253600 :         return values[row * width_ + col];
     141             :     }
     142             : 
     143     4471660 :     T &operator()(int row, int col)
     144             :     {
     145     4471660 :         return values[row * width_ + col];
     146             :     }
     147             : 
     148             :     const T *data() const
     149             :     {
     150             :         return values.data();
     151             :     }
     152             : 
     153             :   private:
     154             :     int width_, height_;
     155             :     std::vector<T> values;
     156             : };
     157             : 
     158             : class Lerc1Image : public TImage<float>
     159             : {
     160             :   protected:
     161             :     struct InfoFromComputeNumBytes
     162             :     {
     163             :         double maxZError;
     164             :         int numTilesVertCnt;
     165             :         int numTilesHoriCnt;
     166             :         int numBytesCnt;
     167             :         float maxCntInImg;
     168             :         int numTilesVertZ;
     169             :         int numTilesHoriZ;
     170             :         int numBytesZ;
     171             :         float maxZInImg;
     172             : 
     173          12 :         InfoFromComputeNumBytes()
     174          12 :         {
     175          12 :             std::memset(this, 0, sizeof(*this));
     176          12 :         }
     177             :     };
     178             : 
     179             :     bool findTiling(double maxZError, int &numTilesVert, int &numTilesHori,
     180             :                     int &numBytesOpt, float &maxValInImg) const;
     181             : 
     182             :     bool writeTiles(double maxZError, int numTilesVert, int numTilesHori,
     183             :                     Byte *bArr, int &numBytes, float &maxValInImg) const;
     184             : 
     185             :     bool readTiles(double maxZErrorInFile, int numTilesVert, int numTilesHori,
     186             :                    float maxValInImg, Byte *bArr, size_t nRemainingBytes);
     187             : 
     188             :     bool computeZStats(int r0, int r1, int c0, int c1, float &zMin, float &zMax,
     189             :                        int &numValidPixel, int &numFinite) const;
     190             : 
     191             :     // returns true if all floating point values in the region have the same
     192             :     // binary representation
     193             :     bool isallsameval(int r0, int r1, int c0, int c1) const;
     194             : 
     195             :     bool writeZTile(Byte **ppByte, int &numBytes, int r0, int r1, int c0,
     196             :                     int c1, int numValidPixel, float zMin, float zMax,
     197             :                     double maxZError) const;
     198             : 
     199             :     bool readZTile(Byte **ppByte, size_t &nRemainingBytes, int r0, int r1,
     200             :                    int c0, int c1, double maxZErrorInFile, float maxZInImg);
     201             : 
     202             :     unsigned int
     203             :     computeNumBytesNeededToWrite(double maxZError, bool onlyZPart,
     204             :                                  InfoFromComputeNumBytes *info) const;
     205             : 
     206             :     std::vector<unsigned int> idataVec;  // temporary buffer
     207             :     BitMaskV1 mask;
     208             : 
     209             :   public:
     210             :     /// binary file IO with optional compression
     211             :     /// (maxZError = 0  means no lossy compression for Z; the mask part is
     212             :     /// compressed lossless or not at all) read succeeds only if maxZError on
     213             :     /// file <= maxZError requested (!)
     214             : 
     215          24 :     Lerc1Image()
     216          24 :     {
     217          24 :     }
     218             : 
     219          24 :     ~Lerc1Image()
     220          24 :     {
     221          24 :     }
     222             : 
     223             :     static unsigned int computeNumBytesNeededToWriteVoidImage();
     224             : 
     225             :     // Only initialize the size from the header, if LERC1
     226             :     static bool getwh(const Byte *ppByte, size_t nBytes, int &w, int &h);
     227             : 
     228          28 :     void resize(int width, int height)
     229             :     {
     230          28 :         setsize(width, height);
     231          28 :         mask.resize(getWidth(), getHeight());
     232          28 :     }
     233             : 
     234    20516000 :     bool IsValid(int row, int col) const
     235             :     {
     236    20516000 :         return mask.IsValid(row * getWidth() + col) != 0;
     237             :     }
     238             : 
     239     3145730 :     void SetMask(int row, int col, bool v)
     240             :     {
     241     3145730 :         mask.Set(row * getWidth() + col, v);
     242     3145730 :     }
     243             : 
     244             :     // Read and write into a memory buffer
     245             :     bool write(Byte **ppByte, double maxZError = 0,
     246             :                bool onlyZPart = false) const;
     247             :     bool read(Byte **ppByte, size_t &nRemainingBytes, double maxZError,
     248             :               bool onlyZPart = false);
     249             : };
     250             : 
     251             : NAMESPACE_LERC1_END
     252             : #endif

Generated by: LCOV version 1.14