/* license:BSD-3-Clause * copyright-holders:Aaron Giles *************************************************************************** bitstream.c Helper classes for reading/writing at the bit level. ***************************************************************************/ #include "bitstream.h" #include /*************************************************************************** * INLINE FUNCTIONS *************************************************************************** */ int bitstream_overflow(struct bitstream* bitstream) { return ((bitstream->doffset - bitstream->bits / 8) > bitstream->dlength); } /*------------------------------------------------- * create_bitstream - constructor *------------------------------------------------- */ struct bitstream* create_bitstream(const void *src, uint32_t srclength) { struct bitstream* bitstream = (struct bitstream*)malloc(sizeof(struct bitstream)); bitstream->buffer = 0; bitstream->bits = 0; bitstream->read = (const uint8_t*)src; bitstream->doffset = 0; bitstream->dlength = srclength; return bitstream; } /*----------------------------------------------------- * bitstream_peek - fetch the requested number of bits * but don't advance the input pointer *----------------------------------------------------- */ uint32_t bitstream_peek(struct bitstream* bitstream, int numbits) { if (numbits == 0) return 0; /* fetch data if we need more */ if (numbits > bitstream->bits) { while (bitstream->bits <= 24) { if (bitstream->doffset < bitstream->dlength) bitstream->buffer |= bitstream->read[bitstream->doffset] << (24 - bitstream->bits); bitstream->doffset++; bitstream->bits += 8; } } /* return the data */ return bitstream->buffer >> (32 - numbits); } /*----------------------------------------------------- * bitstream_remove - advance the input pointer by the * specified number of bits *----------------------------------------------------- */ void bitstream_remove(struct bitstream* bitstream, int numbits) { bitstream->buffer <<= numbits; bitstream->bits -= numbits; } /*----------------------------------------------------- * bitstream_read - fetch the requested number of bits *----------------------------------------------------- */ uint32_t bitstream_read(struct bitstream* bitstream, int numbits) { uint32_t result = bitstream_peek(bitstream, numbits); bitstream_remove(bitstream, numbits); return result; } /*------------------------------------------------- * read_offset - return the current read offset *------------------------------------------------- */ uint32_t bitstream_read_offset(struct bitstream* bitstream) { uint32_t result = bitstream->doffset; int bits = bitstream->bits; while (bits >= 8) { result--; bits -= 8; } return result; } /*------------------------------------------------- * flush - flush to the nearest byte *------------------------------------------------- */ uint32_t bitstream_flush(struct bitstream* bitstream) { while (bitstream->bits >= 8) { bitstream->doffset--; bitstream->bits -= 8; } bitstream->bits = bitstream->buffer = 0; return bitstream->doffset; }