/* * Copyright (c) 2020, the SerenityOS developers. * Copyright (c) 2021, Idan Horowitz * Copyright (c) 2025, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Compress { class CanonicalCode { public: CanonicalCode() = default; ErrorOr read_symbol(LittleEndianInputBitStream&) const; ErrorOr write_symbol(LittleEndianOutputBitStream&, u32) const; static CanonicalCode const& fixed_literal_codes(); static CanonicalCode const& fixed_distance_codes(); static ErrorOr from_bytes(ReadonlyBytes); private: static constexpr size_t max_allowed_prefixed_code_length = 8; struct PrefixTableEntry { u16 symbol_value { 0 }; u16 code_length { 0 }; }; // Decompression - indexed by code Vector m_symbol_codes; Vector m_symbol_values; Array m_prefix_table {}; size_t m_max_prefixed_code_length { 0 }; // Compression - indexed by symbol // Deflate uses a maximum of 288 symbols (maximum of 32 for distances), // but this is also used by webp, which can use up to 256 + 24 + (1 << 11) == 2328 symbols. Vector m_bit_codes {}; Vector m_bit_code_lengths {}; }; ALWAYS_INLINE ErrorOr CanonicalCode::write_symbol(LittleEndianOutputBitStream& stream, u32 symbol) const { auto code = symbol < m_bit_codes.size() ? m_bit_codes[symbol] : 0u; auto length = symbol < m_bit_code_lengths.size() ? m_bit_code_lengths[symbol] : 0u; TRY(stream.write_bits(code, length)); return {}; } class DeflateDecompressor final : public GenericZlibDecompressor { public: static ErrorOr> create(MaybeOwned); static ErrorOr decompress_all(ReadonlyBytes); private: DeflateDecompressor(AK::FixedArray buffer, MaybeOwned stream, z_stream* zstream) : GenericZlibDecompressor(move(buffer), move(stream), zstream) { } }; class DeflateCompressor final : public GenericZlibCompressor { public: static ErrorOr> create(MaybeOwned, GenericZlibCompressionLevel = GenericZlibCompressionLevel::Default); static ErrorOr compress_all(ReadonlyBytes, GenericZlibCompressionLevel = GenericZlibCompressionLevel::Default); private: DeflateCompressor(AK::FixedArray buffer, MaybeOwned stream, z_stream* zstream) : GenericZlibCompressor(move(buffer), move(stream), zstream) { } }; }