Coverage Report

Created: 2025-10-13 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brunsli/c/dec/huffman_decode.cc
Line
Count
Source
1
// Copyright (c) Google LLC 2019
2
//
3
// Use of this source code is governed by an MIT-style
4
// license that can be found in the LICENSE file or at
5
// https://opensource.org/licenses/MIT.
6
7
#include "./huffman_decode.h"
8
9
#include <cstring>  /* for memset */
10
#include <vector>
11
12
#include "../common/constants.h"
13
#include "../common/platform.h"
14
#include <brunsli/types.h>
15
#include "./bit_reader.h"
16
#include "./huffman_table.h"
17
18
namespace brunsli {
19
20
static const int kCodeLengthCodes = 18;
21
static const uint8_t kCodeLengthCodeOrder[kCodeLengthCodes] = {
22
    1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
23
};
24
static const uint8_t kDefaultCodeLength = 8;
25
static const uint8_t kCodeLengthRepeatCode = 16;
26
27
bool ReadHuffmanCodeLengths(const uint8_t* code_length_code_lengths,
28
                           size_t num_symbols, uint8_t* code_lengths,
29
620
                           BrunsliBitReader* br) {
30
620
  size_t symbol = 0;
31
620
  uint8_t prev_code_len = kDefaultCodeLength;
32
620
  size_t repeat = 0;
33
620
  uint8_t repeat_code_len = 0;
34
620
  const int kFullSpace = 1 << 15;
35
620
  int space = kFullSpace;
36
620
  HuffmanCode table[32];
37
38
620
  uint16_t counts[16] = {0};
39
11.7k
  for (int i = 0; i < kCodeLengthCodes; ++i) {
40
11.1k
    ++counts[code_length_code_lengths[i]];
41
11.1k
  }
42
620
  if (!BuildHuffmanTable(table, 5, code_length_code_lengths, kCodeLengthCodes,
43
620
                         &counts[0])) {
44
0
    return false;
45
0
  }
46
47
20.2k
  while (symbol < num_symbols && space > 0) {
48
19.6k
    const HuffmanCode* p = table;
49
19.6k
    uint8_t code_len;
50
19.6k
    p += BrunsliBitReaderGet(br, 5);
51
19.6k
    BrunsliBitReaderDrop(br, p->bits);
52
19.6k
    code_len = (uint8_t)p->value;
53
19.6k
    if (code_len < kCodeLengthRepeatCode) {
54
17.7k
      repeat = 0;
55
17.7k
      code_lengths[symbol++] = code_len;
56
17.7k
      if (code_len != 0) {
57
14.2k
        prev_code_len = code_len;
58
14.2k
        space -= kFullSpace >> code_len;
59
14.2k
      }
60
17.7k
    } else {
61
1.91k
      uint32_t extra_bits = code_len - 14;  // >= 2
62
1.91k
      size_t old_repeat;
63
1.91k
      size_t repeat_delta;
64
1.91k
      uint8_t new_len = 0;
65
1.91k
      if (code_len == kCodeLengthRepeatCode) {
66
1.40k
        new_len = prev_code_len;
67
1.40k
      }
68
1.91k
      if (repeat_code_len != new_len) {
69
543
        repeat = 0;
70
543
        repeat_code_len = new_len;
71
543
      }
72
1.91k
      old_repeat = repeat;
73
1.91k
      if (repeat > 0) {  // >= 3
74
578
        repeat -= 2;
75
578
        repeat <<= extra_bits;
76
578
      }
77
1.91k
      repeat += BrunsliBitReaderRead(br, extra_bits) + 3u;
78
1.91k
      repeat_delta = repeat - old_repeat;
79
1.91k
      if (symbol + repeat_delta > num_symbols) {
80
59
        return false;
81
59
      }
82
1.85k
      memset(&code_lengths[symbol], repeat_code_len, (size_t)repeat_delta);
83
1.85k
      symbol += repeat_delta;
84
1.85k
      if (repeat_code_len != 0) {
85
1.38k
        space -= static_cast<int>(repeat_delta * kFullSpace) >> repeat_code_len;
86
1.38k
      }
87
1.85k
    }
88
19.6k
  }
89
561
  if (space != 0) {
90
185
    return false;
91
185
  }
92
376
  memset(&code_lengths[symbol], 0, (size_t)(num_symbols - symbol));
93
376
  return BrunsliBitReaderIsHealthy(br);
94
561
}
95
96
static BRUNSLI_INLINE bool ReadSimpleCode(uint16_t alphabet_size,
97
                                          BrunsliBitReader* br,
98
1.56k
                                          HuffmanCode* table) {
99
1.56k
  uint32_t max_bits =
100
1.56k
      (alphabet_size > 1u) ? Log2FloorNonZero(alphabet_size - 1u) + 1 : 0;
101
102
1.56k
  size_t num_symbols = BrunsliBitReaderRead(br, 2) + 1;
103
104
1.56k
  uint16_t symbols[4] = {0};
105
4.02k
  for (size_t i = 0; i < num_symbols; ++i) {
106
2.53k
    uint16_t symbol = BrunsliBitReaderRead(br, max_bits);
107
2.53k
    if (symbol >= alphabet_size) {
108
70
      return false;
109
70
    }
110
2.46k
    symbols[i] = symbol;
111
2.46k
  }
112
113
2.25k
  for (size_t i = 0; i < num_symbols - 1; ++i) {
114
2.14k
    for (size_t j = i + 1; j < num_symbols; ++j) {
115
1.38k
      if (symbols[i] == symbols[j]) return false;
116
1.38k
    }
117
815
  }
118
119
  // 4 symbols have to option to encode.
120
1.44k
  if (num_symbols == 4) num_symbols += BrunsliBitReaderRead(br, 1);
121
122
1.44k
  const auto swap_symbols = [&symbols] (size_t i, size_t j) {
123
643
    uint16_t t = symbols[j];
124
643
    symbols[j] = symbols[i];
125
643
    symbols[i] = t;
126
643
  };
127
128
1.44k
  size_t table_size = 1;
129
1.44k
  switch (num_symbols) {
130
1.07k
    case 1:
131
1.07k
      table[0] = {0, symbols[0]};
132
1.07k
      break;
133
143
    case 2:
134
143
      if (symbols[0] > symbols[1]) swap_symbols(0, 1);
135
143
      table[0] = {1, symbols[0]};
136
143
      table[1] = {1, symbols[1]};
137
143
      table_size = 2;
138
143
      break;
139
89
    case 3:
140
89
      if (symbols[1] > symbols[2]) swap_symbols(1, 2);
141
89
      table[0] = {1, symbols[0]};
142
89
      table[2] = {1, symbols[0]};
143
89
      table[1] = {2, symbols[1]};
144
89
      table[3] = {2, symbols[2]};
145
89
      table_size = 4;
146
89
      break;
147
112
    case 4: {
148
448
      for (size_t i = 0; i < 3; ++i) {
149
1.00k
        for (size_t j = i + 1; j < 4; ++j) {
150
672
          if (symbols[i] > symbols[j]) swap_symbols(i, j);
151
672
        }
152
336
      }
153
112
      table[0] = {2, symbols[0]};
154
112
      table[2] = {2, symbols[1]};
155
112
      table[1] = {2, symbols[2]};
156
112
      table[3] = {2, symbols[3]};
157
112
      table_size = 4;
158
112
      break;
159
0
    }
160
27
    case 5: {
161
27
      if (symbols[2] > symbols[3]) swap_symbols(2, 3);
162
27
      table[0] = {1, symbols[0]};
163
27
      table[1] = {2, symbols[1]};
164
27
      table[2] = {1, symbols[0]};
165
27
      table[3] = {3, symbols[2]};
166
27
      table[4] = {1, symbols[0]};
167
27
      table[5] = {2, symbols[1]};
168
27
      table[6] = {1, symbols[0]};
169
27
      table[7] = {3, symbols[3]};
170
27
      table_size = 8;
171
27
      break;
172
0
    }
173
0
    default: {
174
      // Unreachable.
175
0
      return false;
176
0
    }
177
1.44k
  }
178
179
1.44k
  const uint32_t goal_size = 1u << kHuffmanTableBits;
180
12.3k
  while (table_size != goal_size) {
181
10.9k
    memcpy(&table[table_size], &table[0],
182
10.9k
           (size_t)table_size * sizeof(table[0]));
183
10.9k
    table_size <<= 1;
184
10.9k
  }
185
186
1.44k
  return BrunsliBitReaderIsHealthy(br);
187
1.44k
}
188
189
bool HuffmanDecodingData::ReadFromBitStream(
190
    size_t alphabet_size, BrunsliBitReader* br,
191
2.33k
    Arena<HuffmanCode>* arena) {
192
2.33k
  Arena<HuffmanCode> local_arena;
193
2.33k
  if (arena == nullptr) arena = &local_arena;
194
195
2.33k
  if (alphabet_size > (1 << kMaxHuffmanBits)) return false;
196
197
2.33k
  std::vector<uint8_t> code_lengths(alphabet_size, 0);
198
  /* simple_code_or_skip is used as follows:
199
     1 for simple code;
200
     0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
201
2.33k
  uint32_t simple_code_or_skip = BrunsliBitReaderRead(br, 2);
202
2.33k
  if (simple_code_or_skip == 1u) {
203
1.56k
    table_.resize(1u << kHuffmanTableBits);
204
1.56k
    return ReadSimpleCode(static_cast<uint16_t>(alphabet_size), br,
205
1.56k
                          table_.data());
206
1.56k
  }
207
208
770
  uint8_t code_length_code_lengths[kCodeLengthCodes] = {0};
209
770
  int space = 32;
210
770
  int num_codes = 0;
211
  /* Static Huffman code for the code length code lengths */
212
770
  static const HuffmanCode huff[16] = {
213
770
      {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 1},
214
770
      {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 5},
215
770
  };
216
10.0k
  for (size_t i = simple_code_or_skip; i < kCodeLengthCodes && space > 0; ++i) {
217
9.23k
    const int code_len_idx = kCodeLengthCodeOrder[i];
218
9.23k
    const HuffmanCode* p = huff;
219
9.23k
    uint8_t v;
220
9.23k
    p += BrunsliBitReaderGet(br, 4);
221
9.23k
    BrunsliBitReaderDrop(br, p->bits);
222
9.23k
    v = (uint8_t)p->value;
223
9.23k
    code_length_code_lengths[code_len_idx] = v;
224
9.23k
    if (v != 0) {
225
4.67k
      space -= (32u >> v);
226
4.67k
      ++num_codes;
227
4.67k
    }
228
9.23k
  }
229
770
  bool ok = (num_codes == 1 || space == 0) &&
230
620
       ReadHuffmanCodeLengths(code_length_code_lengths, alphabet_size,
231
620
                              &code_lengths[0], br);
232
233
770
  if (!ok || !BrunsliBitReaderIsHealthy(br)) return false;
234
353
  uint16_t counts[16] = {0};
235
43.1k
  for (size_t i = 0; i < alphabet_size; ++i) {
236
42.7k
    ++counts[code_lengths[i]];
237
42.7k
  }
238
353
  arena->reserve(alphabet_size + 376);
239
353
  uint32_t table_size =
240
353
      BuildHuffmanTable(arena->data(), kHuffmanTableBits, &code_lengths[0],
241
353
                        alphabet_size, &counts[0]);
242
353
  table_ = std::vector<HuffmanCode>(arena->data(), arena->data() + table_size);
243
353
  return (table_size > 0);
244
770
}
245
246
// Decodes the next Huffman coded symbol from the bit-stream.
247
1.88M
uint16_t HuffmanDecodingData::ReadSymbol(BrunsliBitReader* br) const {
248
1.88M
  uint32_t n_bits;
249
1.88M
  const HuffmanCode* table = table_.data();
250
1.88M
  table += BrunsliBitReaderGet(br, kHuffmanTableBits);
251
1.88M
  n_bits = table->bits;
252
1.88M
  if (n_bits > kHuffmanTableBits) {
253
1.61k
    BrunsliBitReaderDrop(br, kHuffmanTableBits);
254
1.61k
    n_bits -= kHuffmanTableBits;
255
1.61k
    table += table->value;
256
1.61k
    table += BrunsliBitReaderGet(br, n_bits);
257
1.61k
  }
258
1.88M
  BrunsliBitReaderDrop(br, table->bits);
259
1.88M
  return table->value;
260
1.88M
}
261
262
}  // namespace brunsli