Coverage Report

Created: 2026-09-26 08:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/third_party/LercLib/Huffman.cpp
Line
Count
Source
1
/*
2
Copyright 2015 Esri
3
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7
8
http://www.apache.org/licenses/LICENSE-2.0
9
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
16
A local copy of the license and additional notices are located with the
17
source distribution at:
18
19
http://github.com/Esri/lerc/
20
21
Contributors:  Thomas Maurer
22
*/
23
24
#include <algorithm>
25
#include <queue>
26
#include "Defines.h"
27
#include "Huffman.h"
28
#include "BitStuffer2.h"
29
30
using namespace std;
31
USING_NAMESPACE_LERC
32
33
// -------------------------------------------------------------------------- ;
34
35
bool Huffman::ComputeCodes(const vector<int>& histo)
36
0
{
37
0
  if (histo.empty() || histo.size() >= m_maxHistoSize)
38
0
    return false;
39
40
0
  priority_queue<Node, vector<Node>, less<Node> > pq;
41
42
0
  int numNodes = 0;
43
44
0
  int size = (int)histo.size();
45
0
  for (int i = 0; i < size; i++)    // add all leaf nodes
46
0
    if (histo[i] > 0)
47
0
      pq.push(Node((short)i, histo[i]));
48
49
0
  if (pq.size() < 2)    // histo has only 0 or 1 bin that is not empty; quit Huffman and give it to Lerc
50
0
    return false;
51
52
0
  while (pq.size() > 1)    // build the Huffman tree
53
0
  {
54
0
    Node* child0 = new Node(pq.top());
55
0
    numNodes++;
56
0
    pq.pop();
57
0
    Node* child1 = new Node(pq.top());
58
0
    numNodes++;
59
0
    pq.pop();
60
0
    pq.push(Node(child0, child1));
61
0
  }
62
63
0
  m_codeTable.resize(size);
64
0
  std::fill(m_codeTable.begin(), m_codeTable.end(),
65
0
    std::pair<unsigned short, unsigned int>((short)0, 0));
66
67
0
  if (!pq.top().TreeToLUT(0, 0, m_codeTable))    // fill the LUT
68
0
    return false;
69
70
  //pq.top().FreeTree(numNodes);    // Linux compiler complains
71
0
  Node nodeNonConst = pq.top();
72
0
  nodeNonConst.FreeTree(numNodes);    // free all the nodes
73
74
0
  if (numNodes != 0)    // check the ref count
75
0
    return false;
76
77
0
  if (!ConvertCodesToCanonical())
78
0
    return false;
79
80
0
  return true;
81
0
}
82
83
// -------------------------------------------------------------------------- ;
84
85
bool Huffman::ComputeCompressedSize(const std::vector<int>& histo, int& numBytes, double& avgBpp) const
86
0
{
87
0
  if (histo.empty() || histo.size() >= m_maxHistoSize)
88
0
    return false;
89
90
0
  numBytes = 0;
91
0
  if (!ComputeNumBytesCodeTable(numBytes))    // header and code table
92
0
    return false;
93
94
0
  int numBits = 0, numElem = 0;
95
0
  int size = (int)histo.size();
96
0
  for (int i = 0; i < size; i++)
97
0
    if (histo[i] > 0)
98
0
    {
99
0
      numBits += histo[i] * m_codeTable[i].first;
100
0
      numElem += histo[i];
101
0
    }
102
103
0
  if (numElem == 0)
104
0
    return false;
105
106
0
  int numUInts = ((((numBits + 7) >> 3) + 3) >> 2) + 1;    // add one more as the decode LUT can read ahead
107
0
  numBytes += 4 * numUInts;    // data huffman coded
108
0
  avgBpp = 8 * numBytes / (double)numElem;
109
110
0
  return true;
111
0
}
112
113
// -------------------------------------------------------------------------- ;
114
115
bool Huffman::SetCodes(const vector<pair<unsigned short, unsigned int> >& codeTable)
116
0
{
117
0
  if (codeTable.empty() || codeTable.size() >= m_maxHistoSize)
118
0
    return false;
119
120
0
  m_codeTable = codeTable;
121
0
  return true;
122
0
}
123
124
// -------------------------------------------------------------------------- ;
125
126
bool Huffman::WriteCodeTable(Byte** ppByte, int lerc2Version) const
127
0
{
128
0
  if (!ppByte)
129
0
    return false;
130
131
0
  int i0, i1, maxLen;
132
0
  if (!GetRange(i0, i1, maxLen))
133
0
    return false;
134
135
0
  int size = (int)m_codeTable.size();
136
0
  vector<unsigned int> dataVec(i1 - i0, 0);
137
138
0
  for (int i = i0; i < i1; i++)
139
0
  {
140
0
    int k = GetIndexWrapAround(i, size);
141
0
    dataVec[i - i0] = m_codeTable[k].first;
142
0
  }
143
144
  // header
145
0
  vector<int> intVec;
146
0
  intVec.push_back(4);    // huffman version; 4 guarantees canonical codes
147
0
  intVec.push_back(size);
148
0
  intVec.push_back(i0);   // code range
149
0
  intVec.push_back(i1);
150
151
0
  Byte* ptr = *ppByte;
152
153
0
  size_t len = intVec.size() * sizeof(int);
154
0
  memcpy(ptr, &intVec[0], len);
155
0
  ptr += len;
156
157
0
  BitStuffer2 bitStuffer2;
158
0
  if (!bitStuffer2.EncodeSimple(&ptr, dataVec, lerc2Version))    // code lengths, bit stuffed
159
0
    return false;
160
161
0
  if (!BitStuffCodes(&ptr, i0, i1))    // variable length codes, bit stuffed
162
0
    return false;
163
164
0
  *ppByte = ptr;
165
0
  return true;
166
0
}
167
168
// -------------------------------------------------------------------------- ;
169
170
bool Huffman::ReadCodeTable(const Byte** ppByte, size_t& nBytesRemainingInOut, int lerc2Version)
171
3.73k
{
172
3.73k
  if (!ppByte || !(*ppByte))
173
0
    return false;
174
175
3.73k
  const Byte* ptr = *ppByte;
176
3.73k
  size_t nBytesRemaining = nBytesRemainingInOut;
177
178
3.73k
  vector<int> intVec(4, 0);
179
3.73k
  size_t len = intVec.size() * sizeof(int);
180
181
3.73k
  if (nBytesRemaining < len)
182
0
    return false;
183
184
3.73k
  memcpy(&intVec[0], ptr, len);
185
3.73k
  ptr += len;
186
3.73k
  nBytesRemaining -= len;
187
188
3.73k
  int version = intVec[0];
189
190
3.73k
  if (version < 2)    // allow forward compatibility; for updates that break old decoders increase Lerc2 version number;
191
44
    return false;
192
193
3.69k
  const int size = intVec[1];
194
3.69k
  const int i0 = intVec[2];
195
3.69k
  const int i1 = intVec[3];
196
197
3.69k
  if (i0 >= i1 || i0 < 0 || size < 0 || size > (int)m_maxHistoSize)
198
203
    return false;
199
200
3.48k
  if (GetIndexWrapAround(i0, size) >= size || GetIndexWrapAround(i1 - 1, size) >= size)
201
132
    return false;
202
203
3.35k
  try
204
3.35k
  {
205
3.35k
    vector<unsigned int> dataVec(i1 - i0, 0);
206
3.35k
    BitStuffer2 bitStuffer2;
207
3.35k
    if (!bitStuffer2.Decode(&ptr, nBytesRemaining, dataVec, dataVec.size(), lerc2Version))    // unstuff the code lengths
208
279
      return false;
209
210
3.07k
    if (dataVec.size() != static_cast<size_t>(i1 - i0))
211
125
      return false;
212
213
2.95k
    m_codeTable.resize(size);
214
2.95k
    std::fill(m_codeTable.begin(), m_codeTable.end(),
215
2.95k
      std::pair<unsigned short, unsigned int>((short)0, 0));
216
217
656k
    for (int i = i0; i < i1; i++)
218
653k
    {
219
653k
      int k = GetIndexWrapAround(i, size);
220
653k
      m_codeTable[k].first = (unsigned short)dataVec[i - i0];
221
653k
    }
222
223
2.95k
    if (!BitUnStuffCodes(&ptr, nBytesRemaining, i0, i1))    // unstuff the codes
224
196
      return false;
225
226
2.75k
    *ppByte = ptr;
227
2.75k
    nBytesRemainingInOut = nBytesRemaining;
228
2.75k
    return true;
229
2.95k
  }
230
3.35k
  catch (std::exception&)
231
3.35k
  {
232
0
    return false;
233
0
  }
234
3.35k
}
235
236
// -------------------------------------------------------------------------- ;
237
238
bool Huffman::BuildTreeFromCodes(int& numBitsLUT)
239
2.75k
{
240
2.75k
  int i0 = 0, i1 = 0, maxLen = 0;
241
2.75k
  if (!GetRange(i0, i1, maxLen))
242
88
    return false;
243
244
  // build decode LUT using max of 12 bits
245
2.66k
  int size = (int)m_codeTable.size();
246
2.66k
  int minNumZeroBits = 32;
247
248
2.66k
  bool bNeedTree = maxLen > m_maxNumBitsLUT;
249
2.66k
  numBitsLUT = min(maxLen, m_maxNumBitsLUT);
250
251
2.66k
  int sizeLUT = 1 << numBitsLUT;
252
253
2.66k
  m_decodeLUT.clear();
254
2.66k
  m_decodeLUT.assign((size_t)sizeLUT, pair<short, short>((short)-1, (short)-1));
255
256
430k
  for (int i = i0; i < i1; i++)
257
427k
  {
258
427k
    int k = GetIndexWrapAround(i, size);
259
427k
    int len = m_codeTable[k].first;
260
261
427k
    if (len == 0)
262
260k
      continue;
263
264
167k
    unsigned int code = m_codeTable[k].second;
265
266
167k
    if (len <= numBitsLUT)
267
140k
    {
268
140k
      code <<= (numBitsLUT - len);
269
140k
      unsigned int numEntries = 1 << (numBitsLUT - len);
270
271
61.4M
      for (unsigned int j = 0; j < numEntries; j++)
272
61.3M
      {
273
61.3M
        auto& entry = m_decodeLUT[code | j];
274
61.3M
        entry.first = (short)len;    // add the duplicates
275
61.3M
        entry.second = (short)k;    // add the duplicates
276
61.3M
      }
277
140k
    }
278
26.9k
    else    // for the codes too long for the LUT, count how many leading bits are 0
279
26.9k
    {
280
26.9k
      int shift = 1;
281
244k
      while (code >>= 1) shift++;    // large canonical codes start with zero's
282
26.9k
      minNumZeroBits = min(minNumZeroBits, len - shift);
283
26.9k
    }
284
167k
  }
285
286
2.66k
  m_numBitsToSkipInTree = bNeedTree? minNumZeroBits : 0;
287
288
2.66k
  if (!bNeedTree)    // decode LUT covers it all, no tree needed
289
409
    return true;
290
291
  //m_numBitsToSkipInTree = 0;    // to disable skipping the 0 bits
292
293
2.25k
  ClearTree();  // if there
294
295
2.25k
  Node emptyNode((short)-1, 0);
296
2.25k
  m_root = new Node(emptyNode);
297
298
370k
  for (int i = i0; i < i1; i++)
299
368k
  {
300
368k
    int k = GetIndexWrapAround(i, size);
301
368k
    int len = m_codeTable[k].first;
302
303
368k
    if (len > 0 && len > numBitsLUT)    // add only codes not in the decode LUT
304
26.9k
    {
305
26.9k
      unsigned int code = m_codeTable[k].second;
306
26.9k
      Node* node = m_root;
307
26.9k
      int j = len - m_numBitsToSkipInTree;    // reduce len by number of leading 0 bits from above
308
309
408k
      while (--j >= 0)    // go over the bits
310
381k
      {
311
381k
        if (code & (1 << j))
312
118k
        {
313
118k
          if (!node->child1)
314
67.9k
            node->child1 = new Node(emptyNode);
315
316
118k
          node = node->child1;
317
118k
        }
318
263k
        else
319
263k
        {
320
263k
          if (!node->child0)
321
123k
            node->child0 = new Node(emptyNode);
322
323
263k
          node = node->child0;
324
263k
        }
325
326
381k
        if (j == 0)    // last bit, leaf node
327
26.9k
          node->value = (short)k;    // set the value
328
381k
      }
329
26.9k
    }
330
368k
  }
331
332
2.25k
  return true;
333
2.66k
}
334
335
// -------------------------------------------------------------------------- ;
336
337
void Huffman::Clear()
338
3.73k
{
339
3.73k
  m_codeTable.clear();
340
3.73k
  m_decodeLUT.clear();
341
3.73k
  ClearTree();
342
3.73k
}
343
344
// -------------------------------------------------------------------------- ;
345
346
void Huffman::ClearTree()
347
5.99k
{
348
5.99k
  if (m_root)
349
2.25k
  {
350
2.25k
    int n = 0;
351
2.25k
    m_root->FreeTree(n);
352
2.25k
    delete m_root;
353
2.25k
    m_root = nullptr;
354
2.25k
  }
355
5.99k
}
356
357
// -------------------------------------------------------------------------- ;
358
// -------------------------------------------------------------------------- ;
359
360
bool Huffman::ComputeNumBytesCodeTable(int& numBytes) const
361
0
{
362
0
  int i0, i1, maxLen;
363
0
  if (!GetRange(i0, i1, maxLen))
364
0
    return false;
365
366
0
  int size = (int)m_codeTable.size();
367
0
  int sum = 0;
368
0
  for (int i = i0; i < i1; i++)
369
0
  {
370
0
    int k = GetIndexWrapAround(i, size);
371
0
    sum += m_codeTable[k].first;
372
0
  }
373
374
0
  numBytes = 4 * sizeof(int);    // version, size, first bin, (last + 1) bin
375
376
0
  BitStuffer2 bitStuffer2;
377
0
  numBytes += bitStuffer2.ComputeNumBytesNeededSimple((unsigned int)(i1 - i0), (unsigned int)maxLen);    // code lengths
378
0
  int numUInts = (((sum + 7) >> 3) + 3) >> 2;
379
0
  numBytes += 4 * numUInts;    // byte array with the codes bit stuffed
380
381
0
  return true;
382
0
}
383
384
// -------------------------------------------------------------------------- ;
385
386
bool Huffman::GetRange(int& i0, int& i1, int& maxCodeLength) const
387
2.75k
{
388
2.75k
  if (m_codeTable.empty() || m_codeTable.size() >= m_maxHistoSize)
389
0
    return false;
390
391
  // first, check for peak somewhere in the middle with 0 stretches left and right
392
2.75k
  int size = (int)m_codeTable.size();
393
2.75k
  {
394
2.75k
    int i = 0;
395
1.01M
    while (i < size && m_codeTable[i].first == 0) i++;
396
2.75k
    i0 = i;
397
2.75k
    i = size - 1;
398
34.4M
    while (i >= 0 && m_codeTable[i].first == 0) i--;
399
2.75k
    i1 = i + 1;    // exclusive
400
2.75k
  }
401
402
2.75k
  if (i1 <= i0)
403
88
    return false;
404
405
  // second, cover the common case that the peak is close to 0
406
2.66k
  pair<int, int> segm(0, 0);
407
2.66k
  int j = 0;
408
55.9k
  while (j < size)    // find the largest stretch of 0's, if any
409
53.2k
  {
410
220k
    while (j < size && m_codeTable[j].first > 0) j++;
411
53.2k
    int k0 = j;
412
34.1M
    while (j < size && m_codeTable[j].first == 0) j++;
413
53.2k
    int k1 = j;
414
415
53.2k
    if (k1 - k0 > segm.second)
416
5.58k
      segm = pair<int, int>(k0, k1 - k0);
417
53.2k
  }
418
419
2.66k
  if (size - segm.second < i1 - i0)
420
530
  {
421
530
    i0 = segm.first + segm.second;
422
530
    i1 = segm.first + size;    // do wrap around
423
530
  }
424
425
2.66k
  if (i1 <= i0)
426
0
    return false;
427
428
2.66k
  int maxLen = 0;
429
430k
  for (int i = i0; i < i1; i++)
430
427k
  {
431
427k
    int k = GetIndexWrapAround(i, size);
432
427k
    int len = m_codeTable[k].first;
433
427k
    maxLen = max(maxLen, len);
434
427k
  }
435
436
2.66k
  if (maxLen <= 0 || maxLen > 32)
437
0
    return false;
438
439
2.66k
  maxCodeLength = maxLen;
440
2.66k
  return true;
441
2.66k
}
442
443
// -------------------------------------------------------------------------- ;
444
445
bool Huffman::BitStuffCodes(Byte** ppByte, int i0, int i1) const
446
0
{
447
0
  if (!ppByte)
448
0
    return false;
449
450
0
  int size = (int)m_codeTable.size();
451
0
  int bitPos = 0;
452
453
0
  for (int i = i0; i < i1; i++)
454
0
  {
455
0
    int k = GetIndexWrapAround(i, size);
456
0
    int len = m_codeTable[k].first;
457
0
    if (len > 0)
458
0
    {
459
0
      unsigned int val = m_codeTable[k].second;
460
461
0
      if (!Huffman::PushValue(ppByte, bitPos, val, len))
462
0
        return false;
463
0
    }
464
0
  }
465
466
0
  size_t numUInts = (bitPos > 0 ? 1 : 0);
467
0
  *ppByte += numUInts * sizeof(unsigned int);
468
469
0
  return true;
470
0
}
471
472
// -------------------------------------------------------------------------- ;
473
474
bool Huffman::BitUnStuffCodes(const Byte** ppByte, size_t& nBytesRemainingInOut, int i0, int i1)
475
2.95k
{
476
2.95k
  if (!ppByte || !(*ppByte))
477
0
    return false;
478
479
2.95k
  size_t nBytesRemaining = nBytesRemainingInOut;
480
481
2.95k
  const Byte* ptr0 = *ppByte;
482
2.95k
  const Byte* ptr = ptr0;
483
484
2.95k
  const size_t s4 = sizeof(unsigned int);
485
486
2.95k
  int size = (int)m_codeTable.size();
487
2.95k
  int bitPos = 0;
488
489
641k
  for (int i = i0; i < i1; i++)
490
638k
  {
491
638k
    int k = GetIndexWrapAround(i, size);
492
638k
    int len = m_codeTable[k].first;
493
638k
    if (len > 0)
494
181k
    {
495
181k
      if (nBytesRemaining < s4 || len > 32)
496
109
        return false;
497
498
181k
      unsigned int temp(0);
499
181k
      memcpy(&temp, ptr, s4);
500
181k
      m_codeTable[k].second = (temp << bitPos) >> (32 - len);
501
502
181k
      if (32 - bitPos >= len)
503
148k
      {
504
148k
        bitPos += len;
505
148k
        if (bitPos == 32)
506
5.77k
        {
507
5.77k
          bitPos = 0;
508
5.77k
          ptr += s4;
509
5.77k
          nBytesRemaining -= s4;
510
5.77k
        }
511
148k
      }
512
33.4k
      else
513
33.4k
      {
514
33.4k
        bitPos += len - 32;
515
33.4k
        ptr += s4;
516
33.4k
        nBytesRemaining -= s4;
517
518
33.4k
        if (nBytesRemaining < s4)
519
87
          return false;
520
521
33.3k
        memcpy(&temp, ptr, s4);
522
33.3k
        m_codeTable[k].second |= temp >> (32 - bitPos);    // bitPos > 0
523
33.3k
      }
524
181k
    }
525
638k
  }
526
527
2.75k
  size_t len = (ptr - ptr0) + (bitPos > 0 ? s4 : 0);
528
529
2.75k
  if (nBytesRemainingInOut < len)
530
0
    return false;
531
532
2.75k
  *ppByte += len;
533
2.75k
  nBytesRemainingInOut -= len;
534
535
2.75k
  if (nBytesRemaining != nBytesRemainingInOut
536
2.56k
    && nBytesRemaining != nBytesRemainingInOut + s4)    // the real check
537
0
    return false;
538
539
2.75k
  return true;
540
2.75k
}
541
542
// -------------------------------------------------------------------------- ;
543
544
//struct MyLargerThanOp
545
//{
546
//  inline bool operator() (const pair<int, unsigned int>& p0,
547
//                          const pair<int, unsigned int>& p1)  { return p0.first > p1.first; }
548
//};
549
550
// -------------------------------------------------------------------------- ;
551
552
bool Huffman::ConvertCodesToCanonical()
553
0
{
554
  // from the non canonical code book, create an array to be sorted in descending order:
555
  //   codeLength * tableSize - index
556
557
0
  unsigned int tableSize = (unsigned int)m_codeTable.size();
558
0
  if (tableSize == 0)
559
0
    return true;
560
0
  vector<pair<int, unsigned int> > sortVec(tableSize, pair<int, unsigned int>(0, 0));
561
  //memset(&sortVec[0], 0, tableSize * sizeof(pair<int, unsigned int>));
562
563
0
  for (unsigned int i = 0; i < tableSize; i++)
564
0
    if (m_codeTable[i].first > 0)
565
0
      sortVec[i] = pair<int, unsigned int>(m_codeTable[i].first * tableSize - i, i);
566
567
  // sort descending
568
  //std::sort(sortVec.begin(), sortVec.end(), MyLargerThanOp());
569
570
0
  std::sort(sortVec.begin(), sortVec.end(),
571
0
    [](const pair<int, unsigned int>& p0,
572
0
       const pair<int, unsigned int>& p1) { return p0.first > p1.first; });
573
574
  // create canonical codes and assign to orig code table
575
0
  unsigned int index = sortVec[0].second;
576
0
  unsigned short codeLen = m_codeTable[index].first;    // max code length for this table
577
0
  unsigned int i = 0, codeCanonical = 0;
578
579
0
  while (i < tableSize && sortVec[i].first > 0)
580
0
  {
581
0
    index = sortVec[i++].second;
582
0
    short delta = codeLen - m_codeTable[index].first;  // difference of 2 consecutive code lengths, >= 0 as sorted
583
0
    codeCanonical >>= delta;
584
0
    codeLen -= delta;
585
0
    m_codeTable[index].second = codeCanonical++;
586
0
  }
587
588
0
  return true;
589
0
}
590
591
// -------------------------------------------------------------------------- ;