diff --git a/czi-format/czi-parser/stream/memory_bit_stream.cpp b/czi-format/czi-parser/stream/memory_bit_stream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2d867cddac7e236301530cb4759978064f65292 --- /dev/null +++ b/czi-format/czi-parser/stream/memory_bit_stream.cpp @@ -0,0 +1,111 @@ +#include "memory_bit_stream.h" + +/****************************************************************************************************************************** + * OutMemoryBitStream implementation + ****************************************************************************************************************************/ +OutMemoryBitStream::OutMemoryBitStream() +{ + bitBuffer = 0; + bitBufferSize = 0; +} + +OutMemoryBitStream::~OutMemoryBitStream() +{ + flush_bit_buffer(); + bitBuffer = 0; + bitBufferSize = 0; +} + +void OutMemoryBitStream::operator<<(const bool &bit) +{ + write_bit(bit); +} +void OutMemoryBitStream::write_bit(const bool &bit) +{ + ++bitBufferSize; + if (bit) + { + bitBuffer |= (1 << (8 - bitBufferSize)); + } + + if (bitBufferSize == 8) + { + flush_bit_buffer(); + } +} + +void OutMemoryBitStream::flush_bit_buffer() +{ + if (bitBufferSize > 0) + { + buffer.push_back(bitBuffer); + bitBuffer = 0; + bitBufferSize = 0; + } +} + +ByteArray OutMemoryBitStream::get_buffer() const +{ + return buffer; +} + +ByteArray OutMemoryBitStream::get_flushed_buffer() +{ + flush_bit_buffer(); + return buffer; +} + +/****************************************************************************************************************************** + * InMemoryBitStream implementation + ****************************************************************************************************************************/ + +InMemoryBitStream::InMemoryBitStream(const ByteArray *buffer, size_t bufferPosition) +{ + memoryBuffer = buffer; + memoryBufferPosition = bufferPosition; + bitBufferSize = 0; + bitBuffer = 0; +} + +InMemoryBitStream::~InMemoryBitStream() +{ + memoryBuffer = nullptr; + memoryBufferPosition = 0; + bitBufferSize = 0; + bitBuffer = 0; +} + +void InMemoryBitStream::read_byte_to_bit_buffer() +{ + if (memoryBufferPosition < memoryBuffer->size()) + { + bitBuffer = (*memoryBuffer)[memoryBufferPosition++]; + bitBufferSize = 8; + } + else + { + assert(false && "Out ouf memory buffer"); + } +} + +bool InMemoryBitStream::read_bit() +{ + if (bitBufferSize == 0) + { + read_byte_to_bit_buffer(); + } + + --bitBufferSize; + bool result = bitBuffer & (1 << bitBufferSize); + return result; +} + +void InMemoryBitStream::operator>>(bool &bit) +{ + bit = read_bit(); +} + +bool InMemoryBitStream::can_read() const +{ + return ((bitBufferSize > 0) || (memoryBufferPosition < memoryBuffer->size())); +} \ No newline at end of file diff --git a/czi-format/czi-parser/stream/memory_bit_stream.h b/czi-format/czi-parser/stream/memory_bit_stream.h new file mode 100644 index 0000000000000000000000000000000000000000..8b78d0aa3782d658f3a381821984e739cdae0172 --- /dev/null +++ b/czi-format/czi-parser/stream/memory_bit_stream.h @@ -0,0 +1,60 @@ +#pragma once +#include "../custom_types.h" + +// Class allowing to write invidual bits to memory buffer. +class OutMemoryBitStream +{ + private: + // Memory buffer. + ByteArray buffer; + // Bit buffer. + byte bitBuffer; + // Actual size of bit buffer. + byte bitBufferSize = 0; + + public: + OutMemoryBitStream(); + ~OutMemoryBitStream(); + + // Write bit to memory stream. + void write_bit(const bool &bit); + // Write bit to memory stream. + void operator<<(const bool &bit); + + // If flush buffer is not flushed, flush it to main buffer and clear it. + void flush_bit_buffer(); + // Get buffer of written bits, which may not be flushed. + ByteArray get_buffer() const; + // Get buffer of written bits, which is flushed. + ByteArray get_flushed_buffer(); +}; + +// Class alowing to read invidual bits from memory buffer. +class InMemoryBitStream +{ + private: + // Memory buffer. + const ByteArray *memoryBuffer = nullptr; + // Position in memory buffer. + size_t memoryBufferPosition = 0; + // Bit buffer. + byte bitBuffer = 0; + // Current bit buffer size. + byte bitBufferSize = 0; + + // Read byte into bit buffer. + void read_byte_to_bit_buffer(); + + public: + InMemoryBitStream(const ByteArray *buffer, size_t bufferPosition = 0); + ~InMemoryBitStream(); + + // Read one bit from memory buffer. + bool read_bit(); + // Read one bit from memory buffer. + void operator>>(bool &bit); + // Check wheter atleast one bit can be read. + bool can_read() const; +}; + +#include "memory_bit_stream.cpp" \ No newline at end of file