VideoCodec/Decoder/BinaryStreamReader.cpp
#include "BinaryStreamReader.h"
namespace VideoCodec
{
BinaryStreamReader::BinaryStreamReader(StreamInputModule* inputStream)
{
this->inputStream = inputStream;
this->readBufferPosition = STREAM_READ_BUFFER_SIZE * 16;
this->readBuffer = new unsigned short int[STREAM_READ_BUFFER_SIZE];
this->bufferStart = this->readBuffer;
}
BinaryStreamReader::~BinaryStreamReader()
{
delete[] this->bufferStart;
}
// If the next bits in the stream are identical to the specified pattern, the stream is advanced
// and true is returned. Otherwise, false is returned.
bool BinaryStreamReader::MatchBits(unsigned char bitCount, unsigned short int pattern)
{
unsigned short int streamValue = this->GetBits(bitCount);
// If the value from the stream and the bit pattern are identical then their exclusive OR will be zero.
if ((streamValue ^ pattern) == 0x0000)
{
this->AdvanceReader(bitCount);
return true;
}
else
return false;
}
unsigned short int BinaryStreamReader::GetBits(unsigned char bitCount)
{
if (bitCount == 0)
return 0x0000;
// If the user is trying to read over the end of the buffer, read more data in.
if ((STREAM_READ_BUFFER_SIZE * 16) - this->readBufferPosition < 32)
{
// Read a new load of bits into the buffer.
// Because the maximum read size is the size of an unsigned short int,
// the final element of the buffer is moved to the start and the rest of the buffer
// is read from the file.
this->readBuffer[0] = this->readBuffer[STREAM_READ_BUFFER_SIZE - 2];
this->readBuffer[1] = this->readBuffer[STREAM_READ_BUFFER_SIZE - 1];
this->inputStream->Read(this->readBuffer + 2, sizeof(unsigned short int), STREAM_READ_BUFFER_SIZE - 2);
this->readBufferPosition = 32 - ((STREAM_READ_BUFFER_SIZE * 16) - this->readBufferPosition);
}
// Get the two unsigned short ints which are the current and next elements.
unsigned short int first = this->readBuffer[this->readBufferPosition >> 4];
unsigned short int second = this->readBuffer[(this->readBufferPosition >> 4) + 1];
// Take the lowest four bits of the buffer position to get the offset in 'first'.
unsigned short int offset = (this->readBufferPosition & 0x000F);
// Remove the non-required bits of 'first'.
first <<= offset;
// Remove the non-required bits of 'second'.
second >>= 32 - bitCount - offset;
// Now second contains the correct lower order bits. Or in the bits from first.
return (second | (first >> (16 - bitCount)));
}
void BinaryStreamReader::AdvanceReader(unsigned char bitCount)
{
this->readBufferPosition += bitCount;
if (this->readBufferPosition > (STREAM_READ_BUFFER_SIZE * 16))
{
// The position has gone over the end of the buffer.
this->readBufferPosition -= (STREAM_READ_BUFFER_SIZE * 16);
this->inputStream->Read(this->readBuffer, sizeof(unsigned short int), STREAM_READ_BUFFER_SIZE);
}
}
void BinaryStreamReader::AlignReader()
{
// Move the reader on to the next byte if it is not at the start of a byte already.
if ((this->readBufferPosition & 0x0007) != 0)
this->AdvanceReader(8 - (this->readBufferPosition & 0x0007));
}
}