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
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