2#include "TTauri/Foundation/required.hpp"
3#include "TTauri/Foundation/bits.hpp"
4#include "TTauri/Foundation/numeric_cast.hpp"
12 static_assert(std::is_integral_v<T> && std::is_signed_v<T>);
14 using state_t = T
const *;
36 void add(
int symbol,
int code,
int code_length)
noexcept {
37 tt_assume(code_length >= 1);
40 while (--code_length > 0) {
41 int select = (code >> code_length) & 1;
44 int value = tree[offset];
47 tt_assume(value <= 0);
51 value = -(
static_cast<int>(ssize(tree)) - offset);
53 tree[offset] = numeric_cast<T>(value);
63 int select = code & 1;
66 tt_assume(tree[offset] == 0);
67 tree[offset] = numeric_cast<T>(symbol + 1);
70 [[nodiscard]] state_t start() const noexcept {
86 [[nodiscard]]
int get(
bool code_bit, state_t &state)
const {
87 state +=
static_cast<ptrdiff_t
>(code_bit);
90 TTAURI_THROW(
parse_error(
"Code not in huffman tree."));
94 state -=
static_cast<ptrdiff_t
>(value);
98 [[nodiscard]]
int get_symbol(nonstd::span<std::byte const> bytes,
ssize_t &bit_offset)
const noexcept {
102 if ((symbol =
get(get_bit(bytes, bit_offset), state)) >= 0) {
111 struct symbol_length_t {
115 symbol_length_t(
int symbol,
int length) : symbol(symbol), length(length) {}
119 symbol_lengths.
reserve(nr_symbols);
121 for (
int symbol = 0; symbol != nr_symbols; ++symbol) {
127 if (a.length == b.length) {
128 return a.symbol < b.symbol;
130 return a.length < b.length;
138 for (
auto &&entry: symbol_lengths) {
139 if (entry.length != 0) {
140 code <<= (entry.length - prev_length);
142 r.
add(entry.symbol, code, entry.length);
146 prev_length = entry.length;
152 [[nodiscard]]
static huffman_tree from_lengths(
std::vector<int> const &lengths) {
153 return from_lengths(lengths.
data(), ssize(lengths));
Definition exceptions.hpp:154
Definition huffman.hpp:11
void add(int symbol, int code, int code_length) noexcept
Add a symbol to the huffman_tree.
Definition huffman.hpp:36
static huffman_tree from_lengths(int const *lengths, ssize_t nr_symbols)
Build a canonical-huffman table from a set of lengths.
Definition huffman.hpp:110
int get(bool code_bit, state_t &state) const
Get a symbol from the huffman-tree.
Definition huffman.hpp:86
T emplace_back(T... args)