Coverage Report

Created: 2026-08-31 07:17

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 <brunsli/types.h>
10
11
#include <cstring> /* for memset */
12
#include <vector>
13
14
#include "../common/constants.h"
15
#include "../common/platform.h"
16
#include "./bit_reader.h"
17
#include "./huffman_table.h"
18
19
namespace brunsli {
20
21
static const int kCodeLengthCodes = 18;
22
static const uint8_t kCodeLengthCodeOrder[kCodeLengthCodes] = {
23
    1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
24
};
25
static const uint8_t kDefaultCodeLength = 8;
26
static const uint8_t kCodeLengthRepeatCode = 16;
27
28
bool ReadHuffmanCodeLengths(const uint8_t* code_length_code_lengths,
29
                            size_t num_symbols, uint8_t* code_lengths,
30
306
                            BrunsliBitReader* br) {
31
306
  size_t symbol = 0;
32
306
  uint8_t prev_code_len = kDefaultCodeLength;
33
306
  size_t repeat = 0;
34
306
  uint8_t repeat_code_len = 0;
35
306
  const int kFullSpace = 1 << 15;
36
306
  int space = kFullSpace;
37
306
  HuffmanCode table[32];
38
39
306
  uint16_t counts[16] = {0};
40
5.81k
  for (int i = 0; i < kCodeLengthCodes; ++i) {
41
5.50k
    ++counts[code_length_code_lengths[i]];
42
5.50k
  }
43
306
  if (!BuildHuffmanTable(table, 5, code_length_code_lengths, kCodeLengthCodes,
44
306
                         &counts[0])) {
45
0
    return false;
46
0
  }
47
48
10.6k
  while (symbol < num_symbols && space > 0) {
49
10.4k
    const HuffmanCode* p = table;
50
10.4k
    uint8_t code_len;
51
10.4k
    p += BrunsliBitReaderGet(br, 5);
52
10.4k
    BrunsliBitReaderDrop(br, p->bits);
53
10.4k
    code_len = (uint8_t)p->value;
54
10.4k
    if (code_len < kCodeLengthRepeatCode) {
55
9.61k
      repeat = 0;
56
9.61k
      code_lengths[symbol++] = code_len;
57
9.61k
      if (code_len != 0) {
58
7.58k
        prev_code_len = code_len;
59
7.58k
        space -= kFullSpace >> code_len;
60
7.58k
      }
61
9.61k
    } else {
62
809
      uint32_t extra_bits = code_len - 14;  // >= 2
63
809
      size_t old_repeat;
64
809
      size_t repeat_delta;
65
809
      uint8_t new_len = 0;
66
809
      if (code_len == kCodeLengthRepeatCode) {
67
507
        new_len = prev_code_len;
68
507
      }
69
809
      if (repeat_code_len != new_len) {
70
212
        repeat = 0;
71
212
        repeat_code_len = new_len;
72
212
      }
73
809
      old_repeat = repeat;
74
809
      if (repeat > 0) {  // >= 3
75
172
        repeat -= 2;
76
172
        repeat <<= extra_bits;
77
172
      }
78
809
      repeat += BrunsliBitReaderRead(br, extra_bits) + 3u;
79
809
      repeat_delta = repeat - old_repeat;
80
809
      if (symbol + repeat_delta > num_symbols) {
81
31
        return false;
82
31
      }
83
778
      memset(&code_lengths[symbol], repeat_code_len, (size_t)repeat_delta);
84
778
      symbol += repeat_delta;
85
778
      if (repeat_code_len != 0) {
86
493
        space -= static_cast<int>(repeat_delta * kFullSpace) >> repeat_code_len;
87
493
      }
88
778
    }
89
10.4k
  }
90
275
  if (space != 0) {
91
94
    return false;
92
94
  }
93
181
  memset(&code_lengths[symbol], 0, (size_t)(num_symbols - symbol));
94
181
  return BrunsliBitReaderIsHealthy(br);
95
275
}
96
97
static BRUNSLI_INLINE bool ReadSimpleCode(uint16_t alphabet_size,
98
                                          BrunsliBitReader* br,
99
657
                                          HuffmanCode* table) {
100
657
  uint32_t max_bits =
101
657
      (alphabet_size > 1u) ? Log2FloorNonZero(alphabet_size - 1u) + 1 : 0;
102
103
657
  size_t num_symbols = BrunsliBitReaderRead(br, 2) + 1;
104
105
657
  uint16_t symbols[4] = {0};
106
1.73k
  for (size_t i = 0; i < num_symbols; ++i) {
107
1.10k
    uint16_t symbol = BrunsliBitReaderRead(br, max_bits);
108
1.10k
    if (symbol >= alphabet_size) {
109
29
      return false;
110
29
    }
111
1.07k
    symbols[i] = symbol;
112
1.07k
  }
113
114
989
  for (size_t i = 0; i < num_symbols - 1; ++i) {
115
1.00k
    for (size_t j = i + 1; j < num_symbols; ++j) {
116
641
      if (symbols[i] == symbols[j]) return false;
117
641
    }
118
385
  }
119
120
  // 4 symbols have to option to encode.
121
604
  if (num_symbols == 4) num_symbols += BrunsliBitReaderRead(br, 1);
122
123
604
  const auto swap_symbols = [&symbols](size_t i, size_t j) {
124
217
    uint16_t t = symbols[j];
125
217
    symbols[j] = symbols[i];
126
217
    symbols[i] = t;
127
217
  };
128
129
604
  size_t table_size = 1;
130
604
  switch (num_symbols) {
131
417
    case 1:
132
417
      table[0] = {0, symbols[0]};
133
417
      break;
134
97
    case 2:
135
97
      if (symbols[0] > symbols[1]) swap_symbols(0, 1);
136
97
      table[0] = {1, symbols[0]};
137
97
      table[1] = {1, symbols[1]};
138
97
      table_size = 2;
139
97
      break;
140
26
    case 3:
141
26
      if (symbols[1] > symbols[2]) swap_symbols(1, 2);
142
26
      table[0] = {1, symbols[0]};
143
26
      table[2] = {1, symbols[0]};
144
26
      table[1] = {2, symbols[1]};
145
26
      table[3] = {2, symbols[2]};
146
26
      table_size = 4;
147
26
      break;
148
36
    case 4: {
149
144
      for (size_t i = 0; i < 3; ++i) {
150
324
        for (size_t j = i + 1; j < 4; ++j) {
151
216
          if (symbols[i] > symbols[j]) swap_symbols(i, j);
152
216
        }
153
108
      }
154
36
      table[0] = {2, symbols[0]};
155
36
      table[2] = {2, symbols[1]};
156
36
      table[1] = {2, symbols[2]};
157
36
      table[3] = {2, symbols[3]};
158
36
      table_size = 4;
159
36
      break;
160
0
    }
161
28
    case 5: {
162
28
      if (symbols[2] > symbols[3]) swap_symbols(2, 3);
163
28
      table[0] = {1, symbols[0]};
164
28
      table[1] = {2, symbols[1]};
165
28
      table[2] = {1, symbols[0]};
166
28
      table[3] = {3, symbols[2]};
167
28
      table[4] = {1, symbols[0]};
168
28
      table[5] = {2, symbols[1]};
169
28
      table[6] = {1, symbols[0]};
170
28
      table[7] = {3, symbols[3]};
171
28
      table_size = 8;
172
28
      break;
173
0
    }
174
0
    default: {
175
      // Unreachable.
176
0
      return false;
177
0
    }
178
604
  }
179
180
604
  const uint32_t goal_size = 1u << kHuffmanTableBits;
181
5.13k
  while (table_size != goal_size) {
182
4.52k
    memcpy(&table[table_size], &table[0],
183
4.52k
           (size_t)table_size * sizeof(table[0]));
184
4.52k
    table_size <<= 1;
185
4.52k
  }
186
187
604
  return BrunsliBitReaderIsHealthy(br);
188
604
}
189
190
bool HuffmanDecodingData::ReadFromBitStream(size_t alphabet_size,
191
                                            BrunsliBitReader* br,
192
1.04k
                                            Arena<HuffmanCode>* arena) {
193
1.04k
  Arena<HuffmanCode> local_arena;
194
1.04k
  if (arena == nullptr) arena = &local_arena;
195
196
1.04k
  if (alphabet_size > (1 << kMaxHuffmanBits)) return false;
197
198
1.04k
  std::vector<uint8_t> code_lengths(alphabet_size, 0);
199
  /* simple_code_or_skip is used as follows:
200
     1 for simple code;
201
     0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
202
1.04k
  uint32_t simple_code_or_skip = BrunsliBitReaderRead(br, 2);
203
1.04k
  if (simple_code_or_skip == 1u) {
204
657
    table_.resize(1u << kHuffmanTableBits);
205
657
    return ReadSimpleCode(static_cast<uint16_t>(alphabet_size), br,
206
657
                          table_.data());
207
657
  }
208
209
384
  uint8_t code_length_code_lengths[kCodeLengthCodes] = {0};
210
384
  int space = 32;
211
384
  int num_codes = 0;
212
  /* Static Huffman code for the code length code lengths */
213
384
  static const HuffmanCode huff[16] = {
214
384
      {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 1},
215
384
      {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 5},
216
384
  };
217
5.23k
  for (size_t i = simple_code_or_skip; i < kCodeLengthCodes && space > 0; ++i) {
218
4.84k
    const int code_len_idx = kCodeLengthCodeOrder[i];
219
4.84k
    const HuffmanCode* p = huff;
220
4.84k
    uint8_t v;
221
4.84k
    p += BrunsliBitReaderGet(br, 4);
222
4.84k
    BrunsliBitReaderDrop(br, p->bits);
223
4.84k
    v = (uint8_t)p->value;
224
4.84k
    code_length_code_lengths[code_len_idx] = v;
225
4.84k
    if (v != 0) {
226
2.18k
      space -= (32u >> v);
227
2.18k
      ++num_codes;
228
2.18k
    }
229
4.84k
  }
230
384
  bool ok = (num_codes == 1 || space == 0) &&
231
306
            ReadHuffmanCodeLengths(code_length_code_lengths, alphabet_size,
232
306
                                   &code_lengths[0], br);
233
234
384
  if (!ok || !BrunsliBitReaderIsHealthy(br)) return false;
235
171
  uint16_t counts[16] = {0};
236
19.9k
  for (size_t i = 0; i < alphabet_size; ++i) {
237
19.7k
    ++counts[code_lengths[i]];
238
19.7k
  }
239
171
  arena->reserve(alphabet_size + 376);
240
171
  uint32_t table_size =
241
171
      BuildHuffmanTable(arena->data(), kHuffmanTableBits, &code_lengths[0],
242
171
                        alphabet_size, &counts[0]);
243
171
  table_ = std::vector<HuffmanCode>(arena->data(), arena->data() + table_size);
244
171
  return (table_size > 0);
245
384
}
246
247
// Decodes the next Huffman coded symbol from the bit-stream.
248
1.32M
uint16_t HuffmanDecodingData::ReadSymbol(BrunsliBitReader* br) const {
249
1.32M
  uint32_t n_bits;
250
1.32M
  const HuffmanCode* table = table_.data();
251
1.32M
  table += BrunsliBitReaderGet(br, kHuffmanTableBits);
252
1.32M
  n_bits = table->bits;
253
1.32M
  if (n_bits > kHuffmanTableBits) {
254
633
    BrunsliBitReaderDrop(br, kHuffmanTableBits);
255
633
    n_bits -= kHuffmanTableBits;
256
633
    table += table->value;
257
633
    table += BrunsliBitReaderGet(br, n_bits);
258
633
  }
259
1.32M
  BrunsliBitReaderDrop(br, table->bits);
260
1.32M
  return table->value;
261
1.32M
}
262
263
}  // namespace brunsli