From 9d4c50ca6065df7e5ffe00de98333f83c7e05687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Thu, 24 Jun 2021 23:52:13 +0200 Subject: [PATCH] AK: Add big endian bit reading to InputBitStream The existing InputBitStream methods only read in little endian, as this is what the rest of the system requires. Two new methods allow the input bitstream to read bits in big endian as well, while using the existing state infrastructure. Note that it can lead to issues if little endian and big endian reads are used out of order without aligning to a byte boundary first. --- AK/BitStream.h | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/AK/BitStream.h b/AK/BitStream.h index d09e47e9a8..7bdd646918 100644 --- a/AK/BitStream.h +++ b/AK/BitStream.h @@ -61,9 +61,9 @@ public: return m_stream.discard_or_error(count); } - u32 read_bits(size_t count) + u64 read_bits(size_t count) { - u32 result = 0; + u64 result = 0; size_t nread = 0; while (nread < count) { @@ -88,8 +88,46 @@ public: return result; } + u64 read_bits_big_endian(size_t count) + { + u64 result = 0; + + size_t nread = 0; + while (nread < count) { + if (m_stream.has_any_error()) { + set_fatal_error(); + return 0; + } + + if (m_next_byte.has_value()) { + // read an entire byte + if (((count - nread) >= 8) && m_bit_offset == 0) { + // shift existing bytes over + result <<= 8; + result |= m_next_byte.value(); + nread += 8; + m_next_byte.clear(); + } else { + const auto bit = (m_next_byte.value() >> (7 - m_bit_offset)) & 1; + result <<= 1; + result |= bit; + ++nread; + if (m_bit_offset++ == 7) + m_next_byte.clear(); + } + } else { + m_stream >> m_next_byte; + m_bit_offset = 0; + } + } + + return result; + } + bool read_bit() { return static_cast(read_bits(1)); } + bool read_bit_big_endian() { return static_cast(read_bits_big_endian(1)); } + void align_to_byte_boundary() { if (m_next_byte.has_value())