libchdr_bitstream.c (3209B)
1 /* license:BSD-3-Clause 2 * copyright-holders:Aaron Giles 3 *************************************************************************** 4 5 bitstream.c 6 7 Helper classes for reading/writing at the bit level. 8 9 ***************************************************************************/ 10 11 #include <stdlib.h> 12 #include <libchdr/bitstream.h> 13 14 /*************************************************************************** 15 * INLINE FUNCTIONS 16 *************************************************************************** 17 */ 18 19 int bitstream_overflow(struct bitstream* bitstream) { return ((bitstream->doffset - bitstream->bits / 8) > bitstream->dlength); } 20 21 /*------------------------------------------------- 22 * create_bitstream - constructor 23 *------------------------------------------------- 24 */ 25 26 struct bitstream* create_bitstream(const void *src, uint32_t srclength) 27 { 28 struct bitstream* bitstream = (struct bitstream*)malloc(sizeof(struct bitstream)); 29 bitstream->buffer = 0; 30 bitstream->bits = 0; 31 bitstream->read = (const uint8_t*)src; 32 bitstream->doffset = 0; 33 bitstream->dlength = srclength; 34 return bitstream; 35 } 36 37 38 /*----------------------------------------------------- 39 * bitstream_peek - fetch the requested number of bits 40 * but don't advance the input pointer 41 *----------------------------------------------------- 42 */ 43 44 uint32_t bitstream_peek(struct bitstream* bitstream, int numbits) 45 { 46 if (numbits == 0) 47 return 0; 48 49 /* fetch data if we need more */ 50 if (numbits > bitstream->bits) 51 { 52 while (bitstream->bits <= 24) 53 { 54 if (bitstream->doffset < bitstream->dlength) 55 bitstream->buffer |= bitstream->read[bitstream->doffset] << (24 - bitstream->bits); 56 bitstream->doffset++; 57 bitstream->bits += 8; 58 } 59 } 60 61 /* return the data */ 62 return bitstream->buffer >> (32 - numbits); 63 } 64 65 66 /*----------------------------------------------------- 67 * bitstream_remove - advance the input pointer by the 68 * specified number of bits 69 *----------------------------------------------------- 70 */ 71 72 void bitstream_remove(struct bitstream* bitstream, int numbits) 73 { 74 bitstream->buffer <<= numbits; 75 bitstream->bits -= numbits; 76 } 77 78 79 /*----------------------------------------------------- 80 * bitstream_read - fetch the requested number of bits 81 *----------------------------------------------------- 82 */ 83 84 uint32_t bitstream_read(struct bitstream* bitstream, int numbits) 85 { 86 uint32_t result = bitstream_peek(bitstream, numbits); 87 bitstream_remove(bitstream, numbits); 88 return result; 89 } 90 91 92 /*------------------------------------------------- 93 * read_offset - return the current read offset 94 *------------------------------------------------- 95 */ 96 97 uint32_t bitstream_read_offset(struct bitstream* bitstream) 98 { 99 uint32_t result = bitstream->doffset; 100 int bits = bitstream->bits; 101 while (bits >= 8) 102 { 103 result--; 104 bits -= 8; 105 } 106 return result; 107 } 108 109 110 /*------------------------------------------------- 111 * flush - flush to the nearest byte 112 *------------------------------------------------- 113 */ 114 115 uint32_t bitstream_flush(struct bitstream* bitstream) 116 { 117 while (bitstream->bits >= 8) 118 { 119 bitstream->doffset--; 120 bitstream->bits -= 8; 121 } 122 bitstream->bits = bitstream->buffer = 0; 123 return bitstream->doffset; 124 } 125