blob: b34a890531f14a3d414633c9e8facb5a43933fef (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
#include "bitstream.h"
#include "assert.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
void Bitstream_init(Bitstream *bitstream, const uint8_t *data,
size_t data_size) {
ASSERT(bitstream != NULL);
ASSERT(data != NULL);
bitstream->data = data;
bitstream->data_size = data_size;
bitstream->current_byte_index = 0;
bitstream->current_bit_offset = 0;
}
void bitstream_advance(Bitstream *bitstream, size_t bit_count) {
ASSERT(bitstream != NULL);
uint8_t current_bit = bitstream->current_bit_offset;
bitstream->current_byte_index =
bitstream->current_byte_index + (current_bit + bit_count) / 8;
bitstream->current_bit_offset = (current_bit + bit_count) % 8;
}
void Bitstream_skip(Bitstream *bitstream, size_t bit_count) {
ASSERT(bitstream != NULL);
bitstream_advance(bitstream, bit_count);
}
uint16_t Bitstream_next_bits(Bitstream *bitstream, int bit_count) {
ASSERT(bitstream != NULL);
ASSERT(bit_count <= 16);
ASSERT(bitstream->current_byte_index +
(bitstream->current_bit_offset + bit_count) % 8 <=
bitstream->data_size);
int bit_to_read = bit_count;
uint16_t val = bitstream->data[bitstream->current_byte_index] >>
bitstream->current_bit_offset;
size_t bit_read = MIN(bit_count, 8 - bitstream->current_bit_offset);
bitstream_advance(bitstream, bit_read);
bit_to_read -= bit_read;
while (bit_to_read > 0) {
val |= (bitstream->data[bitstream->current_byte_index] >>
bitstream->current_bit_offset)
<< bit_read;
bit_read = MIN(bit_to_read, 8 - bitstream->current_bit_offset);
bitstream_advance(bitstream, bit_read);
bit_to_read -= bit_read;
}
return (val & ((1 << bit_count) - 1));
}
|