1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
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. *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12 ********************************************************************
14 function: packing variable sized words into an octet stream
16 ********************************************************************/
18 /* We're 'LSb' endian; if we write a word but read individual bits,
19 then we'll read the lsb first */
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 };
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
;
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
){
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
;
53 /* we've either met the end of decode, or gone past it. halt
55 if(b
->headend
<0 || b
->headbit
)
56 /* read has fallen off the end */
64 void oggpack_readinit(oggpack_buffer
*b
,ogg_reference
*r
){
65 memset(b
,0,sizeof(*b
));
69 b
->headptr
=b
->head
->buffer
->data
+b
->head
->begin
;
70 b
->headend
=b
->head
->length
;
74 #define _lookspan() while(!end){\
77 ptr=head->buffer->data + head->begin;\
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
];
88 if(bits
>= b
->headend
<<3){
90 unsigned char *ptr
=b
->headptr
;
91 ogg_reference
*head
=b
->head
;
97 ret
=*ptr
++>>b
->headbit
;
101 ret
|=*ptr
++<<(8-b
->headbit
);
105 ret
|=*ptr
++<<(16-b
->headbit
);
109 ret
|=*ptr
++<<(24-b
->headbit
);
110 if(bits
>32 && b
->headbit
){
113 ret
|=*ptr
<<(32-b
->headbit
);
122 /* make this a switch jump-table */
123 ret
=b
->headptr
[0]>>b
->headbit
;
125 ret
|=b
->headptr
[1]<<(8-b
->headbit
);
127 ret
|=b
->headptr
[2]<<(16-b
->headbit
);
129 ret
|=b
->headptr
[3]<<(24-b
->headbit
);
130 if(bits
>32 && b
->headbit
)
131 ret
|=b
->headptr
[4]<<(32-b
->headbit
);
141 /* limited to 32 at a time */
142 void oggpack_adv(oggpack_buffer
*b
,int bits
){
146 if((b
->headend
-=bits
/8)<1)_span(b
);
149 /* spans forward and finds next byte. Never halts */
150 static void _span_one(oggpack_buffer
*b
){
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
;
162 static int _halt_one(oggpack_buffer
*b
){
170 int oggpack_eop(oggpack_buffer
*b
){
171 if(b
->headend
<0)return -1;
176 long oggpack_read(oggpack_buffer
*b
,int bits
){
177 unsigned long m
=mask
[bits
];
182 if(bits
>= b
->headend
<<3){
184 if(b
->headend
<0)return -1;
187 if (_halt_one(b
)) return -1;
188 ret
=*b
->headptr
>>b
->headbit
;
195 if (_halt_one(b
)) return -1;
196 ret
|=*b
->headptr
<<(8-b
->headbit
);
203 if (_halt_one(b
)) return -1;
204 ret
|=*b
->headptr
<<(16-b
->headbit
);
211 if (_halt_one(b
)) return -1;
212 ret
|=*b
->headptr
<<(24-b
->headbit
);
219 if (_halt_one(b
)) return -1;
220 if(b
->headbit
)ret
|=*b
->headptr
<<(32-b
->headbit
);
233 ret
=b
->headptr
[0]>>b
->headbit
;
235 ret
|=b
->headptr
[1]<<(8-b
->headbit
);
237 ret
|=b
->headptr
[2]<<(16-b
->headbit
);
239 ret
|=b
->headptr
[3]<<(24-b
->headbit
);
240 if(bits
>32 && b
->headbit
){
241 ret
|=b
->headptr
[4]<<(32-b
->headbit
);
256 long oggpack_bytes(oggpack_buffer
*b
){
257 return(b
->count
+b
->headptr
-b
->head
->buffer
->data
-b
->head
->begin
+
261 long oggpack_bits(oggpack_buffer
*b
){
262 return((b
->count
+b
->headptr
-b
->head
->buffer
->data
-b
->head
->begin
)*8+