/
BITS.CPP
219 lines (193 loc) · 4.11 KB
/
BITS.CPP
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/* bits.c, bit-level input */
#include "bits.h"
#define BUFFER_SIZE 1024*1024
/* private data */
static unsigned char bfr[BUFFER_SIZE];
static int byteidx;
static int bitidx;
static size_t bufcount;
static double totbits;
FILE *bitfile;
bool eobs;
void strlwr (char *s)
{
char *c=s;
for (;(*c=tolower(*c));c++) ;
}
/* return total number of generated bits */
double bitcount()
{
return totbits;
}
static bool refill_buffer()
{
size_t i;
i = fread(bfr, sizeof(unsigned char), BUFFER_SIZE, bitfile);
if (i <= 0)
{
eobs = true;
return false;
}
bufcount = i;
return true;
}
/* open the device to read the bit stream from it */
void init_getbits(char *bs_filename)
{
if ((bitfile = fopen(bs_filename, "rb")) == NULL)
{
printf("Unable to open file %s for reading.\n", bs_filename);
exit(1);
}
byteidx = 0;
bitidx = 8;
totbits = 0.0;
bufcount = 0;
eobs = false;
if (!refill_buffer())
{
if (eobs)
{
printf("Unable to read from file %s.\n", bs_filename);
exit(1);
}
}
}
/*close the device containing the bit stream after a read process*/
void finish_getbits()
{
if (bitfile)
fclose(bitfile);
bitfile = NULL;
}
int masks[8]={0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
/*read 1 bit from the bit stream */
unsigned int get1bit()
{
unsigned int bit;
if (eobs)
return 0;
bit = (bfr[byteidx] & masks[bitidx - 1]) >> (bitidx - 1);
totbits++;
bitidx--;
if (!bitidx)
{
bitidx = 8;
byteidx++;
if (byteidx == bufcount)
{
if (bufcount == BUFFER_SIZE)
refill_buffer();
else
eobs = true;
byteidx = 0;
}
}
return bit;
}
/*read N bit from the bit stream */
unsigned int getbits(int N)
{
unsigned int val = 0;
int i = N;
unsigned int j;
// Optimize: we are on byte boundary and want to read multiple of bytes!
if ((bitidx == 8) && ((N & 7) == 0))
{
i = N >> 3;
while (i > 0)
{
val = (val << 8) | bfr[byteidx];
byteidx++;
totbits += 8;
if (byteidx == bufcount)
{
if (bufcount == BUFFER_SIZE)
refill_buffer();
else
eobs = true;
byteidx = 0;
}
i--;
}
return val;
}
while (i > 0)
{
j = get1bit();
val = (val << 1) | j;
i--;
}
return val;
}
/*return the status of the bit stream*/
/* returns 1 if end of bit stream was reached */
/* returns 0 if end of bit stream was not reached */
int end_bs()
{
return eobs;
}
/*this function seeks for a byte aligned sync word (max 32 bits) in the bit stream and
places the bit stream pointer right after the sync.
This function returns 1 if the sync was found otherwise it returns 0 */
int seek_sync(unsigned int sync, int N)
{
unsigned int val;
unsigned int maxi = (int)pow(2.0, (double)N) - 1;
while (bitidx != 8)
get1bit();
val = getbits(N);
while ((val & maxi) != sync)
{
if (eobs)
return 0;
val <<= 8;
val |= getbits(8);
}
return 1;
}
/*look ahead for the next N bits from the bit stream */
unsigned long look_ahead(int N)
{
unsigned long val = 0;
unsigned char *tmp_bfr = bfr;
unsigned char tmp_bfr1[4];
int j = N;
int eo_bs = eobs;
size_t buf_count = bufcount;
int bit_idx = bitidx;
int byte_idx = byteidx;
while (j > 0)
{
if (eo_bs)
return 0;
val <<= 1;
val |= (tmp_bfr[byte_idx] & masks[bit_idx - 1]) >> (bit_idx - 1);
bit_idx--;
j--;
if (!bit_idx)
{
bit_idx = 8;
byte_idx++;
if (byte_idx == buf_count)
{
if (buf_count == BUFFER_SIZE)
{
if (fread(tmp_bfr1, sizeof(unsigned char), 4, bitfile) != 4)
eo_bs = true;
else
tmp_bfr = &tmp_bfr1[0];
if (fseek(bitfile, -4, SEEK_CUR))
{
printf("Unable to set file position.\n");
exit(1);
}
}
else
eo_bs = true;
byte_idx = 0;
}
}
}
return val;
}