From 81eab984fbbe1b8d927f6708a4002c7c8002fc94 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 21 Sep 2023 22:20:57 -0400 Subject: [PATCH] Add endian reads for bits --- BitStream.cs | 71 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/BitStream.cs b/BitStream.cs index 0a47fc1..4da6621 100644 --- a/BitStream.cs +++ b/BitStream.cs @@ -47,36 +47,16 @@ namespace SabreTools.Compression } /// - /// Read a single bit, if possible + /// Read a single bit with MSB as the leftmost bit, if possible /// /// The next bit encoded in a byte, null on error or end of stream - public byte? ReadBit() - { - // If we reached the end of the stream - if (_source.Position >= _source.Length) - return null; + public byte? ReadBitMSB() => ReadBitInternal(true); - // If we don't have a value cached - if (_lastRead == null) - { - // Read the next byte, if possible - _lastRead = ReadSourceByte(); - if (_lastRead == null) - return null; - - // Reset the bit index - _bitIndex = 0; - } - - // Get the value by bit-shifting - int value = (_lastRead.Value >> _bitIndex++) & 0x01; - - // Reset the byte if we're at the end - if (_bitIndex >= 8) - Discard(); - - return (byte)value; - } + /// + /// Read a single bit with LSB as the leftmost bit, if possible + /// + /// The next bit encoded in a byte, null on error or end of stream + public byte? ReadBitLSB() => ReadBitInternal(false); /// /// Read a full byte, if possible @@ -170,6 +150,43 @@ namespace SabreTools.Compression throw new NotImplementedException(); } + /// + /// Read a single bit, if possible + /// + /// True if the value should be read MSB, false for LSB + /// The next bit encoded in a byte, null on error or end of stream + private byte? ReadBitInternal(bool msb) + { + // If we reached the end of the stream + if (_source.Position >= _source.Length) + return null; + + // If we don't have a value cached + if (_lastRead == null) + { + // Read the next byte, if possible + _lastRead = ReadSourceByte(); + if (_lastRead == null) + return null; + + // Reset the bit index + _bitIndex = 0; + } + + // Get the value by bit-shifting + int value; + if (msb) + value = (_lastRead.Value >> _bitIndex++) & 0x01; + else + value = (_lastRead.Value >> (7 - _bitIndex++)) & 0x01; + + // Reset the byte if we're at the end + if (_bitIndex >= 8) + Discard(); + + return (byte)value; + } + /// /// Read a single byte from the underlying stream, if possible ///