From 9248fd7f33da48e202330ec8308e17e7b6de8f3e Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Thu, 6 Jul 2023 13:35:13 -0400 Subject: [PATCH] LibCompress: Move `CanonicalCode`'s initializers inside `CanonicalCode` These routines: - read_prefix_code - read_simple_prefix_code - read_complex_prefix_code were methods of `BrotliDecompressionStream` taking a `CanonicalCode` as an out parameter. This patch puts them in `CanonicalCode` as static methods. --- Userland/Libraries/LibCompress/Brotli.cpp | 71 ++++++++++------------- Userland/Libraries/LibCompress/Brotli.h | 13 +++-- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/Userland/Libraries/LibCompress/Brotli.cpp b/Userland/Libraries/LibCompress/Brotli.cpp index e9cf773f96..dea96ba2df 100644 --- a/Userland/Libraries/LibCompress/Brotli.cpp +++ b/Userland/Libraries/LibCompress/Brotli.cpp @@ -137,7 +137,7 @@ ErrorOr BrotliDecompressionStream::read_variable_length() } } -ErrorOr BrotliDecompressionStream::read_complex_prefix_code_length() +ErrorOr BrotliDecompressionStream::CanonicalCode::read_complex_prefix_code_length(LittleEndianInputBitStream& stream) { // Symbol Code // ------ ---- @@ -148,7 +148,7 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code_length() // 4 01 // 5 1111 - switch (TRY(m_input_stream.read_bits(2))) { + switch (TRY(stream.read_bits(2))) { case 0: return 0; case 1: @@ -156,10 +156,10 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code_length() case 2: return 3; case 3: { - if (TRY(m_input_stream.read_bit()) == 0) { + if (TRY(stream.read_bit()) == 0) { return 2; } else { - if (TRY(m_input_stream.read_bit()) == 0) { + if (TRY(stream.read_bit()) == 0) { return 1; } else { return 5; @@ -171,25 +171,21 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code_length() } } -ErrorOr BrotliDecompressionStream::read_prefix_code(CanonicalCode& code, size_t alphabet_size) +ErrorOr BrotliDecompressionStream::CanonicalCode::read_prefix_code(LittleEndianInputBitStream& stream, size_t alphabet_size) { - size_t hskip = TRY(m_input_stream.read_bits(2)); + size_t hskip = TRY(stream.read_bits(2)); - if (hskip == 1) { - TRY(read_simple_prefix_code(code, alphabet_size)); - } else { - TRY(read_complex_prefix_code(code, alphabet_size, hskip)); - } + if (hskip == 1) + return TRY(read_simple_prefix_code(stream, alphabet_size)); - return {}; + return TRY(read_complex_prefix_code(stream, alphabet_size, hskip)); } -ErrorOr BrotliDecompressionStream::read_simple_prefix_code(CanonicalCode& code, size_t alphabet_size) +ErrorOr BrotliDecompressionStream::CanonicalCode::read_simple_prefix_code(LittleEndianInputBitStream& stream, size_t alphabet_size) { - VERIFY(code.m_symbol_codes.is_empty()); - VERIFY(code.m_symbol_values.is_empty()); + CanonicalCode code {}; - size_t number_of_symbols = 1 + TRY(m_input_stream.read_bits(2)); + size_t number_of_symbols = 1 + TRY(stream.read_bits(2)); size_t symbol_size = 0; while ((1u << symbol_size) < alphabet_size) @@ -197,7 +193,7 @@ ErrorOr BrotliDecompressionStream::read_simple_prefix_code(CanonicalCode& Vector symbols; for (size_t i = 0; i < number_of_symbols; i++) { - size_t symbol = TRY(m_input_stream.read_bits(symbol_size)); + size_t symbol = TRY(stream.read_bits(symbol_size)); symbols.append(symbol); if (symbol >= alphabet_size) @@ -218,7 +214,7 @@ ErrorOr BrotliDecompressionStream::read_simple_prefix_code(CanonicalCode& swap(symbols[1], symbols[2]); code.m_symbol_values = move(symbols); } else if (number_of_symbols == 4) { - bool tree_select = TRY(m_input_stream.read_bit()); + bool tree_select = TRY(stream.read_bit()); if (tree_select) { code.m_symbol_codes.extend({ 0b10, 0b110, 0b1110, 0b1111 }); if (symbols[2] > symbols[3]) @@ -231,10 +227,10 @@ ErrorOr BrotliDecompressionStream::read_simple_prefix_code(CanonicalCode& } } - return {}; + return code; } -ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& code, size_t alphabet_size, size_t hskip) +ErrorOr BrotliDecompressionStream::CanonicalCode::read_complex_prefix_code(LittleEndianInputBitStream& stream, size_t alphabet_size, size_t hskip) { // hskip should only be 0, 2 or 3 VERIFY(hskip != 1); @@ -248,7 +244,7 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& size_t sum = 0; size_t number_of_non_zero_symbols = 0; for (size_t i = hskip; i < 18; i++) { - size_t len = TRY(read_complex_prefix_code_length()); + size_t len = TRY(read_complex_prefix_code_length(stream)); code_length[symbol_mapping[i]] = len; if (len != 0) { @@ -302,7 +298,7 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& Vector result_lengths; size_t result_lengths_count[16] { 0 }; while (i < alphabet_size) { - auto symbol = TRY(temp_code.read_symbol(m_input_stream)); + auto symbol = TRY(temp_code.read_symbol(stream)); if (symbol < 16) { result_symbols.append(i); @@ -327,7 +323,7 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& } else { last_repeat = 0; } - repeat_count += 3 + TRY(m_input_stream.read_bits(2)); + repeat_count += 3 + TRY(stream.read_bits(2)); for (size_t rep = 0; rep < (repeat_count - last_repeat); rep++) { result_symbols.append(i); @@ -358,7 +354,7 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& } else { last_repeat = 0; } - repeat_count += 3 + TRY(m_input_stream.read_bits(3)); + repeat_count += 3 + TRY(stream.read_bits(3)); i += (repeat_count - last_repeat); last_repeat = repeat_count; @@ -368,6 +364,8 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& } result_lengths_count[0] = 0; + CanonicalCode final_code; + size_t code_value = 0; for (size_t bits = 1; bits < 16; bits++) { code_value = (code_value + result_lengths_count[bits - 1]) << 1; @@ -376,14 +374,14 @@ ErrorOr BrotliDecompressionStream::read_complex_prefix_code(CanonicalCode& for (size_t n = 0; n < result_symbols.size(); n++) { size_t len = result_lengths[n]; if (len == bits) { - code.m_symbol_codes.append((1 << bits) | current_code_value); - code.m_symbol_values.append(result_symbols[n]); + final_code.m_symbol_codes.append((1 << bits) | current_code_value); + final_code.m_symbol_values.append(result_symbols[n]); current_code_value++; } } } - return {}; + return final_code; } static void inverse_move_to_front_transform(Span v) @@ -412,8 +410,7 @@ ErrorOr BrotliDecompressionStream::read_context_map(size_t number_of_codes run_length_encoding_max = 1 + TRY(m_input_stream.read_bits(4)); } - BrotliDecompressionStream::CanonicalCode code; - TRY(read_prefix_code(code, number_of_codes + run_length_encoding_max)); + auto const code = TRY(CanonicalCode::read_prefix_code(m_input_stream, number_of_codes + run_length_encoding_max)); size_t i = 0; while (i < context_map_size) { @@ -455,8 +452,8 @@ ErrorOr BrotliDecompressionStream::read_block_configuration(Block& block) if (blocks_of_type == 1) { block.length = 16 * MiB; } else { - TRY(read_prefix_code(block.type_code, 2 + blocks_of_type)); - TRY(read_prefix_code(block.length_code, 26)); + block.type_code = TRY(CanonicalCode::read_prefix_code(m_input_stream, 2 + blocks_of_type)); + block.length_code = TRY(CanonicalCode::read_prefix_code(m_input_stream, 26)); TRY(block_update_length(block)); } @@ -716,23 +713,17 @@ ErrorOr BrotliDecompressionStream::read_some(Bytes output_buffer) m_literal_codes.clear(); for (size_t i = 0; i < number_of_literal_codes; i++) { - CanonicalCode code; - TRY(read_prefix_code(code, 256)); - m_literal_codes.append(move(code)); + m_literal_codes.append(TRY(CanonicalCode::read_prefix_code(m_input_stream, 256))); } m_insert_and_copy_codes.clear(); for (size_t i = 0; i < m_insert_and_copy_block.number_of_types; i++) { - CanonicalCode code; - TRY(read_prefix_code(code, 704)); - m_insert_and_copy_codes.append(move(code)); + m_insert_and_copy_codes.append(TRY(CanonicalCode::read_prefix_code(m_input_stream, 704))); } m_distance_codes.clear(); for (size_t i = 0; i < number_of_distance_codes; i++) { - CanonicalCode code; - TRY(read_prefix_code(code, 16 + m_direct_distances + (48 << m_postfix_bits))); - m_distance_codes.append(move(code)); + m_distance_codes.append(TRY(CanonicalCode::read_prefix_code(m_input_stream, 16 + m_direct_distances + (48 << m_postfix_bits)))); } m_current_state = State::CompressedCommand; diff --git a/Userland/Libraries/LibCompress/Brotli.h b/Userland/Libraries/LibCompress/Brotli.h index 43ccb5f524..fb05a46c23 100644 --- a/Userland/Libraries/LibCompress/Brotli.h +++ b/Userland/Libraries/LibCompress/Brotli.h @@ -27,10 +27,13 @@ public: }; class CanonicalCode { - friend class BrotliDecompressionStream; - public: CanonicalCode() = default; + + static ErrorOr read_prefix_code(LittleEndianInputBitStream&, size_t alphabet_size); + static ErrorOr read_simple_prefix_code(LittleEndianInputBitStream&, size_t alphabet_size); + static ErrorOr read_complex_prefix_code(LittleEndianInputBitStream&, size_t alphabet_size, size_t hskip); + ErrorOr read_symbol(LittleEndianInputBitStream&) const; void clear() { @@ -39,6 +42,8 @@ public: } private: + static ErrorOr read_complex_prefix_code_length(LittleEndianInputBitStream&); + Vector m_symbol_codes; Vector m_symbol_values; }; @@ -114,11 +119,7 @@ private: ErrorOr read_window_length(); ErrorOr read_size_number_of_nibbles(); ErrorOr read_variable_length(); - ErrorOr read_complex_prefix_code_length(); - ErrorOr read_prefix_code(CanonicalCode&, size_t alphabet_size); - ErrorOr read_simple_prefix_code(CanonicalCode&, size_t alphabet_size); - ErrorOr read_complex_prefix_code(CanonicalCode&, size_t alphabet_size, size_t hskip); ErrorOr read_context_map(size_t number_of_codes, Vector& context_map, size_t context_map_size); ErrorOr read_block_configuration(Block&);