aboutsummaryrefslogtreecommitdiff
path: root/deps/libchdr/bitstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/libchdr/bitstream.c')
-rw-r--r--deps/libchdr/bitstream.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/deps/libchdr/bitstream.c b/deps/libchdr/bitstream.c
new file mode 100644
index 0000000..735b97f
--- /dev/null
+++ b/deps/libchdr/bitstream.c
@@ -0,0 +1,118 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ bitstream.c
+
+ Helper classes for reading/writing at the bit level.
+
+***************************************************************************/
+
+#include "bitstream.h"
+#include <stdlib.h>
+
+//**************************************************************************
+// 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;
+}
+