mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 17:40:27 +00:00
LibCompress/Lzw: Move shareable code to a base class
This commit is contained in:
parent
70a3f1f02b
commit
945e09e46d
Notes:
sideshowbarker
2024-07-17 02:39:10 +09:00
Author: https://github.com/LucasChollet Commit: https://github.com/SerenityOS/serenity/commit/945e09e46d Pull-request: https://github.com/SerenityOS/serenity/pull/24191 Reviewed-by: https://github.com/nico ✅ Reviewed-by: https://github.com/timschumi
1 changed files with 71 additions and 54 deletions
|
@ -17,23 +17,85 @@
|
|||
|
||||
namespace Compress {
|
||||
|
||||
template<InputBitStream InputStream>
|
||||
class LzwDecompressor {
|
||||
private:
|
||||
namespace Details {
|
||||
|
||||
class LzwState {
|
||||
public:
|
||||
u16 add_control_code()
|
||||
{
|
||||
u16 const control_code = m_code_table.size();
|
||||
m_code_table.append(Vector<u8> {});
|
||||
m_original_code_table.append(Vector<u8> {});
|
||||
if (m_code_table.size() >= m_table_capacity && m_code_size < max_code_size) {
|
||||
++m_code_size;
|
||||
++m_original_code_size;
|
||||
m_table_capacity *= 2;
|
||||
}
|
||||
return control_code;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_code_table.clear();
|
||||
m_code_table.extend(m_original_code_table);
|
||||
m_code_size = m_original_code_size;
|
||||
m_table_capacity = AK::exp2<u32>(m_code_size);
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr int max_code_size = 12;
|
||||
|
||||
public:
|
||||
explicit LzwDecompressor(MaybeOwned<InputStream> lzw_stream, u8 min_code_size, i32 offset_for_size_change = 0)
|
||||
: m_bit_stream(move(lzw_stream))
|
||||
, m_code_size(min_code_size)
|
||||
LzwState(u8 min_code_size, i32 offset_for_size_change)
|
||||
: m_code_size(min_code_size)
|
||||
, m_original_code_size(min_code_size)
|
||||
, m_table_capacity(AK::exp2<u32>(min_code_size))
|
||||
, m_offset_for_size_change(offset_for_size_change)
|
||||
|
||||
{
|
||||
init_code_table();
|
||||
}
|
||||
|
||||
void init_code_table()
|
||||
{
|
||||
m_code_table.ensure_capacity(m_table_capacity);
|
||||
for (u16 i = 0; i < m_table_capacity; ++i) {
|
||||
m_code_table.unchecked_append({ (u8)i });
|
||||
}
|
||||
m_original_code_table = m_code_table;
|
||||
}
|
||||
|
||||
void extend_code_table(Vector<u8> const& entry)
|
||||
{
|
||||
if (entry.size() > 1 && m_code_table.size() < 4096) {
|
||||
m_code_table.append(entry);
|
||||
if (m_code_table.size() >= (m_table_capacity + m_offset_for_size_change) && m_code_size < max_code_size) {
|
||||
++m_code_size;
|
||||
m_table_capacity *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector<Vector<u8>> m_code_table {};
|
||||
Vector<Vector<u8>> m_original_code_table {};
|
||||
|
||||
u8 m_code_size { 0 };
|
||||
u8 m_original_code_size { 0 };
|
||||
|
||||
u32 m_table_capacity { 0 };
|
||||
i32 m_offset_for_size_change {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<InputBitStream InputStream>
|
||||
class LzwDecompressor : private Details::LzwState {
|
||||
public:
|
||||
explicit LzwDecompressor(MaybeOwned<InputStream> lzw_stream, u8 min_code_size, i32 offset_for_size_change = 0)
|
||||
: LzwState(min_code_size, offset_for_size_change)
|
||||
, m_bit_stream(move(lzw_stream))
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
static ErrorOr<ByteBuffer> decompress_all(ReadonlyBytes bytes, u8 initial_code_size, i32 offset_for_size_change = 0)
|
||||
{
|
||||
auto memory_stream = make<FixedMemoryStream>(bytes);
|
||||
|
@ -62,25 +124,9 @@ public:
|
|||
return decompressed;
|
||||
}
|
||||
|
||||
u16 add_control_code()
|
||||
{
|
||||
u16 const control_code = m_code_table.size();
|
||||
m_code_table.append(Vector<u8> {});
|
||||
m_original_code_table.append(Vector<u8> {});
|
||||
if (m_code_table.size() >= m_table_capacity && m_code_size < max_code_size) {
|
||||
++m_code_size;
|
||||
++m_original_code_size;
|
||||
m_table_capacity *= 2;
|
||||
}
|
||||
return control_code;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_code_table.clear();
|
||||
m_code_table.extend(m_original_code_table);
|
||||
m_code_size = m_original_code_size;
|
||||
m_table_capacity = AK::exp2<u32>(m_code_size);
|
||||
LzwState::reset();
|
||||
m_output.clear();
|
||||
}
|
||||
|
||||
|
@ -120,37 +166,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void init_code_table()
|
||||
{
|
||||
m_code_table.ensure_capacity(m_table_capacity);
|
||||
for (u16 i = 0; i < m_table_capacity; ++i) {
|
||||
m_code_table.unchecked_append({ (u8)i });
|
||||
}
|
||||
m_original_code_table = m_code_table;
|
||||
}
|
||||
|
||||
void extend_code_table(Vector<u8> const& entry)
|
||||
{
|
||||
if (entry.size() > 1 && m_code_table.size() < 4096) {
|
||||
m_code_table.append(entry);
|
||||
if (m_code_table.size() >= (m_table_capacity + m_offset_for_size_change) && m_code_size < max_code_size) {
|
||||
++m_code_size;
|
||||
m_table_capacity *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MaybeOwned<InputStream> m_bit_stream;
|
||||
|
||||
Vector<Vector<u8>> m_code_table {};
|
||||
Vector<Vector<u8>> m_original_code_table {};
|
||||
|
||||
u8 m_code_size { 0 };
|
||||
u8 m_original_code_size { 0 };
|
||||
|
||||
u32 m_table_capacity { 0 };
|
||||
i32 m_offset_for_size_change {};
|
||||
|
||||
u16 m_current_code { 0 };
|
||||
Vector<u8> m_output {};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue