5#include "utility/module.hpp"
10namespace hi::inline
v1 {
14 static_assert(std::is_integral_v<T> && std::is_signed_v<T>);
16 using state_t = T
const *;
39 void add(
int symbol,
int code,
int code_length)
noexcept
44 while (--code_length > 0) {
45 hilet select = (code >> code_length) & 1;
48 int value =
tree[offset];
55 value = -(narrow_cast<int>(ssize(
tree)) - offset);
57 tree[offset] = narrow_cast<T>(value);
67 hilet select = code & 1;
71 tree[offset] = narrow_cast<T>(symbol + 1);
74 [[nodiscard]] state_t start() const noexcept
91 [[nodiscard]]
int get(
bool code_bit, state_t &state)
const
93 state +=
static_cast<ptrdiff_t
>(code_bit);
96 throw parse_error(
"Code not in huffman tree.");
100 state -=
static_cast<ptrdiff_t
>(value);
104 [[nodiscard]]
std::size_t get_symbol(std::span<std::byte const> bytes,
std::size_t &bit_offset)
const noexcept
106 auto state = start();
109 if ((symbol = get(
get_bit(bytes, bit_offset), state)) >= 0) {
122 struct symbol_length_t {
126 symbol_length_t(T symbol, uint8_t length) : symbol(symbol), length(length) {}
130 symbol_lengths.
reserve(nr_symbols);
132 for (T symbol = T{0}; symbol != narrow_cast<T>(nr_symbols); ++symbol) {
138 if (a.length == b.length) {
139 return a.symbol < b.symbol;
141 return a.length < b.length;
149 for (
auto &&entry : symbol_lengths) {
150 if (entry.length != 0) {
151 code <<= (entry.length - prev_length);
153 r.add(entry.symbol, code, entry.length);
157 prev_length = entry.length;
165 return from_lengths(lengths.
data(), lengths.
size());
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hi_assert_not_null(x,...)
Assert if an expression is not nullptr.
Definition assert.hpp:223
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
bool get_bit(std::span< std::byte const > buffer, std::size_t &index) noexcept
Read a single bit from span of bytes Bits are ordered LSB first.
Definition bits.hpp:19
Definition huffman.hpp:13
int get(bool code_bit, state_t &state) const
Get a symbol from the huffman-tree.
Definition huffman.hpp:91
void add(int symbol, int code, int code_length) noexcept
Add a symbol to the huffman_tree.
Definition huffman.hpp:39
static huffman_tree from_lengths(uint8_t const *lengths, std::size_t nr_symbols)
Build a canonical-huffman table from a set of lengths.
Definition huffman.hpp:117
A tree container.
Definition tree.hpp:19
T emplace_back(T... args)