forked from piratfm/fmstick
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bistream.c
123 lines (106 loc) · 2.65 KB
/
bistream.c
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
117
118
119
120
121
122
123
/*
* FILE: bitstream.c
* PROGRAM: RAT
* AUTHOR: Orion Hodson
*
* Copyright (c) 1998-2001 University College London
* All rights reserved.
*/
#ifdef WIN32
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include "bitstream.h"
#define FALSE 0
#define TRUE 1
typedef int BOOL;
typedef struct s_bitstream {
uint8_t *buf; /* head of bitstream */
uint8_t *pos; /* current byte in bitstream */
unsigned int remain; /* bits remaining */
unsigned int len; /* length of bitstream in bytes */
} bs;
int bs_create(bitstream_t **ppb)
{
bs *pb;
pb = (bs*)calloc(1, sizeof(bs));
if (pb) {
*ppb = pb;
return TRUE;
}
return FALSE;
}
int bs_destroy(bitstream_t **ppb)
{
free(*ppb);
return TRUE;
}
int bs_attach(bitstream_t *b,
uint8_t *buf,
int blen)
{
b->buf = b->pos = buf;
b->remain = 8;
b->len = blen;
return TRUE;
}
int bs_put(bitstream_t *b,
uint8_t bits,
uint8_t nbits)
{
assert(nbits != 0 && nbits <= 8);
if (b->remain == 0) {
b->pos++;
b->remain = 8;
}
if (nbits > b->remain) {
unsigned int over = nbits - b->remain;
(*b->pos) |= (bits >> over);
b->pos++;
b->remain = 8 - over;
(*b->pos) = (bits << b->remain);
} else {
(*b->pos) |= bits << (b->remain - nbits);
b->remain -= nbits;
}
assert((unsigned int)(b->pos - b->buf) <= b->len);
return TRUE;
}
uint8_t bs_get(bitstream_t *b,
uint8_t nbits)
{
uint8_t out;
if (b->remain == 0) {
b->pos++;
b->remain = 8;
}
if (nbits > b->remain) {
/* Get high bits */
out = *b->pos;
out <<= (8 - b->remain);
out >>= (8 - nbits);
b->pos++;
b->remain += 8 - nbits;
out |= (*b->pos) >> b->remain;
} else {
out = *b->pos;
out <<= (8 - b->remain);
out >>= (8 - nbits);
b->remain -= nbits;
}
assert((unsigned int)(b->pos - b->buf) <= b->len);
return out;
}
int bs_bytes_used(bitstream_t *b)
{
unsigned int used = (unsigned int)(b->pos - b->buf);
if (b->remain != 8) {
used++;
}
return used;
}