7#include "../utility/utility.hpp"
8#include "../macros.hpp"
13hi_export_module(hikogui.codec.huffman);
15hi_export
namespace hi {
inline namespace v1 {
17hi_export
template<
typename T>
19 static_assert(std::is_integral_v<T> && std::is_signed_v<T>);
21 using state_t = T
const *;
44 void add(
int symbol,
int code,
int code_length)
noexcept
46 hi_axiom(code_length >= 1);
49 while (--code_length > 0) {
50 auto const select = (code >> code_length) & 1;
53 int value = tree[offset];
72 auto const select = code & 1;
75 hi_axiom(tree[offset] == 0);
79 [[nodiscard]] state_t start() const noexcept
96 [[nodiscard]]
int get(
bool code_bit, state_t& state)
const
98 state +=
static_cast<ptrdiff_t
>(code_bit);
105 state -=
static_cast<ptrdiff_t
>(value);
109 [[nodiscard]]
std::size_t get_symbol(std::span<std::byte const> bytes,
std::size_t& bit_offset)
const noexcept
111 auto state = start();
114 if ((symbol =
get(
get_bit(bytes, bit_offset), state)) >= 0) {
124 hi_assert_not_null(lengths);
127 struct symbol_length_t {
131 symbol_length_t(T symbol, uint8_t length) : symbol(symbol), length(length) {}
135 symbol_lengths.
reserve(nr_symbols);
137 for (T symbol = T{0}; symbol !=
narrow_cast<T>(nr_symbols); ++symbol) {
142 std::sort(symbol_lengths.
begin(), symbol_lengths.
end(), [](
auto const& a,
auto const& b) {
143 if (a.length == b.length) {
144 return a.symbol < b.symbol;
146 return a.length < b.length;
154 for (
auto&& entry : symbol_lengths) {
155 if (entry.length != 0) {
156 code <<= (entry.length - prev_length);
158 r.add(entry.symbol, code, entry.length);
162 prev_length = entry.length;
168 [[nodiscard]]
static huffman_tree from_lengths(std::vector<uint8_t>
const& lengths)
170 return from_lengths(lengths.
data(), lengths.
size());
@ select
The widget is selectable.
Definition widget_state.hpp:63
The HikoGUI namespace.
Definition array_generic.hpp:21
The HikoGUI API version 1.
Definition array_generic.hpp:22
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:27
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:378
Definition huffman.hpp:18
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:122
void add(int symbol, int code, int code_length) noexcept
Add a symbol to the huffman_tree.
Definition huffman.hpp:44
int get(bool code_bit, state_t &state) const
Get a symbol from the huffman-tree.
Definition huffman.hpp:96
Exception thrown during parsing on an error.
Definition exception_intf.hpp:48
T emplace_back(T... args)