Coverage Report

Created: 2025-12-31 08:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/third_party/LercLib/Lerc.cpp
Line
Count
Source
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
#include "Defines.h"
25
#include "Lerc.h"
26
#include "Lerc2.h"
27
#include <typeinfo>
28
#include <limits>
29
30
#ifdef HAVE_LERC1_DECODE
31
#include "Lerc1Decode/CntZImage.h"
32
#endif
33
34
using namespace std;
35
USING_NAMESPACE_LERC
36
37
// -------------------------------------------------------------------------- ;
38
39
ErrCode Lerc::ComputeCompressedSize(const void* pData, int version, DataType dt, int nDim, int nCols, int nRows, int nBands,
40
  const BitMask* pBitMask, double maxZErr, unsigned int& numBytesNeeded)
41
0
{
42
0
  switch (dt)
43
0
  {
44
0
  case DT_Char:    return ComputeCompressedSizeTempl((const signed char*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
45
0
  case DT_Byte:    return ComputeCompressedSizeTempl((const Byte*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
46
0
  case DT_Short:   return ComputeCompressedSizeTempl((const short*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
47
0
  case DT_UShort:  return ComputeCompressedSizeTempl((const unsigned short*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
48
0
  case DT_Int:     return ComputeCompressedSizeTempl((const int*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
49
0
  case DT_UInt:    return ComputeCompressedSizeTempl((const unsigned int*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
50
0
  case DT_Float:   return ComputeCompressedSizeTempl((const float*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
51
0
  case DT_Double:  return ComputeCompressedSizeTempl((const double*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, numBytesNeeded);
52
53
0
  default:
54
0
    return ErrCode::WrongParam;
55
0
  }
56
0
}
57
58
// -------------------------------------------------------------------------- ;
59
60
ErrCode Lerc::Encode(const void* pData, int version, DataType dt, int nDim, int nCols, int nRows, int nBands,
61
  const BitMask* pBitMask, double maxZErr, Byte* pBuffer, unsigned int numBytesBuffer, unsigned int& numBytesWritten)
62
0
{
63
0
  switch (dt)
64
0
  {
65
0
  case DT_Char:    return EncodeTempl((const signed char*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
66
0
  case DT_Byte:    return EncodeTempl((const Byte*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
67
0
  case DT_Short:   return EncodeTempl((const short*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
68
0
  case DT_UShort:  return EncodeTempl((const unsigned short*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
69
0
  case DT_Int:     return EncodeTempl((const int*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
70
0
  case DT_UInt:    return EncodeTempl((const unsigned int*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
71
0
  case DT_Float:   return EncodeTempl((const float*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
72
0
  case DT_Double:  return EncodeTempl((const double*)pData, version, nDim, nCols, nRows, nBands, pBitMask, maxZErr, pBuffer, numBytesBuffer, numBytesWritten);
73
74
0
  default:
75
0
    return ErrCode::WrongParam;
76
0
  }
77
0
}
78
79
// -------------------------------------------------------------------------- ;
80
81
ErrCode Lerc::GetLercInfo(const Byte* pLercBlob, unsigned int numBytesBlob, struct LercInfo& lercInfo)
82
26.9k
{
83
26.9k
  lercInfo.RawInit();
84
85
  // first try Lerc2
86
26.9k
  struct Lerc2::HeaderInfo lerc2Info;
87
26.9k
  if (Lerc2::GetHeaderInfo(pLercBlob, numBytesBlob, lerc2Info))
88
24.0k
  {
89
24.0k
    lercInfo.version = lerc2Info.version;
90
24.0k
    lercInfo.nDim = lerc2Info.nDim;
91
24.0k
    lercInfo.nCols = lerc2Info.nCols;
92
24.0k
    lercInfo.nRows = lerc2Info.nRows;
93
24.0k
    lercInfo.numValidPixel = lerc2Info.numValidPixel;
94
24.0k
    lercInfo.nBands = 1;
95
24.0k
    lercInfo.blobSize = lerc2Info.blobSize;
96
24.0k
    lercInfo.dt = (DataType)lerc2Info.dt;
97
24.0k
    lercInfo.zMin = lerc2Info.zMin;
98
24.0k
    lercInfo.zMax = lerc2Info.zMax;
99
24.0k
    lercInfo.maxZError = lerc2Info.maxZError;
100
101
24.0k
    if (lercInfo.blobSize > (int)numBytesBlob)    // truncated blob, we won't be able to read this band
102
237
      return ErrCode::BufferTooSmall;
103
104
23.8k
    struct Lerc2::HeaderInfo hdInfo;
105
24.1k
    while (Lerc2::GetHeaderInfo(pLercBlob + lercInfo.blobSize, numBytesBlob - lercInfo.blobSize, hdInfo))
106
814
    {
107
814
      if (hdInfo.nDim != lercInfo.nDim
108
725
       || hdInfo.nCols != lercInfo.nCols
109
650
       || hdInfo.nRows != lercInfo.nRows
110
564
       || hdInfo.numValidPixel != lercInfo.numValidPixel
111
483
       || (int)hdInfo.dt != (int)lercInfo.dt)
112
       //|| hdInfo.maxZError != lercInfo.maxZError)  // with the new bitplane compression, maxZError can vary between bands
113
387
      {
114
387
        return ErrCode::Failed;
115
387
      }
116
117
427
      if (lercInfo.blobSize > std::numeric_limits<int>::max() - hdInfo.blobSize)
118
27
        return ErrCode::Failed;
119
120
400
      lercInfo.blobSize += hdInfo.blobSize;
121
122
400
      if (lercInfo.blobSize > (int)numBytesBlob)    // truncated blob, we won't be able to read this band
123
82
        return ErrCode::BufferTooSmall;
124
125
318
      lercInfo.nBands++;
126
318
      lercInfo.zMin = min(lercInfo.zMin, hdInfo.zMin);
127
318
      lercInfo.zMax = max(lercInfo.zMax, hdInfo.zMax);
128
318
      lercInfo.maxZError = max(lercInfo.maxZError, hdInfo.maxZError);  // with the new bitplane compression, maxZError can vary between bands
129
318
    }
130
131
23.3k
    return ErrCode::Ok;
132
23.8k
  }
133
134
135
#ifdef HAVE_LERC1_DECODE
136
  // only if not Lerc2, try legacy Lerc1
137
  unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
138
  unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
139
  Byte* pByte = const_cast<Byte*>(pLercBlob);
140
141
  lercInfo.zMin =  FLT_MAX;
142
  lercInfo.zMax = -FLT_MAX;
143
144
  CntZImage cntZImg;
145
  if (numBytesHeaderBand0 <= numBytesBlob && cntZImg.read(&pByte, 1e12, true))    // read just the header
146
  {
147
    size_t nBytesRead = pByte - pLercBlob;
148
    size_t nBytesNeeded = 10 + 4 * sizeof(int) + 1 * sizeof(double);
149
150
    if (nBytesRead < nBytesNeeded)
151
      return ErrCode::Failed;
152
153
    Byte* ptr = const_cast<Byte*>(pLercBlob);
154
    ptr += 10 + 2 * sizeof(int);
155
156
    int height(0), width(0);
157
    memcpy(&height, ptr, sizeof(int));  ptr += sizeof(int);
158
    memcpy(&width,  ptr, sizeof(int));  ptr += sizeof(int);
159
    double maxZErrorInFile(0);
160
    memcpy(&maxZErrorInFile, ptr, sizeof(double));
161
162
    if (height > 20000 || width > 20000)    // guard against bogus numbers; size limitation for old Lerc1
163
      return ErrCode::Failed;
164
165
    lercInfo.nDim = 1;
166
    lercInfo.nCols = width;
167
    lercInfo.nRows = height;
168
    lercInfo.dt = Lerc::DT_Float;
169
    lercInfo.maxZError = maxZErrorInFile;
170
171
    Byte* pByte = const_cast<Byte*>(pLercBlob);
172
    bool onlyZPart = false;
173
174
    while (lercInfo.blobSize + numBytesHeaderBand1 < numBytesBlob)    // means there could be another band
175
    {
176
      if (!cntZImg.read(&pByte, 1e12, false, onlyZPart))
177
        return (lercInfo.nBands > 0) ? ErrCode::Ok : ErrCode::Failed;    // no other band, we are done
178
179
      onlyZPart = true;
180
181
      lercInfo.nBands++;
182
      lercInfo.blobSize = (int)(pByte - pLercBlob);
183
184
      // now that we have decoded it, we can go the extra mile and collect some extra info
185
      int numValidPixels = 0;
186
      float zMin =  FLT_MAX;
187
      float zMax = -FLT_MAX;
188
189
      for (int i = 0; i < height; i++)
190
      {
191
        for (int j = 0; j < width; j++)
192
          if (cntZImg(i, j).cnt > 0)
193
          {
194
            numValidPixels++;
195
            float z = cntZImg(i, j).z;
196
            zMax = max(zMax, z);
197
            zMin = min(zMin, z);
198
          }
199
      }
200
201
      lercInfo.numValidPixel = numValidPixels;
202
      lercInfo.zMin = std::min(lercInfo.zMin, (double)zMin);
203
      lercInfo.zMax = std::max(lercInfo.zMax, (double)zMax);
204
    }
205
206
    return ErrCode::Ok;
207
  }
208
#endif
209
210
2.91k
  return ErrCode::Failed;
211
26.9k
}
212
213
// -------------------------------------------------------------------------- ;
214
215
ErrCode Lerc::Decode(const Byte* pLercBlob, unsigned int numBytesBlob, BitMask* pBitMask,
216
  int nDim, int nCols, int nRows, int nBands, DataType dt, void* pData)
217
39.5k
{
218
39.5k
  switch (dt)
219
39.5k
  {
220
4.81k
  case DT_Char:    return DecodeTempl((signed char*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
221
16.6k
  case DT_Byte:    return DecodeTempl((Byte*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
222
2.62k
  case DT_Short:   return DecodeTempl((short*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
223
8.61k
  case DT_UShort:  return DecodeTempl((unsigned short*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
224
1.59k
  case DT_Int:     return DecodeTempl((int*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
225
3.30k
  case DT_UInt:    return DecodeTempl((unsigned int*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
226
978
  case DT_Float:   return DecodeTempl((float*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
227
992
  case DT_Double:  return DecodeTempl((double*)pData, pLercBlob, numBytesBlob, nDim, nCols, nRows, nBands, pBitMask);
228
229
0
  default:
230
0
    return ErrCode::WrongParam;
231
39.5k
  }
232
39.5k
}
233
234
// -------------------------------------------------------------------------- ;
235
236
ErrCode Lerc::ConvertToDouble(const void* pDataIn, DataType dt, size_t nDataValues, double* pDataOut)
237
0
{
238
0
  switch (dt)
239
0
  {
240
0
  case DT_Char:    return ConvertToDoubleTempl((const signed char*)pDataIn, nDataValues, pDataOut);
241
0
  case DT_Byte:    return ConvertToDoubleTempl((const Byte*)pDataIn, nDataValues, pDataOut);
242
0
  case DT_Short:   return ConvertToDoubleTempl((const short*)pDataIn, nDataValues, pDataOut);
243
0
  case DT_UShort:  return ConvertToDoubleTempl((const unsigned short*)pDataIn, nDataValues, pDataOut);
244
0
  case DT_Int:     return ConvertToDoubleTempl((const int*)pDataIn, nDataValues, pDataOut);
245
0
  case DT_UInt:    return ConvertToDoubleTempl((const unsigned int*)pDataIn, nDataValues, pDataOut);
246
0
  case DT_Float:   return ConvertToDoubleTempl((const float*)pDataIn, nDataValues, pDataOut);
247
  //case DT_Double:  no convert double to double
248
249
0
  default:
250
0
    return ErrCode::WrongParam;
251
0
  }
252
0
}
253
254
// -------------------------------------------------------------------------- ;
255
// -------------------------------------------------------------------------- ;
256
257
template<class T>
258
ErrCode Lerc::ComputeCompressedSizeTempl(const T* pData, int version, int nDim, int nCols, int nRows, int nBands,
259
  const BitMask* pBitMask, double maxZErr, unsigned int& numBytesNeeded)
260
0
{
261
0
  numBytesNeeded = 0;
262
263
0
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || maxZErr < 0)
264
0
    return ErrCode::WrongParam;
265
266
0
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
267
0
    return ErrCode::WrongParam;
268
269
0
  Lerc2 lerc2;
270
0
  if (version >= 0 && !lerc2.SetEncoderToOldVersion(version))
271
0
    return ErrCode::WrongParam;
272
273
0
  bool rv = pBitMask ? lerc2.Set(nDim, nCols, nRows, pBitMask->Bits()) : lerc2.Set(nDim, nCols, nRows);
274
0
  if (!rv)
275
0
    return ErrCode::Failed;
276
277
  // loop over the bands
278
0
  for (int iBand = 0; iBand < nBands; iBand++)
279
0
  {
280
0
    bool encMsk = (iBand == 0);    // store bit mask with first band only
281
0
    const T* arr = pData + nDim * nCols * nRows * iBand;
282
283
0
    ErrCode errCode = CheckForNaN(arr, nDim, nCols, nRows, pBitMask);
284
0
    if (errCode != ErrCode::Ok)
285
0
      return errCode;
286
287
0
    unsigned int nBytes = lerc2.ComputeNumBytesNeededToWrite(arr, maxZErr, encMsk);
288
0
    if (nBytes <= 0)
289
0
      return ErrCode::Failed;
290
291
0
    numBytesNeeded += nBytes;
292
0
  }
293
294
0
  return ErrCode::Ok;
295
0
}
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<signed char>(signed char const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<unsigned char>(unsigned char const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<short>(short const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<unsigned short>(unsigned short const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<int>(int const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<unsigned int>(unsigned int const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<float>(float const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ComputeCompressedSizeTempl<double>(double const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned int&)
296
297
// -------------------------------------------------------------------------- ;
298
299
template<class T>
300
ErrCode Lerc::EncodeTempl(const T* pData, int version, int nDim, int nCols, int nRows, int nBands,
301
  const BitMask* pBitMask, double maxZErr, Byte* pBuffer, unsigned int numBytesBuffer, unsigned int& numBytesWritten)
302
0
{
303
0
  numBytesWritten = 0;
304
305
0
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || maxZErr < 0 || !pBuffer || !numBytesBuffer)
306
0
    return ErrCode::WrongParam;
307
308
0
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
309
0
    return ErrCode::WrongParam;
310
311
0
  Lerc2 lerc2;
312
0
  if (version >= 0 && !lerc2.SetEncoderToOldVersion(version))
313
0
    return ErrCode::WrongParam;
314
315
0
  bool rv = pBitMask ? lerc2.Set(nDim, nCols, nRows, pBitMask->Bits()) : lerc2.Set(nDim, nCols, nRows);
316
0
  if (!rv)
317
0
    return ErrCode::Failed;
318
319
0
  Byte* pByte = pBuffer;
320
321
  // loop over the bands, encode into array of single band Lerc blobs
322
0
  for (int iBand = 0; iBand < nBands; iBand++)
323
0
  {
324
0
    bool encMsk = (iBand == 0);    // store bit mask with first band only
325
0
    const T* arr = pData + nDim * nCols * nRows * iBand;
326
327
0
    ErrCode errCode = CheckForNaN(arr, nDim, nCols, nRows, pBitMask);
328
0
    if (errCode != ErrCode::Ok)
329
0
      return errCode;
330
331
0
    unsigned int nBytes = lerc2.ComputeNumBytesNeededToWrite(arr, maxZErr, encMsk);
332
0
    if (nBytes == 0)
333
0
      return ErrCode::Failed;
334
335
0
    unsigned int nBytesAlloc = nBytes;
336
337
0
    if ((size_t)(pByte - pBuffer) + nBytesAlloc > numBytesBuffer)    // check we have enough space left
338
0
      return ErrCode::BufferTooSmall;
339
340
0
    if (!lerc2.Encode(arr, &pByte))
341
0
      return ErrCode::Failed;
342
0
  }
343
344
0
  numBytesWritten = (unsigned int)(pByte - pBuffer);
345
0
  return ErrCode::Ok;
346
0
}
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<signed char>(signed char const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<unsigned char>(unsigned char const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<short>(short const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<unsigned short>(unsigned short const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<int>(int const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<unsigned int>(unsigned int const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<float>(float const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::EncodeTempl<double>(double const*, int, int, int, int, int, GDAL_LercNS::BitMask const*, double, unsigned char*, unsigned int, unsigned int&)
347
348
// -------------------------------------------------------------------------- ;
349
350
template<class T>
351
ErrCode Lerc::DecodeTempl(T* pData, const Byte* pLercBlob, unsigned int numBytesBlob,
352
  int nDim, int nCols, int nRows, int nBands, BitMask* pBitMask)
353
39.5k
{
354
39.5k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
39.5k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
39.5k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
39.5k
  Lerc2::HeaderInfo hdInfo;
365
366
39.5k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
39.4k
  {
368
39.4k
    size_t nBytesRemaining = numBytesBlob;
369
39.4k
    Lerc2 lerc2;
370
371
45.0k
    for (int iBand = 0; iBand < nBands; iBand++)
372
39.4k
    {
373
39.4k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
39.4k
      {
375
39.4k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
39.4k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
386
          return ErrCode::BufferTooSmall;
380
381
39.0k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
39.0k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
33.4k
          return ErrCode::Failed;
385
39.0k
      }
386
39.4k
    }
387
39.4k
  }
388
389
163
  else    // might be old Lerc1
390
163
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
163
    return ErrCode::Failed;
416
163
#endif
417
163
  }
418
419
5.62k
  return ErrCode::Ok;
420
39.5k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<signed char>(signed char*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
4.81k
{
354
4.81k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
4.81k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
4.81k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
4.81k
  Lerc2::HeaderInfo hdInfo;
365
366
4.81k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
4.79k
  {
368
4.79k
    size_t nBytesRemaining = numBytesBlob;
369
4.79k
    Lerc2 lerc2;
370
371
5.90k
    for (int iBand = 0; iBand < nBands; iBand++)
372
4.79k
    {
373
4.79k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
4.79k
      {
375
4.79k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
4.79k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
0
          return ErrCode::BufferTooSmall;
380
381
4.79k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
4.79k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
3.67k
          return ErrCode::Failed;
385
4.79k
      }
386
4.79k
    }
387
4.79k
  }
388
389
21
  else    // might be old Lerc1
390
21
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
21
    return ErrCode::Failed;
416
21
#endif
417
21
  }
418
419
1.11k
  return ErrCode::Ok;
420
4.81k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<unsigned char>(unsigned char*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
16.6k
{
354
16.6k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
16.6k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
16.6k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
16.6k
  Lerc2::HeaderInfo hdInfo;
365
366
16.6k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
16.5k
  {
368
16.5k
    size_t nBytesRemaining = numBytesBlob;
369
16.5k
    Lerc2 lerc2;
370
371
20.0k
    for (int iBand = 0; iBand < nBands; iBand++)
372
16.5k
    {
373
16.5k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
16.5k
      {
375
16.5k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
16.5k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
173
          return ErrCode::BufferTooSmall;
380
381
16.4k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
16.4k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
12.9k
          return ErrCode::Failed;
385
16.4k
      }
386
16.5k
    }
387
16.5k
  }
388
389
71
  else    // might be old Lerc1
390
71
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
71
    return ErrCode::Failed;
416
71
#endif
417
71
  }
418
419
3.43k
  return ErrCode::Ok;
420
16.6k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<short>(short*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
2.62k
{
354
2.62k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
2.62k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
2.62k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
2.62k
  Lerc2::HeaderInfo hdInfo;
365
366
2.62k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
2.61k
  {
368
2.61k
    size_t nBytesRemaining = numBytesBlob;
369
2.61k
    Lerc2 lerc2;
370
371
2.87k
    for (int iBand = 0; iBand < nBands; iBand++)
372
2.61k
    {
373
2.61k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
2.61k
      {
375
2.61k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
2.61k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
8
          return ErrCode::BufferTooSmall;
380
381
2.60k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
2.60k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
2.35k
          return ErrCode::Failed;
385
2.60k
      }
386
2.61k
    }
387
2.61k
  }
388
389
10
  else    // might be old Lerc1
390
10
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
10
    return ErrCode::Failed;
416
10
#endif
417
10
  }
418
419
258
  return ErrCode::Ok;
420
2.62k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<unsigned short>(unsigned short*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
8.61k
{
354
8.61k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
8.61k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
8.61k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
8.61k
  Lerc2::HeaderInfo hdInfo;
365
366
8.61k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
8.60k
  {
368
8.60k
    size_t nBytesRemaining = numBytesBlob;
369
8.60k
    Lerc2 lerc2;
370
371
8.92k
    for (int iBand = 0; iBand < nBands; iBand++)
372
8.60k
    {
373
8.60k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
8.60k
      {
375
8.60k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
8.60k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
175
          return ErrCode::BufferTooSmall;
380
381
8.43k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
8.43k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
8.12k
          return ErrCode::Failed;
385
8.43k
      }
386
8.60k
    }
387
8.60k
  }
388
389
11
  else    // might be old Lerc1
390
11
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
11
    return ErrCode::Failed;
416
11
#endif
417
11
  }
418
419
312
  return ErrCode::Ok;
420
8.61k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<int>(int*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
1.59k
{
354
1.59k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
1.59k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
1.59k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
1.59k
  Lerc2::HeaderInfo hdInfo;
365
366
1.59k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
1.58k
  {
368
1.58k
    size_t nBytesRemaining = numBytesBlob;
369
1.58k
    Lerc2 lerc2;
370
371
1.66k
    for (int iBand = 0; iBand < nBands; iBand++)
372
1.58k
    {
373
1.58k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
1.58k
      {
375
1.58k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
1.58k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
8
          return ErrCode::BufferTooSmall;
380
381
1.58k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
1.58k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
1.50k
          return ErrCode::Failed;
385
1.58k
      }
386
1.58k
    }
387
1.58k
  }
388
389
10
  else    // might be old Lerc1
390
10
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
10
    return ErrCode::Failed;
416
10
#endif
417
10
  }
418
419
80
  return ErrCode::Ok;
420
1.59k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<unsigned int>(unsigned int*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
3.30k
{
354
3.30k
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
3.30k
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
3.30k
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
3.30k
  Lerc2::HeaderInfo hdInfo;
365
366
3.30k
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
3.27k
  {
368
3.27k
    size_t nBytesRemaining = numBytesBlob;
369
3.27k
    Lerc2 lerc2;
370
371
3.54k
    for (int iBand = 0; iBand < nBands; iBand++)
372
3.27k
    {
373
3.27k
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
3.27k
      {
375
3.27k
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
3.27k
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
16
          return ErrCode::BufferTooSmall;
380
381
3.25k
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
3.25k
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
2.98k
          return ErrCode::Failed;
385
3.25k
      }
386
3.27k
    }
387
3.27k
  }
388
389
29
  else    // might be old Lerc1
390
29
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
29
    return ErrCode::Failed;
416
29
#endif
417
29
  }
418
419
275
  return ErrCode::Ok;
420
3.30k
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<float>(float*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
978
{
354
978
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
978
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
978
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
978
  Lerc2::HeaderInfo hdInfo;
365
366
978
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
973
  {
368
973
    size_t nBytesRemaining = numBytesBlob;
369
973
    Lerc2 lerc2;
370
371
1.04k
    for (int iBand = 0; iBand < nBands; iBand++)
372
973
    {
373
973
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
973
      {
375
973
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
973
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
6
          return ErrCode::BufferTooSmall;
380
381
967
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
967
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
894
          return ErrCode::Failed;
385
967
      }
386
973
    }
387
973
  }
388
389
5
  else    // might be old Lerc1
390
5
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
5
    return ErrCode::Failed;
416
5
#endif
417
5
  }
418
419
73
  return ErrCode::Ok;
420
978
}
GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::DecodeTempl<double>(double*, unsigned char const*, unsigned int, int, int, int, int, GDAL_LercNS::BitMask*)
Line
Count
Source
353
992
{
354
992
  if (!pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || !pLercBlob || !numBytesBlob)
355
0
    return ErrCode::WrongParam;
356
357
992
  if (pBitMask && (pBitMask->GetHeight() != nRows || pBitMask->GetWidth() != nCols))
358
0
    return ErrCode::WrongParam;
359
360
992
  const Byte* pByte = pLercBlob;
361
#ifdef HAVE_LERC1_DECODE
362
  Byte* pByte1 = const_cast<Byte*>(pLercBlob);
363
#endif
364
992
  Lerc2::HeaderInfo hdInfo;
365
366
992
  if (Lerc2::GetHeaderInfo(pByte, numBytesBlob, hdInfo) && hdInfo.version >= 1)    // is Lerc2
367
986
  {
368
986
    size_t nBytesRemaining = numBytesBlob;
369
986
    Lerc2 lerc2;
370
371
1.06k
    for (int iBand = 0; iBand < nBands; iBand++)
372
986
    {
373
986
      if (((size_t)(pByte - pLercBlob) < numBytesBlob) && Lerc2::GetHeaderInfo(pByte, nBytesRemaining, hdInfo))
374
986
      {
375
986
        if (hdInfo.nDim != nDim || hdInfo.nCols != nCols || hdInfo.nRows != nRows)
376
0
          return ErrCode::Failed;
377
378
986
        if ((pByte - pLercBlob) + (size_t)hdInfo.blobSize > numBytesBlob)
379
0
          return ErrCode::BufferTooSmall;
380
381
986
        T* arr = pData + nDim * nCols * nRows * iBand;
382
383
986
        if (!lerc2.Decode(&pByte, nBytesRemaining, arr, (pBitMask && iBand == 0) ? pBitMask->Bits() : nullptr))
384
907
          return ErrCode::Failed;
385
986
      }
386
986
    }
387
986
  }
388
389
6
  else    // might be old Lerc1
390
6
  {
391
#ifdef HAVE_LERC1_DECODE
392
    unsigned int numBytesHeaderBand0 = CntZImage::computeNumBytesNeededToReadHeader(false);
393
    unsigned int numBytesHeaderBand1 = CntZImage::computeNumBytesNeededToReadHeader(true);
394
    CntZImage zImg;
395
396
    for (int iBand = 0; iBand < nBands; iBand++)
397
    {
398
      unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
399
      if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
400
        return ErrCode::BufferTooSmall;
401
402
      bool onlyZPart = iBand > 0;
403
      if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
404
        return ErrCode::Failed;
405
406
      if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
407
        return ErrCode::Failed;
408
409
      T* arr = pData + nCols * nRows * iBand;
410
411
      if (!Convert(zImg, arr, pBitMask))
412
        return ErrCode::Failed;
413
    }
414
#else
415
6
    return ErrCode::Failed;
416
6
#endif
417
6
  }
418
419
79
  return ErrCode::Ok;
420
992
}
421
422
// -------------------------------------------------------------------------- ;
423
// -------------------------------------------------------------------------- ;
424
425
#ifdef HAVE_LERC1_DECODE
426
template<class T>
427
bool Lerc::Convert(const CntZImage& zImg, T* arr, BitMask* pBitMask)
428
{
429
  if (!arr || !zImg.getSize())
430
    return false;
431
432
  const bool fltPnt = (typeid(*arr) == typeid(double)) || (typeid(*arr) == typeid(float));
433
434
  int h = zImg.getHeight();
435
  int w = zImg.getWidth();
436
437
  if (pBitMask && (pBitMask->GetHeight() != h || pBitMask->GetWidth() != w))
438
    return false;
439
440
  if (pBitMask)
441
    pBitMask->SetAllValid();
442
443
  const CntZ* srcPtr = zImg.getData();
444
  T* dstPtr = arr;
445
  int num = w * h;
446
  for (int k = 0; k < num; k++)
447
  {
448
    if (srcPtr->cnt > 0)
449
      *dstPtr = fltPnt ? (T)srcPtr->z : (T)floor(srcPtr->z + 0.5);
450
    else if (pBitMask)
451
      pBitMask->SetInvalid(k);
452
453
    srcPtr++;
454
    dstPtr++;
455
  }
456
457
  return true;
458
}
459
#endif
460
461
// -------------------------------------------------------------------------- ;
462
463
template<class T>
464
ErrCode Lerc::ConvertToDoubleTempl(const T* pDataIn, size_t nDataValues, double* pDataOut)
465
0
{
466
0
  if (!pDataIn || !nDataValues || !pDataOut)
467
0
    return ErrCode::WrongParam;
468
469
0
  for (size_t k = 0; k < nDataValues; k++)
470
0
    pDataOut[k] = pDataIn[k];
471
472
0
  return ErrCode::Ok;
473
0
}
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<signed char>(signed char const*, unsigned long, double*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<unsigned char>(unsigned char const*, unsigned long, double*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<short>(short const*, unsigned long, double*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<unsigned short>(unsigned short const*, unsigned long, double*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<int>(int const*, unsigned long, double*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<unsigned int>(unsigned int const*, unsigned long, double*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::ConvertToDoubleTempl<float>(float const*, unsigned long, double*)
474
475
// -------------------------------------------------------------------------- ;
476
477
template<class T> ErrCode Lerc::CheckForNaN(const T* arr, int nDim, int nCols, int nRows, const BitMask* pBitMask)
478
0
{
479
0
  if (!arr || nDim <= 0 || nCols <= 0 || nRows <= 0)
480
0
    return ErrCode::WrongParam;
481
482
0
#ifdef CHECK_FOR_NAN
483
484
0
  if (typeid(T) == typeid(double) || typeid(T) == typeid(float))
485
0
  {
486
0
    bool foundNaN = false;
487
488
0
    for (int k = 0, i = 0; i < nRows; i++)
489
0
    {
490
0
      const T* rowArr = &(arr[i * nCols * nDim]);
491
492
0
      if (!pBitMask)    // all valid
493
0
      {
494
0
        for (int n = 0, j = 0; j < nCols; j++, n += nDim)
495
0
          for (int m = 0; m < nDim; m++)
496
0
            if (std::isnan((double)rowArr[n + m]))
497
0
              foundNaN = true;
498
0
      }
499
0
      else    // not all valid
500
0
      {
501
0
        for (int n = 0, j = 0; j < nCols; j++, k++, n += nDim)
502
0
          if (pBitMask->IsValid(k))
503
0
          {
504
0
            for (int m = 0; m < nDim; m++)
505
0
              if (std::isnan((double)rowArr[n + m]))
506
0
                foundNaN = true;
507
0
          }
508
0
      }
509
510
0
      if (foundNaN)
511
0
        return ErrCode::NaN;
512
0
    }
513
0
  }
514
515
0
#endif
516
517
0
  return ErrCode::Ok;
518
0
}
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<signed char>(signed char const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<unsigned char>(unsigned char const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<short>(short const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<unsigned short>(unsigned short const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<int>(int const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<unsigned int>(unsigned int const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<float>(float const*, int, int, int, GDAL_LercNS::BitMask const*)
Unexecuted instantiation: GDAL_LercNS::ErrCode GDAL_LercNS::Lerc::CheckForNaN<double>(double const*, int, int, int, GDAL_LercNS::BitMask const*)
519
520
// -------------------------------------------------------------------------- ;
521