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/Lerc2.h
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
#ifndef LERC2_H
25
#define LERC2_H
26
27
#include <algorithm>
28
#include <cfloat>
29
#include <cmath>
30
#include <limits>
31
#include <string>
32
#include <typeinfo>
33
#include "Defines.h"
34
#include "BitMask.h"
35
#include "BitStuffer2.h"
36
#include "Huffman.h"
37
#include "RLE.h"
38
39
NAMESPACE_LERC_START
40
41
/**   Lerc2 v1
42
 *
43
 *    -- allow for lossless compression of all common data types
44
 *    -- avoid data type conversions and copies
45
 *    -- optimized compression for segmented rasters (10-15x lossless)
46
 *    -- micro block is 8x8 fixed, only gets doubled to 16x16 if bit rate < 1 bpp
47
 *    -- cnt is replaced by bit mask
48
 *    -- Lerc blob header has data range [min, max]
49
 *    -- harden consistency checks to detect if the byte blob has been tampered with
50
 *    -- drop support for big endian, this is legacy now
51
 *
52
 *    Lerc2 v2
53
 *
54
 *    -- add Huffman coding for better lossless compression of 8 bit data types Char, Byte
55
 *
56
 *    Lerc2 v3
57
 *
58
 *    -- add checksum for the entire byte blob, for more rigorous detection of compressed data corruption
59
 *    -- for the main bit stuffing routine, use an extra uint buffer for guaranteed memory alignment
60
 *    -- this also allows dropping the NumExtraBytesToAllocate functions
61
 *
62
 *    Lerc2 v4
63
 *
64
 *    -- allow array per pixel, nDim values per pixel. Such as RGB, complex number, or larger arrays per pixel
65
 *    -- extend Huffman coding for 8 bit data types from delta only to trying both delta and orig
66
 *    -- for integer data types, allow to drop bit planes containing only random noise
67
 *
68
 */
69
70
class Lerc2
71
{
72
public:
73
  Lerc2();
74
  Lerc2(int nDim, int nCols, int nRows, const Byte* pMaskBits = nullptr);    // valid / invalid bits as byte array
75
39.4k
  ~Lerc2()  {}
76
77
  bool SetEncoderToOldVersion(int version);    // call this to encode compatible to an old decoder
78
79
  bool Set(int nDim, int nCols, int nRows, const Byte* pMaskBits = nullptr);
80
81
  template<class T>
82
  unsigned int ComputeNumBytesNeededToWrite(const T* arr, double maxZError, bool encodeMask);
83
84
  //static unsigned int MinNumBytesNeededToReadHeader();
85
86
  /// dst buffer already allocated;  byte ptr is moved like a file pointer
87
  template<class T>
88
  bool Encode(const T* arr, Byte** ppByte);
89
90
  // data types supported by Lerc2
91
  enum DataType {DT_Char = 0, DT_Byte, DT_Short, DT_UShort, DT_Int, DT_UInt, DT_Float, DT_Double, DT_Undefined};
92
93
  struct HeaderInfo
94
  {
95
    int version;
96
    unsigned int checksum;
97
    int nRows,
98
        nCols,
99
        nDim,
100
        numValidPixel,
101
        microBlockSize,
102
        blobSize;
103
104
    DataType dt;
105
106
    double  maxZError,
107
            zMin,    // if nDim > 1, this is the overall range
108
            zMax;
109
110
208k
    void RawInit()  { memset(this, 0, sizeof(struct HeaderInfo)); }
111
112
23.3k
    bool TryHuffman() const  { return version > 1 && (dt == DT_Byte || dt == DT_Char) && maxZError == 0.5; }
113
  };
114
115
  static bool GetHeaderInfo(const Byte* pByte, size_t nBytesRemaining, struct HeaderInfo& headerInfo);
116
117
  /// dst buffer already allocated;  byte ptr is moved like a file pointer
118
  template<class T>
119
  bool Decode(const Byte** ppByte, size_t& nBytesRemaining, T* arr, Byte* pMaskBits = nullptr);    // if mask ptr is not 0, mask bits are returned (even if all valid or same as previous)
120
121
private:
122
  static const int kCurrVersion = 4;    // 2: added Huffman coding to 8 bit types DT_Char, DT_Byte;
123
                                        // 3: changed the bit stuffing to using a uint aligned buffer,
124
                                        //    added Fletcher32 checksum
125
                                        // 4: allow nDim values per pixel
126
127
  enum ImageEncodeMode { IEM_Tiling = 0, IEM_DeltaHuffman, IEM_Huffman };
128
  enum BlockEncodeMode { BEM_RawBinary = 0, BEM_BitStuffSimple, BEM_BitStuffLUT };
129
130
  int         m_microBlockSize,
131
              m_maxValToQuantize;
132
  BitMask     m_bitMask;
133
  HeaderInfo  m_headerInfo;
134
  BitStuffer2 m_bitStuffer2;
135
  bool        m_encodeMask,
136
              m_writeDataOneSweep;
137
  ImageEncodeMode  m_imageEncodeMode;
138
139
  std::vector<double> m_zMinVec, m_zMaxVec;
140
  std::vector<std::pair<unsigned short, unsigned int> > m_huffmanCodes;    // <= 256 codes, 1.5 kB
141
142
private:
143
202k
  static std::string FileKey()  { return "Lerc2 "; }
144
169k
  static bool IsLittleEndianSystem()  { int n = 1;  return (1 == *((Byte*)&n)) && (4 == sizeof(int)); }
145
  void Init();
146
147
  static unsigned int ComputeNumBytesHeaderToWrite(const struct HeaderInfo& hd);
148
  static bool WriteHeader(Byte** ppByte, const struct HeaderInfo& hd);
149
  static bool ReadHeader(const Byte** ppByte, size_t& nBytesRemaining, struct HeaderInfo& hd);
150
151
  bool WriteMask(Byte** ppByte) const;
152
  bool ReadMask(const Byte** ppByte, size_t& nBytesRemaining);
153
154
  bool DoChecksOnEncode(Byte* pBlobBegin, Byte* pBlobEnd) const;
155
  static unsigned int ComputeChecksumFletcher32(const Byte* pByte, int len);
156
157
  static void AddUIntToCounts(int* pCounts, unsigned int val, int nBits);
158
  static void AddIntToCounts(int* pCounts, int val, int nBits);
159
160
  template<class T>
161
  bool TryBitPlaneCompression(const T* data, double eps, double& newMaxZError) const;
162
163
  template<class T>
164
  bool WriteDataOneSweep(const T* data, Byte** ppByte) const;
165
166
  template<class T>
167
  bool ReadDataOneSweep(const Byte** ppByte, size_t& nBytesRemaining, T* data) const;
168
169
  template<class T>
170
  bool WriteTiles(const T* data, Byte** ppByte, int& numBytes, std::vector<double>& zMinVec, std::vector<double>& zMaxVec) const;
171
172
  template<class T>
173
  bool ReadTiles(const Byte** ppByte, size_t& nBytesRemaining, T* data) const;
174
175
  template<class T>
176
  bool GetValidDataAndStats(const T* data, int i0, int i1, int j0, int j1, int iDim,
177
    T* dataBuf, T& zMinA, T& zMaxA, int& numValidPixel, bool& tryLutA) const;
178
179
  static double ComputeMaxVal(double zMin, double zMax, double maxZError);
180
181
  template<class T>
182
  bool NeedToQuantize(int numValidPixel, T zMin, T zMax) const;
183
184
  template<class T>
185
  bool Quantize(const T* dataBuf, int num, T zMin, std::vector<unsigned int>& quantVec) const;
186
187
  template<class T>
188
  int NumBytesTile(int numValidPixel, T zMin, T zMax, bool tryLut, BlockEncodeMode& blockEncodeMode,
189
                   const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const;
190
191
  template<class T>
192
  bool WriteTile(const T* dataBuf, int num, Byte** ppByte, int& numBytesWritten, int j0, T zMin, T zMax,
193
    const std::vector<unsigned int>& quantVec, BlockEncodeMode blockEncodeMode,
194
    const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const;
195
196
  template<class T>
197
  bool ReadTile(const Byte** ppByte, size_t& nBytesRemaining, T* data, int i0, int i1, int j0, int j1, int iDim,
198
                std::vector<unsigned int>& bufferVec) const;
199
200
  template<class T>
201
  int TypeCode(T z, DataType& dtUsed) const;
202
203
  DataType GetDataTypeUsed(int typeCode) const;
204
205
  static DataType ValidateDataType(int dt);
206
207
  static bool WriteVariableDataType(Byte** ppByte, double z, DataType dtUsed);
208
209
  static double ReadVariableDataType(const Byte** ppByte, DataType dtUsed);
210
211
  template<class T> DataType GetDataType(T z) const;
212
213
  static unsigned int GetMaxValToQuantize(DataType dt);
214
215
  static unsigned int GetDataTypeSize(DataType dt);
216
217
  static void SortQuantArray(const std::vector<unsigned int>& quantVec,
218
    std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec);
219
220
  template<class T>
221
  void ComputeHuffmanCodes(const T* data, int& numBytes, ImageEncodeMode& imageEncodeMode,
222
    std::vector<std::pair<unsigned short, unsigned int> >& codes) const;
223
224
  template<class T>
225
  void ComputeHistoForHuffman(const T* data, std::vector<int>& histo, std::vector<int>& deltaHisto) const;
226
227
  template<class T>
228
  bool EncodeHuffman(const T* data, Byte** ppByte) const;
229
230
  template<class T>
231
  bool DecodeHuffman(const Byte** ppByte, size_t& nBytesRemaining, T* data) const;
232
233
  template<class T>
234
  bool WriteMinMaxRanges(const T* data, Byte** ppByte) const;
235
236
  template<class T>
237
  bool ReadMinMaxRanges(const Byte** ppByte, size_t& nBytesRemaining, const T* data);
238
239
  bool CheckMinMaxRanges(bool& minMaxEqual) const;
240
241
  template<class T>
242
  bool FillConstImage(T* data) const;
243
};
244
245
// -------------------------------------------------------------------------- ;
246
// -------------------------------------------------------------------------- ;
247
248
template<class T>
249
unsigned int Lerc2::ComputeNumBytesNeededToWrite(const T* arr, double maxZError, bool encodeMask)
250
0
{
251
0
  if (!arr || !IsLittleEndianSystem())
252
0
    return 0;
253
254
  // header
255
0
  unsigned int nBytesHeaderMask = ComputeNumBytesHeaderToWrite(m_headerInfo);
256
257
  // valid / invalid mask
258
0
  int numValid = m_headerInfo.numValidPixel;
259
0
  int numTotal = m_headerInfo.nCols * m_headerInfo.nRows;
260
261
0
  bool needMask = numValid > 0 && numValid < numTotal;
262
263
0
  m_encodeMask = encodeMask;
264
265
0
  nBytesHeaderMask += 1 * sizeof(int);    // the mask encode numBytes
266
267
0
  if (needMask && encodeMask)
268
0
  {
269
0
    RLE rle;
270
0
    size_t n = rle.computeNumBytesRLE((const Byte*)m_bitMask.Bits(), m_bitMask.Size());
271
0
    nBytesHeaderMask += (unsigned int)n;
272
0
  }
273
274
0
  m_headerInfo.dt = GetDataType(arr[0]);
275
276
0
  if (m_headerInfo.dt == DT_Undefined)
277
0
    return 0;
278
279
0
  if (maxZError == 777)    // cheat code
280
0
    maxZError = -0.01;
281
282
0
  if (m_headerInfo.dt < DT_Float)    // integer types
283
0
  {
284
    // interpret a negative maxZError as bit plane epsilon; dflt = 0.01;
285
0
    if (maxZError < 0 && (!TryBitPlaneCompression(arr, -maxZError, maxZError)))
286
0
      maxZError = 0;
287
288
0
    maxZError = std::max(0.5, floor(maxZError));
289
0
  }
290
0
  else if (maxZError < 0)    // don't allow bit plane compression for float or double yet
291
0
    return 0;
292
293
0
  m_headerInfo.maxZError = maxZError;
294
0
  m_headerInfo.zMin = 0;
295
0
  m_headerInfo.zMax = 0;
296
0
  m_headerInfo.microBlockSize = m_microBlockSize;
297
0
  m_headerInfo.blobSize = nBytesHeaderMask;
298
299
0
  if (numValid == 0)
300
0
    return nBytesHeaderMask;
301
302
0
  m_maxValToQuantize = GetMaxValToQuantize(m_headerInfo.dt);
303
304
0
  Byte* ptr = nullptr;    // only emulate the writing and just count the bytes needed
305
0
  int nBytesTiling = 0;
306
307
0
  if (!WriteTiles(arr, &ptr, nBytesTiling, m_zMinVec, m_zMaxVec))    // also fills the min max ranges
308
0
    return 0;
309
310
0
  m_headerInfo.zMin = *std::min_element(m_zMinVec.begin(), m_zMinVec.end());
311
0
  m_headerInfo.zMax = *std::max_element(m_zMaxVec.begin(), m_zMaxVec.end());
312
313
0
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
314
0
    return nBytesHeaderMask;
315
316
0
  int nDim = m_headerInfo.nDim;
317
318
0
  if (m_headerInfo.version >= 4)
319
0
  {
320
    // add the min max ranges behind the mask and before the main data;
321
    // so we do not write it if no valid pixel or all same value const
322
0
    m_headerInfo.blobSize += 2 * nDim * sizeof(T);
323
324
0
    bool minMaxEqual = false;
325
0
    if (!CheckMinMaxRanges(minMaxEqual))
326
0
      return 0;
327
328
0
    if (minMaxEqual)
329
0
      return m_headerInfo.blobSize;    // all nDim bands are const
330
0
  }
331
332
  // data
333
0
  m_imageEncodeMode = IEM_Tiling;
334
0
  int nBytesData = nBytesTiling;
335
0
  int nBytesHuffman = 0;
336
337
0
  if (m_headerInfo.TryHuffman())
338
0
  {
339
0
    ImageEncodeMode huffmanEncMode;
340
0
    ComputeHuffmanCodes(arr, nBytesHuffman, huffmanEncMode, m_huffmanCodes);    // save Huffman codes for later use
341
342
0
    if (!m_huffmanCodes.empty() && nBytesHuffman < nBytesTiling)
343
0
    {
344
0
      m_imageEncodeMode = huffmanEncMode;
345
0
      nBytesData = nBytesHuffman;
346
0
    }
347
0
    else
348
0
      m_huffmanCodes.resize(0);
349
0
  }
350
351
0
  m_writeDataOneSweep = false;
352
0
  int nBytesDataOneSweep = (int)(numValid * nDim * sizeof(T));
353
354
0
  {
355
    // try with double block size to reduce block header overhead, if
356
0
    if ( (nBytesTiling * 8 < numTotal * nDim * 2)    // resulting bit rate < x (2 bpp)
357
0
      && (nBytesTiling < 4 * nBytesDataOneSweep)     // bit stuffing is effective
358
0
      && (nBytesHuffman == 0 || nBytesTiling < 2 * nBytesHuffman) )    // not much worse than huffman (otherwise huffman wins anyway)
359
0
    {
360
0
      m_headerInfo.microBlockSize = m_microBlockSize * 2;
361
362
0
      std::vector<double> zMinVec, zMaxVec;
363
0
      int nBytes2 = 0;
364
0
      if (!WriteTiles(arr, &ptr, nBytes2, zMinVec, zMaxVec))    // no huffman in here anymore
365
0
        return 0;
366
367
0
      if (nBytes2 <= nBytesData)
368
0
      {
369
0
        nBytesData = nBytes2;
370
0
        m_imageEncodeMode = IEM_Tiling;
371
0
        m_huffmanCodes.resize(0);
372
0
      }
373
0
      else
374
0
      {
375
0
        m_headerInfo.microBlockSize = m_microBlockSize;    // reset to orig
376
0
      }
377
0
    }
378
0
  }
379
380
0
  if (m_headerInfo.TryHuffman())
381
0
    nBytesData += 1;    // flag for image encode mode
382
383
0
  if (nBytesDataOneSweep <= nBytesData)
384
0
  {
385
0
    m_writeDataOneSweep = true;    // fallback: write data binary uncompressed in one sweep
386
0
    m_headerInfo.blobSize += 1 + nBytesDataOneSweep;    // header, mask, min max ranges, flag, data one sweep
387
0
  }
388
0
  else
389
0
  {
390
0
    m_writeDataOneSweep = false;
391
0
    m_headerInfo.blobSize += 1 + nBytesData;    // header, mask, min max ranges, flag(s), data
392
0
  }
393
394
0
  return m_headerInfo.blobSize;
395
0
}
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<signed char>(signed char const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<unsigned char>(unsigned char const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<short>(short const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<unsigned short>(unsigned short const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<int>(int const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<unsigned int>(unsigned int const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<float>(float const*, double, bool)
Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<double>(double const*, double, bool)
396
397
// -------------------------------------------------------------------------- ;
398
399
template<class T>
400
bool Lerc2::Encode(const T* arr, Byte** ppByte)
401
0
{
402
0
  if (!arr || !ppByte || !IsLittleEndianSystem())
403
0
    return false;
404
405
0
  Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
406
407
0
  if (!WriteHeader(ppByte, m_headerInfo))
408
0
    return false;
409
410
0
  if (!WriteMask(ppByte))
411
0
    return false;
412
413
0
  if (m_headerInfo.numValidPixel == 0 || m_headerInfo.zMin == m_headerInfo.zMax)
414
0
  {
415
0
    return DoChecksOnEncode(ptrBlob, *ppByte);
416
0
  }
417
418
0
  if (m_headerInfo.version >= 4)
419
0
  {
420
0
    if (!WriteMinMaxRanges(arr, ppByte))
421
0
      return false;
422
423
0
    bool minMaxEqual = false;
424
0
    if (!CheckMinMaxRanges(minMaxEqual))
425
0
      return false;
426
427
0
    if (minMaxEqual)
428
0
      return DoChecksOnEncode(ptrBlob, *ppByte);
429
0
  }
430
431
0
  **ppByte = m_writeDataOneSweep ? 1 : 0;    // write flag
432
0
  (*ppByte)++;
433
434
0
  if (!m_writeDataOneSweep)
435
0
  {
436
0
    if (m_headerInfo.TryHuffman())
437
0
    {
438
0
      **ppByte = (Byte)m_imageEncodeMode;    // Huffman or tiling encode mode
439
0
      (*ppByte)++;
440
441
0
      if (!m_huffmanCodes.empty())   // Huffman, no tiling
442
0
      {
443
0
        if (m_imageEncodeMode != IEM_DeltaHuffman && m_imageEncodeMode != IEM_Huffman)
444
0
          return false;
445
446
0
        if (!EncodeHuffman(arr, ppByte))    // data bit stuffed
447
0
          return false;
448
449
0
        return DoChecksOnEncode(ptrBlob, *ppByte);
450
0
      }
451
0
    }
452
453
0
    int numBytes = 0;
454
0
    std::vector<double> zMinVec, zMaxVec;
455
0
    if (!WriteTiles(arr, ppByte, numBytes, zMinVec, zMaxVec))
456
0
      return false;
457
0
  }
458
0
  else
459
0
  {
460
0
    if (!WriteDataOneSweep(arr, ppByte))
461
0
      return false;
462
0
  }
463
464
0
  return DoChecksOnEncode(ptrBlob, *ppByte);
465
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<signed char>(signed char const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<unsigned char>(unsigned char const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<short>(short const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<unsigned short>(unsigned short const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<int>(int const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<unsigned int>(unsigned int const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<float>(float const*, unsigned char**)
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<double>(double const*, unsigned char**)
466
467
// -------------------------------------------------------------------------- ;
468
469
template<class T>
470
bool Lerc2::Decode(const Byte** ppByte, size_t& nBytesRemaining, T* arr, Byte* pMaskBits)
471
39.0k
{
472
39.0k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
39.0k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
39.0k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
39.0k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
39.0k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
39.0k
  if (m_headerInfo.version >= 3)
485
33.6k
  {
486
33.6k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
33.6k
    if (m_headerInfo.blobSize < nBytes)
488
203
      return false;
489
33.4k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
33.4k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
33.4k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
33.4k
  }
498
499
38.8k
  if (!ReadMask(ppByte, nBytesRemaining))
500
6.60k
    return false;
501
502
32.2k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
3.32k
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
32.2k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
32.2k
  if (m_headerInfo.numValidPixel == 0)
508
263
    return true;
509
510
31.9k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
1.24k
  {
512
1.24k
    if (!FillConstImage(arr))
513
0
      return false;
514
515
1.24k
    return true;
516
1.24k
  }
517
518
30.7k
  if (m_headerInfo.version >= 4)
519
25.3k
  {
520
25.3k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
1.08k
      return false;
522
523
24.2k
    bool minMaxEqual = false;
524
24.2k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
24.2k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
502
    {
529
502
      if (!FillConstImage(arr))
530
0
        return false;
531
532
502
      return true;    // done
533
502
    }
534
24.2k
  }
535
536
29.1k
  if (nBytesRemaining < 1)
537
242
    return false;
538
539
28.8k
  Byte readDataOneSweep = **ppByte;    // read flag
540
28.8k
  (*ppByte)++;
541
28.8k
  nBytesRemaining--;
542
543
28.8k
  if (!readDataOneSweep)
544
23.3k
  {
545
23.3k
    if (m_headerInfo.TryHuffman())
546
10.8k
    {
547
10.8k
      if (nBytesRemaining < 1)
548
11
        return false;
549
550
10.8k
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
10.8k
      (*ppByte)++;
552
10.8k
      nBytesRemaining--;
553
554
10.8k
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
133
        return false;
556
557
10.7k
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
10.7k
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
9.92k
      {
561
9.92k
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
9.28k
          return false;
563
564
633
        return true;    // done.
565
9.92k
      }
566
10.7k
    }
567
568
13.3k
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
12.6k
      return false;
570
13.3k
  }
571
5.49k
  else
572
5.49k
  {
573
5.49k
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
3.14k
      return false;
575
5.49k
  }
576
577
2.98k
  return true;
578
28.8k
}
bool GDAL_LercNS::Lerc2::Decode<signed char>(unsigned char const**, unsigned long&, signed char*, unsigned char*)
Line
Count
Source
471
4.79k
{
472
4.79k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
4.79k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
4.79k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
4.79k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
4.79k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
4.79k
  if (m_headerInfo.version >= 3)
485
3.79k
  {
486
3.79k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
3.79k
    if (m_headerInfo.blobSize < nBytes)
488
0
      return false;
489
3.79k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
3.79k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
3.79k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
3.79k
  }
498
499
4.79k
  if (!ReadMask(ppByte, nBytesRemaining))
500
101
    return false;
501
502
4.69k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
4.69k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
4.69k
  if (m_headerInfo.numValidPixel == 0)
508
24
    return true;
509
510
4.66k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
359
  {
512
359
    if (!FillConstImage(arr))
513
0
      return false;
514
515
359
    return true;
516
359
  }
517
518
4.30k
  if (m_headerInfo.version >= 4)
519
3.63k
  {
520
3.63k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
0
      return false;
522
523
3.63k
    bool minMaxEqual = false;
524
3.63k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
3.63k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
72
    {
529
72
      if (!FillConstImage(arr))
530
0
        return false;
531
532
72
      return true;    // done
533
72
    }
534
3.63k
  }
535
536
4.23k
  if (nBytesRemaining < 1)
537
0
    return false;
538
539
4.23k
  Byte readDataOneSweep = **ppByte;    // read flag
540
4.23k
  (*ppByte)++;
541
4.23k
  nBytesRemaining--;
542
543
4.23k
  if (!readDataOneSweep)
544
3.64k
  {
545
3.64k
    if (m_headerInfo.TryHuffman())
546
2.47k
    {
547
2.47k
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
2.47k
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
2.47k
      (*ppByte)++;
552
2.47k
      nBytesRemaining--;
553
554
2.47k
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
26
        return false;
556
557
2.45k
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
2.45k
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
2.42k
      {
561
2.42k
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
2.33k
          return false;
563
564
84
        return true;    // done.
565
2.42k
      }
566
2.45k
    }
567
568
1.19k
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
1.17k
      return false;
570
1.19k
  }
571
594
  else
572
594
  {
573
594
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
42
      return false;
575
594
  }
576
577
575
  return true;
578
4.23k
}
bool GDAL_LercNS::Lerc2::Decode<unsigned char>(unsigned char const**, unsigned long&, unsigned char*, unsigned char*)
Line
Count
Source
471
16.4k
{
472
16.4k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
16.4k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
16.4k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
16.4k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
16.4k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
16.4k
  if (m_headerInfo.version >= 3)
485
13.1k
  {
486
13.1k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
13.1k
    if (m_headerInfo.blobSize < nBytes)
488
28
      return false;
489
13.1k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
13.1k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
13.1k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
13.1k
  }
498
499
16.3k
  if (!ReadMask(ppByte, nBytesRemaining))
500
837
    return false;
501
502
15.5k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
3.32k
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
15.5k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
15.5k
  if (m_headerInfo.numValidPixel == 0)
508
146
    return true;
509
510
15.4k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
608
  {
512
608
    if (!FillConstImage(arr))
513
0
      return false;
514
515
608
    return true;
516
608
  }
517
518
14.7k
  if (m_headerInfo.version >= 4)
519
12.2k
  {
520
12.2k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
221
      return false;
522
523
12.0k
    bool minMaxEqual = false;
524
12.0k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
12.0k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
151
    {
529
151
      if (!FillConstImage(arr))
530
0
        return false;
531
532
151
      return true;    // done
533
151
    }
534
12.0k
  }
535
536
14.4k
  if (nBytesRemaining < 1)
537
67
    return false;
538
539
14.3k
  Byte readDataOneSweep = **ppByte;    // read flag
540
14.3k
  (*ppByte)++;
541
14.3k
  nBytesRemaining--;
542
543
14.3k
  if (!readDataOneSweep)
544
10.8k
  {
545
10.8k
    if (m_headerInfo.TryHuffman())
546
8.38k
    {
547
8.38k
      if (nBytesRemaining < 1)
548
11
        return false;
549
550
8.37k
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
8.37k
      (*ppByte)++;
552
8.37k
      nBytesRemaining--;
553
554
8.37k
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
107
        return false;
556
557
8.26k
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
8.26k
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
7.49k
      {
561
7.49k
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
6.95k
          return false;
563
564
549
        return true;    // done.
565
7.49k
      }
566
8.26k
    }
567
568
3.21k
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
2.72k
      return false;
570
3.21k
  }
571
3.52k
  else
572
3.52k
  {
573
3.52k
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
2.03k
      return false;
575
3.52k
  }
576
577
1.98k
  return true;
578
14.3k
}
bool GDAL_LercNS::Lerc2::Decode<short>(unsigned char const**, unsigned long&, short*, unsigned char*)
Line
Count
Source
471
2.60k
{
472
2.60k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
2.60k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
2.60k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
2.60k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
2.60k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
2.60k
  if (m_headerInfo.version >= 3)
485
2.55k
  {
486
2.55k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
2.55k
    if (m_headerInfo.blobSize < nBytes)
488
30
      return false;
489
2.52k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
2.52k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
2.52k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
2.52k
  }
498
499
2.57k
  if (!ReadMask(ppByte, nBytesRemaining))
500
328
    return false;
501
502
2.25k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
2.25k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
2.25k
  if (m_headerInfo.numValidPixel == 0)
508
32
    return true;
509
510
2.21k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
60
  {
512
60
    if (!FillConstImage(arr))
513
0
      return false;
514
515
60
    return true;
516
60
  }
517
518
2.15k
  if (m_headerInfo.version >= 4)
519
2.09k
  {
520
2.09k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
148
      return false;
522
523
1.95k
    bool minMaxEqual = false;
524
1.95k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
1.95k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
81
    {
529
81
      if (!FillConstImage(arr))
530
0
        return false;
531
532
81
      return true;    // done
533
81
    }
534
1.95k
  }
535
536
1.92k
  if (nBytesRemaining < 1)
537
22
    return false;
538
539
1.90k
  Byte readDataOneSweep = **ppByte;    // read flag
540
1.90k
  (*ppByte)++;
541
1.90k
  nBytesRemaining--;
542
543
1.90k
  if (!readDataOneSweep)
544
1.80k
  {
545
1.80k
    if (m_headerInfo.TryHuffman())
546
0
    {
547
0
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
0
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
0
      (*ppByte)++;
552
0
      nBytesRemaining--;
553
554
0
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
0
        return false;
556
557
0
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
0
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
0
      {
561
0
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
0
          return false;
563
564
0
        return true;    // done.
565
0
      }
566
0
    }
567
568
1.80k
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
1.75k
      return false;
570
1.80k
  }
571
101
  else
572
101
  {
573
101
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
72
      return false;
575
101
  }
576
577
85
  return true;
578
1.90k
}
bool GDAL_LercNS::Lerc2::Decode<unsigned short>(unsigned char const**, unsigned long&, unsigned short*, unsigned char*)
Line
Count
Source
471
8.43k
{
472
8.43k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
8.43k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
8.43k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
8.43k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
8.43k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
8.43k
  if (m_headerInfo.version >= 3)
485
8.38k
  {
486
8.38k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
8.38k
    if (m_headerInfo.blobSize < nBytes)
488
32
      return false;
489
8.35k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
8.35k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
8.35k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
8.35k
  }
498
499
8.40k
  if (!ReadMask(ppByte, nBytesRemaining))
500
4.87k
    return false;
501
502
3.52k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
3.52k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
3.52k
  if (m_headerInfo.numValidPixel == 0)
508
32
    return true;
509
510
3.49k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
39
  {
512
39
    if (!FillConstImage(arr))
513
0
      return false;
514
515
39
    return true;
516
39
  }
517
518
3.45k
  if (m_headerInfo.version >= 4)
519
2.31k
  {
520
2.31k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
141
      return false;
522
523
2.16k
    bool minMaxEqual = false;
524
2.16k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
2.16k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
119
    {
529
119
      if (!FillConstImage(arr))
530
0
        return false;
531
532
119
      return true;    // done
533
119
    }
534
2.16k
  }
535
536
3.19k
  if (nBytesRemaining < 1)
537
37
    return false;
538
539
3.16k
  Byte readDataOneSweep = **ppByte;    // read flag
540
3.16k
  (*ppByte)++;
541
3.16k
  nBytesRemaining--;
542
543
3.16k
  if (!readDataOneSweep)
544
2.73k
  {
545
2.73k
    if (m_headerInfo.TryHuffman())
546
0
    {
547
0
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
0
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
0
      (*ppByte)++;
552
0
      nBytesRemaining--;
553
554
0
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
0
        return false;
556
557
0
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
0
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
0
      {
561
0
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
0
          return false;
563
564
0
        return true;    // done.
565
0
      }
566
0
    }
567
568
2.73k
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
2.67k
      return false;
570
2.73k
  }
571
427
  else
572
427
  {
573
427
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
360
      return false;
575
427
  }
576
577
122
  return true;
578
3.16k
}
bool GDAL_LercNS::Lerc2::Decode<int>(unsigned char const**, unsigned long&, int*, unsigned char*)
Line
Count
Source
471
1.58k
{
472
1.58k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
1.58k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
1.58k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
1.58k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
1.58k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
1.58k
  if (m_headerInfo.version >= 3)
485
1.48k
  {
486
1.48k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
1.48k
    if (m_headerInfo.blobSize < nBytes)
488
32
      return false;
489
1.45k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
1.45k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
1.45k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
1.45k
  }
498
499
1.54k
  if (!ReadMask(ppByte, nBytesRemaining))
500
170
    return false;
501
502
1.37k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
1.37k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
1.37k
  if (m_headerInfo.numValidPixel == 0)
508
5
    return true;
509
510
1.37k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
28
  {
512
28
    if (!FillConstImage(arr))
513
0
      return false;
514
515
28
    return true;
516
28
  }
517
518
1.34k
  if (m_headerInfo.version >= 4)
519
1.25k
  {
520
1.25k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
211
      return false;
522
523
1.03k
    bool minMaxEqual = false;
524
1.03k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
1.03k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
23
    {
529
23
      if (!FillConstImage(arr))
530
0
        return false;
531
532
23
      return true;    // done
533
23
    }
534
1.03k
  }
535
536
1.11k
  if (nBytesRemaining < 1)
537
22
    return false;
538
539
1.08k
  Byte readDataOneSweep = **ppByte;    // read flag
540
1.08k
  (*ppByte)++;
541
1.08k
  nBytesRemaining--;
542
543
1.08k
  if (!readDataOneSweep)
544
979
  {
545
979
    if (m_headerInfo.TryHuffman())
546
0
    {
547
0
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
0
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
0
      (*ppByte)++;
552
0
      nBytesRemaining--;
553
554
0
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
0
        return false;
556
557
0
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
0
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
0
      {
561
0
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
0
          return false;
563
564
0
        return true;    // done.
565
0
      }
566
0
    }
567
568
979
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
977
      return false;
570
979
  }
571
110
  else
572
110
  {
573
110
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
88
      return false;
575
110
  }
576
577
24
  return true;
578
1.08k
}
bool GDAL_LercNS::Lerc2::Decode<unsigned int>(unsigned char const**, unsigned long&, unsigned int*, unsigned char*)
Line
Count
Source
471
3.25k
{
472
3.25k
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
3.25k
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
3.25k
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
3.25k
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
3.25k
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
3.25k
  if (m_headerInfo.version >= 3)
485
2.41k
  {
486
2.41k
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
2.41k
    if (m_headerInfo.blobSize < nBytes)
488
31
      return false;
489
2.38k
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
2.38k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
2.38k
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
2.38k
  }
498
499
3.22k
  if (!ReadMask(ppByte, nBytesRemaining))
500
144
    return false;
501
502
3.08k
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
3.08k
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
3.08k
  if (m_headerInfo.numValidPixel == 0)
508
22
    return true;
509
510
3.05k
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
99
  {
512
99
    if (!FillConstImage(arr))
513
0
      return false;
514
515
99
    return true;
516
99
  }
517
518
2.95k
  if (m_headerInfo.version >= 4)
519
2.23k
  {
520
2.23k
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
91
      return false;
522
523
2.14k
    bool minMaxEqual = false;
524
2.14k
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
2.14k
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
21
    {
529
21
      if (!FillConstImage(arr))
530
0
        return false;
531
532
21
      return true;    // done
533
21
    }
534
2.14k
  }
535
536
2.84k
  if (nBytesRemaining < 1)
537
34
    return false;
538
539
2.81k
  Byte readDataOneSweep = **ppByte;    // read flag
540
2.81k
  (*ppByte)++;
541
2.81k
  nBytesRemaining--;
542
543
2.81k
  if (!readDataOneSweep)
544
2.24k
  {
545
2.24k
    if (m_headerInfo.TryHuffman())
546
0
    {
547
0
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
0
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
0
      (*ppByte)++;
552
0
      nBytesRemaining--;
553
554
0
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
0
        return false;
556
557
0
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
0
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
0
      {
561
0
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
0
          return false;
563
564
0
        return true;    // done.
565
0
      }
566
0
    }
567
568
2.24k
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
2.23k
      return false;
570
2.24k
  }
571
570
  else
572
570
  {
573
570
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
446
      return false;
575
570
  }
576
577
133
  return true;
578
2.81k
}
bool GDAL_LercNS::Lerc2::Decode<float>(unsigned char const**, unsigned long&, float*, unsigned char*)
Line
Count
Source
471
967
{
472
967
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
967
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
967
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
967
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
967
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
967
  if (m_headerInfo.version >= 3)
485
873
  {
486
873
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
873
    if (m_headerInfo.blobSize < nBytes)
488
29
      return false;
489
844
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
844
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
844
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
844
  }
498
499
938
  if (!ReadMask(ppByte, nBytesRemaining))
500
80
    return false;
501
502
858
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
858
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
858
  if (m_headerInfo.numValidPixel == 0)
508
1
    return true;
509
510
857
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
22
  {
512
22
    if (!FillConstImage(arr))
513
0
      return false;
514
515
22
    return true;
516
22
  }
517
518
835
  if (m_headerInfo.version >= 4)
519
755
  {
520
755
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
120
      return false;
522
523
635
    bool minMaxEqual = false;
524
635
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
635
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
19
    {
529
19
      if (!FillConstImage(arr))
530
0
        return false;
531
532
19
      return true;    // done
533
19
    }
534
635
  }
535
536
696
  if (nBytesRemaining < 1)
537
34
    return false;
538
539
662
  Byte readDataOneSweep = **ppByte;    // read flag
540
662
  (*ppByte)++;
541
662
  nBytesRemaining--;
542
543
662
  if (!readDataOneSweep)
544
588
  {
545
588
    if (m_headerInfo.TryHuffman())
546
0
    {
547
0
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
0
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
0
      (*ppByte)++;
552
0
      nBytesRemaining--;
553
554
0
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
0
        return false;
556
557
0
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
0
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
0
      {
561
0
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
0
          return false;
563
564
0
        return true;    // done.
565
0
      }
566
0
    }
567
568
588
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
585
      return false;
570
588
  }
571
74
  else
572
74
  {
573
74
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
46
      return false;
575
74
  }
576
577
31
  return true;
578
662
}
bool GDAL_LercNS::Lerc2::Decode<double>(unsigned char const**, unsigned long&, double*, unsigned char*)
Line
Count
Source
471
986
{
472
986
  if (!arr || !ppByte || !IsLittleEndianSystem())
473
0
    return false;
474
475
986
  const Byte* ptrBlob = *ppByte;    // keep a ptr to the start of the blob
476
986
  size_t nBytesRemaining00 = nBytesRemaining;
477
478
986
  if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo))
479
0
    return false;
480
481
986
  if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize)
482
0
    return false;
483
484
986
  if (m_headerInfo.version >= 3)
485
930
  {
486
930
    int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int));    // start right after the checksum entry
487
930
    if (m_headerInfo.blobSize < nBytes)
488
21
      return false;
489
909
    unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes);
490
909
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
491
    // For fuzzing, ignore checksum verification
492
909
    (void)checksum;
493
#else
494
    if (checksum != m_headerInfo.checksum)
495
      return false;
496
#endif
497
909
  }
498
499
965
  if (!ReadMask(ppByte, nBytesRemaining))
500
77
    return false;
501
502
888
  if (pMaskBits)    // return proper mask bits even if they were not stored
503
0
    memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size());
504
505
888
  memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T));
506
507
888
  if (m_headerInfo.numValidPixel == 0)
508
1
    return true;
509
510
887
  if (m_headerInfo.zMin == m_headerInfo.zMax)    // image is const
511
30
  {
512
30
    if (!FillConstImage(arr))
513
0
      return false;
514
515
30
    return true;
516
30
  }
517
518
857
  if (m_headerInfo.version >= 4)
519
812
  {
520
812
    if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr))
521
157
      return false;
522
523
655
    bool minMaxEqual = false;
524
655
    if (!CheckMinMaxRanges(minMaxEqual))
525
0
      return false;
526
527
655
    if (minMaxEqual)    // if all bands are const, fill outgoing and done
528
16
    {
529
16
      if (!FillConstImage(arr))
530
0
        return false;
531
532
16
      return true;    // done
533
16
    }
534
655
  }
535
536
684
  if (nBytesRemaining < 1)
537
26
    return false;
538
539
658
  Byte readDataOneSweep = **ppByte;    // read flag
540
658
  (*ppByte)++;
541
658
  nBytesRemaining--;
542
543
658
  if (!readDataOneSweep)
544
572
  {
545
572
    if (m_headerInfo.TryHuffman())
546
0
    {
547
0
      if (nBytesRemaining < 1)
548
0
        return false;
549
550
0
      Byte flag = **ppByte;    // read flag Huffman / Lerc2
551
0
      (*ppByte)++;
552
0
      nBytesRemaining--;
553
554
0
      if (flag > 2 || (m_headerInfo.version < 4 && flag > 1))
555
0
        return false;
556
557
0
      m_imageEncodeMode = (ImageEncodeMode)flag;
558
559
0
      if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman)
560
0
      {
561
0
        if (!DecodeHuffman(ppByte, nBytesRemaining, arr))
562
0
          return false;
563
564
0
        return true;    // done.
565
0
      }
566
0
    }
567
568
572
    if (!ReadTiles(ppByte, nBytesRemaining, arr))
569
565
      return false;
570
572
  }
571
86
  else
572
86
  {
573
86
    if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr))
574
61
      return false;
575
86
  }
576
577
32
  return true;
578
658
}
579
580
// -------------------------------------------------------------------------- ;
581
// -------------------------------------------------------------------------- ;
582
583
inline
584
void Lerc2::AddUIntToCounts(int* pCounts, unsigned int val, int nBits)
585
0
{
586
0
  pCounts[0] += val & 1;
587
0
  for (int i = 1; i < nBits; i++)
588
0
    pCounts[i] += (val >>= 1) & 1;
589
0
}
590
591
// -------------------------------------------------------------------------- ;
592
593
inline
594
void Lerc2::AddIntToCounts(int* pCounts, int val, int nBits)
595
0
{
596
0
  pCounts[0] += val & 1;
597
0
  for (int i = 1; i < nBits; i++)
598
0
    pCounts[i] += (val >>= 1) & 1;
599
0
}
600
601
// -------------------------------------------------------------------------- ;
602
603
// for the theory and math, see
604
// https://pdfs.semanticscholar.org/d064/2e2ad1a4c3b445b0d795770f604a5d9e269c.pdf
605
606
template<class T>
607
bool Lerc2::TryBitPlaneCompression(const T* data, double eps, double& newMaxZError) const
608
0
{
609
0
  newMaxZError = 0;    // lossless is the obvious fallback
610
611
0
  if (!data || eps <= 0)
612
0
    return false;
613
614
0
  const HeaderInfo& hd = m_headerInfo;
615
0
  const int nDim = hd.nDim;
616
0
  const int maxShift = 8 * GetDataTypeSize(hd.dt);
617
0
  const int minCnt = 5000;
618
619
0
  if (hd.numValidPixel < minCnt)    // not enough data for good stats
620
0
    return false;
621
622
0
  std::vector<int> cntDiffVec(nDim * maxShift, 0);
623
0
  int cnt = 0;
624
625
0
  if (nDim == 1 && hd.numValidPixel == hd.nCols * hd.nRows)    // special but common case
626
0
  {
627
0
    if (hd.dt == DT_Byte || hd.dt == DT_UShort || hd.dt == DT_UInt)    // unsigned int
628
0
    {
629
0
      for (int i = 0; i < hd.nRows - 1; i++)
630
0
        for (int k = i * hd.nCols, j = 0; j < hd.nCols - 1; j++, k++)
631
0
        {
632
0
          unsigned int c = ((unsigned int)data[k]) ^ ((unsigned int)data[k + 1]);
633
0
          AddUIntToCounts(&cntDiffVec[0], c, maxShift);
634
0
          cnt++;
635
0
          c = ((unsigned int)data[k]) ^ ((unsigned int)data[k + hd.nCols]);
636
0
          AddUIntToCounts(&cntDiffVec[0], c, maxShift);
637
0
          cnt++;
638
0
        }
639
0
    }
640
0
    else if (hd.dt == DT_Char || hd.dt == DT_Short || hd.dt == DT_Int)    // signed int
641
0
    {
642
0
      for (int i = 0; i < hd.nRows - 1; i++)
643
0
        for (int k = i * hd.nCols, j = 0; j < hd.nCols - 1; j++, k++)
644
0
        {
645
0
          int c = ((int)data[k]) ^ ((int)data[k + 1]);
646
0
          AddIntToCounts(&cntDiffVec[0], c, maxShift);
647
0
          cnt++;
648
0
          c = ((int)data[k]) ^ ((int)data[k + hd.nCols]);
649
0
          AddIntToCounts(&cntDiffVec[0], c, maxShift);
650
0
          cnt++;
651
0
        }
652
0
    }
653
0
    else
654
0
      return false;    // unsupported data type
655
0
  }
656
657
0
  else    // general case:  nDim > 1 or not all pixel valid
658
0
  {
659
0
    if (hd.dt == DT_Byte || hd.dt == DT_UShort || hd.dt == DT_UInt)    // unsigned int
660
0
    {
661
0
      for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
662
0
        for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
663
0
          if (m_bitMask.IsValid(k))
664
0
          {
665
0
            if (j < hd.nCols - 1 && m_bitMask.IsValid(k + 1))    // hori
666
0
            {
667
0
              for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift)
668
0
              {
669
0
                unsigned int c = ((unsigned int)data[m0 + iDim]) ^ ((unsigned int)data[m0 + iDim + nDim]);
670
0
                AddUIntToCounts(&cntDiffVec[s0], c, maxShift);
671
0
              }
672
0
              cnt++;
673
0
            }
674
0
            if (i < hd.nRows - 1 && m_bitMask.IsValid(k + hd.nCols))    // vert
675
0
            {
676
0
              for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift)
677
0
              {
678
0
                unsigned int c = ((unsigned int)data[m0 + iDim]) ^ ((unsigned int)data[m0 + iDim + nDim * hd.nCols]);
679
0
                AddUIntToCounts(&cntDiffVec[s0], c, maxShift);
680
0
              }
681
0
              cnt++;
682
0
            }
683
0
          }
684
0
    }
685
0
    else if (hd.dt == DT_Char || hd.dt == DT_Short || hd.dt == DT_Int)    // signed int
686
0
    {
687
0
      for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
688
0
        for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
689
0
          if (m_bitMask.IsValid(k))
690
0
          {
691
0
            if (j < hd.nCols - 1 && m_bitMask.IsValid(k + 1))    // hori
692
0
            {
693
0
              for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift)
694
0
              {
695
0
                int c = ((int)data[m0 + iDim]) ^ ((int)data[m0 + iDim + nDim]);
696
0
                AddIntToCounts(&cntDiffVec[s0], c, maxShift);
697
0
              }
698
0
              cnt++;
699
0
            }
700
0
            if (i < hd.nRows - 1 && m_bitMask.IsValid(k + hd.nCols))    // vert
701
0
            {
702
0
              for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift)
703
0
              {
704
0
                int c = ((int)data[m0 + iDim]) ^ ((int)data[m0 + iDim + nDim * hd.nCols]);
705
0
                AddIntToCounts(&cntDiffVec[s0], c, maxShift);
706
0
              }
707
0
              cnt++;
708
0
            }
709
0
          }
710
0
    }
711
0
    else
712
0
      return false;    // unsupported data type
713
0
  }
714
715
0
  if (cnt < minCnt)    // not enough data for good stats
716
0
    return false;
717
718
0
  int nCutFound = 0, lastPlaneKept = 0;
719
0
  const bool printAll = false;
720
721
0
  for (int s = maxShift - 1; s >= 0; s--)
722
0
  {
723
0
    if (printAll) printf("bit plane %2d: ", s);
724
0
    bool bCrit = true;
725
726
0
    for (int iDim = 0; iDim < nDim; iDim++)
727
0
    {
728
0
      double x = cntDiffVec[iDim * maxShift + s];
729
0
      double n = cnt;
730
0
      double m = x / n;
731
      //double stdDev = sqrt(x * x / n - m * m) / n;
732
733
      //printf("  %.4f +- %.4f  ", (float)(2 * m), (float)(2 * stdDev));
734
0
      if (printAll) printf("  %.4f ", (float)(2 * m));
735
736
0
      if (fabs(1 - 2 * m) >= eps)
737
0
        bCrit = false;
738
0
    }
739
0
    if (printAll) printf("\n");
740
741
0
    if (bCrit && nCutFound < 2)
742
0
    {
743
0
      if (nCutFound == 0)
744
0
        lastPlaneKept = s;
745
746
0
      if (nCutFound == 1 && s < lastPlaneKept - 1)
747
0
      {
748
0
        lastPlaneKept = s;
749
0
        nCutFound = 0;
750
0
        if (printAll) printf(" reset ");
751
0
      }
752
753
0
      nCutFound++;
754
0
      if (printAll && nCutFound == 1) printf("\n");
755
0
    }
756
0
  }
757
758
0
  lastPlaneKept = std::max(0, lastPlaneKept);
759
0
  if (printAll) printf("%d \n", lastPlaneKept);
760
761
0
  newMaxZError = (1 << lastPlaneKept) >> 1;    // turn lastPlaneKept into new maxZError
762
763
0
  return true;
764
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<signed char>(signed char const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<unsigned char>(unsigned char const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<short>(short const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<unsigned short>(unsigned short const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<int>(int const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<unsigned int>(unsigned int const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<float>(float const*, double, double&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<double>(double const*, double, double&) const
765
766
// -------------------------------------------------------------------------- ;
767
768
template<class T>
769
bool Lerc2::WriteDataOneSweep(const T* data, Byte** ppByte) const
770
0
{
771
0
  if (!data || !ppByte)
772
0
    return false;
773
774
0
  Byte* ptr = (*ppByte);
775
0
  const HeaderInfo& hd = m_headerInfo;
776
0
  int nDim = hd.nDim;
777
0
  int len = nDim * sizeof(T);
778
779
0
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
780
0
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
781
0
      if (m_bitMask.IsValid(k))
782
0
      {
783
0
        memcpy(ptr, &data[m0], len);
784
0
        ptr += len;
785
0
      }
786
787
0
  (*ppByte) = ptr;
788
0
  return true;
789
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<signed char>(signed char const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<unsigned char>(unsigned char const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<short>(short const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<unsigned short>(unsigned short const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<int>(int const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<unsigned int>(unsigned int const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<float>(float const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<double>(double const*, unsigned char**) const
790
791
// -------------------------------------------------------------------------- ;
792
793
template<class T>
794
bool Lerc2::ReadDataOneSweep(const Byte** ppByte, size_t& nBytesRemaining, T* data) const
795
5.49k
{
796
5.49k
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
5.49k
  const Byte* ptr = (*ppByte);
800
5.49k
  const HeaderInfo& hd = m_headerInfo;
801
5.49k
  int nDim = hd.nDim;
802
5.49k
  int len = nDim * sizeof(T);
803
804
5.49k
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
5.49k
  if (nBytesRemaining < nValidPix * len)
807
3.14k
    return false;
808
809
2.95M
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
27.2M
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
24.2M
      if (m_bitMask.IsValid(k))
812
415k
      {
813
415k
        memcpy(&data[m0], ptr, len);
814
415k
        ptr += len;
815
415k
      }
816
817
2.34k
  (*ppByte) = ptr;
818
2.34k
  nBytesRemaining -= nValidPix * len;
819
820
2.34k
  return true;
821
5.49k
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<signed char>(unsigned char const**, unsigned long&, signed char*) const
Line
Count
Source
795
594
{
796
594
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
594
  const Byte* ptr = (*ppByte);
800
594
  const HeaderInfo& hd = m_headerInfo;
801
594
  int nDim = hd.nDim;
802
594
  int len = nDim * sizeof(T);
803
804
594
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
594
  if (nBytesRemaining < nValidPix * len)
807
42
    return false;
808
809
2.05k
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
83.2k
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
81.7k
      if (m_bitMask.IsValid(k))
812
17.2k
      {
813
17.2k
        memcpy(&data[m0], ptr, len);
814
17.2k
        ptr += len;
815
17.2k
      }
816
817
552
  (*ppByte) = ptr;
818
552
  nBytesRemaining -= nValidPix * len;
819
820
552
  return true;
821
594
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<unsigned char>(unsigned char const**, unsigned long&, unsigned char*) const
Line
Count
Source
795
3.52k
{
796
3.52k
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
3.52k
  const Byte* ptr = (*ppByte);
800
3.52k
  const HeaderInfo& hd = m_headerInfo;
801
3.52k
  int nDim = hd.nDim;
802
3.52k
  int len = nDim * sizeof(T);
803
804
3.52k
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
3.52k
  if (nBytesRemaining < nValidPix * len)
807
2.03k
    return false;
808
809
1.57M
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
20.1M
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
18.5M
      if (m_bitMask.IsValid(k))
812
107k
      {
813
107k
        memcpy(&data[m0], ptr, len);
814
107k
        ptr += len;
815
107k
      }
816
817
1.49k
  (*ppByte) = ptr;
818
1.49k
  nBytesRemaining -= nValidPix * len;
819
820
1.49k
  return true;
821
3.52k
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<short>(unsigned char const**, unsigned long&, short*) const
Line
Count
Source
795
101
{
796
101
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
101
  const Byte* ptr = (*ppByte);
800
101
  const HeaderInfo& hd = m_headerInfo;
801
101
  int nDim = hd.nDim;
802
101
  int len = nDim * sizeof(T);
803
804
101
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
101
  if (nBytesRemaining < nValidPix * len)
807
72
    return false;
808
809
9.82k
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
32.6k
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
22.8k
      if (m_bitMask.IsValid(k))
812
8.24k
      {
813
8.24k
        memcpy(&data[m0], ptr, len);
814
8.24k
        ptr += len;
815
8.24k
      }
816
817
29
  (*ppByte) = ptr;
818
29
  nBytesRemaining -= nValidPix * len;
819
820
29
  return true;
821
101
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<unsigned short>(unsigned char const**, unsigned long&, unsigned short*) const
Line
Count
Source
795
427
{
796
427
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
427
  const Byte* ptr = (*ppByte);
800
427
  const HeaderInfo& hd = m_headerInfo;
801
427
  int nDim = hd.nDim;
802
427
  int len = nDim * sizeof(T);
803
804
427
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
427
  if (nBytesRemaining < nValidPix * len)
807
360
    return false;
808
809
1.37k
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
1.46M
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
1.46M
      if (m_bitMask.IsValid(k))
812
227k
      {
813
227k
        memcpy(&data[m0], ptr, len);
814
227k
        ptr += len;
815
227k
      }
816
817
67
  (*ppByte) = ptr;
818
67
  nBytesRemaining -= nValidPix * len;
819
820
67
  return true;
821
427
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<int>(unsigned char const**, unsigned long&, int*) const
Line
Count
Source
795
110
{
796
110
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
110
  const Byte* ptr = (*ppByte);
800
110
  const HeaderInfo& hd = m_headerInfo;
801
110
  int nDim = hd.nDim;
802
110
  int len = nDim * sizeof(T);
803
804
110
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
110
  if (nBytesRemaining < nValidPix * len)
807
88
    return false;
808
809
1.16k
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
6.40k
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
5.26k
      if (m_bitMask.IsValid(k))
812
1.86k
      {
813
1.86k
        memcpy(&data[m0], ptr, len);
814
1.86k
        ptr += len;
815
1.86k
      }
816
817
22
  (*ppByte) = ptr;
818
22
  nBytesRemaining -= nValidPix * len;
819
820
22
  return true;
821
110
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<unsigned int>(unsigned char const**, unsigned long&, unsigned int*) const
Line
Count
Source
795
570
{
796
570
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
570
  const Byte* ptr = (*ppByte);
800
570
  const HeaderInfo& hd = m_headerInfo;
801
570
  int nDim = hd.nDim;
802
570
  int len = nDim * sizeof(T);
803
804
570
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
570
  if (nBytesRemaining < nValidPix * len)
807
446
    return false;
808
809
1.31M
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
5.26M
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
3.94M
      if (m_bitMask.IsValid(k))
812
4.22k
      {
813
4.22k
        memcpy(&data[m0], ptr, len);
814
4.22k
        ptr += len;
815
4.22k
      }
816
817
124
  (*ppByte) = ptr;
818
124
  nBytesRemaining -= nValidPix * len;
819
820
124
  return true;
821
570
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<float>(unsigned char const**, unsigned long&, float*) const
Line
Count
Source
795
74
{
796
74
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
74
  const Byte* ptr = (*ppByte);
800
74
  const HeaderInfo& hd = m_headerInfo;
801
74
  int nDim = hd.nDim;
802
74
  int len = nDim * sizeof(T);
803
804
74
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
74
  if (nBytesRemaining < nValidPix * len)
807
46
    return false;
808
809
47.4k
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
146k
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
99.1k
      if (m_bitMask.IsValid(k))
812
33.2k
      {
813
33.2k
        memcpy(&data[m0], ptr, len);
814
33.2k
        ptr += len;
815
33.2k
      }
816
817
28
  (*ppByte) = ptr;
818
28
  nBytesRemaining -= nValidPix * len;
819
820
28
  return true;
821
74
}
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<double>(unsigned char const**, unsigned long&, double*) const
Line
Count
Source
795
86
{
796
86
  if (!data || !ppByte || !(*ppByte))
797
0
    return false;
798
799
86
  const Byte* ptr = (*ppByte);
800
86
  const HeaderInfo& hd = m_headerInfo;
801
86
  int nDim = hd.nDim;
802
86
  int len = nDim * sizeof(T);
803
804
86
  size_t nValidPix = (size_t)m_bitMask.CountValidBits();
805
806
86
  if (nBytesRemaining < nValidPix * len)
807
61
    return false;
808
809
1.81k
  for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++)
810
45.4k
    for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim)
811
43.7k
      if (m_bitMask.IsValid(k))
812
15.3k
      {
813
15.3k
        memcpy(&data[m0], ptr, len);
814
15.3k
        ptr += len;
815
15.3k
      }
816
817
25
  (*ppByte) = ptr;
818
25
  nBytesRemaining -= nValidPix * len;
819
820
25
  return true;
821
86
}
822
823
// -------------------------------------------------------------------------- ;
824
825
template<class T>
826
bool Lerc2::WriteTiles(const T* data, Byte** ppByte, int& numBytes, std::vector<double>& zMinVec, std::vector<double>& zMaxVec) const
827
0
{
828
0
  if (!data || !ppByte)
829
0
    return false;
830
831
0
  numBytes = 0;
832
0
  int numBytesLerc = 0;
833
834
0
  std::vector<unsigned int> quantVec;
835
0
  std::vector<std::pair<unsigned int, unsigned int> > sortedQuantVec;
836
837
0
  const HeaderInfo& hd = m_headerInfo;
838
0
  int mbSize = hd.microBlockSize;
839
0
  int nDim = hd.nDim;
840
841
0
  std::vector<T> dataVec(mbSize * mbSize, 0);
842
0
  T* dataBuf = &dataVec[0];
843
844
0
  zMinVec.assign(nDim, DBL_MAX);
845
0
  zMaxVec.assign(nDim, -DBL_MAX);
846
847
0
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
848
0
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
849
850
0
  for (int iTile = 0; iTile < numTilesVert; iTile++)
851
0
  {
852
0
    int tileH = mbSize;
853
0
    int i0 = iTile * tileH;
854
0
    if (iTile == numTilesVert - 1)
855
0
      tileH = hd.nRows - i0;
856
857
0
    for (int jTile = 0; jTile < numTilesHori; jTile++)
858
0
    {
859
0
      int tileW = mbSize;
860
0
      int j0 = jTile * tileW;
861
0
      if (jTile == numTilesHori - 1)
862
0
        tileW = hd.nCols - j0;
863
864
0
      for (int iDim = 0; iDim < nDim; iDim++)
865
0
      {
866
0
        T zMin = 0, zMax = 0;
867
0
        int numValidPixel = 0;
868
0
        bool tryLut = false;
869
870
0
        if (!GetValidDataAndStats(data, i0, i0 + tileH, j0, j0 + tileW, iDim, dataBuf, zMin, zMax, numValidPixel, tryLut))
871
0
          return false;
872
873
0
        if (numValidPixel > 0)
874
0
        {
875
0
          zMinVec[iDim] = (std::min)(zMinVec[iDim], (double)zMin);
876
0
          zMaxVec[iDim] = (std::max)(zMaxVec[iDim], (double)zMax);
877
0
        }
878
879
        //tryLut = false;
880
881
        // if needed, quantize the data here once
882
0
        if ((*ppByte || tryLut) && NeedToQuantize(numValidPixel, zMin, zMax))
883
0
        {
884
0
          if (!Quantize(dataBuf, numValidPixel, zMin, quantVec))
885
0
            return false;
886
887
0
          if (tryLut)
888
0
            SortQuantArray(quantVec, sortedQuantVec);
889
0
        }
890
891
0
        BlockEncodeMode blockEncodeMode;
892
0
        int numBytesNeeded = NumBytesTile(numValidPixel, zMin, zMax, tryLut, blockEncodeMode, sortedQuantVec);
893
0
        numBytesLerc += numBytesNeeded;
894
895
0
        if (*ppByte)
896
0
        {
897
0
          int numBytesWritten = 0;
898
899
0
          if (!WriteTile(dataBuf, numValidPixel, ppByte, numBytesWritten, j0, zMin, zMax, quantVec, blockEncodeMode, sortedQuantVec))
900
0
            return false;
901
902
0
          if (numBytesWritten != numBytesNeeded)
903
0
            return false;
904
0
        }
905
0
      }
906
0
    }
907
0
  }
908
909
0
  numBytes += numBytesLerc;
910
0
  return true;
911
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<signed char>(signed char const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<unsigned char>(unsigned char const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<short>(short const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<unsigned short>(unsigned short const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<int>(int const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<unsigned int>(unsigned int const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<float>(float const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<double>(double const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const
912
913
// -------------------------------------------------------------------------- ;
914
915
template<class T>
916
bool Lerc2::ReadTiles(const Byte** ppByte, size_t& nBytesRemaining, T* data) const
917
13.3k
{
918
13.3k
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
13.3k
  std::vector<unsigned int> bufferVec;
922
923
13.3k
  const HeaderInfo& hd = m_headerInfo;
924
13.3k
  int mbSize = hd.microBlockSize;
925
13.3k
  int nDim = hd.nDim;
926
927
13.3k
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
522
    return false;
929
930
12.8k
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
12.8k
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
12.8k
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
12.8k
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
12.8k
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
206k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
206k
  {
941
206k
    int tileH = mbSize;
942
206k
    int i0 = iTile * tileH;
943
206k
    if (iTile == numTilesVert - 1)
944
2.95k
      tileH = hd.nRows - i0;
945
946
538k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
344k
    {
948
344k
      int tileW = mbSize;
949
344k
      int j0 = jTile * tileW;
950
344k
      if (jTile == numTilesHori - 1)
951
198k
        tileW = hd.nCols - j0;
952
953
752k
      for (int iDim = 0; iDim < nDim; iDim++)
954
419k
      {
955
419k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
12.1k
          return false;
957
419k
      }
958
344k
    }
959
206k
  }
960
961
643
  return true;
962
12.8k
}
bool GDAL_LercNS::Lerc2::ReadTiles<signed char>(unsigned char const**, unsigned long&, signed char*) const
Line
Count
Source
917
1.19k
{
918
1.19k
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
1.19k
  std::vector<unsigned int> bufferVec;
922
923
1.19k
  const HeaderInfo& hd = m_headerInfo;
924
1.19k
  int mbSize = hd.microBlockSize;
925
1.19k
  int nDim = hd.nDim;
926
927
1.19k
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
55
    return false;
929
930
1.14k
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
1.14k
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
1.14k
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
1.14k
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
1.14k
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
1.24k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
1.22k
  {
941
1.22k
    int tileH = mbSize;
942
1.22k
    int i0 = iTile * tileH;
943
1.22k
    if (iTile == numTilesVert - 1)
944
286
      tileH = hd.nRows - i0;
945
946
2.11k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
2.00k
    {
948
2.00k
      int tileW = mbSize;
949
2.00k
      int j0 = jTile * tileW;
950
2.00k
      if (jTile == numTilesHori - 1)
951
267
        tileW = hd.nCols - j0;
952
953
16.1k
      for (int iDim = 0; iDim < nDim; iDim++)
954
15.2k
      {
955
15.2k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
1.11k
          return false;
957
15.2k
      }
958
2.00k
    }
959
1.22k
  }
960
961
23
  return true;
962
1.14k
}
bool GDAL_LercNS::Lerc2::ReadTiles<unsigned char>(unsigned char const**, unsigned long&, unsigned char*) const
Line
Count
Source
917
3.21k
{
918
3.21k
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
3.21k
  std::vector<unsigned int> bufferVec;
922
923
3.21k
  const HeaderInfo& hd = m_headerInfo;
924
3.21k
  int mbSize = hd.microBlockSize;
925
3.21k
  int nDim = hd.nDim;
926
927
3.21k
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
166
    return false;
929
930
3.04k
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
3.04k
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
3.04k
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
3.04k
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
3.04k
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
28.0k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
27.5k
  {
941
27.5k
    int tileH = mbSize;
942
27.5k
    int i0 = iTile * tileH;
943
27.5k
    if (iTile == numTilesVert - 1)
944
909
      tileH = hd.nRows - i0;
945
946
59.8k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
34.8k
    {
948
34.8k
      int tileW = mbSize;
949
34.8k
      int j0 = jTile * tileW;
950
34.8k
      if (jTile == numTilesHori - 1)
951
25.9k
        tileW = hd.nCols - j0;
952
953
87.0k
      for (int iDim = 0; iDim < nDim; iDim++)
954
54.7k
      {
955
54.7k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
2.55k
          return false;
957
54.7k
      }
958
34.8k
    }
959
27.5k
  }
960
961
488
  return true;
962
3.04k
}
bool GDAL_LercNS::Lerc2::ReadTiles<short>(unsigned char const**, unsigned long&, short*) const
Line
Count
Source
917
1.80k
{
918
1.80k
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
1.80k
  std::vector<unsigned int> bufferVec;
922
923
1.80k
  const HeaderInfo& hd = m_headerInfo;
924
1.80k
  int mbSize = hd.microBlockSize;
925
1.80k
  int nDim = hd.nDim;
926
927
1.80k
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
60
    return false;
929
930
1.74k
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
1.74k
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
1.74k
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
1.74k
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
1.74k
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
45.8k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
45.7k
  {
941
45.7k
    int tileH = mbSize;
942
45.7k
    int i0 = iTile * tileH;
943
45.7k
    if (iTile == numTilesVert - 1)
944
212
      tileH = hd.nRows - i0;
945
946
95.9k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
51.8k
    {
948
51.8k
      int tileW = mbSize;
949
51.8k
      int j0 = jTile * tileW;
950
51.8k
      if (jTile == numTilesHori - 1)
951
44.8k
        tileW = hd.nCols - j0;
952
953
112k
      for (int iDim = 0; iDim < nDim; iDim++)
954
62.1k
      {
955
62.1k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
1.69k
          return false;
957
62.1k
      }
958
51.8k
    }
959
45.7k
  }
960
961
56
  return true;
962
1.74k
}
bool GDAL_LercNS::Lerc2::ReadTiles<unsigned short>(unsigned char const**, unsigned long&, unsigned short*) const
Line
Count
Source
917
2.73k
{
918
2.73k
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
2.73k
  std::vector<unsigned int> bufferVec;
922
923
2.73k
  const HeaderInfo& hd = m_headerInfo;
924
2.73k
  int mbSize = hd.microBlockSize;
925
2.73k
  int nDim = hd.nDim;
926
927
2.73k
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
77
    return false;
929
930
2.65k
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
2.65k
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
2.65k
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
2.65k
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
2.65k
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
3.78k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
3.73k
  {
941
3.73k
    int tileH = mbSize;
942
3.73k
    int i0 = iTile * tileH;
943
3.73k
    if (iTile == numTilesVert - 1)
944
345
      tileH = hd.nRows - i0;
945
946
5.66k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
4.53k
    {
948
4.53k
      int tileW = mbSize;
949
4.53k
      int j0 = jTile * tileW;
950
4.53k
      if (jTile == numTilesHori - 1)
951
1.79k
        tileW = hd.nCols - j0;
952
953
14.9k
      for (int iDim = 0; iDim < nDim; iDim++)
954
13.0k
      {
955
13.0k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
2.60k
          return false;
957
13.0k
      }
958
4.53k
    }
959
3.73k
  }
960
961
55
  return true;
962
2.65k
}
bool GDAL_LercNS::Lerc2::ReadTiles<int>(unsigned char const**, unsigned long&, int*) const
Line
Count
Source
917
979
{
918
979
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
979
  std::vector<unsigned int> bufferVec;
922
923
979
  const HeaderInfo& hd = m_headerInfo;
924
979
  int mbSize = hd.microBlockSize;
925
979
  int nDim = hd.nDim;
926
927
979
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
51
    return false;
929
930
928
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
928
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
928
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
928
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
928
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
2.26k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
2.26k
  {
941
2.26k
    int tileH = mbSize;
942
2.26k
    int i0 = iTile * tileH;
943
2.26k
    if (iTile == numTilesVert - 1)
944
159
      tileH = hd.nRows - i0;
945
946
4.44k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
3.10k
    {
948
3.10k
      int tileW = mbSize;
949
3.10k
      int j0 = jTile * tileW;
950
3.10k
      if (jTile == numTilesHori - 1)
951
1.77k
        tileW = hd.nCols - j0;
952
953
9.54k
      for (int iDim = 0; iDim < nDim; iDim++)
954
7.36k
      {
955
7.36k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
926
          return false;
957
7.36k
      }
958
3.10k
    }
959
2.26k
  }
960
961
2
  return true;
962
928
}
bool GDAL_LercNS::Lerc2::ReadTiles<unsigned int>(unsigned char const**, unsigned long&, unsigned int*) const
Line
Count
Source
917
2.24k
{
918
2.24k
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
2.24k
  std::vector<unsigned int> bufferVec;
922
923
2.24k
  const HeaderInfo& hd = m_headerInfo;
924
2.24k
  int mbSize = hd.microBlockSize;
925
2.24k
  int nDim = hd.nDim;
926
927
2.24k
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
56
    return false;
929
930
2.18k
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
2.18k
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
2.18k
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
2.18k
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
2.18k
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
122k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
122k
  {
941
122k
    int tileH = mbSize;
942
122k
    int i0 = iTile * tileH;
943
122k
    if (iTile == numTilesVert - 1)
944
625
      tileH = hd.nRows - i0;
945
946
365k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
244k
    {
948
244k
      int tileW = mbSize;
949
244k
      int j0 = jTile * tileW;
950
244k
      if (jTile == numTilesHori - 1)
951
121k
        tileW = hd.nCols - j0;
952
953
497k
      for (int iDim = 0; iDim < nDim; iDim++)
954
255k
      {
955
255k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
2.17k
          return false;
957
255k
      }
958
244k
    }
959
122k
  }
960
961
9
  return true;
962
2.18k
}
bool GDAL_LercNS::Lerc2::ReadTiles<float>(unsigned char const**, unsigned long&, float*) const
Line
Count
Source
917
588
{
918
588
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
588
  std::vector<unsigned int> bufferVec;
922
923
588
  const HeaderInfo& hd = m_headerInfo;
924
588
  int mbSize = hd.microBlockSize;
925
588
  int nDim = hd.nDim;
926
927
588
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
17
    return false;
929
930
571
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
571
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
571
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
571
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
571
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
1.64k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
1.63k
  {
941
1.63k
    int tileH = mbSize;
942
1.63k
    int i0 = iTile * tileH;
943
1.63k
    if (iTile == numTilesVert - 1)
944
122
      tileH = hd.nRows - i0;
945
946
3.48k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
2.41k
    {
948
2.41k
      int tileW = mbSize;
949
2.41k
      int j0 = jTile * tileW;
950
2.41k
      if (jTile == numTilesHori - 1)
951
1.37k
        tileW = hd.nCols - j0;
952
953
9.09k
      for (int iDim = 0; iDim < nDim; iDim++)
954
7.25k
      {
955
7.25k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
568
          return false;
957
7.25k
      }
958
2.41k
    }
959
1.63k
  }
960
961
3
  return true;
962
571
}
bool GDAL_LercNS::Lerc2::ReadTiles<double>(unsigned char const**, unsigned long&, double*) const
Line
Count
Source
917
572
{
918
572
  if (!data || !ppByte || !(*ppByte))
919
0
    return false;
920
921
572
  std::vector<unsigned int> bufferVec;
922
923
572
  const HeaderInfo& hd = m_headerInfo;
924
572
  int mbSize = hd.microBlockSize;
925
572
  int nDim = hd.nDim;
926
927
572
  if (mbSize > 32)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
928
40
    return false;
929
930
532
  if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 ||
931
532
      hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) ||
932
532
      hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) )
933
0
  {
934
0
    return false;
935
0
  }
936
532
  int numTilesVert = (hd.nRows + mbSize - 1) / mbSize;
937
532
  int numTilesHori = (hd.nCols + mbSize - 1) / mbSize;
938
939
1.03k
  for (int iTile = 0; iTile < numTilesVert; iTile++)
940
1.02k
  {
941
1.02k
    int tileH = mbSize;
942
1.02k
    int i0 = iTile * tileH;
943
1.02k
    if (iTile == numTilesVert - 1)
944
294
      tileH = hd.nRows - i0;
945
946
1.70k
    for (int jTile = 0; jTile < numTilesHori; jTile++)
947
1.20k
    {
948
1.20k
      int tileW = mbSize;
949
1.20k
      int j0 = jTile * tileW;
950
1.20k
      if (jTile == numTilesHori - 1)
951
854
        tileW = hd.nCols - j0;
952
953
5.22k
      for (int iDim = 0; iDim < nDim; iDim++)
954
4.54k
      {
955
4.54k
        if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec))
956
525
          return false;
957
4.54k
      }
958
1.20k
    }
959
1.02k
  }
960
961
7
  return true;
962
532
}
963
964
// -------------------------------------------------------------------------- ;
965
966
template<class T>
967
bool Lerc2::GetValidDataAndStats(const T* data, int i0, int i1, int j0, int j1, int iDim,
968
  T* dataBuf, T& zMin, T& zMax, int& numValidPixel, bool& tryLut) const
969
0
{
970
0
  const HeaderInfo& hd = m_headerInfo;
971
972
0
  if (!data || i0 < 0 || j0 < 0 || i1 > hd.nRows || j1 > hd.nCols || iDim < 0 || iDim > hd.nDim || !dataBuf)
973
0
    return false;
974
975
0
  zMin = 0;
976
0
  zMax = 0;
977
0
  tryLut = false;
978
979
0
  T prevVal = 0;
980
0
  int cnt = 0, cntSameVal = 0;
981
0
  int nDim = hd.nDim;
982
983
0
  if (hd.numValidPixel == hd.nCols * hd.nRows)    // all valid, no mask
984
0
  {
985
0
    for (int i = i0; i < i1; i++)
986
0
    {
987
0
      int k = i * hd.nCols + j0;
988
0
      int m = k * nDim + iDim;
989
990
0
      for (int j = j0; j < j1; j++, k++, m += nDim)
991
0
      {
992
0
        T val = data[m];
993
0
        dataBuf[cnt] = val;
994
995
0
        if (cnt > 0)
996
0
        {
997
0
          if (val < zMin)
998
0
            zMin = val;
999
0
          else if (val > zMax)
1000
0
            zMax = val;
1001
1002
0
          if (val == prevVal)
1003
0
            cntSameVal++;
1004
0
        }
1005
0
        else
1006
0
          zMin = zMax = val;    // init
1007
1008
0
        prevVal = val;
1009
0
        cnt++;
1010
0
      }
1011
0
    }
1012
0
  }
1013
0
  else    // not all valid, use mask
1014
0
  {
1015
0
    for (int i = i0; i < i1; i++)
1016
0
    {
1017
0
      int k = i * hd.nCols + j0;
1018
0
      int m = k * nDim + iDim;
1019
1020
0
      for (int j = j0; j < j1; j++, k++, m += nDim)
1021
0
        if (m_bitMask.IsValid(k))
1022
0
        {
1023
0
          T val = data[m];
1024
0
          dataBuf[cnt] = val;
1025
1026
0
          if (cnt > 0)
1027
0
          {
1028
0
            if (val < zMin)
1029
0
              zMin = val;
1030
0
            else if (val > zMax)
1031
0
              zMax = val;
1032
1033
0
            if (val == prevVal)
1034
0
              cntSameVal++;
1035
0
          }
1036
0
          else
1037
0
            zMin = zMax = val;    // init
1038
1039
0
          prevVal = val;
1040
0
          cnt++;
1041
0
        }
1042
0
    }
1043
0
  }
1044
1045
0
  if (cnt > 4)
1046
0
    tryLut = (zMax > zMin + hd.maxZError) && (2 * cntSameVal > cnt);
1047
1048
0
  numValidPixel = cnt;
1049
0
  return true;
1050
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<signed char>(signed char const*, int, int, int, int, int, signed char*, signed char&, signed char&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<unsigned char>(unsigned char const*, int, int, int, int, int, unsigned char*, unsigned char&, unsigned char&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<short>(short const*, int, int, int, int, int, short*, short&, short&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<unsigned short>(unsigned short const*, int, int, int, int, int, unsigned short*, unsigned short&, unsigned short&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<int>(int const*, int, int, int, int, int, int*, int&, int&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<unsigned int>(unsigned int const*, int, int, int, int, int, unsigned int*, unsigned int&, unsigned int&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<float>(float const*, int, int, int, int, int, float*, float&, float&, int&, bool&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<double>(double const*, int, int, int, int, int, double*, double&, double&, int&, bool&) const
1051
1052
// -------------------------------------------------------------------------- ;
1053
1054
inline double Lerc2::ComputeMaxVal(double zMin, double zMax, double maxZError)
1055
0
{
1056
0
  double fac = 1 / (2 * maxZError);    // must match the code in Decode(), don't touch it
1057
0
  return (zMax - zMin) * fac;
1058
0
}
1059
1060
// -------------------------------------------------------------------------- ;
1061
1062
template<class T>
1063
bool Lerc2::NeedToQuantize(int numValidPixel, T zMin, T zMax) const
1064
0
{
1065
0
  if (numValidPixel == 0 || m_headerInfo.maxZError == 0)
1066
0
    return false;
1067
1068
0
  double maxVal = ComputeMaxVal(zMin, zMax, m_headerInfo.maxZError);
1069
0
  return !(maxVal > m_maxValToQuantize || (unsigned int)(maxVal + 0.5) == 0);
1070
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<signed char>(int, signed char, signed char) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<unsigned char>(int, unsigned char, unsigned char) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<short>(int, short, short) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<unsigned short>(int, unsigned short, unsigned short) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<int>(int, int, int) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<unsigned int>(int, unsigned int, unsigned int) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<float>(int, float, float) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<double>(int, double, double) const
1071
1072
// -------------------------------------------------------------------------- ;
1073
1074
template<class T>
1075
bool Lerc2::Quantize(const T* dataBuf, int num, T zMin, std::vector<unsigned int>& quantVec) const
1076
0
{
1077
0
  quantVec.resize(num);
1078
1079
0
  if (m_headerInfo.dt < DT_Float && m_headerInfo.maxZError == 0.5)    // int lossless
1080
0
  {
1081
0
    for (int i = 0; i < num; i++)
1082
0
      quantVec[i] = (unsigned int)(dataBuf[i] - zMin);    // ok, as char, short get promoted to int by C++ integral promotion rule
1083
0
  }
1084
0
  else    // float and/or lossy
1085
0
  {
1086
0
    double scale = 1 / (2 * m_headerInfo.maxZError);
1087
0
    double zMinDbl = (double)zMin;
1088
1089
0
    for (int i = 0; i < num; i++)
1090
0
      quantVec[i] = (unsigned int)(((double)dataBuf[i] - zMinDbl) * scale + 0.5);    // ok, consistent with ComputeMaxVal(...)
1091
      //quantVec[i] = (unsigned int)((dataBuf[i] - zMin) * scale + 0.5);    // bad, not consistent with ComputeMaxVal(...)
1092
0
  }
1093
1094
0
  return true;
1095
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<signed char>(signed char const*, int, signed char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<unsigned char>(unsigned char const*, int, unsigned char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<short>(short const*, int, short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<unsigned short>(unsigned short const*, int, unsigned short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<int>(int const*, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<unsigned int>(unsigned int const*, int, unsigned int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<float>(float const*, int, float, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<double>(double const*, int, double, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
1096
1097
// -------------------------------------------------------------------------- ;
1098
1099
template<class T>
1100
int Lerc2::NumBytesTile(int numValidPixel, T zMin, T zMax, bool tryLut, BlockEncodeMode& blockEncodeMode,
1101
                         const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const
1102
0
{
1103
0
  blockEncodeMode = BEM_RawBinary;
1104
1105
0
  if (numValidPixel == 0 || (zMin == 0 && zMax == 0))
1106
0
    return 1;
1107
1108
0
  double maxVal = 0, maxZError = m_headerInfo.maxZError;
1109
0
  int nBytesRaw = (int)(1 + numValidPixel * sizeof(T));
1110
1111
0
  if ((maxZError == 0 && zMax > zMin)
1112
0
    || (maxZError > 0 && (maxVal = ComputeMaxVal(zMin, zMax, maxZError)) > m_maxValToQuantize))
1113
0
  {
1114
0
    return nBytesRaw;
1115
0
  }
1116
0
  else
1117
0
  {
1118
0
    DataType dtUsed;
1119
0
    TypeCode(zMin, dtUsed);
1120
0
    int nBytes = 1 + GetDataTypeSize(dtUsed);
1121
1122
0
    unsigned int maxElem = (unsigned int)(maxVal + 0.5);
1123
0
    if (maxElem > 0)
1124
0
    {
1125
0
      nBytes += (!tryLut) ? m_bitStuffer2.ComputeNumBytesNeededSimple(numValidPixel, maxElem)
1126
0
                          : m_bitStuffer2.ComputeNumBytesNeededLut(sortedQuantVec, tryLut);
1127
0
    }
1128
1129
0
    if (nBytes < nBytesRaw)
1130
0
      blockEncodeMode = (!tryLut || maxElem == 0) ? BEM_BitStuffSimple : BEM_BitStuffLUT;
1131
0
    else
1132
0
      nBytes = nBytesRaw;
1133
1134
0
    return nBytes;
1135
0
  }
1136
0
}
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<signed char>(int, signed char, signed char, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<unsigned char>(int, unsigned char, unsigned char, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<short>(int, short, short, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<unsigned short>(int, unsigned short, unsigned short, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<int>(int, int, int, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<unsigned int>(int, unsigned int, unsigned int, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<float>(int, float, float, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<double>(int, double, double, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
1137
1138
// -------------------------------------------------------------------------- ;
1139
1140
template<class T>
1141
bool Lerc2::WriteTile(const T* dataBuf, int num, Byte** ppByte, int& numBytesWritten, int j0, T zMin, T zMax,
1142
  const std::vector<unsigned int>& quantVec, BlockEncodeMode blockEncodeMode,
1143
  const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const
1144
0
{
1145
0
  Byte* ptr = *ppByte;
1146
0
  Byte comprFlag = ((j0 >> 3) & 15) << 2;    // use bits 2345 for integrity check
1147
1148
0
  if (num == 0 || (zMin == 0 && zMax == 0))    // special cases
1149
0
  {
1150
0
    *ptr++ = comprFlag | 2;    // set compression flag to 2 to mark tile as constant 0
1151
0
    numBytesWritten = 1;
1152
0
    *ppByte = ptr;
1153
0
    return true;
1154
0
  }
1155
1156
0
  if (blockEncodeMode == BEM_RawBinary)
1157
0
  {
1158
0
    *ptr++ = comprFlag | 0;    // write z's binary uncompressed
1159
1160
0
    memcpy(ptr, dataBuf, num * sizeof(T));
1161
0
    ptr += num * sizeof(T);
1162
0
  }
1163
0
  else
1164
0
  {
1165
0
    double maxVal = (m_headerInfo.maxZError > 0) ? ComputeMaxVal(zMin, zMax, m_headerInfo.maxZError) : 0;
1166
1167
    // write z's as int arr bit stuffed
1168
0
    unsigned int maxElem = (unsigned int)(maxVal + 0.5);
1169
0
    if (maxElem == 0)
1170
0
      comprFlag |= 3;    // set compression flag to 3 to mark tile as constant zMin
1171
0
    else
1172
0
      comprFlag |= 1;    // use bit stuffing
1173
1174
0
    DataType dtUsed;
1175
0
    int bits67 = TypeCode(zMin, dtUsed);
1176
0
    comprFlag |= bits67 << 6;
1177
1178
0
    *ptr++ = comprFlag;
1179
1180
0
    if (!WriteVariableDataType(&ptr, (double)zMin, dtUsed))
1181
0
      return false;
1182
1183
0
    if (maxElem > 0)
1184
0
    {
1185
0
      if ((int)quantVec.size() != num)
1186
0
        return false;
1187
1188
0
      if (blockEncodeMode == BEM_BitStuffSimple)
1189
0
      {
1190
0
        if (!m_bitStuffer2.EncodeSimple(&ptr, quantVec, m_headerInfo.version))
1191
0
          return false;
1192
0
      }
1193
0
      else if (blockEncodeMode == BEM_BitStuffLUT)
1194
0
      {
1195
0
        if (!m_bitStuffer2.EncodeLut(&ptr, sortedQuantVec, m_headerInfo.version))
1196
0
          return false;
1197
0
      }
1198
0
      else
1199
0
        return false;
1200
0
    }
1201
0
  }
1202
1203
0
  numBytesWritten = (int)(ptr - *ppByte);
1204
0
  *ppByte = ptr;
1205
0
  return true;
1206
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<signed char>(signed char const*, int, unsigned char**, int&, int, signed char, signed char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<unsigned char>(unsigned char const*, int, unsigned char**, int&, int, unsigned char, unsigned char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<short>(short const*, int, unsigned char**, int&, int, short, short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<unsigned short>(unsigned short const*, int, unsigned char**, int&, int, unsigned short, unsigned short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<int>(int const*, int, unsigned char**, int&, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<unsigned int>(unsigned int const*, int, unsigned char**, int&, int, unsigned int, unsigned int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<float>(float const*, int, unsigned char**, int&, int, float, float, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<double>(double const*, int, unsigned char**, int&, int, double, double, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const
1207
1208
// -------------------------------------------------------------------------- ;
1209
1210
template<class T>
1211
bool Lerc2::ReadTile(const Byte** ppByte, size_t& nBytesRemainingInOut, T* data, int i0, int i1, int j0, int j1, int iDim,
1212
                     std::vector<unsigned int>& bufferVec) const
1213
419k
{
1214
419k
  const Byte* ptr = *ppByte;
1215
419k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
419k
  if (nBytesRemaining < 1)
1218
584
    return false;
1219
1220
419k
  Byte comprFlag = *ptr++;
1221
419k
  nBytesRemaining--;
1222
1223
419k
  int bits67 = comprFlag >> 6;
1224
419k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
419k
  if (testCode != ((j0 >> 3) & 15))
1226
6.69k
    return false;
1227
1228
412k
  const HeaderInfo& hd = m_headerInfo;
1229
412k
  int nCols = hd.nCols;
1230
412k
  int nDim = hd.nDim;
1231
1232
412k
  comprFlag &= 3;
1233
1234
412k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
28.2k
  {
1236
141k
    for (int i = i0; i < i1; i++)
1237
113k
    {
1238
113k
      int k = i * nCols + j0;
1239
113k
      int m = k * nDim + iDim;
1240
1241
1.20M
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
1.09M
        if (m_bitMask.IsValid(k))
1243
885k
          data[m] = 0;
1244
113k
    }
1245
1246
28.2k
    *ppByte = ptr;
1247
28.2k
    nBytesRemainingInOut = nBytesRemaining;
1248
28.2k
    return true;
1249
28.2k
  }
1250
1251
384k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
351k
  {
1253
351k
    const T* srcPtr = (const T*)ptr;
1254
351k
    int cnt = 0;
1255
1256
1.68M
    for (int i = i0; i < i1; i++)
1257
1.33M
    {
1258
1.33M
      int k = i * nCols + j0;
1259
1.33M
      int m = k * nDim + iDim;
1260
1261
6.56M
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
5.23M
        if (m_bitMask.IsValid(k))
1263
502k
        {
1264
502k
          if (nBytesRemaining < sizeof(T))
1265
769
            return false;
1266
1267
502k
          data[m] = *srcPtr++;
1268
502k
          nBytesRemaining -= sizeof(T);
1269
1270
502k
          cnt++;
1271
502k
        }
1272
1.33M
    }
1273
1274
350k
    ptr += cnt * sizeof(T);
1275
350k
  }
1276
32.4k
  else
1277
32.4k
  {
1278
    // read z's as int arr bit stuffed
1279
32.4k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
32.4k
    if( dtUsed == DT_Undefined )
1281
158
      return false;
1282
32.2k
    size_t n = GetDataTypeSize(dtUsed);
1283
32.2k
    if (nBytesRemaining < n)
1284
262
      return false;
1285
1286
32.0k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
32.0k
    nBytesRemaining -= n;
1288
1289
32.0k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
16.7k
    {
1291
133k
      for (int i = i0; i < i1; i++)
1292
116k
      {
1293
116k
        int k = i * nCols + j0;
1294
116k
        int m = k * nDim + iDim;
1295
1296
984k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
868k
          if (m_bitMask.IsValid(k))
1298
168k
            data[m] = (T)offset;
1299
116k
      }
1300
16.7k
    }
1301
15.2k
    else
1302
15.2k
    {
1303
15.2k
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
15.2k
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
2.81k
        return false;
1306
1307
12.4k
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
12.4k
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
12.4k
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
12.4k
      if (bufferVec.size() == maxElementCount)    // all valid
1312
5.27k
      {
1313
42.6k
        for (int i = i0; i < i1; i++)
1314
37.3k
        {
1315
37.3k
          int k = i * nCols + j0;
1316
37.3k
          int m = k * nDim + iDim;
1317
1318
366k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
329k
          {
1320
329k
            double z = offset + *srcPtr++ * invScale;
1321
329k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
329k
          }
1323
37.3k
        }
1324
5.27k
      }
1325
7.15k
      else    // not all valid
1326
7.15k
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
7.15k
        {
1346
7.15k
          size_t bufferVecIdx = 0;
1347
1348
85.2k
          for (int i = i0; i < i1; i++)
1349
78.9k
          {
1350
78.9k
            int k = i * nCols + j0;
1351
78.9k
            int m = k * nDim + iDim;
1352
1353
777k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
699k
              if (m_bitMask.IsValid(k))
1355
88.9k
              {
1356
88.9k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
881
                  return false;
1358
1359
88.0k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
88.0k
                bufferVecIdx++;
1361
88.0k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
88.0k
              }
1363
78.9k
          }
1364
7.15k
        }
1365
7.15k
      }
1366
12.4k
    }
1367
32.0k
  }
1368
1369
379k
  *ppByte = ptr;
1370
379k
  nBytesRemainingInOut = nBytesRemaining;
1371
379k
  return true;
1372
412k
}
bool GDAL_LercNS::Lerc2::ReadTile<signed char>(unsigned char const**, unsigned long&, signed char*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
15.2k
{
1214
15.2k
  const Byte* ptr = *ppByte;
1215
15.2k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
15.2k
  if (nBytesRemaining < 1)
1218
21
    return false;
1219
1220
15.2k
  Byte comprFlag = *ptr++;
1221
15.2k
  nBytesRemaining--;
1222
1223
15.2k
  int bits67 = comprFlag >> 6;
1224
15.2k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
15.2k
  if (testCode != ((j0 >> 3) & 15))
1226
696
    return false;
1227
1228
14.5k
  const HeaderInfo& hd = m_headerInfo;
1229
14.5k
  int nCols = hd.nCols;
1230
14.5k
  int nDim = hd.nDim;
1231
1232
14.5k
  comprFlag &= 3;
1233
1234
14.5k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
4.43k
  {
1236
12.8k
    for (int i = i0; i < i1; i++)
1237
8.45k
    {
1238
8.45k
      int k = i * nCols + j0;
1239
8.45k
      int m = k * nDim + iDim;
1240
1241
48.5k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
40.1k
        if (m_bitMask.IsValid(k))
1243
17.1k
          data[m] = 0;
1244
8.45k
    }
1245
1246
4.43k
    *ppByte = ptr;
1247
4.43k
    nBytesRemainingInOut = nBytesRemaining;
1248
4.43k
    return true;
1249
4.43k
  }
1250
1251
10.1k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
8.77k
  {
1253
8.77k
    const T* srcPtr = (const T*)ptr;
1254
8.77k
    int cnt = 0;
1255
1256
30.8k
    for (int i = i0; i < i1; i++)
1257
22.0k
    {
1258
22.0k
      int k = i * nCols + j0;
1259
22.0k
      int m = k * nDim + iDim;
1260
1261
166k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
144k
        if (m_bitMask.IsValid(k))
1263
65.1k
        {
1264
65.1k
          if (nBytesRemaining < sizeof(T))
1265
54
            return false;
1266
1267
65.1k
          data[m] = *srcPtr++;
1268
65.1k
          nBytesRemaining -= sizeof(T);
1269
1270
65.1k
          cnt++;
1271
65.1k
        }
1272
22.0k
    }
1273
1274
8.71k
    ptr += cnt * sizeof(T);
1275
8.71k
  }
1276
1.32k
  else
1277
1.32k
  {
1278
    // read z's as int arr bit stuffed
1279
1.32k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
1.32k
    if( dtUsed == DT_Undefined )
1281
0
      return false;
1282
1.32k
    size_t n = GetDataTypeSize(dtUsed);
1283
1.32k
    if (nBytesRemaining < n)
1284
0
      return false;
1285
1286
1.32k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
1.32k
    nBytesRemaining -= n;
1288
1289
1.32k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
735
    {
1291
3.60k
      for (int i = i0; i < i1; i++)
1292
2.87k
      {
1293
2.87k
        int k = i * nCols + j0;
1294
2.87k
        int m = k * nDim + iDim;
1295
1296
21.8k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
18.9k
          if (m_bitMask.IsValid(k))
1298
15.9k
            data[m] = (T)offset;
1299
2.87k
      }
1300
735
    }
1301
593
    else
1302
593
    {
1303
593
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
593
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
194
        return false;
1306
1307
399
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
399
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
399
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
399
      if (bufferVec.size() == maxElementCount)    // all valid
1312
95
      {
1313
889
        for (int i = i0; i < i1; i++)
1314
794
        {
1315
794
          int k = i * nCols + j0;
1316
794
          int m = k * nDim + iDim;
1317
1318
12.7k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
11.9k
          {
1320
11.9k
            double z = offset + *srcPtr++ * invScale;
1321
11.9k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
11.9k
          }
1323
794
        }
1324
95
      }
1325
304
      else    // not all valid
1326
304
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
304
        {
1346
304
          size_t bufferVecIdx = 0;
1347
1348
1.79k
          for (int i = i0; i < i1; i++)
1349
1.64k
          {
1350
1.64k
            int k = i * nCols + j0;
1351
1.64k
            int m = k * nDim + iDim;
1352
1353
22.1k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
20.6k
              if (m_bitMask.IsValid(k))
1355
7.93k
              {
1356
7.93k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
152
                  return false;
1358
1359
7.78k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
7.78k
                bufferVecIdx++;
1361
7.78k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
7.78k
              }
1363
1.64k
          }
1364
304
        }
1365
304
      }
1366
399
    }
1367
1.32k
  }
1368
1369
9.70k
  *ppByte = ptr;
1370
9.70k
  nBytesRemainingInOut = nBytesRemaining;
1371
9.70k
  return true;
1372
14.5k
}
bool GDAL_LercNS::Lerc2::ReadTile<unsigned char>(unsigned char const**, unsigned long&, unsigned char*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
54.7k
{
1214
54.7k
  const Byte* ptr = *ppByte;
1215
54.7k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
54.7k
  if (nBytesRemaining < 1)
1218
108
    return false;
1219
1220
54.6k
  Byte comprFlag = *ptr++;
1221
54.6k
  nBytesRemaining--;
1222
1223
54.6k
  int bits67 = comprFlag >> 6;
1224
54.6k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
54.6k
  if (testCode != ((j0 >> 3) & 15))
1226
1.49k
    return false;
1227
1228
53.1k
  const HeaderInfo& hd = m_headerInfo;
1229
53.1k
  int nCols = hd.nCols;
1230
53.1k
  int nDim = hd.nDim;
1231
1232
53.1k
  comprFlag &= 3;
1233
1234
53.1k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
10.9k
  {
1236
80.0k
    for (int i = i0; i < i1; i++)
1237
69.1k
    {
1238
69.1k
      int k = i * nCols + j0;
1239
69.1k
      int m = k * nDim + iDim;
1240
1241
911k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
842k
        if (m_bitMask.IsValid(k))
1243
821k
          data[m] = 0;
1244
69.1k
    }
1245
1246
10.9k
    *ppByte = ptr;
1247
10.9k
    nBytesRemainingInOut = nBytesRemaining;
1248
10.9k
    return true;
1249
10.9k
  }
1250
1251
42.2k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
27.3k
  {
1253
27.3k
    const T* srcPtr = (const T*)ptr;
1254
27.3k
    int cnt = 0;
1255
1256
309k
    for (int i = i0; i < i1; i++)
1257
282k
    {
1258
282k
      int k = i * nCols + j0;
1259
282k
      int m = k * nDim + iDim;
1260
1261
2.44M
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
2.15M
        if (m_bitMask.IsValid(k))
1263
293k
        {
1264
293k
          if (nBytesRemaining < sizeof(T))
1265
63
            return false;
1266
1267
293k
          data[m] = *srcPtr++;
1268
293k
          nBytesRemaining -= sizeof(T);
1269
1270
293k
          cnt++;
1271
293k
        }
1272
282k
    }
1273
1274
27.2k
    ptr += cnt * sizeof(T);
1275
27.2k
  }
1276
14.9k
  else
1277
14.9k
  {
1278
    // read z's as int arr bit stuffed
1279
14.9k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
14.9k
    if( dtUsed == DT_Undefined )
1281
11
      return false;
1282
14.9k
    size_t n = GetDataTypeSize(dtUsed);
1283
14.9k
    if (nBytesRemaining < n)
1284
37
      return false;
1285
1286
14.9k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
14.9k
    nBytesRemaining -= n;
1288
1289
14.9k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
6.08k
    {
1291
93.0k
      for (int i = i0; i < i1; i++)
1292
86.9k
      {
1293
86.9k
        int k = i * nCols + j0;
1294
86.9k
        int m = k * nDim + iDim;
1295
1296
771k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
684k
          if (m_bitMask.IsValid(k))
1298
118k
            data[m] = (T)offset;
1299
86.9k
      }
1300
6.08k
    }
1301
8.85k
    else
1302
8.85k
    {
1303
8.85k
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
8.85k
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
643
        return false;
1306
1307
8.20k
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
8.20k
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
8.20k
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
8.20k
      if (bufferVec.size() == maxElementCount)    // all valid
1312
3.77k
      {
1313
32.9k
        for (int i = i0; i < i1; i++)
1314
29.1k
        {
1315
29.1k
          int k = i * nCols + j0;
1316
29.1k
          int m = k * nDim + iDim;
1317
1318
261k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
232k
          {
1320
232k
            double z = offset + *srcPtr++ * invScale;
1321
232k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
232k
          }
1323
29.1k
        }
1324
3.77k
      }
1325
4.43k
      else    // not all valid
1326
4.43k
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
4.43k
        {
1346
4.43k
          size_t bufferVecIdx = 0;
1347
1348
70.5k
          for (int i = i0; i < i1; i++)
1349
66.3k
          {
1350
66.3k
            int k = i * nCols + j0;
1351
66.3k
            int m = k * nDim + iDim;
1352
1353
611k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
544k
              if (m_bitMask.IsValid(k))
1355
55.3k
              {
1356
55.3k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
202
                  return false;
1358
1359
55.1k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
55.1k
                bufferVecIdx++;
1361
55.1k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
55.1k
              }
1363
66.3k
          }
1364
4.43k
        }
1365
4.43k
      }
1366
8.20k
    }
1367
14.9k
  }
1368
1369
41.3k
  *ppByte = ptr;
1370
41.3k
  nBytesRemainingInOut = nBytesRemaining;
1371
41.3k
  return true;
1372
53.1k
}
bool GDAL_LercNS::Lerc2::ReadTile<short>(unsigned char const**, unsigned long&, short*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
62.1k
{
1214
62.1k
  const Byte* ptr = *ppByte;
1215
62.1k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
62.1k
  if (nBytesRemaining < 1)
1218
88
    return false;
1219
1220
62.0k
  Byte comprFlag = *ptr++;
1221
62.0k
  nBytesRemaining--;
1222
1223
62.0k
  int bits67 = comprFlag >> 6;
1224
62.0k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
62.0k
  if (testCode != ((j0 >> 3) & 15))
1226
1.08k
    return false;
1227
1228
60.9k
  const HeaderInfo& hd = m_headerInfo;
1229
60.9k
  int nCols = hd.nCols;
1230
60.9k
  int nDim = hd.nDim;
1231
1232
60.9k
  comprFlag &= 3;
1233
1234
60.9k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
3.48k
  {
1236
11.2k
    for (int i = i0; i < i1; i++)
1237
7.78k
    {
1238
7.78k
      int k = i * nCols + j0;
1239
7.78k
      int m = k * nDim + iDim;
1240
1241
37.6k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
29.9k
        if (m_bitMask.IsValid(k))
1243
10.1k
          data[m] = 0;
1244
7.78k
    }
1245
1246
3.48k
    *ppByte = ptr;
1247
3.48k
    nBytesRemainingInOut = nBytesRemaining;
1248
3.48k
    return true;
1249
3.48k
  }
1250
1251
57.5k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
54.9k
  {
1253
54.9k
    const T* srcPtr = (const T*)ptr;
1254
54.9k
    int cnt = 0;
1255
1256
548k
    for (int i = i0; i < i1; i++)
1257
494k
    {
1258
494k
      int k = i * nCols + j0;
1259
494k
      int m = k * nDim + iDim;
1260
1261
2.50M
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
2.01M
        if (m_bitMask.IsValid(k))
1263
35.4k
        {
1264
35.4k
          if (nBytesRemaining < sizeof(T))
1265
105
            return false;
1266
1267
35.3k
          data[m] = *srcPtr++;
1268
35.3k
          nBytesRemaining -= sizeof(T);
1269
1270
35.3k
          cnt++;
1271
35.3k
        }
1272
494k
    }
1273
1274
54.8k
    ptr += cnt * sizeof(T);
1275
54.8k
  }
1276
2.55k
  else
1277
2.55k
  {
1278
    // read z's as int arr bit stuffed
1279
2.55k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
2.55k
    if( dtUsed == DT_Undefined )
1281
39
      return false;
1282
2.51k
    size_t n = GetDataTypeSize(dtUsed);
1283
2.51k
    if (nBytesRemaining < n)
1284
32
      return false;
1285
1286
2.48k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
2.48k
    nBytesRemaining -= n;
1288
1289
2.48k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
1.00k
    {
1291
4.70k
      for (int i = i0; i < i1; i++)
1292
3.69k
      {
1293
3.69k
        int k = i * nCols + j0;
1294
3.69k
        int m = k * nDim + iDim;
1295
1296
31.4k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
27.7k
          if (m_bitMask.IsValid(k))
1298
7.25k
            data[m] = (T)offset;
1299
3.69k
      }
1300
1.00k
    }
1301
1.48k
    else
1302
1.48k
    {
1303
1.48k
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
1.48k
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
223
        return false;
1306
1307
1.25k
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
1.25k
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
1.25k
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
1.25k
      if (bufferVec.size() == maxElementCount)    // all valid
1312
587
      {
1313
2.64k
        for (int i = i0; i < i1; i++)
1314
2.05k
        {
1315
2.05k
          int k = i * nCols + j0;
1316
2.05k
          int m = k * nDim + iDim;
1317
1318
17.3k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
15.3k
          {
1320
15.3k
            double z = offset + *srcPtr++ * invScale;
1321
15.3k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
15.3k
          }
1323
2.05k
        }
1324
587
      }
1325
670
      else    // not all valid
1326
670
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
670
        {
1346
670
          size_t bufferVecIdx = 0;
1347
1348
4.38k
          for (int i = i0; i < i1; i++)
1349
3.84k
          {
1350
3.84k
            int k = i * nCols + j0;
1351
3.84k
            int m = k * nDim + iDim;
1352
1353
45.8k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
42.0k
              if (m_bitMask.IsValid(k))
1355
10.5k
              {
1356
10.5k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
122
                  return false;
1358
1359
10.4k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
10.4k
                bufferVecIdx++;
1361
10.4k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
10.4k
              }
1363
3.84k
          }
1364
670
        }
1365
670
      }
1366
1.25k
    }
1367
2.48k
  }
1368
1369
56.9k
  *ppByte = ptr;
1370
56.9k
  nBytesRemainingInOut = nBytesRemaining;
1371
56.9k
  return true;
1372
60.9k
}
bool GDAL_LercNS::Lerc2::ReadTile<unsigned short>(unsigned char const**, unsigned long&, unsigned short*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
13.0k
{
1214
13.0k
  const Byte* ptr = *ppByte;
1215
13.0k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
13.0k
  if (nBytesRemaining < 1)
1218
90
    return false;
1219
1220
12.9k
  Byte comprFlag = *ptr++;
1221
12.9k
  nBytesRemaining--;
1222
1223
12.9k
  int bits67 = comprFlag >> 6;
1224
12.9k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
12.9k
  if (testCode != ((j0 >> 3) & 15))
1226
938
    return false;
1227
1228
11.9k
  const HeaderInfo& hd = m_headerInfo;
1229
11.9k
  int nCols = hd.nCols;
1230
11.9k
  int nDim = hd.nDim;
1231
1232
11.9k
  comprFlag &= 3;
1233
1234
11.9k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
2.76k
  {
1236
8.89k
    for (int i = i0; i < i1; i++)
1237
6.12k
    {
1238
6.12k
      int k = i * nCols + j0;
1239
6.12k
      int m = k * nDim + iDim;
1240
1241
31.7k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
25.6k
        if (m_bitMask.IsValid(k))
1243
10.3k
          data[m] = 0;
1244
6.12k
    }
1245
1246
2.76k
    *ppByte = ptr;
1247
2.76k
    nBytesRemainingInOut = nBytesRemaining;
1248
2.76k
    return true;
1249
2.76k
  }
1250
1251
9.21k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
5.99k
  {
1253
5.99k
    const T* srcPtr = (const T*)ptr;
1254
5.99k
    int cnt = 0;
1255
1256
20.2k
    for (int i = i0; i < i1; i++)
1257
14.4k
    {
1258
14.4k
      int k = i * nCols + j0;
1259
14.4k
      int m = k * nDim + iDim;
1260
1261
61.2k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
46.9k
        if (m_bitMask.IsValid(k))
1263
15.8k
        {
1264
15.8k
          if (nBytesRemaining < sizeof(T))
1265
102
            return false;
1266
1267
15.7k
          data[m] = *srcPtr++;
1268
15.7k
          nBytesRemaining -= sizeof(T);
1269
1270
15.7k
          cnt++;
1271
15.7k
        }
1272
14.4k
    }
1273
1274
5.89k
    ptr += cnt * sizeof(T);
1275
5.89k
  }
1276
3.21k
  else
1277
3.21k
  {
1278
    // read z's as int arr bit stuffed
1279
3.21k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
3.21k
    if( dtUsed == DT_Undefined )
1281
64
      return false;
1282
3.15k
    size_t n = GetDataTypeSize(dtUsed);
1283
3.15k
    if (nBytesRemaining < n)
1284
26
      return false;
1285
1286
3.12k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
3.12k
    nBytesRemaining -= n;
1288
1289
3.12k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
1.29k
    {
1291
4.64k
      for (int i = i0; i < i1; i++)
1292
3.34k
      {
1293
3.34k
        int k = i * nCols + j0;
1294
3.34k
        int m = k * nDim + iDim;
1295
1296
21.7k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
18.3k
          if (m_bitMask.IsValid(k))
1298
5.19k
            data[m] = (T)offset;
1299
3.34k
      }
1300
1.29k
    }
1301
1.83k
    else
1302
1.83k
    {
1303
1.83k
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
1.83k
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
1.17k
        return false;
1306
1307
655
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
655
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
655
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
655
      if (bufferVec.size() == maxElementCount)    // all valid
1312
224
      {
1313
1.08k
        for (int i = i0; i < i1; i++)
1314
863
        {
1315
863
          int k = i * nCols + j0;
1316
863
          int m = k * nDim + iDim;
1317
1318
6.87k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
6.01k
          {
1320
6.01k
            double z = offset + *srcPtr++ * invScale;
1321
6.01k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
6.01k
          }
1323
863
        }
1324
224
      }
1325
431
      else    // not all valid
1326
431
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
431
        {
1346
431
          size_t bufferVecIdx = 0;
1347
1348
1.71k
          for (int i = i0; i < i1; i++)
1349
1.48k
          {
1350
1.48k
            int k = i * nCols + j0;
1351
1.48k
            int m = k * nDim + iDim;
1352
1353
18.8k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
17.5k
              if (m_bitMask.IsValid(k))
1355
3.52k
              {
1356
3.52k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
203
                  return false;
1358
1359
3.32k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
3.32k
                bufferVecIdx++;
1361
3.32k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
3.32k
              }
1363
1.48k
          }
1364
431
        }
1365
431
      }
1366
655
    }
1367
3.12k
  }
1368
1369
7.64k
  *ppByte = ptr;
1370
7.64k
  nBytesRemainingInOut = nBytesRemaining;
1371
7.64k
  return true;
1372
11.9k
}
bool GDAL_LercNS::Lerc2::ReadTile<int>(unsigned char const**, unsigned long&, int*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
7.36k
{
1214
7.36k
  const Byte* ptr = *ppByte;
1215
7.36k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
7.36k
  if (nBytesRemaining < 1)
1218
61
    return false;
1219
1220
7.30k
  Byte comprFlag = *ptr++;
1221
7.30k
  nBytesRemaining--;
1222
1223
7.30k
  int bits67 = comprFlag >> 6;
1224
7.30k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
7.30k
  if (testCode != ((j0 >> 3) & 15))
1226
521
    return false;
1227
1228
6.78k
  const HeaderInfo& hd = m_headerInfo;
1229
6.78k
  int nCols = hd.nCols;
1230
6.78k
  int nDim = hd.nDim;
1231
1232
6.78k
  comprFlag &= 3;
1233
1234
6.78k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
1.58k
  {
1236
9.28k
    for (int i = i0; i < i1; i++)
1237
7.69k
    {
1238
7.69k
      int k = i * nCols + j0;
1239
7.69k
      int m = k * nDim + iDim;
1240
1241
36.0k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
28.3k
        if (m_bitMask.IsValid(k))
1243
9.80k
          data[m] = 0;
1244
7.69k
    }
1245
1246
1.58k
    *ppByte = ptr;
1247
1.58k
    nBytesRemainingInOut = nBytesRemaining;
1248
1.58k
    return true;
1249
1.58k
  }
1250
1251
5.19k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
3.39k
  {
1253
3.39k
    const T* srcPtr = (const T*)ptr;
1254
3.39k
    int cnt = 0;
1255
1256
11.9k
    for (int i = i0; i < i1; i++)
1257
8.64k
    {
1258
8.64k
      int k = i * nCols + j0;
1259
8.64k
      int m = k * nDim + iDim;
1260
1261
37.5k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
29.0k
        if (m_bitMask.IsValid(k))
1263
7.80k
        {
1264
7.80k
          if (nBytesRemaining < sizeof(T))
1265
125
            return false;
1266
1267
7.67k
          data[m] = *srcPtr++;
1268
7.67k
          nBytesRemaining -= sizeof(T);
1269
1270
7.67k
          cnt++;
1271
7.67k
        }
1272
8.64k
    }
1273
1274
3.26k
    ptr += cnt * sizeof(T);
1275
3.26k
  }
1276
1.80k
  else
1277
1.80k
  {
1278
    // read z's as int arr bit stuffed
1279
1.80k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
1.80k
    if( dtUsed == DT_Undefined )
1281
0
      return false;
1282
1.80k
    size_t n = GetDataTypeSize(dtUsed);
1283
1.80k
    if (nBytesRemaining < n)
1284
30
      return false;
1285
1286
1.77k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
1.77k
    nBytesRemaining -= n;
1288
1289
1.77k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
1.23k
    {
1291
8.11k
      for (int i = i0; i < i1; i++)
1292
6.88k
      {
1293
6.88k
        int k = i * nCols + j0;
1294
6.88k
        int m = k * nDim + iDim;
1295
1296
36.4k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
29.6k
          if (m_bitMask.IsValid(k))
1298
8.37k
            data[m] = (T)offset;
1299
6.88k
      }
1300
1.23k
    }
1301
544
    else
1302
544
    {
1303
544
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
544
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
143
        return false;
1306
1307
401
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
401
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
401
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
401
      if (bufferVec.size() == maxElementCount)    // all valid
1312
139
      {
1313
1.92k
        for (int i = i0; i < i1; i++)
1314
1.78k
        {
1315
1.78k
          int k = i * nCols + j0;
1316
1.78k
          int m = k * nDim + iDim;
1317
1318
29.5k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
27.7k
          {
1320
27.7k
            double z = offset + *srcPtr++ * invScale;
1321
27.7k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
27.7k
          }
1323
1.78k
        }
1324
139
      }
1325
262
      else    // not all valid
1326
262
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
262
        {
1346
262
          size_t bufferVecIdx = 0;
1347
1348
1.80k
          for (int i = i0; i < i1; i++)
1349
1.58k
          {
1350
1.58k
            int k = i * nCols + j0;
1351
1.58k
            int m = k * nDim + iDim;
1352
1353
23.8k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
22.3k
              if (m_bitMask.IsValid(k))
1355
5.12k
              {
1356
5.12k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
46
                  return false;
1358
1359
5.08k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
5.08k
                bufferVecIdx++;
1361
5.08k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
5.08k
              }
1363
1.58k
          }
1364
262
        }
1365
262
      }
1366
401
    }
1367
1.77k
  }
1368
1369
4.85k
  *ppByte = ptr;
1370
4.85k
  nBytesRemainingInOut = nBytesRemaining;
1371
4.85k
  return true;
1372
6.78k
}
bool GDAL_LercNS::Lerc2::ReadTile<unsigned int>(unsigned char const**, unsigned long&, unsigned int*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
255k
{
1214
255k
  const Byte* ptr = *ppByte;
1215
255k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
255k
  if (nBytesRemaining < 1)
1218
126
    return false;
1219
1220
255k
  Byte comprFlag = *ptr++;
1221
255k
  nBytesRemaining--;
1222
1223
255k
  int bits67 = comprFlag >> 6;
1224
255k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
255k
  if (testCode != ((j0 >> 3) & 15))
1226
1.41k
    return false;
1227
1228
253k
  const HeaderInfo& hd = m_headerInfo;
1229
253k
  int nCols = hd.nCols;
1230
253k
  int nDim = hd.nDim;
1231
1232
253k
  comprFlag &= 3;
1233
1234
253k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
2.70k
  {
1236
11.5k
    for (int i = i0; i < i1; i++)
1237
8.86k
    {
1238
8.86k
      int k = i * nCols + j0;
1239
8.86k
      int m = k * nDim + iDim;
1240
1241
127k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
118k
        if (m_bitMask.IsValid(k))
1243
12.8k
          data[m] = 0;
1244
8.86k
    }
1245
1246
2.70k
    *ppByte = ptr;
1247
2.70k
    nBytesRemainingInOut = nBytesRemaining;
1248
2.70k
    return true;
1249
2.70k
  }
1250
1251
250k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
246k
  {
1253
246k
    const T* srcPtr = (const T*)ptr;
1254
246k
    int cnt = 0;
1255
1256
738k
    for (int i = i0; i < i1; i++)
1257
492k
    {
1258
492k
      int k = i * nCols + j0;
1259
492k
      int m = k * nDim + iDim;
1260
1261
1.25M
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
766k
        if (m_bitMask.IsValid(k))
1263
61.6k
        {
1264
61.6k
          if (nBytesRemaining < sizeof(T))
1265
148
            return false;
1266
1267
61.5k
          data[m] = *srcPtr++;
1268
61.5k
          nBytesRemaining -= sizeof(T);
1269
1270
61.5k
          cnt++;
1271
61.5k
        }
1272
492k
    }
1273
1274
246k
    ptr += cnt * sizeof(T);
1275
246k
  }
1276
4.73k
  else
1277
4.73k
  {
1278
    // read z's as int arr bit stuffed
1279
4.73k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
4.73k
    if( dtUsed == DT_Undefined )
1281
44
      return false;
1282
4.69k
    size_t n = GetDataTypeSize(dtUsed);
1283
4.69k
    if (nBytesRemaining < n)
1284
82
      return false;
1285
1286
4.60k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
4.60k
    nBytesRemaining -= n;
1288
1289
4.60k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
3.24k
    {
1291
11.3k
      for (int i = i0; i < i1; i++)
1292
8.13k
      {
1293
8.13k
        int k = i * nCols + j0;
1294
8.13k
        int m = k * nDim + iDim;
1295
1296
89.6k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
81.5k
          if (m_bitMask.IsValid(k))
1298
9.91k
            data[m] = (T)offset;
1299
8.13k
      }
1300
3.24k
    }
1301
1.36k
    else
1302
1.36k
    {
1303
1.36k
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
1.36k
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
282
        return false;
1306
1307
1.08k
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
1.08k
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
1.08k
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
1.08k
      if (bufferVec.size() == maxElementCount)    // all valid
1312
358
      {
1313
2.86k
        for (int i = i0; i < i1; i++)
1314
2.50k
        {
1315
2.50k
          int k = i * nCols + j0;
1316
2.50k
          int m = k * nDim + iDim;
1317
1318
38.2k
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
35.7k
          {
1320
35.7k
            double z = offset + *srcPtr++ * invScale;
1321
35.7k
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
35.7k
          }
1323
2.50k
        }
1324
358
      }
1325
726
      else    // not all valid
1326
726
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
726
        {
1346
726
          size_t bufferVecIdx = 0;
1347
1348
3.98k
          for (int i = i0; i < i1; i++)
1349
3.34k
          {
1350
3.34k
            int k = i * nCols + j0;
1351
3.34k
            int m = k * nDim + iDim;
1352
1353
53.0k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
49.8k
              if (m_bitMask.IsValid(k))
1355
5.81k
              {
1356
5.81k
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
84
                  return false;
1358
1359
5.72k
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
5.72k
                bufferVecIdx++;
1361
5.72k
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
5.72k
              }
1363
3.34k
          }
1364
726
        }
1365
726
      }
1366
1.08k
    }
1367
4.60k
  }
1368
1369
250k
  *ppByte = ptr;
1370
250k
  nBytesRemainingInOut = nBytesRemaining;
1371
250k
  return true;
1372
253k
}
bool GDAL_LercNS::Lerc2::ReadTile<float>(unsigned char const**, unsigned long&, float*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
7.25k
{
1214
7.25k
  const Byte* ptr = *ppByte;
1215
7.25k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
7.25k
  if (nBytesRemaining < 1)
1218
34
    return false;
1219
1220
7.21k
  Byte comprFlag = *ptr++;
1221
7.21k
  nBytesRemaining--;
1222
1223
7.21k
  int bits67 = comprFlag >> 6;
1224
7.21k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
7.21k
  if (testCode != ((j0 >> 3) & 15))
1226
309
    return false;
1227
1228
6.90k
  const HeaderInfo& hd = m_headerInfo;
1229
6.90k
  int nCols = hd.nCols;
1230
6.90k
  int nDim = hd.nDim;
1231
1232
6.90k
  comprFlag &= 3;
1233
1234
6.90k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
1.21k
  {
1236
3.64k
    for (int i = i0; i < i1; i++)
1237
2.42k
    {
1238
2.42k
      int k = i * nCols + j0;
1239
2.42k
      int m = k * nDim + iDim;
1240
1241
6.97k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
4.54k
        if (m_bitMask.IsValid(k))
1243
1.38k
          data[m] = 0;
1244
2.42k
    }
1245
1246
1.21k
    *ppByte = ptr;
1247
1.21k
    nBytesRemainingInOut = nBytesRemaining;
1248
1.21k
    return true;
1249
1.21k
  }
1250
1251
5.69k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
2.75k
  {
1253
2.75k
    const T* srcPtr = (const T*)ptr;
1254
2.75k
    int cnt = 0;
1255
1256
9.05k
    for (int i = i0; i < i1; i++)
1257
6.37k
    {
1258
6.37k
      int k = i * nCols + j0;
1259
6.37k
      int m = k * nDim + iDim;
1260
1261
40.1k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
33.8k
        if (m_bitMask.IsValid(k))
1263
20.1k
        {
1264
20.1k
          if (nBytesRemaining < sizeof(T))
1265
78
            return false;
1266
1267
20.1k
          data[m] = *srcPtr++;
1268
20.1k
          nBytesRemaining -= sizeof(T);
1269
1270
20.1k
          cnt++;
1271
20.1k
        }
1272
6.37k
    }
1273
1274
2.68k
    ptr += cnt * sizeof(T);
1275
2.68k
  }
1276
2.93k
  else
1277
2.93k
  {
1278
    // read z's as int arr bit stuffed
1279
2.93k
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
2.93k
    if( dtUsed == DT_Undefined )
1281
0
      return false;
1282
2.93k
    size_t n = GetDataTypeSize(dtUsed);
1283
2.93k
    if (nBytesRemaining < n)
1284
14
      return false;
1285
1286
2.91k
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
2.91k
    nBytesRemaining -= n;
1288
1289
2.91k
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
2.45k
    {
1291
5.78k
      for (int i = i0; i < i1; i++)
1292
3.33k
      {
1293
3.33k
        int k = i * nCols + j0;
1294
3.33k
        int m = k * nDim + iDim;
1295
1296
9.16k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
5.83k
          if (m_bitMask.IsValid(k))
1298
2.39k
            data[m] = (T)offset;
1299
3.33k
      }
1300
2.45k
    }
1301
463
    else
1302
463
    {
1303
463
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
463
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
100
        return false;
1306
1307
363
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
363
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
363
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
363
      if (bufferVec.size() == maxElementCount)    // all valid
1312
97
      {
1313
291
        for (int i = i0; i < i1; i++)
1314
194
        {
1315
194
          int k = i * nCols + j0;
1316
194
          int m = k * nDim + iDim;
1317
1318
580
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
386
          {
1320
386
            double z = offset + *srcPtr++ * invScale;
1321
386
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
386
          }
1323
194
        }
1324
97
      }
1325
266
      else    // not all valid
1326
266
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
266
        {
1346
266
          size_t bufferVecIdx = 0;
1347
1348
766
          for (int i = i0; i < i1; i++)
1349
533
          {
1350
533
            int k = i * nCols + j0;
1351
533
            int m = k * nDim + iDim;
1352
1353
1.84k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
1.34k
              if (m_bitMask.IsValid(k))
1355
462
              {
1356
462
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
33
                  return false;
1358
1359
429
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
429
                bufferVecIdx++;
1361
429
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
429
              }
1363
533
          }
1364
266
        }
1365
266
      }
1366
363
    }
1367
2.91k
  }
1368
1369
5.46k
  *ppByte = ptr;
1370
5.46k
  nBytesRemainingInOut = nBytesRemaining;
1371
5.46k
  return true;
1372
6.90k
}
bool GDAL_LercNS::Lerc2::ReadTile<double>(unsigned char const**, unsigned long&, double*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const
Line
Count
Source
1213
4.54k
{
1214
4.54k
  const Byte* ptr = *ppByte;
1215
4.54k
  size_t nBytesRemaining = nBytesRemainingInOut;
1216
1217
4.54k
  if (nBytesRemaining < 1)
1218
56
    return false;
1219
1220
4.48k
  Byte comprFlag = *ptr++;
1221
4.48k
  nBytesRemaining--;
1222
1223
4.48k
  int bits67 = comprFlag >> 6;
1224
4.48k
  int testCode = (comprFlag >> 2) & 15;    // use bits 2345 for integrity check
1225
4.48k
  if (testCode != ((j0 >> 3) & 15))
1226
248
    return false;
1227
1228
4.23k
  const HeaderInfo& hd = m_headerInfo;
1229
4.23k
  int nCols = hd.nCols;
1230
4.23k
  int nDim = hd.nDim;
1231
1232
4.23k
  comprFlag &= 3;
1233
1234
4.23k
  if (comprFlag == 2)    // entire tile is constant 0 (all the valid pixels)
1235
1.18k
  {
1236
4.01k
    for (int i = i0; i < i1; i++)
1237
2.82k
    {
1238
2.82k
      int k = i * nCols + j0;
1239
2.82k
      int m = k * nDim + iDim;
1240
1241
8.79k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1242
5.96k
        if (m_bitMask.IsValid(k))
1243
2.23k
          data[m] = 0;
1244
2.82k
    }
1245
1246
1.18k
    *ppByte = ptr;
1247
1.18k
    nBytesRemainingInOut = nBytesRemaining;
1248
1.18k
    return true;
1249
1.18k
  }
1250
1251
3.05k
  else if (comprFlag == 0)    // read z's binary uncompressed
1252
2.19k
  {
1253
2.19k
    const T* srcPtr = (const T*)ptr;
1254
2.19k
    int cnt = 0;
1255
1256
16.0k
    for (int i = i0; i < i1; i++)
1257
13.9k
    {
1258
13.9k
      int k = i * nCols + j0;
1259
13.9k
      int m = k * nDim + iDim;
1260
1261
55.3k
      for (int j = j0; j < j1; j++, k++, m += nDim)
1262
41.5k
        if (m_bitMask.IsValid(k))
1263
2.89k
        {
1264
2.89k
          if (nBytesRemaining < sizeof(T))
1265
94
            return false;
1266
1267
2.80k
          data[m] = *srcPtr++;
1268
2.80k
          nBytesRemaining -= sizeof(T);
1269
1270
2.80k
          cnt++;
1271
2.80k
        }
1272
13.9k
    }
1273
1274
2.09k
    ptr += cnt * sizeof(T);
1275
2.09k
  }
1276
858
  else
1277
858
  {
1278
    // read z's as int arr bit stuffed
1279
858
    DataType dtUsed = GetDataTypeUsed(bits67);
1280
858
    if( dtUsed == DT_Undefined )
1281
0
      return false;
1282
858
    size_t n = GetDataTypeSize(dtUsed);
1283
858
    if (nBytesRemaining < n)
1284
41
      return false;
1285
1286
817
    double offset = ReadVariableDataType(&ptr, dtUsed);
1287
817
    nBytesRemaining -= n;
1288
1289
817
    if (comprFlag == 3)    // entire tile is constant zMin (all the valid pixels)
1290
710
    {
1291
1.72k
      for (int i = i0; i < i1; i++)
1292
1.01k
      {
1293
1.01k
        int k = i * nCols + j0;
1294
1.01k
        int m = k * nDim + iDim;
1295
1296
3.13k
        for (int j = j0; j < j1; j++, k++, m += nDim)
1297
2.11k
          if (m_bitMask.IsValid(k))
1298
961
            data[m] = (T)offset;
1299
1.01k
      }
1300
710
    }
1301
107
    else
1302
107
    {
1303
107
      size_t maxElementCount = (i1 - i0) * (j1 - j0);
1304
107
      if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version))
1305
47
        return false;
1306
1307
60
      double invScale = 2 * hd.maxZError;    // for int types this is int
1308
60
      double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax;
1309
60
      const unsigned int* srcPtr = bufferVec.data();
1310
1311
60
      if (bufferVec.size() == maxElementCount)    // all valid
1312
0
      {
1313
0
        for (int i = i0; i < i1; i++)
1314
0
        {
1315
0
          int k = i * nCols + j0;
1316
0
          int m = k * nDim + iDim;
1317
1318
0
          for (int j = j0; j < j1; j++, k++, m += nDim)
1319
0
          {
1320
0
            double z = offset + *srcPtr++ * invScale;
1321
0
            data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1322
0
          }
1323
0
        }
1324
0
      }
1325
60
      else    // not all valid
1326
60
      {
1327
#ifndef GDAL_COMPILATION
1328
        if (hd.version > 2)
1329
        {
1330
          for (int i = i0; i < i1; i++)
1331
          {
1332
            int k = i * nCols + j0;
1333
            int m = k * nDim + iDim;
1334
1335
            for (int j = j0; j < j1; j++, k++, m += nDim)
1336
              if (m_bitMask.IsValid(k))
1337
              {
1338
                double z = offset + *srcPtr++ * invScale;
1339
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1340
              }
1341
          }
1342
        }
1343
        else  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1344
#endif
1345
60
        {
1346
60
          size_t bufferVecIdx = 0;
1347
1348
211
          for (int i = i0; i < i1; i++)
1349
190
          {
1350
190
            int k = i * nCols + j0;
1351
190
            int m = k * nDim + iDim;
1352
1353
1.23k
            for (int j = j0; j < j1; j++, k++, m += nDim)
1354
1.08k
              if (m_bitMask.IsValid(k))
1355
160
              {
1356
160
                if (bufferVecIdx == bufferVec.size())  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
1357
39
                  return false;
1358
1359
121
                double z = offset + bufferVec[bufferVecIdx] * invScale;
1360
121
                bufferVecIdx++;
1361
121
                data[m] = (T)std::min(z, zMax);    // make sure we stay in the orig range
1362
121
              }
1363
190
          }
1364
60
        }
1365
60
      }
1366
60
    }
1367
817
  }
1368
1369
2.82k
  *ppByte = ptr;
1370
2.82k
  nBytesRemainingInOut = nBytesRemaining;
1371
2.82k
  return true;
1372
4.23k
}
1373
1374
// -------------------------------------------------------------------------- ;
1375
1376
template<class T>
1377
int Lerc2::TypeCode(T z, DataType& dtUsed) const
1378
0
{
1379
0
  Byte b = (Byte)z;
1380
0
  DataType dt = m_headerInfo.dt;
1381
0
  switch (dt)
1382
0
  {
1383
0
    case DT_Short:
1384
0
    {
1385
0
      signed char c = (signed char)z;
1386
0
      int tc = (T)c == z ? 2 : (T)b == z ? 1 : 0;
1387
0
      dtUsed = (DataType)(dt - tc);
1388
0
      return tc;
1389
0
    }
1390
0
    case DT_UShort:
1391
0
    {
1392
0
      int tc = (T)b == z ? 1 : 0;
1393
0
      dtUsed = (DataType)(dt - 2 * tc);
1394
0
      return tc;
1395
0
    }
1396
0
    case DT_Int:
1397
0
    {
1398
0
      short s = (short)z;
1399
0
      unsigned short us = (unsigned short)z;
1400
0
      int tc = (T)b == z ? 3 : (T)s == z ? 2 : (T)us == z ? 1 : 0;
1401
0
      dtUsed = (DataType)(dt - tc);
1402
0
      return tc;
1403
0
    }
1404
0
    case DT_UInt:
1405
0
    {
1406
0
      unsigned short us = (unsigned short)z;
1407
0
      int tc = (T)b == z ? 2 : (T)us == z ? 1 : 0;
1408
0
      dtUsed = (DataType)(dt - 2 * tc);
1409
0
      return tc;
1410
0
    }
1411
0
    case DT_Float:
1412
0
    {
1413
0
      short s = (short)z;
1414
0
      int tc = (T)b == z ? 2 : (T)s == z ? 1 : 0;
1415
0
      dtUsed = tc == 0 ? dt : (tc == 1 ? DT_Short : DT_Byte);
1416
0
      return tc;
1417
0
    }
1418
0
    case DT_Double:
1419
0
    {
1420
0
      short s = (short)z;
1421
0
      int l = (int)z;
1422
0
      float f = (float)z;
1423
0
      int tc = (T)s == z ? 3 : (T)l == z ? 2 : (T)f == z ? 1 : 0;
1424
0
      dtUsed = tc == 0 ? dt : (DataType)(dt - 2 * tc + 1);
1425
0
      return tc;
1426
0
    }
1427
0
    default:
1428
0
    {
1429
0
      dtUsed = dt;
1430
0
      return 0;
1431
0
    }
1432
0
  }
1433
0
}
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<signed char>(signed char, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<unsigned char>(unsigned char, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<short>(short, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<unsigned short>(unsigned short, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<int>(int, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<unsigned int>(unsigned int, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<float>(float, GDAL_LercNS::Lerc2::DataType&) const
Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<double>(double, GDAL_LercNS::Lerc2::DataType&) const
1434
1435
// -------------------------------------------------------------------------- ;
1436
1437
inline Lerc2::DataType Lerc2::ValidateDataType(int dt)
1438
13.0k
{
1439
13.0k
  if( dt >= DT_Char && dt <= DT_Double )
1440
12.8k
    return static_cast<DataType>(dt);
1441
147
  return DT_Undefined;
1442
13.0k
}
1443
1444
// -------------------------------------------------------------------------- ;
1445
1446
inline
1447
Lerc2::DataType Lerc2::GetDataTypeUsed(int tc) const
1448
32.4k
{
1449
32.4k
  DataType dt = m_headerInfo.dt;
1450
32.4k
  switch (dt)
1451
32.4k
  {
1452
2.55k
    case DT_Short:
1453
4.36k
    case DT_Int:     return ValidateDataType(dt - tc);
1454
3.21k
    case DT_UShort:
1455
7.95k
    case DT_UInt:    return ValidateDataType(dt - 2 * tc);
1456
2.93k
    case DT_Float:   return tc == 0 ? dt : (tc == 1 ? DT_Short : DT_Byte);
1457
858
    case DT_Double:  return tc == 0 ? dt : ValidateDataType(dt - 2 * tc + 1);
1458
16.3k
    default:
1459
16.3k
      return dt;
1460
32.4k
  }
1461
32.4k
}
1462
1463
// -------------------------------------------------------------------------- ;
1464
1465
inline
1466
bool Lerc2::WriteVariableDataType(Byte** ppByte, double z, DataType dtUsed)
1467
0
{
1468
0
  Byte* ptr = *ppByte;
1469
1470
0
  switch (dtUsed)
1471
0
  {
1472
0
    case DT_Char:
1473
0
    {
1474
0
      *((signed char*)ptr) = (signed char)z;
1475
0
      ptr++;
1476
0
      break;
1477
0
    }
1478
0
    case DT_Byte:
1479
0
    {
1480
0
      *((Byte*)ptr) = (Byte)z;
1481
0
      ptr++;
1482
0
      break;
1483
0
    }
1484
0
    case DT_Short:
1485
0
    {
1486
0
      short s = (short)z;
1487
0
      memcpy(ptr, &s, sizeof(short));
1488
0
      ptr += 2;
1489
0
      break;
1490
0
    }
1491
0
    case DT_UShort:
1492
0
    {
1493
0
      unsigned short us = (unsigned short)z;
1494
0
      memcpy(ptr, &us, sizeof(unsigned short));
1495
0
      ptr += 2;
1496
0
      break;
1497
0
    }
1498
0
    case DT_Int:
1499
0
    {
1500
0
      int i = (int)z;
1501
0
      memcpy(ptr, &i, sizeof(int));
1502
0
      ptr += 4;
1503
0
      break;
1504
0
    }
1505
0
    case DT_UInt:
1506
0
    {
1507
0
      unsigned int n = (unsigned int)z;
1508
0
      memcpy(ptr, &n, sizeof(unsigned int));
1509
0
      ptr += 4;
1510
0
      break;
1511
0
    }
1512
0
    case DT_Float:
1513
0
    {
1514
0
      float f = (float)z;
1515
0
      memcpy(ptr, &f, sizeof(float));
1516
0
      ptr += 4;
1517
0
      break;
1518
0
    }
1519
0
    case DT_Double:
1520
0
    {
1521
0
      memcpy(ptr, &z, sizeof(double));
1522
0
      ptr += 8;
1523
0
      break;
1524
0
    }
1525
1526
0
    default:
1527
0
      return false;
1528
0
  }
1529
1530
0
  *ppByte = ptr;
1531
0
  return true;
1532
0
}
1533
1534
// -------------------------------------------------------------------------- ;
1535
1536
inline
1537
double Lerc2::ReadVariableDataType(const Byte** ppByte, DataType dtUsed)
1538
32.0k
{
1539
32.0k
  const Byte* ptr = *ppByte;
1540
1541
32.0k
  switch (dtUsed)
1542
32.0k
  {
1543
11.1k
    case DT_Char:
1544
11.1k
    {
1545
11.1k
      signed char c = *((signed char*)ptr);
1546
11.1k
      *ppByte = ptr + 1;
1547
11.1k
      return c;
1548
0
    }
1549
11.8k
    case DT_Byte:
1550
11.8k
    {
1551
11.8k
      Byte b = *((Byte*)ptr);
1552
11.8k
      *ppByte = ptr + 1;
1553
11.8k
      return b;
1554
0
    }
1555
1.57k
    case DT_Short:
1556
1.57k
    {
1557
1.57k
      short s;
1558
1.57k
      memcpy(&s, ptr, sizeof(short));
1559
1.57k
      *ppByte = ptr + 2;
1560
1.57k
      return s;
1561
0
    }
1562
3.62k
    case DT_UShort:
1563
3.62k
    {
1564
3.62k
      unsigned short us;
1565
3.62k
      memcpy(&us, ptr, sizeof(unsigned short));
1566
3.62k
      *ppByte = ptr + 2;
1567
3.62k
      return us;
1568
0
    }
1569
1.14k
    case DT_Int:
1570
1.14k
    {
1571
1.14k
      int i;
1572
1.14k
      memcpy(&i, ptr, sizeof(int));
1573
1.14k
      *ppByte = ptr + 4;
1574
1.14k
      return i;
1575
0
    }
1576
2.09k
    case DT_UInt:
1577
2.09k
    {
1578
2.09k
      unsigned int n;
1579
2.09k
      memcpy(&n, ptr, sizeof(unsigned int));
1580
2.09k
      *ppByte = ptr + 4;
1581
2.09k
      return n;
1582
0
    }
1583
482
    case DT_Float:
1584
482
    {
1585
482
      float f;
1586
482
      memcpy(&f, ptr, sizeof(float));
1587
482
      *ppByte = ptr + 4;
1588
482
      return f;
1589
0
    }
1590
137
    case DT_Double:
1591
137
    {
1592
137
      double d;
1593
137
      memcpy(&d, ptr, sizeof(double));
1594
137
      *ppByte = ptr + 8;
1595
137
      return d;
1596
0
    }
1597
0
    default:
1598
0
      return 0;
1599
32.0k
  }
1600
32.0k
}
1601
1602
// -------------------------------------------------------------------------- ;
1603
1604
template<class T>
1605
Lerc2::DataType Lerc2::GetDataType(T z) const
1606
0
{
1607
0
  const std::type_info& ti = typeid(z);
1608
1609
0
       if (ti == typeid(signed char))     return DT_Char;
1610
0
  else if (ti == typeid(Byte))            return DT_Byte;
1611
0
  else if (ti == typeid(short))           return DT_Short;
1612
0
  else if (ti == typeid(unsigned short))  return DT_UShort;
1613
0
  else if (ti == typeid(int ) && sizeof(int ) == 4)   return DT_Int;
1614
0
  else if (ti == typeid(long) && sizeof(long) == 4)   return DT_Int;
1615
0
  else if (ti == typeid(unsigned int ) && sizeof(unsigned int ) == 4)   return DT_UInt;
1616
0
  else if (ti == typeid(unsigned long) && sizeof(unsigned long) == 4)   return DT_UInt;
1617
0
  else if (ti == typeid(float))           return DT_Float;
1618
0
  else if (ti == typeid(double))          return DT_Double;
1619
0
  else
1620
0
    return DT_Undefined;
1621
0
}
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<signed char>(signed char) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<unsigned char>(unsigned char) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<short>(short) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<unsigned short>(unsigned short) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<int>(int) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<unsigned int>(unsigned int) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<float>(float) const
Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<double>(double) const
1622
1623
// -------------------------------------------------------------------------- ;
1624
1625
inline
1626
unsigned int Lerc2::GetMaxValToQuantize(DataType dt)
1627
0
{
1628
0
  switch (dt)
1629
0
  {
1630
0
    case DT_Char:
1631
0
    case DT_Byte:    //return (1 <<  7) - 1;    // disabled: allow LUT mode for 8 bit segmented
1632
0
    case DT_Short:
1633
0
    case DT_UShort:  return (1 << 15) - 1;
1634
1635
0
    case DT_Int:
1636
0
    case DT_UInt:
1637
0
    case DT_Float:
1638
0
    case DT_Double:  return (1 << 30) - 1;
1639
1640
0
    default:
1641
0
      return 0;
1642
0
  }
1643
0
}
1644
1645
// -------------------------------------------------------------------------- ;
1646
1647
inline
1648
unsigned int Lerc2::GetDataTypeSize(DataType dt)
1649
32.2k
{
1650
32.2k
  switch (dt)
1651
32.2k
  {
1652
11.1k
    case DT_Char:
1653
23.0k
    case DT_Byte:   return 1;
1654
1.61k
    case DT_Short:
1655
5.28k
    case DT_UShort: return 2;
1656
1.15k
    case DT_Int:
1657
3.30k
    case DT_UInt:
1658
3.83k
    case DT_Float:  return 4;
1659
141
    case DT_Double: return 8;
1660
1661
0
    default:
1662
0
      return 0;
1663
32.2k
  }
1664
32.2k
}
1665
1666
// -------------------------------------------------------------------------- ;
1667
1668
template<class T>
1669
void Lerc2::ComputeHuffmanCodes(const T* data, int& numBytes, ImageEncodeMode& imageEncodeMode, std::vector<std::pair<unsigned short, unsigned int> >& codes) const
1670
0
{
1671
0
  std::vector<int> histo, deltaHisto;
1672
0
  ComputeHistoForHuffman(data, histo, deltaHisto);
1673
1674
0
  int nBytes0 = 0, nBytes1 = 0;
1675
0
  double avgBpp0 = 0, avgBpp1 = 0;
1676
0
  Huffman huffman0, huffman1;
1677
1678
0
  if (m_headerInfo.version >= 4)
1679
0
  {
1680
0
    if (!huffman0.ComputeCodes(histo) || !huffman0.ComputeCompressedSize(histo, nBytes0, avgBpp0))
1681
0
      nBytes0 = 0;
1682
0
  }
1683
1684
0
  if (!huffman1.ComputeCodes(deltaHisto) || !huffman1.ComputeCompressedSize(deltaHisto, nBytes1, avgBpp1))
1685
0
    nBytes1 = 0;
1686
1687
0
  if (nBytes0 > 0 && nBytes1 > 0)    // regular case, pick the better of the two
1688
0
  {
1689
0
    imageEncodeMode = (nBytes0 <= nBytes1) ? IEM_Huffman : IEM_DeltaHuffman;
1690
0
    codes = (nBytes0 <= nBytes1) ? huffman0.GetCodes() : huffman1.GetCodes();
1691
0
    numBytes = (std::min)(nBytes0, nBytes1);
1692
0
  }
1693
0
  else if (nBytes0 == 0 && nBytes1 == 0)    // rare case huffman cannot handle, fall back to tiling
1694
0
  {
1695
0
    imageEncodeMode = IEM_Tiling;
1696
0
    codes.resize(0);
1697
0
    numBytes = 0;
1698
0
  }
1699
0
  else    // rare also, pick the valid one, the other is 0
1700
0
  {
1701
0
    imageEncodeMode = (nBytes0 > nBytes1) ? IEM_Huffman : IEM_DeltaHuffman;
1702
0
    codes = (nBytes0 > nBytes1) ? huffman0.GetCodes() : huffman1.GetCodes();
1703
0
    numBytes = (std::max)(nBytes0, nBytes1);
1704
0
  }
1705
0
}
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<signed char>(signed char const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<unsigned char>(unsigned char const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<short>(short const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<unsigned short>(unsigned short const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<int>(int const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<unsigned int>(unsigned int const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<float>(float const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<double>(double const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const
1706
1707
// -------------------------------------------------------------------------- ;
1708
1709
template<class T>
1710
void Lerc2::ComputeHistoForHuffman(const T* data, std::vector<int>& histo, std::vector<int>& deltaHisto) const
1711
0
{
1712
0
  histo.resize(256);
1713
0
  deltaHisto.resize(256);
1714
1715
0
  memset(&histo[0], 0, histo.size() * sizeof(int));
1716
0
  memset(&deltaHisto[0], 0, deltaHisto.size() * sizeof(int));
1717
1718
0
  int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0;
1719
0
  int height = m_headerInfo.nRows;
1720
0
  int width = m_headerInfo.nCols;
1721
0
  int nDim = m_headerInfo.nDim;
1722
1723
0
  if (m_headerInfo.numValidPixel == width * height)    // all valid
1724
0
  {
1725
0
    for (int iDim = 0; iDim < nDim; iDim++)
1726
0
    {
1727
0
      T prevVal = 0;
1728
0
      for (int m = iDim, i = 0; i < height; i++)
1729
0
        for (int j = 0; j < width; j++, m += nDim)
1730
0
        {
1731
0
          T val = data[m];
1732
0
          T delta = val;
1733
1734
0
          if (j > 0)
1735
0
            delta -= prevVal;    // use overflow
1736
0
          else if (i > 0)
1737
0
            delta -= data[m - width * nDim];
1738
0
          else
1739
0
            delta -= prevVal;
1740
1741
0
          prevVal = val;
1742
1743
0
          histo[offset + (int)val]++;
1744
0
          deltaHisto[offset + (int)delta]++;
1745
0
        }
1746
0
    }
1747
0
  }
1748
0
  else    // not all valid
1749
0
  {
1750
0
    for (int iDim = 0; iDim < nDim; iDim++)
1751
0
    {
1752
0
      T prevVal = 0;
1753
0
      for (int k = 0, m = iDim, i = 0; i < height; i++)
1754
0
        for (int j = 0; j < width; j++, k++, m += nDim)
1755
0
          if (m_bitMask.IsValid(k))
1756
0
          {
1757
0
            T val = data[m];
1758
0
            T delta = val;
1759
1760
0
            if (j > 0 && m_bitMask.IsValid(k - 1))
1761
0
            {
1762
0
              delta -= prevVal;    // use overflow
1763
0
            }
1764
0
            else if (i > 0 && m_bitMask.IsValid(k - width))
1765
0
            {
1766
0
              delta -= data[m - width * nDim];
1767
0
            }
1768
0
            else
1769
0
              delta -= prevVal;
1770
1771
0
            prevVal = val;
1772
1773
0
            histo[offset + (int)val]++;
1774
0
            deltaHisto[offset + (int)delta]++;
1775
0
          }
1776
0
    }
1777
0
  }
1778
0
}
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<signed char>(signed char const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<unsigned char>(unsigned char const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<short>(short const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<unsigned short>(unsigned short const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<int>(int const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<unsigned int>(unsigned int const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<float>(float const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<double>(double const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const
1779
1780
// -------------------------------------------------------------------------- ;
1781
1782
template<class T>
1783
bool Lerc2::EncodeHuffman(const T* data, Byte** ppByte) const
1784
0
{
1785
0
  if (!data || !ppByte)
1786
0
    return false;
1787
1788
0
  Huffman huffman;
1789
0
  if (!huffman.SetCodes(m_huffmanCodes) || !huffman.WriteCodeTable(ppByte, m_headerInfo.version))    // header and code table
1790
0
    return false;
1791
1792
0
  int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0;
1793
0
  int height = m_headerInfo.nRows;
1794
0
  int width = m_headerInfo.nCols;
1795
0
  int nDim = m_headerInfo.nDim;
1796
1797
0
  unsigned int* arr = (unsigned int*)(*ppByte);
1798
0
  unsigned int* dstPtr = arr;
1799
0
  int bitPos = 0;
1800
1801
0
  if (m_imageEncodeMode == IEM_DeltaHuffman)
1802
0
  {
1803
0
    for (int iDim = 0; iDim < nDim; iDim++)
1804
0
    {
1805
0
      T prevVal = 0;
1806
0
      for (int k = 0, m = iDim, i = 0; i < height; i++)
1807
0
        for (int j = 0; j < width; j++, k++, m += nDim)
1808
0
          if (m_bitMask.IsValid(k))
1809
0
          {
1810
0
            T val = data[m];
1811
0
            T delta = val;
1812
1813
0
            if (j > 0 && m_bitMask.IsValid(k - 1))
1814
0
            {
1815
0
              delta -= prevVal;    // use overflow
1816
0
            }
1817
0
            else if (i > 0 && m_bitMask.IsValid(k - width))
1818
0
            {
1819
0
              delta -= data[m - width * nDim];
1820
0
            }
1821
0
            else
1822
0
              delta -= prevVal;
1823
1824
0
            prevVal = val;
1825
1826
            // bit stuff the huffman code for this delta
1827
0
            int kBin = offset + (int)delta;
1828
0
            int len = m_huffmanCodes[kBin].first;
1829
0
            if (len <= 0)
1830
0
              return false;
1831
1832
0
            unsigned int code = m_huffmanCodes[kBin].second;
1833
1834
0
            if (32 - bitPos >= len)
1835
0
            {
1836
0
              if (bitPos == 0)
1837
0
                *dstPtr = 0;
1838
1839
0
              *dstPtr |= code << (32 - bitPos - len);
1840
0
              bitPos += len;
1841
0
              if (bitPos == 32)
1842
0
              {
1843
0
                bitPos = 0;
1844
0
                dstPtr++;
1845
0
              }
1846
0
            }
1847
0
            else
1848
0
            {
1849
0
              bitPos += len - 32;
1850
0
              *dstPtr++ |= code >> bitPos;
1851
0
              *dstPtr = code << (32 - bitPos);
1852
0
            }
1853
0
          }
1854
0
    }
1855
0
  }
1856
1857
0
  else if (m_imageEncodeMode == IEM_Huffman)
1858
0
  {
1859
0
    for (int k = 0, m0 = 0, i = 0; i < height; i++)
1860
0
      for (int j = 0; j < width; j++, k++, m0 += nDim)
1861
0
        if (m_bitMask.IsValid(k))
1862
0
          for (int m = 0; m < nDim; m++)
1863
0
          {
1864
0
            T val = data[m0 + m];
1865
1866
            // bit stuff the huffman code for this val
1867
0
            int kBin = offset + (int)val;
1868
0
            int len = m_huffmanCodes[kBin].first;
1869
0
            if (len <= 0)
1870
0
              return false;
1871
1872
0
            unsigned int code = m_huffmanCodes[kBin].second;
1873
1874
0
            if (32 - bitPos >= len)
1875
0
            {
1876
0
              if (bitPos == 0)
1877
0
                *dstPtr = 0;
1878
1879
0
              *dstPtr |= code << (32 - bitPos - len);
1880
0
              bitPos += len;
1881
0
              if (bitPos == 32)
1882
0
              {
1883
0
                bitPos = 0;
1884
0
                dstPtr++;
1885
0
              }
1886
0
            }
1887
0
            else
1888
0
            {
1889
0
              bitPos += len - 32;
1890
0
              *dstPtr++ |= code >> bitPos;
1891
0
              *dstPtr = code << (32 - bitPos);
1892
0
            }
1893
0
          }
1894
0
  }
1895
1896
0
  else
1897
0
    return false;
1898
1899
0
  size_t numUInts = dstPtr - arr + (bitPos > 0 ? 1 : 0) + 1;    // add one more as the decode LUT can read ahead
1900
0
  *ppByte += numUInts * sizeof(unsigned int);
1901
0
  return true;
1902
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<signed char>(signed char const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<unsigned char>(unsigned char const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<short>(short const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<unsigned short>(unsigned short const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<int>(int const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<unsigned int>(unsigned int const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<float>(float const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<double>(double const*, unsigned char**) const
1903
1904
// -------------------------------------------------------------------------- ;
1905
1906
template<class T>
1907
bool Lerc2::DecodeHuffman(const Byte** ppByte, size_t& nBytesRemainingInOut, T* data) const
1908
9.92k
{
1909
9.92k
  if (!data || !ppByte || !(*ppByte))
1910
0
    return false;
1911
1912
9.92k
  Huffman huffman;
1913
9.92k
  if (!huffman.ReadCodeTable(ppByte, nBytesRemainingInOut, m_headerInfo.version))    // header and code table
1914
2.25k
    return false;
1915
1916
7.66k
  int numBitsLUT = 0;
1917
7.66k
  if (!huffman.BuildTreeFromCodes(numBitsLUT))
1918
168
    return false;
1919
1920
7.49k
  int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0;
1921
7.49k
  int height = m_headerInfo.nRows;
1922
7.49k
  int width = m_headerInfo.nCols;
1923
7.49k
  int nDim = m_headerInfo.nDim;
1924
1925
7.49k
  const unsigned int* arr = (const unsigned int*)(*ppByte);
1926
7.49k
  const unsigned int* srcPtr = arr;
1927
7.49k
  int bitPos = 0;
1928
7.49k
  size_t nBytesRemaining = nBytesRemainingInOut;
1929
1930
7.49k
  if (m_headerInfo.numValidPixel == width * height)    // all valid
1931
3.41k
  {
1932
3.41k
    if (m_imageEncodeMode == IEM_DeltaHuffman)
1933
1.61k
    {
1934
6.96k
      for (int iDim = 0; iDim < nDim; iDim++)
1935
6.84k
      {
1936
6.84k
        T prevVal = 0;
1937
57.8k
        for (int m = iDim, i = 0; i < height; i++)
1938
1.09M
          for (int j = 0; j < width; j++, m += nDim)
1939
1.04M
          {
1940
1.04M
            int val = 0;
1941
1.04M
            if (nBytesRemaining >= 4 * sizeof(unsigned int))
1942
1.01M
            {
1943
1.01M
              if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1944
404
                return false;
1945
1.01M
            }
1946
28.1k
            else
1947
28.1k
            {
1948
28.1k
              if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1949
1.09k
                return false;
1950
28.1k
            }
1951
1952
1.04M
            T delta = (T)(val - offset);
1953
1954
1.04M
            if (j > 0)
1955
990k
              delta += prevVal;    // use overflow
1956
52.1k
            else if (i > 0)
1957
45.4k
              delta += data[m - width * nDim];
1958
6.71k
            else
1959
6.71k
              delta += prevVal;
1960
1961
1.04M
            data[m] = delta;
1962
1.04M
            prevVal = delta;
1963
1.04M
          }
1964
6.84k
      }
1965
1.61k
    }
1966
1967
1.79k
    else if (m_imageEncodeMode == IEM_Huffman)
1968
1.79k
    {
1969
8.43k
      for (int k = 0, m0 = 0, i = 0; i < height; i++)
1970
115k
        for (int j = 0; j < width; j++, k++, m0 += nDim)
1971
3.57M
          for (int m = 0; m < nDim; m++)
1972
3.47M
          {
1973
3.47M
            int val = 0;
1974
3.47M
            if (nBytesRemaining >= 4 * sizeof(unsigned int))
1975
3.43M
            {
1976
3.43M
              if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1977
440
                return false;
1978
3.43M
            }
1979
30.8k
            else
1980
30.8k
            {
1981
30.8k
              if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1982
1.23k
                return false;
1983
30.8k
            }
1984
1985
3.46M
            data[m0 + m] = (T)(val - offset);
1986
3.46M
          }
1987
1.79k
    }
1988
1989
0
    else
1990
0
      return false;
1991
3.41k
  }
1992
1993
4.08k
  else    // not all valid
1994
4.08k
  {
1995
4.08k
    if (m_imageEncodeMode == IEM_DeltaHuffman)
1996
1.96k
    {
1997
5.44k
      for (int iDim = 0; iDim < nDim; iDim++)
1998
5.25k
      {
1999
5.25k
        T prevVal = 0;
2000
486k
        for (int k = 0, m = iDim, i = 0; i < height; i++)
2001
33.1M
          for (int j = 0; j < width; j++, k++, m += nDim)
2002
32.6M
            if (m_bitMask.IsValid(k))
2003
485k
            {
2004
485k
              int val = 0;
2005
485k
              if (nBytesRemaining >= 4 * sizeof(unsigned int))
2006
454k
              {
2007
454k
                if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2008
535
                  return false;
2009
454k
              }
2010
30.3k
              else
2011
30.3k
              {
2012
30.3k
                if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2013
1.23k
                  return false;
2014
30.3k
              }
2015
2016
483k
              T delta = (T)(val - offset);
2017
2018
483k
              if (j > 0 && m_bitMask.IsValid(k - 1))
2019
265k
              {
2020
265k
                delta += prevVal;    // use overflow
2021
265k
              }
2022
217k
              else if (i > 0 && m_bitMask.IsValid(k - width))
2023
52.1k
              {
2024
52.1k
                delta += data[m - width * nDim];
2025
52.1k
              }
2026
165k
              else
2027
165k
                delta += prevVal;
2028
2029
483k
              data[m] = delta;
2030
483k
              prevVal = delta;
2031
483k
            }
2032
5.25k
      }
2033
1.96k
    }
2034
2035
2.12k
    else if (m_imageEncodeMode == IEM_Huffman)
2036
2.12k
    {
2037
14.0k
      for (int k = 0, m0 = 0, i = 0; i < height; i++)
2038
340k
        for (int j = 0; j < width; j++, k++, m0 += nDim)
2039
328k
          if (m_bitMask.IsValid(k))
2040
12.2M
            for (int m = 0; m < nDim; m++)
2041
12.1M
            {
2042
12.1M
              int val = 0;
2043
12.1M
              if (nBytesRemaining >= 4 * sizeof(unsigned int))
2044
12.1M
              {
2045
12.1M
                if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2046
567
                  return false;
2047
12.1M
              }
2048
36.3k
              else
2049
36.3k
              {
2050
36.3k
                if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2051
1.29k
                  return false;
2052
36.3k
              }
2053
2054
12.1M
              data[m0 + m] = (T)(val - offset);
2055
12.1M
            }
2056
2.12k
    }
2057
2058
0
    else
2059
0
      return false;
2060
4.08k
  }
2061
2062
692
  size_t numUInts = srcPtr - arr + (bitPos > 0 ? 1 : 0) + 1;    // add one more as the decode LUT can read ahead
2063
692
  size_t len = numUInts * sizeof(unsigned int);
2064
2065
692
  if (nBytesRemainingInOut < len)
2066
59
    return false;
2067
2068
633
  *ppByte += len;
2069
633
  nBytesRemainingInOut -= len;
2070
633
  return true;
2071
692
}
bool GDAL_LercNS::Lerc2::DecodeHuffman<signed char>(unsigned char const**, unsigned long&, signed char*) const
Line
Count
Source
1908
2.42k
{
1909
2.42k
  if (!data || !ppByte || !(*ppByte))
1910
0
    return false;
1911
1912
2.42k
  Huffman huffman;
1913
2.42k
  if (!huffman.ReadCodeTable(ppByte, nBytesRemainingInOut, m_headerInfo.version))    // header and code table
1914
453
    return false;
1915
1916
1.96k
  int numBitsLUT = 0;
1917
1.96k
  if (!huffman.BuildTreeFromCodes(numBitsLUT))
1918
47
    return false;
1919
1920
1.92k
  int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0;
1921
1.92k
  int height = m_headerInfo.nRows;
1922
1.92k
  int width = m_headerInfo.nCols;
1923
1.92k
  int nDim = m_headerInfo.nDim;
1924
1925
1.92k
  const unsigned int* arr = (const unsigned int*)(*ppByte);
1926
1.92k
  const unsigned int* srcPtr = arr;
1927
1.92k
  int bitPos = 0;
1928
1.92k
  size_t nBytesRemaining = nBytesRemainingInOut;
1929
1930
1.92k
  if (m_headerInfo.numValidPixel == width * height)    // all valid
1931
874
  {
1932
874
    if (m_imageEncodeMode == IEM_DeltaHuffman)
1933
440
    {
1934
469
      for (int iDim = 0; iDim < nDim; iDim++)
1935
460
      {
1936
460
        T prevVal = 0;
1937
1.88k
        for (int m = iDim, i = 0; i < height; i++)
1938
33.4k
          for (int j = 0; j < width; j++, m += nDim)
1939
32.0k
          {
1940
32.0k
            int val = 0;
1941
32.0k
            if (nBytesRemaining >= 4 * sizeof(unsigned int))
1942
24.3k
            {
1943
24.3k
              if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1944
118
                return false;
1945
24.3k
            }
1946
7.71k
            else
1947
7.71k
            {
1948
7.71k
              if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1949
313
                return false;
1950
7.71k
            }
1951
1952
31.6k
            T delta = (T)(val - offset);
1953
1954
31.6k
            if (j > 0)
1955
29.8k
              delta += prevVal;    // use overflow
1956
1.79k
            else if (i > 0)
1957
1.36k
              delta += data[m - width * nDim];
1958
428
            else
1959
428
              delta += prevVal;
1960
1961
31.6k
            data[m] = delta;
1962
31.6k
            prevVal = delta;
1963
31.6k
          }
1964
460
      }
1965
440
    }
1966
1967
434
    else if (m_imageEncodeMode == IEM_Huffman)
1968
434
    {
1969
762
      for (int k = 0, m0 = 0, i = 0; i < height; i++)
1970
8.08k
        for (int j = 0; j < width; j++, k++, m0 += nDim)
1971
30.5k
          for (int m = 0; m < nDim; m++)
1972
23.1k
          {
1973
23.1k
            int val = 0;
1974
23.1k
            if (nBytesRemaining >= 4 * sizeof(unsigned int))
1975
16.7k
            {
1976
16.7k
              if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1977
115
                return false;
1978
16.7k
            }
1979
6.41k
            else
1980
6.41k
            {
1981
6.41k
              if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1982
314
                return false;
1983
6.41k
            }
1984
1985
22.7k
            data[m0 + m] = (T)(val - offset);
1986
22.7k
          }
1987
434
    }
1988
1989
0
    else
1990
0
      return false;
1991
874
  }
1992
1993
1.04k
  else    // not all valid
1994
1.04k
  {
1995
1.04k
    if (m_imageEncodeMode == IEM_DeltaHuffman)
1996
522
    {
1997
1.07k
      for (int iDim = 0; iDim < nDim; iDim++)
1998
1.03k
      {
1999
1.03k
        T prevVal = 0;
2000
13.9k
        for (int k = 0, m = iDim, i = 0; i < height; i++)
2001
275k
          for (int j = 0; j < width; j++, k++, m += nDim)
2002
262k
            if (m_bitMask.IsValid(k))
2003
28.4k
            {
2004
28.4k
              int val = 0;
2005
28.4k
              if (nBytesRemaining >= 4 * sizeof(unsigned int))
2006
18.4k
              {
2007
18.4k
                if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2008
124
                  return false;
2009
18.4k
              }
2010
10.0k
              else
2011
10.0k
              {
2012
10.0k
                if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2013
360
                  return false;
2014
10.0k
              }
2015
2016
27.9k
              T delta = (T)(val - offset);
2017
2018
27.9k
              if (j > 0 && m_bitMask.IsValid(k - 1))
2019
11.4k
              {
2020
11.4k
                delta += prevVal;    // use overflow
2021
11.4k
              }
2022
16.5k
              else if (i > 0 && m_bitMask.IsValid(k - width))
2023
4.58k
              {
2024
4.58k
                delta += data[m - width * nDim];
2025
4.58k
              }
2026
11.9k
              else
2027
11.9k
                delta += prevVal;
2028
2029
27.9k
              data[m] = delta;
2030
27.9k
              prevVal = delta;
2031
27.9k
            }
2032
1.03k
      }
2033
522
    }
2034
2035
525
    else if (m_imageEncodeMode == IEM_Huffman)
2036
525
    {
2037
2.13k
      for (int k = 0, m0 = 0, i = 0; i < height; i++)
2038
36.1k
        for (int j = 0; j < width; j++, k++, m0 += nDim)
2039
34.5k
          if (m_bitMask.IsValid(k))
2040
27.8k
            for (int m = 0; m < nDim; m++)
2041
23.3k
            {
2042
23.3k
              int val = 0;
2043
23.3k
              if (nBytesRemaining >= 4 * sizeof(unsigned int))
2044
13.0k
              {
2045
13.0k
                if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2046
115
                  return false;
2047
13.0k
              }
2048
10.3k
              else
2049
10.3k
              {
2050
10.3k
                if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2051
371
                  return false;
2052
10.3k
              }
2053
2054
22.8k
              data[m0 + m] = (T)(val - offset);
2055
22.8k
            }
2056
525
    }
2057
2058
0
    else
2059
0
      return false;
2060
1.04k
  }
2061
2062
91
  size_t numUInts = srcPtr - arr + (bitPos > 0 ? 1 : 0) + 1;    // add one more as the decode LUT can read ahead
2063
91
  size_t len = numUInts * sizeof(unsigned int);
2064
2065
91
  if (nBytesRemainingInOut < len)
2066
7
    return false;
2067
2068
84
  *ppByte += len;
2069
84
  nBytesRemainingInOut -= len;
2070
84
  return true;
2071
91
}
bool GDAL_LercNS::Lerc2::DecodeHuffman<unsigned char>(unsigned char const**, unsigned long&, unsigned char*) const
Line
Count
Source
1908
7.49k
{
1909
7.49k
  if (!data || !ppByte || !(*ppByte))
1910
0
    return false;
1911
1912
7.49k
  Huffman huffman;
1913
7.49k
  if (!huffman.ReadCodeTable(ppByte, nBytesRemainingInOut, m_headerInfo.version))    // header and code table
1914
1.80k
    return false;
1915
1916
5.69k
  int numBitsLUT = 0;
1917
5.69k
  if (!huffman.BuildTreeFromCodes(numBitsLUT))
1918
121
    return false;
1919
1920
5.57k
  int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0;
1921
5.57k
  int height = m_headerInfo.nRows;
1922
5.57k
  int width = m_headerInfo.nCols;
1923
5.57k
  int nDim = m_headerInfo.nDim;
1924
1925
5.57k
  const unsigned int* arr = (const unsigned int*)(*ppByte);
1926
5.57k
  const unsigned int* srcPtr = arr;
1927
5.57k
  int bitPos = 0;
1928
5.57k
  size_t nBytesRemaining = nBytesRemainingInOut;
1929
1930
5.57k
  if (m_headerInfo.numValidPixel == width * height)    // all valid
1931
2.53k
  {
1932
2.53k
    if (m_imageEncodeMode == IEM_DeltaHuffman)
1933
1.17k
    {
1934
6.49k
      for (int iDim = 0; iDim < nDim; iDim++)
1935
6.38k
      {
1936
6.38k
        T prevVal = 0;
1937
55.9k
        for (int m = iDim, i = 0; i < height; i++)
1938
1.06M
          for (int j = 0; j < width; j++, m += nDim)
1939
1.01M
          {
1940
1.01M
            int val = 0;
1941
1.01M
            if (nBytesRemaining >= 4 * sizeof(unsigned int))
1942
991k
            {
1943
991k
              if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1944
286
                return false;
1945
991k
            }
1946
20.4k
            else
1947
20.4k
            {
1948
20.4k
              if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1949
783
                return false;
1950
20.4k
            }
1951
1952
1.01M
            T delta = (T)(val - offset);
1953
1954
1.01M
            if (j > 0)
1955
960k
              delta += prevVal;    // use overflow
1956
50.3k
            else if (i > 0)
1957
44.0k
              delta += data[m - width * nDim];
1958
6.29k
            else
1959
6.29k
              delta += prevVal;
1960
1961
1.01M
            data[m] = delta;
1962
1.01M
            prevVal = delta;
1963
1.01M
          }
1964
6.38k
      }
1965
1.17k
    }
1966
1967
1.36k
    else if (m_imageEncodeMode == IEM_Huffman)
1968
1.36k
    {
1969
7.67k
      for (int k = 0, m0 = 0, i = 0; i < height; i++)
1970
107k
        for (int j = 0; j < width; j++, k++, m0 += nDim)
1971
3.54M
          for (int m = 0; m < nDim; m++)
1972
3.44M
          {
1973
3.44M
            int val = 0;
1974
3.44M
            if (nBytesRemaining >= 4 * sizeof(unsigned int))
1975
3.42M
            {
1976
3.42M
              if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1977
325
                return false;
1978
3.42M
            }
1979
24.4k
            else
1980
24.4k
            {
1981
24.4k
              if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
1982
924
                return false;
1983
24.4k
            }
1984
1985
3.44M
            data[m0 + m] = (T)(val - offset);
1986
3.44M
          }
1987
1.36k
    }
1988
1989
0
    else
1990
0
      return false;
1991
2.53k
  }
1992
1993
3.04k
  else    // not all valid
1994
3.04k
  {
1995
3.04k
    if (m_imageEncodeMode == IEM_DeltaHuffman)
1996
1.44k
    {
1997
4.37k
      for (int iDim = 0; iDim < nDim; iDim++)
1998
4.21k
      {
1999
4.21k
        T prevVal = 0;
2000
472k
        for (int k = 0, m = iDim, i = 0; i < height; i++)
2001
32.8M
          for (int j = 0; j < width; j++, k++, m += nDim)
2002
32.4M
            if (m_bitMask.IsValid(k))
2003
456k
            {
2004
456k
              int val = 0;
2005
456k
              if (nBytesRemaining >= 4 * sizeof(unsigned int))
2006
436k
              {
2007
436k
                if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2008
411
                  return false;
2009
436k
              }
2010
20.3k
              else
2011
20.3k
              {
2012
20.3k
                if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2013
872
                  return false;
2014
20.3k
              }
2015
2016
455k
              T delta = (T)(val - offset);
2017
2018
455k
              if (j > 0 && m_bitMask.IsValid(k - 1))
2019
254k
              {
2020
254k
                delta += prevVal;    // use overflow
2021
254k
              }
2022
201k
              else if (i > 0 && m_bitMask.IsValid(k - width))
2023
47.5k
              {
2024
47.5k
                delta += data[m - width * nDim];
2025
47.5k
              }
2026
153k
              else
2027
153k
                delta += prevVal;
2028
2029
455k
              data[m] = delta;
2030
455k
              prevVal = delta;
2031
455k
            }
2032
4.21k
      }
2033
1.44k
    }
2034
2035
1.60k
    else if (m_imageEncodeMode == IEM_Huffman)
2036
1.60k
    {
2037
11.9k
      for (int k = 0, m0 = 0, i = 0; i < height; i++)
2038
303k
        for (int j = 0; j < width; j++, k++, m0 += nDim)
2039
293k
          if (m_bitMask.IsValid(k))
2040
12.2M
            for (int m = 0; m < nDim; m++)
2041
12.1M
            {
2042
12.1M
              int val = 0;
2043
12.1M
              if (nBytesRemaining >= 4 * sizeof(unsigned int))
2044
12.1M
              {
2045
12.1M
                if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2046
452
                  return false;
2047
12.1M
              }
2048
26.0k
              else
2049
26.0k
              {
2050
26.0k
                if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val))
2051
924
                  return false;
2052
26.0k
              }
2053
2054
12.1M
              data[m0 + m] = (T)(val - offset);
2055
12.1M
            }
2056
1.60k
    }
2057
2058
0
    else
2059
0
      return false;
2060
3.04k
  }
2061
2062
601
  size_t numUInts = srcPtr - arr + (bitPos > 0 ? 1 : 0) + 1;    // add one more as the decode LUT can read ahead
2063
601
  size_t len = numUInts * sizeof(unsigned int);
2064
2065
601
  if (nBytesRemainingInOut < len)
2066
52
    return false;
2067
2068
549
  *ppByte += len;
2069
549
  nBytesRemainingInOut -= len;
2070
549
  return true;
2071
601
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<short>(unsigned char const**, unsigned long&, short*) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<unsigned short>(unsigned char const**, unsigned long&, unsigned short*) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<int>(unsigned char const**, unsigned long&, int*) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<unsigned int>(unsigned char const**, unsigned long&, unsigned int*) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<float>(unsigned char const**, unsigned long&, float*) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<double>(unsigned char const**, unsigned long&, double*) const
2072
2073
// -------------------------------------------------------------------------- ;
2074
2075
template<class T>
2076
bool Lerc2::WriteMinMaxRanges(const T* /*data*/, Byte** ppByte) const
2077
0
{
2078
0
  if (!ppByte || !(*ppByte))
2079
0
    return false;
2080
2081
  //printf("write min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2082
2083
0
  int nDim = m_headerInfo.nDim;
2084
0
  if (/* nDim < 2 || */ (int)m_zMinVec.size() != nDim || (int)m_zMaxVec.size() != nDim)
2085
0
    return false;
2086
2087
0
  std::vector<T> zVec(nDim);
2088
0
  size_t len = nDim * sizeof(T);
2089
2090
0
  for (int i = 0; i < nDim; i++)
2091
0
    zVec[i] = (T)m_zMinVec[i];
2092
2093
0
  memcpy(*ppByte, &zVec[0], len);
2094
0
  (*ppByte) += len;
2095
2096
0
  for (int i = 0; i < nDim; i++)
2097
0
    zVec[i] = (T)m_zMaxVec[i];
2098
2099
0
  memcpy(*ppByte, &zVec[0], len);
2100
0
  (*ppByte) += len;
2101
2102
0
  return true;
2103
0
}
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<signed char>(signed char const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<unsigned char>(unsigned char const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<short>(short const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<unsigned short>(unsigned short const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<int>(int const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<unsigned int>(unsigned int const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<float>(float const*, unsigned char**) const
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<double>(double const*, unsigned char**) const
2104
2105
// -------------------------------------------------------------------------- ;
2106
2107
template<class T>
2108
bool Lerc2::ReadMinMaxRanges(const Byte** ppByte, size_t& nBytesRemaining, const T* /*data*/)
2109
25.3k
{
2110
25.3k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
25.3k
  int nDim = m_headerInfo.nDim;
2114
2115
25.3k
  m_zMinVec.resize(nDim);
2116
25.3k
  m_zMaxVec.resize(nDim);
2117
2118
25.3k
  std::vector<T> zVec(nDim);
2119
25.3k
  size_t len = nDim * sizeof(T);
2120
2121
25.3k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
667
    return false;
2123
2124
24.6k
  (*ppByte) += len;
2125
24.6k
  nBytesRemaining -= len;
2126
2127
817k
  for (int i = 0; i < nDim; i++)
2128
793k
    m_zMinVec[i] = zVec[i];
2129
2130
24.6k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
422
    return false;
2132
2133
24.2k
  (*ppByte) += len;
2134
24.2k
  nBytesRemaining -= len;
2135
2136
785k
  for (int i = 0; i < nDim; i++)
2137
761k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
24.2k
  return true;
2142
24.6k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<signed char>(unsigned char const**, unsigned long&, signed char const*)
Line
Count
Source
2109
3.63k
{
2110
3.63k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
3.63k
  int nDim = m_headerInfo.nDim;
2114
2115
3.63k
  m_zMinVec.resize(nDim);
2116
3.63k
  m_zMaxVec.resize(nDim);
2117
2118
3.63k
  std::vector<T> zVec(nDim);
2119
3.63k
  size_t len = nDim * sizeof(T);
2120
2121
3.63k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
0
    return false;
2123
2124
3.63k
  (*ppByte) += len;
2125
3.63k
  nBytesRemaining -= len;
2126
2127
177k
  for (int i = 0; i < nDim; i++)
2128
174k
    m_zMinVec[i] = zVec[i];
2129
2130
3.63k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
0
    return false;
2132
2133
3.63k
  (*ppByte) += len;
2134
3.63k
  nBytesRemaining -= len;
2135
2136
177k
  for (int i = 0; i < nDim; i++)
2137
174k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
3.63k
  return true;
2142
3.63k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<unsigned char>(unsigned char const**, unsigned long&, unsigned char const*)
Line
Count
Source
2109
12.2k
{
2110
12.2k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
12.2k
  int nDim = m_headerInfo.nDim;
2114
2115
12.2k
  m_zMinVec.resize(nDim);
2116
12.2k
  m_zMaxVec.resize(nDim);
2117
2118
12.2k
  std::vector<T> zVec(nDim);
2119
12.2k
  size_t len = nDim * sizeof(T);
2120
2121
12.2k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
140
    return false;
2123
2124
12.1k
  (*ppByte) += len;
2125
12.1k
  nBytesRemaining -= len;
2126
2127
510k
  for (int i = 0; i < nDim; i++)
2128
498k
    m_zMinVec[i] = zVec[i];
2129
2130
12.1k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
81
    return false;
2132
2133
12.0k
  (*ppByte) += len;
2134
12.0k
  nBytesRemaining -= len;
2135
2136
504k
  for (int i = 0; i < nDim; i++)
2137
492k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
12.0k
  return true;
2142
12.1k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<short>(unsigned char const**, unsigned long&, short const*)
Line
Count
Source
2109
2.09k
{
2110
2.09k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
2.09k
  int nDim = m_headerInfo.nDim;
2114
2115
2.09k
  m_zMinVec.resize(nDim);
2116
2.09k
  m_zMaxVec.resize(nDim);
2117
2118
2.09k
  std::vector<T> zVec(nDim);
2119
2.09k
  size_t len = nDim * sizeof(T);
2120
2121
2.09k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
103
    return false;
2123
2124
1.99k
  (*ppByte) += len;
2125
1.99k
  nBytesRemaining -= len;
2126
2127
21.0k
  for (int i = 0; i < nDim; i++)
2128
19.0k
    m_zMinVec[i] = zVec[i];
2129
2130
1.99k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
45
    return false;
2132
2133
1.95k
  (*ppByte) += len;
2134
1.95k
  nBytesRemaining -= len;
2135
2136
20.4k
  for (int i = 0; i < nDim; i++)
2137
18.5k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
1.95k
  return true;
2142
1.99k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<unsigned short>(unsigned char const**, unsigned long&, unsigned short const*)
Line
Count
Source
2109
2.31k
{
2110
2.31k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
2.31k
  int nDim = m_headerInfo.nDim;
2114
2115
2.31k
  m_zMinVec.resize(nDim);
2116
2.31k
  m_zMaxVec.resize(nDim);
2117
2118
2.31k
  std::vector<T> zVec(nDim);
2119
2.31k
  size_t len = nDim * sizeof(T);
2120
2121
2.31k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
96
    return false;
2123
2124
2.21k
  (*ppByte) += len;
2125
2.21k
  nBytesRemaining -= len;
2126
2127
20.4k
  for (int i = 0; i < nDim; i++)
2128
18.2k
    m_zMinVec[i] = zVec[i];
2129
2130
2.21k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
45
    return false;
2132
2133
2.16k
  (*ppByte) += len;
2134
2.16k
  nBytesRemaining -= len;
2135
2136
19.9k
  for (int i = 0; i < nDim; i++)
2137
17.7k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
2.16k
  return true;
2142
2.21k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<int>(unsigned char const**, unsigned long&, int const*)
Line
Count
Source
2109
1.25k
{
2110
1.25k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
1.25k
  int nDim = m_headerInfo.nDim;
2114
2115
1.25k
  m_zMinVec.resize(nDim);
2116
1.25k
  m_zMaxVec.resize(nDim);
2117
2118
1.25k
  std::vector<T> zVec(nDim);
2119
1.25k
  size_t len = nDim * sizeof(T);
2120
2121
1.25k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
95
    return false;
2123
2124
1.15k
  (*ppByte) += len;
2125
1.15k
  nBytesRemaining -= len;
2126
2127
10.9k
  for (int i = 0; i < nDim; i++)
2128
9.77k
    m_zMinVec[i] = zVec[i];
2129
2130
1.15k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
116
    return false;
2132
2133
1.03k
  (*ppByte) += len;
2134
1.03k
  nBytesRemaining -= len;
2135
2136
9.53k
  for (int i = 0; i < nDim; i++)
2137
8.49k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
1.03k
  return true;
2142
1.15k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<unsigned int>(unsigned char const**, unsigned long&, unsigned int const*)
Line
Count
Source
2109
2.23k
{
2110
2.23k
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
2.23k
  int nDim = m_headerInfo.nDim;
2114
2115
2.23k
  m_zMinVec.resize(nDim);
2116
2.23k
  m_zMaxVec.resize(nDim);
2117
2118
2.23k
  std::vector<T> zVec(nDim);
2119
2.23k
  size_t len = nDim * sizeof(T);
2120
2121
2.23k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
52
    return false;
2123
2124
2.18k
  (*ppByte) += len;
2125
2.18k
  nBytesRemaining -= len;
2126
2127
16.8k
  for (int i = 0; i < nDim; i++)
2128
14.6k
    m_zMinVec[i] = zVec[i];
2129
2130
2.18k
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
39
    return false;
2132
2133
2.14k
  (*ppByte) += len;
2134
2.14k
  nBytesRemaining -= len;
2135
2136
16.4k
  for (int i = 0; i < nDim; i++)
2137
14.3k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
2.14k
  return true;
2142
2.18k
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<float>(unsigned char const**, unsigned long&, float const*)
Line
Count
Source
2109
755
{
2110
755
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
755
  int nDim = m_headerInfo.nDim;
2114
2115
755
  m_zMinVec.resize(nDim);
2116
755
  m_zMaxVec.resize(nDim);
2117
2118
755
  std::vector<T> zVec(nDim);
2119
755
  size_t len = nDim * sizeof(T);
2120
2121
755
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
84
    return false;
2123
2124
671
  (*ppByte) += len;
2125
671
  nBytesRemaining -= len;
2126
2127
9.10k
  for (int i = 0; i < nDim; i++)
2128
8.43k
    m_zMinVec[i] = zVec[i];
2129
2130
671
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
36
    return false;
2132
2133
635
  (*ppByte) += len;
2134
635
  nBytesRemaining -= len;
2135
2136
8.28k
  for (int i = 0; i < nDim; i++)
2137
7.65k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
635
  return true;
2142
671
}
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<double>(unsigned char const**, unsigned long&, double const*)
Line
Count
Source
2109
812
{
2110
812
  if (!ppByte || !(*ppByte))
2111
0
    return false;
2112
2113
812
  int nDim = m_headerInfo.nDim;
2114
2115
812
  m_zMinVec.resize(nDim);
2116
812
  m_zMaxVec.resize(nDim);
2117
2118
812
  std::vector<T> zVec(nDim);
2119
812
  size_t len = nDim * sizeof(T);
2120
2121
812
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2122
97
    return false;
2123
2124
715
  (*ppByte) += len;
2125
715
  nBytesRemaining -= len;
2126
2127
51.0k
  for (int i = 0; i < nDim; i++)
2128
50.3k
    m_zMinVec[i] = zVec[i];
2129
2130
715
  if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len))
2131
60
    return false;
2132
2133
655
  (*ppByte) += len;
2134
655
  nBytesRemaining -= len;
2135
2136
28.8k
  for (int i = 0; i < nDim; i++)
2137
28.2k
    m_zMaxVec[i] = zVec[i];
2138
2139
  //printf("read min / max = %f  %f\n", m_zMinVec[0], m_zMaxVec[0]);
2140
2141
655
  return true;
2142
715
}
2143
2144
// -------------------------------------------------------------------------- ;
2145
2146
inline
2147
bool Lerc2::CheckMinMaxRanges(bool& minMaxEqual) const
2148
24.2k
{
2149
24.2k
  int nDim = m_headerInfo.nDim;
2150
24.2k
  if ((int)m_zMinVec.size() != nDim || (int)m_zMaxVec.size() != nDim)
2151
0
    return false;
2152
2153
24.2k
  minMaxEqual = (0 == memcmp(&m_zMinVec[0], &m_zMaxVec[0], nDim * sizeof(m_zMinVec[0])));
2154
24.2k
  return true;
2155
24.2k
}
2156
2157
// -------------------------------------------------------------------------- ;
2158
2159
template<class T>
2160
bool Lerc2::FillConstImage(T* data) const
2161
1.74k
{
2162
1.74k
  if (!data)
2163
0
    return false;
2164
2165
1.74k
  const HeaderInfo& hd = m_headerInfo;
2166
1.74k
  int nCols = hd.nCols;
2167
1.74k
  int nRows = hd.nRows;
2168
1.74k
  int nDim = hd.nDim;
2169
1.74k
  T z0 = (T)hd.zMin;
2170
2171
1.74k
  if (nDim == 1)
2172
1.36k
  {
2173
19.2M
    for (int k = 0, i = 0; i < nRows; i++)
2174
99.1M
      for (int j = 0; j < nCols; j++, k++)
2175
79.8M
        if (m_bitMask.IsValid(k))
2176
4.49M
          data[k] = z0;
2177
1.36k
  }
2178
387
  else
2179
387
  {
2180
387
    std::vector<T> zBufVec(nDim, z0);
2181
2182
387
    if (hd.zMin != hd.zMax)
2183
236
    {
2184
236
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
1.60k
      for (int m = 0; m < nDim; m++)
2188
1.36k
        zBufVec[m] = (T)m_zMinVec[m];
2189
236
    }
2190
2191
387
    int len = nDim * sizeof(T);
2192
1.67M
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
16.9M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
15.3M
        if (m_bitMask.IsValid(k))
2195
1.40M
          memcpy(&data[m], &zBufVec[0], len);
2196
387
  }
2197
2198
1.74k
  return true;
2199
1.74k
}
bool GDAL_LercNS::Lerc2::FillConstImage<signed char>(signed char*) const
Line
Count
Source
2161
431
{
2162
431
  if (!data)
2163
0
    return false;
2164
2165
431
  const HeaderInfo& hd = m_headerInfo;
2166
431
  int nCols = hd.nCols;
2167
431
  int nRows = hd.nRows;
2168
431
  int nDim = hd.nDim;
2169
431
  T z0 = (T)hd.zMin;
2170
2171
431
  if (nDim == 1)
2172
409
  {
2173
3.03k
    for (int k = 0, i = 0; i < nRows; i++)
2174
253k
      for (int j = 0; j < nCols; j++, k++)
2175
251k
        if (m_bitMask.IsValid(k))
2176
37.9k
          data[k] = z0;
2177
409
  }
2178
22
  else
2179
22
  {
2180
22
    std::vector<T> zBufVec(nDim, z0);
2181
2182
22
    if (hd.zMin != hd.zMax)
2183
12
    {
2184
12
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
168
      for (int m = 0; m < nDim; m++)
2188
156
        zBufVec[m] = (T)m_zMinVec[m];
2189
12
    }
2190
2191
22
    int len = nDim * sizeof(T);
2192
31.0k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
651k
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
620k
        if (m_bitMask.IsValid(k))
2195
83.4k
          memcpy(&data[m], &zBufVec[0], len);
2196
22
  }
2197
2198
431
  return true;
2199
431
}
bool GDAL_LercNS::Lerc2::FillConstImage<unsigned char>(unsigned char*) const
Line
Count
Source
2161
759
{
2162
759
  if (!data)
2163
0
    return false;
2164
2165
759
  const HeaderInfo& hd = m_headerInfo;
2166
759
  int nCols = hd.nCols;
2167
759
  int nRows = hd.nRows;
2168
759
  int nDim = hd.nDim;
2169
759
  T z0 = (T)hd.zMin;
2170
2171
759
  if (nDim == 1)
2172
632
  {
2173
10.3M
    for (int k = 0, i = 0; i < nRows; i++)
2174
49.7M
      for (int j = 0; j < nCols; j++, k++)
2175
39.4M
        if (m_bitMask.IsValid(k))
2176
1.46M
          data[k] = z0;
2177
632
  }
2178
127
  else
2179
127
  {
2180
127
    std::vector<T> zBufVec(nDim, z0);
2181
2182
127
    if (hd.zMin != hd.zMax)
2183
79
    {
2184
79
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
631
      for (int m = 0; m < nDim; m++)
2188
552
        zBufVec[m] = (T)m_zMinVec[m];
2189
79
    }
2190
2191
127
    int len = nDim * sizeof(T);
2192
532k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
5.29M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
4.76M
        if (m_bitMask.IsValid(k))
2195
404k
          memcpy(&data[m], &zBufVec[0], len);
2196
127
  }
2197
2198
759
  return true;
2199
759
}
bool GDAL_LercNS::Lerc2::FillConstImage<short>(short*) const
Line
Count
Source
2161
141
{
2162
141
  if (!data)
2163
0
    return false;
2164
2165
141
  const HeaderInfo& hd = m_headerInfo;
2166
141
  int nCols = hd.nCols;
2167
141
  int nRows = hd.nRows;
2168
141
  int nDim = hd.nDim;
2169
141
  T z0 = (T)hd.zMin;
2170
2171
141
  if (nDim == 1)
2172
101
  {
2173
2.65M
    for (int k = 0, i = 0; i < nRows; i++)
2174
13.0M
      for (int j = 0; j < nCols; j++, k++)
2175
10.3M
        if (m_bitMask.IsValid(k))
2176
1.69M
          data[k] = z0;
2177
101
  }
2178
40
  else
2179
40
  {
2180
40
    std::vector<T> zBufVec(nDim, z0);
2181
2182
40
    if (hd.zMin != hd.zMax)
2183
20
    {
2184
20
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
184
      for (int m = 0; m < nDim; m++)
2188
164
        zBufVec[m] = (T)m_zMinVec[m];
2189
20
    }
2190
2191
40
    int len = nDim * sizeof(T);
2192
138k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
3.89M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
3.75M
        if (m_bitMask.IsValid(k))
2195
426k
          memcpy(&data[m], &zBufVec[0], len);
2196
40
  }
2197
2198
141
  return true;
2199
141
}
bool GDAL_LercNS::Lerc2::FillConstImage<unsigned short>(unsigned short*) const
Line
Count
Source
2161
158
{
2162
158
  if (!data)
2163
0
    return false;
2164
2165
158
  const HeaderInfo& hd = m_headerInfo;
2166
158
  int nCols = hd.nCols;
2167
158
  int nRows = hd.nRows;
2168
158
  int nDim = hd.nDim;
2169
158
  T z0 = (T)hd.zMin;
2170
2171
158
  if (nDim == 1)
2172
75
  {
2173
1.28M
    for (int k = 0, i = 0; i < nRows; i++)
2174
9.47M
      for (int j = 0; j < nCols; j++, k++)
2175
8.18M
        if (m_bitMask.IsValid(k))
2176
309k
          data[k] = z0;
2177
75
  }
2178
83
  else
2179
83
  {
2180
83
    std::vector<T> zBufVec(nDim, z0);
2181
2182
83
    if (hd.zMin != hd.zMax)
2183
74
    {
2184
74
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
317
      for (int m = 0; m < nDim; m++)
2188
243
        zBufVec[m] = (T)m_zMinVec[m];
2189
74
    }
2190
2191
83
    int len = nDim * sizeof(T);
2192
173k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
2.32M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
2.15M
        if (m_bitMask.IsValid(k))
2195
189k
          memcpy(&data[m], &zBufVec[0], len);
2196
83
  }
2197
2198
158
  return true;
2199
158
}
bool GDAL_LercNS::Lerc2::FillConstImage<int>(int*) const
Line
Count
Source
2161
51
{
2162
51
  if (!data)
2163
0
    return false;
2164
2165
51
  const HeaderInfo& hd = m_headerInfo;
2166
51
  int nCols = hd.nCols;
2167
51
  int nRows = hd.nRows;
2168
51
  int nDim = hd.nDim;
2169
51
  T z0 = (T)hd.zMin;
2170
2171
51
  if (nDim == 1)
2172
21
  {
2173
2.06M
    for (int k = 0, i = 0; i < nRows; i++)
2174
13.4M
      for (int j = 0; j < nCols; j++, k++)
2175
11.3M
        if (m_bitMask.IsValid(k))
2176
100k
          data[k] = z0;
2177
21
  }
2178
30
  else
2179
30
  {
2180
30
    std::vector<T> zBufVec(nDim, z0);
2181
2182
30
    if (hd.zMin != hd.zMax)
2183
15
    {
2184
15
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
101
      for (int m = 0; m < nDim; m++)
2188
86
        zBufVec[m] = (T)m_zMinVec[m];
2189
15
    }
2190
2191
30
    int len = nDim * sizeof(T);
2192
116k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
1.18M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
1.07M
        if (m_bitMask.IsValid(k))
2195
47.1k
          memcpy(&data[m], &zBufVec[0], len);
2196
30
  }
2197
2198
51
  return true;
2199
51
}
bool GDAL_LercNS::Lerc2::FillConstImage<unsigned int>(unsigned int*) const
Line
Count
Source
2161
120
{
2162
120
  if (!data)
2163
0
    return false;
2164
2165
120
  const HeaderInfo& hd = m_headerInfo;
2166
120
  int nCols = hd.nCols;
2167
120
  int nRows = hd.nRows;
2168
120
  int nDim = hd.nDim;
2169
120
  T z0 = (T)hd.zMin;
2170
2171
120
  if (nDim == 1)
2172
87
  {
2173
826k
    for (int k = 0, i = 0; i < nRows; i++)
2174
3.72M
      for (int j = 0; j < nCols; j++, k++)
2175
2.90M
        if (m_bitMask.IsValid(k))
2176
200k
          data[k] = z0;
2177
87
  }
2178
33
  else
2179
33
  {
2180
33
    std::vector<T> zBufVec(nDim, z0);
2181
2182
33
    if (hd.zMin != hd.zMax)
2183
17
    {
2184
17
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
105
      for (int m = 0; m < nDim; m++)
2188
88
        zBufVec[m] = (T)m_zMinVec[m];
2189
17
    }
2190
2191
33
    int len = nDim * sizeof(T);
2192
308k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
1.67M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
1.36M
        if (m_bitMask.IsValid(k))
2195
125k
          memcpy(&data[m], &zBufVec[0], len);
2196
33
  }
2197
2198
120
  return true;
2199
120
}
bool GDAL_LercNS::Lerc2::FillConstImage<float>(float*) const
Line
Count
Source
2161
41
{
2162
41
  if (!data)
2163
0
    return false;
2164
2165
41
  const HeaderInfo& hd = m_headerInfo;
2166
41
  int nCols = hd.nCols;
2167
41
  int nRows = hd.nRows;
2168
41
  int nDim = hd.nDim;
2169
41
  T z0 = (T)hd.zMin;
2170
2171
41
  if (nDim == 1)
2172
17
  {
2173
1.17M
    for (int k = 0, i = 0; i < nRows; i++)
2174
6.18M
      for (int j = 0; j < nCols; j++, k++)
2175
5.01M
        if (m_bitMask.IsValid(k))
2176
335k
          data[k] = z0;
2177
17
  }
2178
24
  else
2179
24
  {
2180
24
    std::vector<T> zBufVec(nDim, z0);
2181
2182
24
    if (hd.zMin != hd.zMax)
2183
9
    {
2184
9
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
46
      for (int m = 0; m < nDim; m++)
2188
37
        zBufVec[m] = (T)m_zMinVec[m];
2189
9
    }
2190
2191
24
    int len = nDim * sizeof(T);
2192
141k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
1.12M
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
980k
        if (m_bitMask.IsValid(k))
2195
87.5k
          memcpy(&data[m], &zBufVec[0], len);
2196
24
  }
2197
2198
41
  return true;
2199
41
}
bool GDAL_LercNS::Lerc2::FillConstImage<double>(double*) const
Line
Count
Source
2161
46
{
2162
46
  if (!data)
2163
0
    return false;
2164
2165
46
  const HeaderInfo& hd = m_headerInfo;
2166
46
  int nCols = hd.nCols;
2167
46
  int nRows = hd.nRows;
2168
46
  int nDim = hd.nDim;
2169
46
  T z0 = (T)hd.zMin;
2170
2171
46
  if (nDim == 1)
2172
18
  {
2173
923k
    for (int k = 0, i = 0; i < nRows; i++)
2174
3.27M
      for (int j = 0; j < nCols; j++, k++)
2175
2.35M
        if (m_bitMask.IsValid(k))
2176
359k
          data[k] = z0;
2177
18
  }
2178
28
  else
2179
28
  {
2180
28
    std::vector<T> zBufVec(nDim, z0);
2181
2182
28
    if (hd.zMin != hd.zMax)
2183
10
    {
2184
10
      if ((int)m_zMinVec.size() != nDim)
2185
0
        return false;
2186
2187
51
      for (int m = 0; m < nDim; m++)
2188
41
        zBufVec[m] = (T)m_zMinVec[m];
2189
10
    }
2190
2191
28
    int len = nDim * sizeof(T);
2192
231k
    for (int k = 0, m = 0, i = 0; i < nRows; i++)
2193
828k
      for (int j = 0; j < nCols; j++, k++, m += nDim)
2194
596k
        if (m_bitMask.IsValid(k))
2195
37.4k
          memcpy(&data[m], &zBufVec[0], len);
2196
28
  }
2197
2198
46
  return true;
2199
46
}
2200
2201
// -------------------------------------------------------------------------- ;
2202
2203
NAMESPACE_LERC_END
2204
#endif