private int read(int bitsCount)
{
//Codes are packed into a continuous bit stream, high-order bit first.
//This stream is then divided into 8-bit bytes, high-order bit first.
//Thus, codes can straddle byte boundaries arbitrarily. After the EOD marker (code value 257),
//any leftover bits in the final byte are set to 0.
if (bitsCount < 0 || bitsCount > 32)
throw new ArgumentOutOfRangeException("bitsCount");
if (bitsCount == 0)
return 0;
int bitsRead = 0;
int result = 0;
byte[] bt = new byte[1];
while (bitsRead == 0 || (bitsRead - m_positionInByte < bitsCount))
{
m_stream.Read(bt, 0, 1);
result = (result << bitsInByte);
result += bt[0];
bitsRead += 8;
}
m_positionInByte = (m_positionInByte + bitsCount) % 8;
if (m_positionInByte != 0)
{
result = (result >> (bitsInByte - m_positionInByte));
m_stream.Seek(-1, SeekOrigin.Current);
}
if (bitsCount < 32)
{
int mask = ((1 << bitsCount) - 1);
result = result & mask;
}
return result;
}