Coverage Report

Created: 2025-06-09 07:43

/src/gdal/third_party/LercLib/Lerc.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright 2015 Esri
3
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7
8
http://www.apache.org/licenses/LICENSE-2.0
9
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
16
A local copy of the license and additional notices are located with the
17
source distribution at:
18
19
http://github.com/Esri/lerc/
20
21
Contributors:  Thomas Maurer
22
*/
23
24
#pragma once
25
26
#include <cstring>
27
#include <vector>
28
#include "Lerc_types.h"
29
#include "BitMask.h"
30
#include "Lerc2.h"
31
32
NAMESPACE_LERC_START
33
34
#ifdef HAVE_LERC1_DECODE
35
  class CntZImage;
36
#endif
37
38
  class Lerc
39
  {
40
  public:
41
0
    Lerc() {}
42
0
    ~Lerc() {}
43
44
    // data types supported by Lerc
45
    enum DataType { DT_Char, DT_Byte, DT_Short, DT_UShort, DT_Int, DT_UInt, DT_Float, DT_Double, DT_Undefined };
46
47
    // all functions are provided in 2 flavors
48
    // - using void pointers to the image data, can be called on a Lerc lib or dll
49
    // - data templated, can be called if compiled together
50
51
52
    // Encode
53
54
    // if more than 1 band, the outgoing Lerc blob has the single band Lerc blobs concatenated; 
55
    // or, if you have multiple values per pixel and stored as [RGB, RGB, ... ], then set nDim accordingly (e.g., 3)
56
57
    // computes the number of bytes needed to allocate the buffer, accurate to the byte;
58
    // does not encode the image data, but uses statistics and formulas to compute the buffer size needed;
59
    // this function is optional, you can also use a buffer large enough to call Encode() directly, 
60
    // or, if encoding a batch of same width / height tiles, call this function once, double the buffer size, and
61
    // then just call Encode() on all tiles;
62
63
    static ErrCode ComputeCompressedSize(
64
      const void* pData,               // raw image data, row by row, band by band
65
      int version,                     // 2 = v2.2, 3 = v2.3, 4 = v2.4
66
      DataType dt,                     // data type, char to double
67
      int nDim,                        // number of values per pixel
68
      int nCols,                       // number of cols
69
      int nRows,                       // number of rows
70
      int nBands,                      // number of bands
71
      const BitMask* pBitMask,         // 0 if all pixels are valid
72
      double maxZErr,                  // max coding error per pixel, defines the precision
73
      unsigned int& numBytesNeeded);   // size of outgoing Lerc blob
74
75
    // encodes or compresses the image data into the buffer
76
77
    static ErrCode Encode(
78
      const void* pData,               // raw image data, row by row, band by band
79
      int version,                     // 2 = v2.2, 3 = v2.3, 4 = v2.4
80
      DataType dt,                     // data type, char to double
81
      int nDim,                        // number of values per pixel
82
      int nCols,                       // number of cols
83
      int nRows,                       // number of rows
84
      int nBands,                      // number of bands
85
      const BitMask* pBitMask,         // 0 if all pixels are valid
86
      double maxZErr,                  // max coding error per pixel, defines the precision
87
      Byte* pBuffer,                   // buffer to write to, function fails if buffer too small
88
      unsigned int numBytesBuffer,     // buffer size
89
      unsigned int& numBytesWritten);  // num bytes written to buffer
90
91
92
    // Decode
93
94
    struct LercInfo
95
    {
96
      int version,        // Lerc version number (0 for old Lerc1, 1 to 4 for Lerc 2.1 to 2.4)
97
        nDim,             // number of values per pixel
98
        nCols,            // number of columns
99
        nRows,            // number of rows
100
        numValidPixel,    // number of valid pixels
101
        nBands,           // number of bands
102
        blobSize;         // total blob size in bytes
103
      DataType dt;        // data type (float only for old Lerc1)
104
      double zMin,        // min pixel value, over all data values
105
        zMax,             // max pixel value, over all data values
106
        maxZError;        // maxZError used for encoding
107
108
360
      void RawInit()  { memset(this, 0, sizeof(struct LercInfo)); }
109
    };
110
111
    // again, this function is optional;
112
    // call it on a Lerc blob to get the above struct returned, from this the data arrays
113
    // can be constructed before calling Decode();
114
    // same as above, for a batch of Lerc blobs of the same kind, you can call this function on 
115
    // the first blob, get the info, and on the other Lerc blobs just call Decode();
116
    // this function is very fast on (newer) Lerc2 blobs as it only reads the blob headers;
117
118
    // Remark on param numBytesBlob. Usually it is known, either the file size of the blob written to disk, 
119
    // or the size of the blob transmitted. It should be accurate for 2 reasons:
120
    // _ function finds out how many single band Lerc blobs are concatenated
121
    // _ function checks for truncated file or blob
122
    // It is OK to pass numBytesBlob too large as long as there is no other (valid) Lerc blob following next.
123
    // If in doubt, check the code in Lerc::GetLercInfo(...) for the exact logic. 
124
125
    static ErrCode GetLercInfo(const Byte* pLercBlob,       // Lerc blob to decode
126
                               unsigned int numBytesBlob,   // size of Lerc blob in bytes
127
                               struct LercInfo& lercInfo);
128
129
    // setup outgoing arrays accordingly, then call Decode()
130
131
    static ErrCode Decode(
132
      const Byte* pLercBlob,           // Lerc blob to decode
133
      unsigned int numBytesBlob,       // size of Lerc blob in bytes
134
      BitMask* pBitMask,               // gets filled if not 0, even if all valid
135
      int nDim,                        // number of values per pixel
136
      int nCols,                       // number of cols
137
      int nRows,                       // number of rows
138
      int nBands,                      // number of bands
139
      DataType dt,                     // data type of outgoing array
140
      void* pData);                    // outgoing data bands
141
142
143
    static ErrCode ConvertToDouble(
144
      const void* pDataIn,             // pixel data of image tile of data type dt (< double)
145
      DataType dt,                     // data type of input data
146
      size_t nDataValues,              // total number of data values (nDim * nCols * nRows * nBands)
147
      double* pDataOut);               // pixel data converted to double
148
149
150
    // same as functions above, but data templated instead of using void pointers
151
152
    template<class T> static ErrCode ComputeCompressedSizeTempl(
153
      const T* pData,                  // raw image data, row by row, band by 
154
      int version,                     // 2 = v2.2, 3 = v2.3, 4 = v2.4
155
      int nDim,                        // number of values per pixel
156
      int nCols,                       // number of cols
157
      int nRows,                       // number of rows
158
      int nBands,                      // number of bands
159
      const BitMask* pBitMask,         // 0 means all pixels are valid
160
      double maxZErr,                  // max coding error per pixel, defines the precision
161
      unsigned int& numBytes);         // size of outgoing Lerc blob
162
163
    template<class T> static ErrCode EncodeTempl(
164
      const T* pData,                  // raw image data, row by row, band by band
165
      int version,                     // 2 = v2.2, 3 = v2.3, 4 = v2.4
166
      int nDim,                        // number of values per pixel
167
      int nCols,                       // number of cols
168
      int nRows,                       // number of rows
169
      int nBands,                      // number of bands
170
      const BitMask* pBitMask,         // 0 means all pixels are valid
171
      double maxZErr,                  // max coding error per pixel, defines the precision
172
      Byte* pBuffer,                   // buffer to write to, function will fail if buffer too small
173
      unsigned int numBytesBuffer,     // buffer size
174
      unsigned int& numBytesWritten);  // num bytes written to buffer
175
176
    template<class T> static ErrCode DecodeTempl(
177
      T* pData,                        // outgoing data bands
178
      const Byte* pLercBlob,           // Lerc blob to decode
179
      unsigned int numBytesBlob,       // size of Lerc blob in bytes
180
      int nDim,                        // number of values per pixel
181
      int nCols,                       // number of cols
182
      int nRows,                       // number of rows
183
      int nBands,                      // number of bands
184
      BitMask* pBitMask);              // gets filled if not 0, even if all valid
185
186
  private:
187
#ifdef HAVE_LERC1_DECODE
188
    template<class T> static bool Convert(const CntZImage& zImg, T* arr, BitMask* pBitMask);
189
#endif
190
    template<class T> static ErrCode ConvertToDoubleTempl(const T* pDataIn, size_t nDataValues, double* pDataOut);
191
192
    template<class T> static ErrCode CheckForNaN(const T* arr, int nDim, int nCols, int nRows, const BitMask* pBitMask);
193
  };
194
NAMESPACE_LERC_END