1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 14:07:45 +00:00

LibCompress/LZW: Use a parameter to choose when to change the code size

Some users of the LZW algorithm use a different value to determine when
the size of the code changes. GIF increments the size when the number of
elements in the table is equal to 2^code_size while TIFF does it for a
count of 2^code_size - 1.

This patch adds the parameter m_offset_for_size_change with a default
value of 0 and our decoder will increment the code size when we reach
a table length of 2^code_size + m_offset_for_size_change. This allows us
to support both situations.
This commit is contained in:
Lucas CHOLLET 2023-11-09 22:46:37 -05:00 committed by Andreas Kling
parent 0c0d7e8fd3
commit fcaebe56d7

View file

@ -22,11 +22,13 @@ private:
static constexpr int max_code_size = 12; static constexpr int max_code_size = 12;
public: public:
explicit LZWDecoder(MaybeOwned<InputStream> lzw_stream, u8 min_code_size) explicit LZWDecoder(MaybeOwned<InputStream> lzw_stream, u8 min_code_size, i32 offset_for_size_change = 0)
: m_bit_stream(move(lzw_stream)) : m_bit_stream(move(lzw_stream))
, m_code_size(min_code_size) , m_code_size(min_code_size)
, m_original_code_size(min_code_size) , m_original_code_size(min_code_size)
, m_table_capacity(AK::exp2<u32>(min_code_size)) , m_table_capacity(AK::exp2<u32>(min_code_size))
, m_offset_for_size_change(offset_for_size_change)
{ {
init_code_table(); init_code_table();
} }
@ -102,7 +104,7 @@ private:
{ {
if (entry.size() > 1 && m_code_table.size() < 4096) { if (entry.size() > 1 && m_code_table.size() < 4096) {
m_code_table.append(entry); m_code_table.append(entry);
if (m_code_table.size() >= m_table_capacity && m_code_size < max_code_size) { if (m_code_table.size() >= (m_table_capacity + m_offset_for_size_change) && m_code_size < max_code_size) {
++m_code_size; ++m_code_size;
m_table_capacity *= 2; m_table_capacity *= 2;
} }
@ -118,6 +120,7 @@ private:
u8 m_original_code_size { 0 }; u8 m_original_code_size { 0 };
u32 m_table_capacity { 0 }; u32 m_table_capacity { 0 };
i32 m_offset_for_size_change {};
u16 m_current_code { 0 }; u16 m_current_code { 0 };
Vector<u8> m_output {}; Vector<u8> m_output {};