1
/********************************************************************
3
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
9
* by the Xiph.Org Foundation http://www.xiph.org/ *
11
********************************************************************
13
function: packing variable sized words into an octet stream
14
last mod: $Id: bitwise.c,v 1.2 2005/04/24 08:36:23 henry Exp $
16
********************************************************************/
18
/* We're 'LSb' endian; if we write a word but read individual bits,
19
then we'll read the lsb first */
25
#define BUFFER_INCREMENT 256
27
static const unsigned long mask[]=
28
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
29
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
30
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
31
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
32
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
33
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
34
0x3fffffff,0x7fffffff,0xffffffff };
36
static const unsigned int mask8B[]=
37
{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
39
void oggpack_writeinit(oggpack_buffer *b){
40
memset(b,0,sizeof(*b));
41
b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT);
43
b->storage=BUFFER_INCREMENT;
46
void oggpackB_writeinit(oggpack_buffer *b){
50
void oggpack_writetrunc(oggpack_buffer *b,long bits){
53
b->ptr=b->buffer+bytes;
59
void oggpackB_writetrunc(oggpack_buffer *b,long bits){
62
b->ptr=b->buffer+bytes;
65
*b->ptr&=mask8B[bits];
68
/* Takes only up to 32 bits. */
69
void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
70
if(b->endbyte+4>=b->storage){
71
b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
72
b->storage+=BUFFER_INCREMENT;
73
b->ptr=b->buffer+b->endbyte;
79
b->ptr[0]|=value<<b->endbit;
82
b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
84
b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
86
b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
89
b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
102
/* Takes only up to 32 bits. */
103
void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
104
if(b->endbyte+4>=b->storage){
105
b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
106
b->storage+=BUFFER_INCREMENT;
107
b->ptr=b->buffer+b->endbyte;
110
value=(value&mask[bits])<<(32-bits);
113
b->ptr[0]|=value>>(24+b->endbit);
116
b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
118
b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
120
b->ptr[3]=(unsigned char)(value>>(b->endbit));
123
b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
136
void oggpack_writealign(oggpack_buffer *b){
137
int bits=8-b->endbit;
139
oggpack_write(b,0,bits);
142
void oggpackB_writealign(oggpack_buffer *b){
143
int bits=8-b->endbit;
145
oggpackB_write(b,0,bits);
148
static void oggpack_writecopy_helper(oggpack_buffer *b,
151
void (*w)(oggpack_buffer *,
155
unsigned char *ptr=(unsigned char *)source;
162
/* unaligned copy. Do it the hard way. */
164
w(b,(unsigned long)(ptr[i]),8);
166
/* aligned block copy */
167
if(b->endbyte+bytes+1>=b->storage){
168
b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
169
b->buffer=_ogg_realloc(b->buffer,b->storage);
170
b->ptr=b->buffer+b->endbyte;
173
memmove(b->ptr,source,bytes);
181
w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
183
w(b,(unsigned long)(ptr[bytes]),bits);
187
void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
188
oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
191
void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
192
oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
195
void oggpack_reset(oggpack_buffer *b){
198
b->endbit=b->endbyte=0;
201
void oggpackB_reset(oggpack_buffer *b){
205
void oggpack_writeclear(oggpack_buffer *b){
206
_ogg_free(b->buffer);
207
memset(b,0,sizeof(*b));
210
void oggpackB_writeclear(oggpack_buffer *b){
211
oggpack_writeclear(b);
214
void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
215
memset(b,0,sizeof(*b));
216
b->buffer=b->ptr=buf;
220
void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
221
oggpack_readinit(b,buf,bytes);
224
/* Read in bits without advancing the bitptr; bits <= 32 */
225
long oggpack_look(oggpack_buffer *b,int bits){
227
unsigned long m=mask[bits];
231
if(b->endbyte+4>=b->storage){
232
/* not the main path */
233
if(b->endbyte*8+bits>b->storage*8)return(-1);
236
ret=b->ptr[0]>>b->endbit;
238
ret|=b->ptr[1]<<(8-b->endbit);
240
ret|=b->ptr[2]<<(16-b->endbit);
242
ret|=b->ptr[3]<<(24-b->endbit);
243
if(bits>32 && b->endbit)
244
ret|=b->ptr[4]<<(32-b->endbit);
251
/* Read in bits without advancing the bitptr; bits <= 32 */
252
long oggpackB_look(oggpack_buffer *b,int bits){
258
if(b->endbyte+4>=b->storage){
259
/* not the main path */
260
if(b->endbyte*8+bits>b->storage*8)return(-1);
263
ret=b->ptr[0]<<(24+b->endbit);
265
ret|=b->ptr[1]<<(16+b->endbit);
267
ret|=b->ptr[2]<<(8+b->endbit);
269
ret|=b->ptr[3]<<(b->endbit);
270
if(bits>32 && b->endbit)
271
ret|=b->ptr[4]>>(8-b->endbit);
275
return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
278
long oggpack_look1(oggpack_buffer *b){
279
if(b->endbyte>=b->storage)return(-1);
280
return((b->ptr[0]>>b->endbit)&1);
283
long oggpackB_look1(oggpack_buffer *b){
284
if(b->endbyte>=b->storage)return(-1);
285
return((b->ptr[0]>>(7-b->endbit))&1);
288
void oggpack_adv(oggpack_buffer *b,int bits){
295
void oggpackB_adv(oggpack_buffer *b,int bits){
299
void oggpack_adv1(oggpack_buffer *b){
307
void oggpackB_adv1(oggpack_buffer *b){
312
long oggpack_read(oggpack_buffer *b,int bits){
314
unsigned long m=mask[bits];
318
if(b->endbyte+4>=b->storage){
319
/* not the main path */
321
if(b->endbyte*8+bits>b->storage*8)goto overflow;
324
ret=b->ptr[0]>>b->endbit;
326
ret|=b->ptr[1]<<(8-b->endbit);
328
ret|=b->ptr[2]<<(16-b->endbit);
330
ret|=b->ptr[3]<<(24-b->endbit);
331
if(bits>32 && b->endbit){
332
ret|=b->ptr[4]<<(32-b->endbit);
348
long oggpackB_read(oggpack_buffer *b,int bits){
354
if(b->endbyte+4>=b->storage){
355
/* not the main path */
357
if(b->endbyte*8+bits>b->storage*8)goto overflow;
360
ret=b->ptr[0]<<(24+b->endbit);
362
ret|=b->ptr[1]<<(16+b->endbit);
364
ret|=b->ptr[2]<<(8+b->endbit);
366
ret|=b->ptr[3]<<(b->endbit);
367
if(bits>32 && b->endbit)
368
ret|=b->ptr[4]>>(8-b->endbit);
372
ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
382
long oggpack_read1(oggpack_buffer *b){
385
if(b->endbyte>=b->storage){
386
/* not the main path */
391
ret=(b->ptr[0]>>b->endbit)&1;
404
long oggpackB_read1(oggpack_buffer *b){
407
if(b->endbyte>=b->storage){
408
/* not the main path */
413
ret=(b->ptr[0]>>(7-b->endbit))&1;
426
long oggpack_bytes(oggpack_buffer *b){
427
return(b->endbyte+(b->endbit+7)/8);
430
long oggpack_bits(oggpack_buffer *b){
431
return(b->endbyte*8+b->endbit);
434
long oggpackB_bytes(oggpack_buffer *b){
435
return oggpack_bytes(b);
438
long oggpackB_bits(oggpack_buffer *b){
439
return oggpack_bits(b);
442
unsigned char *oggpack_get_buffer(oggpack_buffer *b){
446
unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
447
return oggpack_get_buffer(b);
450
#undef BUFFER_INCREMENT