I'm looking at the C# library called BitStream, which allows you to write and read any number of bits to a standard C# Stream
object. I noticed what seemed to me a strange design decision:
When adding bits to an empty byte, the bits are added to the MSB of the byte. For example:
var s = new BitStream();
s.Write(true);
Debug.Assert(s.ToByteArray()[0] == 0x80); // and not 0x01
var s = new BitStream();
s.Write(0x7,0,4);
s.Write(0x3,0,4);
Debug.Assert(s.ToByteArray()[0] == 0x73); // and not 0x37
However, when referencing bits in a number as the input, the first bit of the input number is the LSB. For example
//s.Write(int input,int bit_offset, int count_bits)
//when referencing the LSB and the next bit we'll write
s.Write(data,0,2); //and not s.Write(data,data_bits_number,data_bits_number-2)
It seems inconsistent to me. Since in this case, when "gradually" copying a byte like in the previous example (the first four bits, and then the last four bits), we will not get the original byte. We need to copy it "backwards" (first the last four bits, then the first four bits).
Is there a reason for that design that I'm missing? Any other implementation of bits stream with this behaviour? What are the design considerations for that?
It seems that ffmpeg
bitstream behaves in a way I consider consistent. Look at the amount it shifts the byte before OR
ing it with the src
pointer in the put_bits
function.
As a side note:
The first byte added, is the first byte in the byte array. For example
var s = new BitStream();
s.Write(0x1,0,4);
s.Write(0x2,0,4);
s.Write(0x3,0,4);
Debug.Assert(s.ToByteArray()[0] == 0x12); // and not s.ToByteArray()[1] == 0x12