Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/genplus-gx/core/tremor/bitwise.c
2 views
1
/********************************************************************
2
* *
3
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
4
* *
5
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8
* *
9
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
11
* *
12
********************************************************************
13
14
function: packing variable sized words into an octet stream
15
16
********************************************************************/
17
18
/* We're 'LSb' endian; if we write a word but read individual bits,
19
then we'll read the lsb first */
20
21
#include <string.h>
22
#include <stdlib.h>
23
#include "ogg.h"
24
25
static unsigned long mask[]=
26
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
27
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
28
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
29
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
30
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
31
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
32
0x3fffffff,0x7fffffff,0xffffffff };
33
34
/* mark read process as having run off the end */
35
static void _adv_halt(oggpack_buffer *b){
36
b->headptr=b->head->buffer->data+b->head->begin+b->head->length;
37
b->headend=-1;
38
b->headbit=0;
39
}
40
41
/* spans forward, skipping as many bytes as headend is negative; if
42
headend is zero, simply finds next byte. If we're up to the end
43
of the buffer, leaves headend at zero. If we've read past the end,
44
halt the decode process. */
45
static void _span(oggpack_buffer *b){
46
while(b->headend<1){
47
if(b->head->next){
48
b->count+=b->head->length;
49
b->head=b->head->next;
50
b->headptr=b->head->buffer->data+b->head->begin-b->headend;
51
b->headend+=b->head->length;
52
}else{
53
/* we've either met the end of decode, or gone past it. halt
54
only if we're past */
55
if(b->headend<0 || b->headbit)
56
/* read has fallen off the end */
57
_adv_halt(b);
58
59
break;
60
}
61
}
62
}
63
64
void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
65
memset(b,0,sizeof(*b));
66
67
b->tail=b->head=r;
68
b->count=0;
69
b->headptr=b->head->buffer->data+b->head->begin;
70
b->headend=b->head->length;
71
_span(b);
72
}
73
74
#define _lookspan() while(!end){\
75
head=head->next;\
76
if(!head) return -1;\
77
ptr=head->buffer->data + head->begin;\
78
end=head->length;\
79
}
80
81
/* Read in bits without advancing the bitptr; bits <= 32 */
82
long oggpack_look(oggpack_buffer *b,int bits){
83
unsigned long m=mask[bits];
84
unsigned long ret=-1;
85
86
bits+=b->headbit;
87
88
if(bits >= b->headend<<3){
89
int end=b->headend;
90
unsigned char *ptr=b->headptr;
91
ogg_reference *head=b->head;
92
93
if(end<0)return -1;
94
95
if(bits){
96
_lookspan();
97
ret=*ptr++>>b->headbit;
98
if(bits>8){
99
--end;
100
_lookspan();
101
ret|=*ptr++<<(8-b->headbit);
102
if(bits>16){
103
--end;
104
_lookspan();
105
ret|=*ptr++<<(16-b->headbit);
106
if(bits>24){
107
--end;
108
_lookspan();
109
ret|=*ptr++<<(24-b->headbit);
110
if(bits>32 && b->headbit){
111
--end;
112
_lookspan();
113
ret|=*ptr<<(32-b->headbit);
114
}
115
}
116
}
117
}
118
}
119
120
}else{
121
122
/* make this a switch jump-table */
123
ret=b->headptr[0]>>b->headbit;
124
if(bits>8){
125
ret|=b->headptr[1]<<(8-b->headbit);
126
if(bits>16){
127
ret|=b->headptr[2]<<(16-b->headbit);
128
if(bits>24){
129
ret|=b->headptr[3]<<(24-b->headbit);
130
if(bits>32 && b->headbit)
131
ret|=b->headptr[4]<<(32-b->headbit);
132
}
133
}
134
}
135
}
136
137
ret&=m;
138
return ret;
139
}
140
141
/* limited to 32 at a time */
142
void oggpack_adv(oggpack_buffer *b,int bits){
143
bits+=b->headbit;
144
b->headbit=bits&7;
145
b->headptr+=bits/8;
146
if((b->headend-=bits/8)<1)_span(b);
147
}
148
149
/* spans forward and finds next byte. Never halts */
150
static void _span_one(oggpack_buffer *b){
151
while(b->headend<1){
152
if(b->head->next){
153
b->count+=b->head->length;
154
b->head=b->head->next;
155
b->headptr=b->head->buffer->data+b->head->begin;
156
b->headend=b->head->length;
157
}else
158
break;
159
}
160
}
161
162
static int _halt_one(oggpack_buffer *b){
163
if(b->headend<1){
164
_adv_halt(b);
165
return -1;
166
}
167
return 0;
168
}
169
170
int oggpack_eop(oggpack_buffer *b){
171
if(b->headend<0)return -1;
172
return 0;
173
}
174
175
/* bits <= 32 */
176
long oggpack_read(oggpack_buffer *b,int bits){
177
unsigned long m=mask[bits];
178
ogg_uint32_t ret=-1;
179
180
bits+=b->headbit;
181
182
if(bits >= b->headend<<3){
183
184
if(b->headend<0)return -1;
185
186
if(bits){
187
if (_halt_one(b)) return -1;
188
ret=*b->headptr>>b->headbit;
189
190
if(bits>=8){
191
++b->headptr;
192
--b->headend;
193
_span_one(b);
194
if(bits>8){
195
if (_halt_one(b)) return -1;
196
ret|=*b->headptr<<(8-b->headbit);
197
198
if(bits>=16){
199
++b->headptr;
200
--b->headend;
201
_span_one(b);
202
if(bits>16){
203
if (_halt_one(b)) return -1;
204
ret|=*b->headptr<<(16-b->headbit);
205
206
if(bits>=24){
207
++b->headptr;
208
--b->headend;
209
_span_one(b);
210
if(bits>24){
211
if (_halt_one(b)) return -1;
212
ret|=*b->headptr<<(24-b->headbit);
213
214
if(bits>=32){
215
++b->headptr;
216
--b->headend;
217
_span_one(b);
218
if(bits>32){
219
if (_halt_one(b)) return -1;
220
if(b->headbit)ret|=*b->headptr<<(32-b->headbit);
221
222
}
223
}
224
}
225
}
226
}
227
}
228
}
229
}
230
}
231
}else{
232
233
ret=b->headptr[0]>>b->headbit;
234
if(bits>8){
235
ret|=b->headptr[1]<<(8-b->headbit);
236
if(bits>16){
237
ret|=b->headptr[2]<<(16-b->headbit);
238
if(bits>24){
239
ret|=b->headptr[3]<<(24-b->headbit);
240
if(bits>32 && b->headbit){
241
ret|=b->headptr[4]<<(32-b->headbit);
242
}
243
}
244
}
245
}
246
247
b->headptr+=bits/8;
248
b->headend-=bits/8;
249
}
250
251
ret&=m;
252
b->headbit=bits&7;
253
return ret;
254
}
255
256
long oggpack_bytes(oggpack_buffer *b){
257
return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
258
(b->headbit+7)/8);
259
}
260
261
long oggpack_bits(oggpack_buffer *b){
262
return((b->count+b->headptr-b->head->buffer->data-b->head->begin)*8+
263
b->headbit);
264
}
265
266
267