#pragma once #include #include #include #include namespace LibDEFLATE { class HuffmanTree { BAN_NON_COPYABLE(HuffmanTree); public: static constexpr uint8_t MAX_BITS = 15; struct Leaf { uint16_t code; uint8_t len; }; struct Instant { uint16_t symbol; uint8_t len; }; HuffmanTree() {} HuffmanTree(HuffmanTree&& other) { *this = BAN::move(other); } HuffmanTree& operator=(HuffmanTree&& other); static BAN::ErrorOr create(BAN::Span bit_lengths); static BAN::ErrorOr fixed_tree(); BAN::Optional get_symbol_instant(uint16_t code) const; BAN::Optional get_symbol(uint16_t code, uint8_t len) const; uint8_t instant_bits() const { return m_instant_bits; } uint8_t min_bits() const { return m_min_bits; } uint8_t max_bits() const { return m_max_bits; } bool empty() const { return m_min_bits == 0; } private: BAN::ErrorOr initialize(BAN::Span bit_lengths); BAN::ErrorOr build_instant_table(BAN::Span tree); BAN::ErrorOr build_slow_table(BAN::Span tree); private: uint8_t m_instant_bits { 0 }; uint8_t m_min_bits { 0 }; uint8_t m_max_bits { 0 }; BAN::Vector m_instant; BAN::Array m_min_code; BAN::Vector> m_slow_table; }; }