Brotli.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2022, Michiel Visser <opensource@webmichiel.nl>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/BitStream.h>
  8. #include <AK/CircularQueue.h>
  9. #include <AK/FixedArray.h>
  10. #include <AK/Vector.h>
  11. namespace Compress {
  12. namespace Brotli {
  13. class CanonicalCode {
  14. public:
  15. CanonicalCode() = default;
  16. CanonicalCode(Vector<size_t> codes, Vector<size_t> values)
  17. : m_symbol_codes(move(codes))
  18. , m_symbol_values(move(values)) {};
  19. static ErrorOr<CanonicalCode> read_prefix_code(LittleEndianInputBitStream&, size_t alphabet_size);
  20. static ErrorOr<CanonicalCode> read_simple_prefix_code(LittleEndianInputBitStream&, size_t alphabet_size);
  21. static ErrorOr<CanonicalCode> read_complex_prefix_code(LittleEndianInputBitStream&, size_t alphabet_size, size_t hskip);
  22. ErrorOr<size_t> read_symbol(LittleEndianInputBitStream&) const;
  23. private:
  24. static ErrorOr<size_t> read_complex_prefix_code_length(LittleEndianInputBitStream&);
  25. Vector<size_t> m_symbol_codes;
  26. Vector<size_t> m_symbol_values;
  27. };
  28. }
  29. class BrotliDecompressionStream : public Stream {
  30. using CanonicalCode = Brotli::CanonicalCode;
  31. public:
  32. enum class State {
  33. WindowSize,
  34. Idle,
  35. UncompressedData,
  36. CompressedCommand,
  37. CompressedLiteral,
  38. CompressedDistance,
  39. CompressedCopy,
  40. CompressedDictionary,
  41. };
  42. struct Block {
  43. size_t type;
  44. size_t type_previous;
  45. size_t number_of_types;
  46. size_t length;
  47. CanonicalCode type_code;
  48. CanonicalCode length_code;
  49. };
  50. class LookbackBuffer {
  51. private:
  52. LookbackBuffer(FixedArray<u8>& buffer)
  53. : m_buffer(move(buffer))
  54. {
  55. }
  56. public:
  57. static ErrorOr<LookbackBuffer> try_create(size_t size)
  58. {
  59. auto buffer = TRY(FixedArray<u8>::create(size));
  60. return LookbackBuffer { buffer };
  61. }
  62. void write(u8 value)
  63. {
  64. m_buffer[m_offset] = value;
  65. m_offset = (m_offset + 1) % m_buffer.size();
  66. m_total_written++;
  67. }
  68. u8 lookback(size_t offset) const
  69. {
  70. VERIFY(offset <= m_total_written);
  71. VERIFY(offset <= m_buffer.size());
  72. size_t index = (m_offset + m_buffer.size() - offset) % m_buffer.size();
  73. return m_buffer[index];
  74. }
  75. u8 lookback(size_t offset, u8 fallback) const
  76. {
  77. if (offset > m_total_written || offset > m_buffer.size())
  78. return fallback;
  79. VERIFY(offset <= m_total_written);
  80. VERIFY(offset <= m_buffer.size());
  81. size_t index = (m_offset + m_buffer.size() - offset) % m_buffer.size();
  82. return m_buffer[index];
  83. }
  84. size_t total_written() { return m_total_written; }
  85. private:
  86. FixedArray<u8> m_buffer;
  87. size_t m_offset { 0 };
  88. size_t m_total_written { 0 };
  89. };
  90. public:
  91. BrotliDecompressionStream(MaybeOwned<Stream>);
  92. ErrorOr<Bytes> read_some(Bytes output_buffer) override;
  93. ErrorOr<size_t> write_some(ReadonlyBytes bytes) override { return m_input_stream.write_some(bytes); }
  94. bool is_eof() const override;
  95. bool is_open() const override { return m_input_stream.is_open(); }
  96. void close() override { m_input_stream.close(); }
  97. private:
  98. ErrorOr<size_t> read_window_length();
  99. ErrorOr<size_t> read_size_number_of_nibbles();
  100. ErrorOr<size_t> read_variable_length();
  101. ErrorOr<void> read_context_map(size_t number_of_codes, Vector<u8>& context_map, size_t context_map_size);
  102. ErrorOr<void> read_block_configuration(Block&);
  103. ErrorOr<void> block_update_length(Block&);
  104. ErrorOr<void> block_read_new_state(Block&);
  105. size_t literal_code_index_from_context();
  106. LittleEndianInputBitStream m_input_stream;
  107. State m_current_state { State::WindowSize };
  108. Optional<LookbackBuffer> m_lookback_buffer;
  109. size_t m_window_size { 0 };
  110. bool m_read_final_block { false };
  111. size_t m_postfix_bits { 0 };
  112. size_t m_direct_distances { 0 };
  113. size_t m_distances[4] { 4, 11, 15, 16 };
  114. size_t m_bytes_left { 0 };
  115. size_t m_insert_length { 0 };
  116. size_t m_copy_length { 0 };
  117. bool m_implicit_zero_distance { false };
  118. size_t m_distance { 0 };
  119. ByteBuffer m_dictionary_data;
  120. Block m_literal_block;
  121. Vector<u8> m_literal_context_modes;
  122. Block m_insert_and_copy_block;
  123. Block m_distance_block;
  124. Vector<u8> m_context_mapping_literal;
  125. Vector<u8> m_context_mapping_distance;
  126. Vector<CanonicalCode> m_literal_codes;
  127. Vector<CanonicalCode> m_insert_and_copy_codes;
  128. Vector<CanonicalCode> m_distance_codes;
  129. };
  130. }