-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitstream.h
116 lines (97 loc) · 2.35 KB
/
bitstream.h
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once
#include <stdint.h>
#include <stddef.h>
#ifndef inline
#define inline __inline
#endif
typedef struct bitstream_t {
uint8_t *data;
uint8_t pos;
} bitstream_t;
static inline void bitstream_open(bitstream_t *t, void *data)
{
t->data = data;
t->pos = 0;
}
static inline void bitstream_seek_forward(bitstream_t *t, size_t bits)
{
bits += t->pos;
t->data += bits >> 3;
t->pos = bits & 7;
}
static inline void bitstream_seek_back(bitstream_t *t, size_t bits)
{
bits -= t->pos;
uint8_t o = bits & 7;
if (o) {
t->data -= (bits >> 3) + 1;
t->pos = 8 - o;
} else {
t->data -= bits >> 3;
t->pos = 0;
}
}
static inline uint8_t bitstream_peek_1(bitstream_t *t)
{
uint8_t u = *t->data << t->pos;
return u >> 7;
}
static inline uint8_t bitstream_read_1(bitstream_t *t)
{
uint8_t u = bitstream_peek_1(t);
bitstream_seek_forward(t, 1);
return u;
}
static inline uint8_t bitstream_peek_most8(bitstream_t *t, uint8_t bits)
{
uint8_t u = 0;
uint8_t *p = t->data;
uint8_t pos = t->pos;
if (bits + pos > 8) {
u |= *p++ << pos;
u >>= 8 - bits;
bits -= 8 - pos;
pos = 0;
}
uint8_t b = *p << pos;
return u | b >> 8 - bits;
}
static inline uint8_t bitstream_read_most8(bitstream_t *t, uint8_t bits)
{
uint8_t u = bitstream_peek_most8(t, bits);
bitstream_seek_forward(t, bits);
return u;
}
uint32_t bitstream_read_most32(bitstream_t *t, uint8_t bits);
size_t bitstream_read_exp_golomb_ue_v(bitstream_t *t);
static inline int bitstream_read_exp_golomb_se_v(bitstream_t *t)
{
size_t u = bitstream_read_exp_golomb_ue_v(t);
if (u & 1) return u + 1 >> 1;
else return -(int)(u >> 1);
}
static inline void bitstream_set1(bitstream_t *t)
{
*t->data |= 1 << (7 - t->pos);
}
static inline void bitstream_write1(bitstream_t *t)
{
bitstream_set1(t);
bitstream_seek_forward(t, 1);
}
static inline void bitstream_clear1(bitstream_t *t)
{
*t->data &= ~(1 << (7 - t->pos));
}
static inline void bitstream_write0(bitstream_t *t)
{
bitstream_clear1(t);
bitstream_seek_forward(t, 1);
}
void bitstream_copy(bitstream_t *t, bitstream_t *src, size_t bits);
static inline void bitstream_write(bitstream_t *t, void *data, size_t bits)
{
bitstream_t w;
bitstream_open(&w, data);
bitstream_copy(t, &w, bits);
}