VideoCodec/Encoder/BinaryStreamBuilder.cpp

#include "BinaryStreamBuilder.h" namespace VideoCodec {    BinaryStreamBuilder::BinaryStreamBuilder()    {       this->isInitialized = false;    }        BinaryStreamBuilder::~BinaryStreamBuilder()    {    }        void BinaryStreamBuilder::AllocateStream(FrameDataBitLength streamSizeBits)    {       if (this->isInitialized)       {          Logger::LogMessage("Warning: The binary stream builder has already been initialized.");          delete this->data;       }              // There are eight bits for each unsigned char in the underlying array.       this->data = new unsigned char[streamSizeBits % 8 != 0 ? (streamSizeBits >> 3) + 1 : streamSizeBits >> 3];       this->dataIndex = 0;       this->workingPosition = 0;       this->workingValue = 0;              this->writtenBitCount = 0;       this->streamCapacity = streamSizeBits;              this->isInitialized = true;    }        void BinaryStreamBuilder::PutValue(unsigned short int value, unsigned char bitCount)    {       if (!this->isInitialized)       {          Logger::LogMessage("Warning: Binary stream was not initialized.");          return;       }              // If bitCount exceeds the size of the data type for the value being put into the stream,       // we put zeros in for the first bits which overhang the edge of the value.       if (bitCount > 16)          this->PutValue(0x0000, bitCount - 16);              // Move the MSB so that it is at the highest position.       // The value is then copied in by shifting the input value and the working value to the left       // and copying bits.       value <<= (16 - bitCount);              // Write bits into the working value until we run out of bits or the working value has no more bits left.       while (bitCount != 0)       {          this->workingValue |= ((value & 0x8000) >> 15);          if (this->workingPosition == 7)          {             // Flush the working value into the data array and move onto the next one.             this->data[this->dataIndex] = this->workingValue;             this->dataIndex++;             this->workingValue = 0;             this->workingPosition = 0;          }          else          {             this->workingValue <<= 1;             this->workingPosition++;          }          value <<= 1;          bitCount--;          this->writtenBitCount++;       }    }        void BinaryStreamBuilder::AlignStream()    {       // If some bits are outstanding in the working data, write them and advance the current index.       if (this->workingPosition != 0)       {          this->workingValue <<= 7 - this->workingPosition;          this->data[this->dataIndex] = this->workingValue;          this->workingValue = 0x00;          this->writtenBitCount += 8 - this->workingPosition;          this->workingPosition = 0;          this->dataIndex++;       }    }        unsigned char* BinaryStreamBuilder::GetStream()    {       if (!this->workingPosition == 0)       {          Logger::LogMessage("Warning: AlignStream() was not called before retrieving the underlying binary data. Unalign bits may have been lost.");       }              return this->data;    }        long int BinaryStreamBuilder::GetWrittenBitCount()    {       return this->writtenBitCount;    }        long int BinaryStreamBuilder::GetStreamCapacity()    {       return this->streamCapacity;    } }