diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libtremor/bitwise.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libtremor/bitwise.c')
-rw-r--r-- | lib/rbcodec/codecs/libtremor/bitwise.c | 867 |
1 files changed, 867 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libtremor/bitwise.c b/lib/rbcodec/codecs/libtremor/bitwise.c new file mode 100644 index 0000000000..040384abc6 --- /dev/null +++ b/lib/rbcodec/codecs/libtremor/bitwise.c | |||
@@ -0,0 +1,867 @@ | |||
1 | /******************************************************************** | ||
2 | * * | ||
3 | * THIS FILE IS PART OF THE Ogg CONTAINER 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. * | ||
7 | * * | ||
8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * | ||
9 | * by the Xiph.Org Foundation http://www.xiph.org/ * | ||
10 | * * | ||
11 | ******************************************************************** | ||
12 | |||
13 | function: packing variable sized words into an octet stream | ||
14 | last mod: $Id$ | ||
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 <limits.h> | ||
24 | #include "ogg.h" | ||
25 | |||
26 | #define BUFFER_INCREMENT 256 | ||
27 | |||
28 | const unsigned long mask[] ICONST_ATTR = | ||
29 | {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, | ||
30 | 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, | ||
31 | 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, | ||
32 | 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, | ||
33 | 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, | ||
34 | 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, | ||
35 | 0x3fffffff,0x7fffffff,0xffffffff }; | ||
36 | |||
37 | #if 0 | ||
38 | static const unsigned int mask8B[]= | ||
39 | {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; | ||
40 | |||
41 | void oggpack_writeinit(oggpack_buffer *b){ | ||
42 | memset(b,0,sizeof(*b)); | ||
43 | b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); | ||
44 | b->buffer[0]='\0'; | ||
45 | b->storage=BUFFER_INCREMENT; | ||
46 | } | ||
47 | |||
48 | void oggpackB_writeinit(oggpack_buffer *b){ | ||
49 | oggpack_writeinit(b); | ||
50 | } | ||
51 | |||
52 | int oggpack_writecheck(oggpack_buffer *b){ | ||
53 | if(!b->ptr || !b->storage)return -1; | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | int oggpackB_writecheck(oggpack_buffer *b){ | ||
58 | return oggpack_writecheck(b); | ||
59 | } | ||
60 | |||
61 | void oggpack_writetrunc(oggpack_buffer *b,long bits){ | ||
62 | long bytes=bits>>3; | ||
63 | if(b->ptr){ | ||
64 | bits-=bytes*8; | ||
65 | b->ptr=b->buffer+bytes; | ||
66 | b->endbit=bits; | ||
67 | b->endbyte=bytes; | ||
68 | *b->ptr&=mask[bits]; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | void oggpackB_writetrunc(oggpack_buffer *b,long bits){ | ||
73 | long bytes=bits>>3; | ||
74 | if(b->ptr){ | ||
75 | bits-=bytes*8; | ||
76 | b->ptr=b->buffer+bytes; | ||
77 | b->endbit=bits; | ||
78 | b->endbyte=bytes; | ||
79 | *b->ptr&=mask8B[bits]; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | /* Takes only up to 32 bits. */ | ||
84 | void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ | ||
85 | if(bits<0 || bits>32) goto err; | ||
86 | if(b->endbyte>=b->storage-4){ | ||
87 | void *ret; | ||
88 | if(!b->ptr)return; | ||
89 | if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; | ||
90 | ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); | ||
91 | if(!ret) goto err; | ||
92 | b->buffer=ret; | ||
93 | b->storage+=BUFFER_INCREMENT; | ||
94 | b->ptr=b->buffer+b->endbyte; | ||
95 | } | ||
96 | |||
97 | value&=mask[bits]; | ||
98 | bits+=b->endbit; | ||
99 | |||
100 | b->ptr[0]|=value<<b->endbit; | ||
101 | |||
102 | if(bits>=8){ | ||
103 | b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); | ||
104 | if(bits>=16){ | ||
105 | b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); | ||
106 | if(bits>=24){ | ||
107 | b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); | ||
108 | if(bits>=32){ | ||
109 | if(b->endbit) | ||
110 | b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); | ||
111 | else | ||
112 | b->ptr[4]=0; | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | b->endbyte+=bits/8; | ||
119 | b->ptr+=bits/8; | ||
120 | b->endbit=bits&7; | ||
121 | return; | ||
122 | err: | ||
123 | oggpack_writeclear(b); | ||
124 | } | ||
125 | |||
126 | /* Takes only up to 32 bits. */ | ||
127 | void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ | ||
128 | if(bits<0 || bits>32) goto err; | ||
129 | if(b->endbyte>=b->storage-4){ | ||
130 | void *ret; | ||
131 | if(!b->ptr)return; | ||
132 | if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; | ||
133 | ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); | ||
134 | if(!ret) goto err; | ||
135 | b->buffer=ret; | ||
136 | b->storage+=BUFFER_INCREMENT; | ||
137 | b->ptr=b->buffer+b->endbyte; | ||
138 | } | ||
139 | |||
140 | value=(value&mask[bits])<<(32-bits); | ||
141 | bits+=b->endbit; | ||
142 | |||
143 | b->ptr[0]|=value>>(24+b->endbit); | ||
144 | |||
145 | if(bits>=8){ | ||
146 | b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); | ||
147 | if(bits>=16){ | ||
148 | b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); | ||
149 | if(bits>=24){ | ||
150 | b->ptr[3]=(unsigned char)(value>>(b->endbit)); | ||
151 | if(bits>=32){ | ||
152 | if(b->endbit) | ||
153 | b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); | ||
154 | else | ||
155 | b->ptr[4]=0; | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | b->endbyte+=bits/8; | ||
162 | b->ptr+=bits/8; | ||
163 | b->endbit=bits&7; | ||
164 | return; | ||
165 | err: | ||
166 | oggpack_writeclear(b); | ||
167 | } | ||
168 | |||
169 | void oggpack_writealign(oggpack_buffer *b){ | ||
170 | int bits=8-b->endbit; | ||
171 | if(bits<8) | ||
172 | oggpack_write(b,0,bits); | ||
173 | } | ||
174 | |||
175 | void oggpackB_writealign(oggpack_buffer *b){ | ||
176 | int bits=8-b->endbit; | ||
177 | if(bits<8) | ||
178 | oggpackB_write(b,0,bits); | ||
179 | } | ||
180 | |||
181 | static void oggpack_writecopy_helper(oggpack_buffer *b, | ||
182 | void *source, | ||
183 | long bits, | ||
184 | void (*w)(oggpack_buffer *, | ||
185 | unsigned long, | ||
186 | int), | ||
187 | int msb){ | ||
188 | unsigned char *ptr=(unsigned char *)source; | ||
189 | |||
190 | long bytes=bits/8; | ||
191 | bits-=bytes*8; | ||
192 | |||
193 | if(b->endbit){ | ||
194 | int i; | ||
195 | /* unaligned copy. Do it the hard way. */ | ||
196 | for(i=0;i<bytes;i++) | ||
197 | w(b,(unsigned long)(ptr[i]),8); | ||
198 | }else{ | ||
199 | /* aligned block copy */ | ||
200 | if(b->endbyte+bytes+1>=b->storage){ | ||
201 | void *ret; | ||
202 | if(!b->ptr) goto err; | ||
203 | if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err; | ||
204 | b->storage=b->endbyte+bytes+BUFFER_INCREMENT; | ||
205 | ret=_ogg_realloc(b->buffer,b->storage); | ||
206 | if(!ret) goto err; | ||
207 | b->buffer=ret; | ||
208 | b->ptr=b->buffer+b->endbyte; | ||
209 | } | ||
210 | |||
211 | memmove(b->ptr,source,bytes); | ||
212 | b->ptr+=bytes; | ||
213 | b->endbyte+=bytes; | ||
214 | *b->ptr=0; | ||
215 | |||
216 | } | ||
217 | if(bits){ | ||
218 | if(msb) | ||
219 | w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); | ||
220 | else | ||
221 | w(b,(unsigned long)(ptr[bytes]),bits); | ||
222 | } | ||
223 | return; | ||
224 | err: | ||
225 | oggpack_writeclear(b); | ||
226 | } | ||
227 | |||
228 | void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ | ||
229 | oggpack_writecopy_helper(b,source,bits,oggpack_write,0); | ||
230 | } | ||
231 | |||
232 | void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ | ||
233 | oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); | ||
234 | } | ||
235 | |||
236 | void oggpack_reset(oggpack_buffer *b){ | ||
237 | if(!b->ptr)return; | ||
238 | b->ptr=b->buffer; | ||
239 | b->buffer[0]=0; | ||
240 | b->endbit=b->endbyte=0; | ||
241 | } | ||
242 | |||
243 | void oggpackB_reset(oggpack_buffer *b){ | ||
244 | oggpack_reset(b); | ||
245 | } | ||
246 | |||
247 | void oggpack_writeclear(oggpack_buffer *b){ | ||
248 | if(b->buffer)_ogg_free(b->buffer); | ||
249 | memset(b,0,sizeof(*b)); | ||
250 | } | ||
251 | |||
252 | void oggpackB_writeclear(oggpack_buffer *b){ | ||
253 | oggpack_writeclear(b); | ||
254 | } | ||
255 | #endif | ||
256 | void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ | ||
257 | memset(b,0,sizeof(*b)); | ||
258 | b->buffer=b->ptr=buf; | ||
259 | b->storage=bytes; | ||
260 | } | ||
261 | #if 0 | ||
262 | void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ | ||
263 | oggpack_readinit(b,buf,bytes); | ||
264 | } | ||
265 | #endif | ||
266 | /* Read in bits without advancing the bitptr; bits <= 32 */ | ||
267 | /* moved to ogg.h for inlining */ | ||
268 | #if 0 | ||
269 | long oggpack_look(oggpack_buffer *b,int bits){ | ||
270 | unsigned long ret; | ||
271 | unsigned long m; | ||
272 | |||
273 | if(bits<0 || bits>32) return -1; | ||
274 | m=mask[bits]; | ||
275 | bits+=b->endbit; | ||
276 | |||
277 | if(b->endbyte >= b->storage-4){ | ||
278 | /* not the main path */ | ||
279 | if(b->endbyte > b->storage-((bits+7)>>3)) return -1; | ||
280 | /* special case to avoid reading b->ptr[0], which might be past the end of | ||
281 | the buffer; also skips some useless accounting */ | ||
282 | else if(!bits)return(0L); | ||
283 | } | ||
284 | |||
285 | ret=b->ptr[0]>>b->endbit; | ||
286 | if(bits>8){ | ||
287 | ret|=b->ptr[1]<<(8-b->endbit); | ||
288 | if(bits>16){ | ||
289 | ret|=b->ptr[2]<<(16-b->endbit); | ||
290 | if(bits>24){ | ||
291 | ret|=b->ptr[3]<<(24-b->endbit); | ||
292 | if(bits>32 && b->endbit) | ||
293 | ret|=b->ptr[4]<<(32-b->endbit); | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | return(m&ret); | ||
298 | } | ||
299 | #endif | ||
300 | |||
301 | #if 0 | ||
302 | /* Read in bits without advancing the bitptr; bits <= 32 */ | ||
303 | long oggpackB_look(oggpack_buffer *b,int bits){ | ||
304 | unsigned long ret; | ||
305 | int m=32-bits; | ||
306 | |||
307 | if(m<0 || m>32) return -1; | ||
308 | bits+=b->endbit; | ||
309 | |||
310 | if(b->endbyte >= b->storage-4){ | ||
311 | /* not the main path */ | ||
312 | if(b->endbyte > b->storage-((bits+7)>>3)) return -1; | ||
313 | /* special case to avoid reading b->ptr[0], which might be past the end of | ||
314 | the buffer; also skips some useless accounting */ | ||
315 | else if(!bits)return(0L); | ||
316 | } | ||
317 | |||
318 | ret=b->ptr[0]<<(24+b->endbit); | ||
319 | if(bits>8){ | ||
320 | ret|=b->ptr[1]<<(16+b->endbit); | ||
321 | if(bits>16){ | ||
322 | ret|=b->ptr[2]<<(8+b->endbit); | ||
323 | if(bits>24){ | ||
324 | ret|=b->ptr[3]<<(b->endbit); | ||
325 | if(bits>32 && b->endbit) | ||
326 | ret|=b->ptr[4]>>(8-b->endbit); | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); | ||
331 | } | ||
332 | |||
333 | long oggpack_look1(oggpack_buffer *b){ | ||
334 | if(b->endbyte>=b->storage)return(-1); | ||
335 | return((b->ptr[0]>>b->endbit)&1); | ||
336 | } | ||
337 | |||
338 | long oggpackB_look1(oggpack_buffer *b){ | ||
339 | if(b->endbyte>=b->storage)return(-1); | ||
340 | return((b->ptr[0]>>(7-b->endbit))&1); | ||
341 | } | ||
342 | #endif | ||
343 | /* moved to ogg.h for inlining | ||
344 | void oggpack_adv(oggpack_buffer *b,int bits){ | ||
345 | bits+=b->endbit; | ||
346 | |||
347 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; | ||
348 | |||
349 | b->ptr+=bits/8; | ||
350 | b->endbyte+=bits/8; | ||
351 | b->endbit=bits&7; | ||
352 | return; | ||
353 | |||
354 | overflow: | ||
355 | b->ptr=NULL; | ||
356 | b->endbyte=b->storage; | ||
357 | b->endbit=1; | ||
358 | } | ||
359 | */ | ||
360 | #if 0 | ||
361 | void oggpackB_adv(oggpack_buffer *b,int bits){ | ||
362 | oggpack_adv(b,bits); | ||
363 | } | ||
364 | |||
365 | void oggpack_adv1(oggpack_buffer *b){ | ||
366 | if(++(b->endbit)>7){ | ||
367 | b->endbit=0; | ||
368 | b->ptr++; | ||
369 | b->endbyte++; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | void oggpackB_adv1(oggpack_buffer *b){ | ||
374 | oggpack_adv1(b); | ||
375 | } | ||
376 | #endif | ||
377 | /* bits <= 32 */ | ||
378 | long oggpack_read(oggpack_buffer *b,int bits) ICODE_ATTR_TREMOR_NOT_MDCT; | ||
379 | long oggpack_read(oggpack_buffer *b,int bits){ | ||
380 | long ret; | ||
381 | unsigned long m; | ||
382 | |||
383 | if(bits<0 || bits>32) goto err; | ||
384 | m=mask[bits]; | ||
385 | bits+=b->endbit; | ||
386 | |||
387 | if(b->endbyte >= b->storage-4){ | ||
388 | /* not the main path */ | ||
389 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; | ||
390 | /* special case to avoid reading b->ptr[0], which might be past the end of | ||
391 | the buffer; also skips some useless accounting */ | ||
392 | else if(!bits)return(0L); | ||
393 | } | ||
394 | |||
395 | ret=b->ptr[0]>>b->endbit; | ||
396 | if(bits>8){ | ||
397 | ret|=b->ptr[1]<<(8-b->endbit); | ||
398 | if(bits>16){ | ||
399 | ret|=b->ptr[2]<<(16-b->endbit); | ||
400 | if(bits>24){ | ||
401 | ret|=b->ptr[3]<<(24-b->endbit); | ||
402 | if(bits>32 && b->endbit){ | ||
403 | ret|=b->ptr[4]<<(32-b->endbit); | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | } | ||
408 | ret&=m; | ||
409 | b->ptr+=bits/8; | ||
410 | b->endbyte+=bits/8; | ||
411 | b->endbit=bits&7; | ||
412 | return ret; | ||
413 | |||
414 | overflow: | ||
415 | err: | ||
416 | b->ptr=NULL; | ||
417 | b->endbyte=b->storage; | ||
418 | b->endbit=1; | ||
419 | return -1L; | ||
420 | } | ||
421 | #if 0 | ||
422 | /* bits <= 32 */ | ||
423 | long oggpackB_read(oggpack_buffer *b,int bits){ | ||
424 | long ret; | ||
425 | long m=32-bits; | ||
426 | |||
427 | if(m<0 || m>32) goto err; | ||
428 | bits+=b->endbit; | ||
429 | |||
430 | if(b->endbyte+4>=b->storage){ | ||
431 | /* not the main path */ | ||
432 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; | ||
433 | /* special case to avoid reading b->ptr[0], which might be past the end of | ||
434 | the buffer; also skips some useless accounting */ | ||
435 | else if(!bits)return(0L); | ||
436 | } | ||
437 | |||
438 | ret=b->ptr[0]<<(24+b->endbit); | ||
439 | if(bits>8){ | ||
440 | ret|=b->ptr[1]<<(16+b->endbit); | ||
441 | if(bits>16){ | ||
442 | ret|=b->ptr[2]<<(8+b->endbit); | ||
443 | if(bits>24){ | ||
444 | ret|=b->ptr[3]<<(b->endbit); | ||
445 | if(bits>32 && b->endbit) | ||
446 | ret|=b->ptr[4]>>(8-b->endbit); | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); | ||
451 | |||
452 | b->ptr+=bits/8; | ||
453 | b->endbyte+=bits/8; | ||
454 | b->endbit=bits&7; | ||
455 | return ret; | ||
456 | |||
457 | overflow: | ||
458 | err: | ||
459 | b->ptr=NULL; | ||
460 | b->endbyte=b->storage; | ||
461 | b->endbit=1; | ||
462 | return -1L; | ||
463 | } | ||
464 | |||
465 | long oggpack_read1(oggpack_buffer *b){ | ||
466 | long ret; | ||
467 | |||
468 | if(b->endbyte >= b->storage) goto overflow; | ||
469 | ret=(b->ptr[0]>>b->endbit)&1; | ||
470 | |||
471 | b->endbit++; | ||
472 | if(b->endbit>7){ | ||
473 | b->endbit=0; | ||
474 | b->ptr++; | ||
475 | b->endbyte++; | ||
476 | } | ||
477 | return ret; | ||
478 | |||
479 | overflow: | ||
480 | b->ptr=NULL; | ||
481 | b->endbyte=b->storage; | ||
482 | b->endbit=1; | ||
483 | return -1L; | ||
484 | } | ||
485 | |||
486 | long oggpackB_read1(oggpack_buffer *b){ | ||
487 | long ret; | ||
488 | |||
489 | if(b->endbyte >= b->storage) goto overflow; | ||
490 | ret=(b->ptr[0]>>(7-b->endbit))&1; | ||
491 | |||
492 | b->endbit++; | ||
493 | if(b->endbit>7){ | ||
494 | b->endbit=0; | ||
495 | b->ptr++; | ||
496 | b->endbyte++; | ||
497 | } | ||
498 | return ret; | ||
499 | |||
500 | overflow: | ||
501 | b->ptr=NULL; | ||
502 | b->endbyte=b->storage; | ||
503 | b->endbit=1; | ||
504 | return -1L; | ||
505 | } | ||
506 | #endif | ||
507 | /* moved to ogg.h for inlining | ||
508 | long oggpack_bytes(oggpack_buffer *b){ | ||
509 | return(b->endbyte+(b->endbit+7)/8); | ||
510 | } | ||
511 | */ | ||
512 | #if 0 | ||
513 | long oggpack_bits(oggpack_buffer *b){ | ||
514 | return(b->endbyte*8+b->endbit); | ||
515 | } | ||
516 | |||
517 | long oggpackB_bytes(oggpack_buffer *b){ | ||
518 | return oggpack_bytes(b); | ||
519 | } | ||
520 | |||
521 | long oggpackB_bits(oggpack_buffer *b){ | ||
522 | return oggpack_bits(b); | ||
523 | } | ||
524 | |||
525 | unsigned char *oggpack_get_buffer(oggpack_buffer *b){ | ||
526 | return(b->buffer); | ||
527 | } | ||
528 | |||
529 | unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ | ||
530 | return oggpack_get_buffer(b); | ||
531 | } | ||
532 | #endif | ||
533 | /* Self test of the bitwise routines; everything else is based on | ||
534 | them, so they damned well better be solid. */ | ||
535 | |||
536 | #ifdef _V_SELFTEST | ||
537 | #include <stdio.h> | ||
538 | |||
539 | static int ilog(unsigned int v){ | ||
540 | int ret=0; | ||
541 | while(v){ | ||
542 | ret++; | ||
543 | v>>=1; | ||
544 | } | ||
545 | return(ret); | ||
546 | } | ||
547 | |||
548 | oggpack_buffer o; | ||
549 | oggpack_buffer r; | ||
550 | |||
551 | void report(char *in){ | ||
552 | fprintf(stderr,"%s",in); | ||
553 | exit(1); | ||
554 | } | ||
555 | |||
556 | void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ | ||
557 | long bytes,i; | ||
558 | unsigned char *buffer; | ||
559 | |||
560 | oggpack_reset(&o); | ||
561 | for(i=0;i<vals;i++) | ||
562 | oggpack_write(&o,b[i],bits?bits:ilog(b[i])); | ||
563 | buffer=oggpack_get_buffer(&o); | ||
564 | bytes=oggpack_bytes(&o); | ||
565 | if(bytes!=compsize)report("wrong number of bytes!\n"); | ||
566 | for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ | ||
567 | for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); | ||
568 | report("wrote incorrect value!\n"); | ||
569 | } | ||
570 | oggpack_readinit(&r,buffer,bytes); | ||
571 | for(i=0;i<vals;i++){ | ||
572 | int tbit=bits?bits:ilog(b[i]); | ||
573 | if(oggpack_look(&r,tbit)==-1) | ||
574 | report("out of data!\n"); | ||
575 | if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit])) | ||
576 | report("looked at incorrect value!\n"); | ||
577 | if(tbit==1) | ||
578 | if(oggpack_look1(&r)!=(b[i]&mask[tbit])) | ||
579 | report("looked at single bit incorrect value!\n"); | ||
580 | if(tbit==1){ | ||
581 | if(oggpack_read1(&r)!=(b[i]&mask[tbit])) | ||
582 | report("read incorrect single bit value!\n"); | ||
583 | }else{ | ||
584 | if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit])) | ||
585 | report("read incorrect value!\n"); | ||
586 | } | ||
587 | } | ||
588 | if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | ||
589 | } | ||
590 | |||
591 | void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ | ||
592 | long bytes,i; | ||
593 | unsigned char *buffer; | ||
594 | |||
595 | oggpackB_reset(&o); | ||
596 | for(i=0;i<vals;i++) | ||
597 | oggpackB_write(&o,b[i],bits?bits:ilog(b[i])); | ||
598 | buffer=oggpackB_get_buffer(&o); | ||
599 | bytes=oggpackB_bytes(&o); | ||
600 | if(bytes!=compsize)report("wrong number of bytes!\n"); | ||
601 | for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ | ||
602 | for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); | ||
603 | report("wrote incorrect value!\n"); | ||
604 | } | ||
605 | oggpackB_readinit(&r,buffer,bytes); | ||
606 | for(i=0;i<vals;i++){ | ||
607 | int tbit=bits?bits:ilog(b[i]); | ||
608 | if(oggpackB_look(&r,tbit)==-1) | ||
609 | report("out of data!\n"); | ||
610 | if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit])) | ||
611 | report("looked at incorrect value!\n"); | ||
612 | if(tbit==1) | ||
613 | if(oggpackB_look1(&r)!=(b[i]&mask[tbit])) | ||
614 | report("looked at single bit incorrect value!\n"); | ||
615 | if(tbit==1){ | ||
616 | if(oggpackB_read1(&r)!=(b[i]&mask[tbit])) | ||
617 | report("read incorrect single bit value!\n"); | ||
618 | }else{ | ||
619 | if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit])) | ||
620 | report("read incorrect value!\n"); | ||
621 | } | ||
622 | } | ||
623 | if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | ||
624 | } | ||
625 | |||
626 | int main(void){ | ||
627 | unsigned char *buffer; | ||
628 | long bytes,i; | ||
629 | static unsigned long testbuffer1[]= | ||
630 | {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, | ||
631 | 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; | ||
632 | int test1size=43; | ||
633 | |||
634 | static unsigned long testbuffer2[]= | ||
635 | {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212, | ||
636 | 1233432,534,5,346435231,14436467,7869299,76326614,167548585, | ||
637 | 85525151,0,12321,1,349528352}; | ||
638 | int test2size=21; | ||
639 | |||
640 | static unsigned long testbuffer3[]= | ||
641 | {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1, | ||
642 | 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1}; | ||
643 | int test3size=56; | ||
644 | |||
645 | static unsigned long large[]= | ||
646 | {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212, | ||
647 | 1233432,534,5,2146435231,14436467,7869299,76326614,167548585, | ||
648 | 85525151,0,12321,1,2146528352}; | ||
649 | |||
650 | int onesize=33; | ||
651 | static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40, | ||
652 | 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172, | ||
653 | 223,4}; | ||
654 | static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222, | ||
655 | 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18, | ||
656 | 245,251,128}; | ||
657 | |||
658 | int twosize=6; | ||
659 | static int two[6]={61,255,255,251,231,29}; | ||
660 | static int twoB[6]={247,63,255,253,249,120}; | ||
661 | |||
662 | int threesize=54; | ||
663 | static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254, | ||
664 | 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83, | ||
665 | 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10, | ||
666 | 100,52,4,14,18,86,77,1}; | ||
667 | static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183, | ||
668 | 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98, | ||
669 | 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104, | ||
670 | 200,20,254,4,58,106,176,144,0}; | ||
671 | |||
672 | int foursize=38; | ||
673 | static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72, | ||
674 | 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169, | ||
675 | 28,2,133,0,1}; | ||
676 | static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41, | ||
677 | 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67, | ||
678 | 129,10,4,32}; | ||
679 | |||
680 | int fivesize=45; | ||
681 | static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62, | ||
682 | 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169, | ||
683 | 84,75,159,2,1,0,132,192,8,0,0,18,22}; | ||
684 | static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226, | ||
685 | 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77, | ||
686 | 172,150,169,129,79,128,0,6,4,32,0,27,9,0}; | ||
687 | |||
688 | int sixsize=7; | ||
689 | static int six[7]={17,177,170,242,169,19,148}; | ||
690 | static int sixB[7]={136,141,85,79,149,200,41}; | ||
691 | |||
692 | /* Test read/write together */ | ||
693 | /* Later we test against pregenerated bitstreams */ | ||
694 | oggpack_writeinit(&o); | ||
695 | |||
696 | fprintf(stderr,"\nSmall preclipped packing (LSb): "); | ||
697 | cliptest(testbuffer1,test1size,0,one,onesize); | ||
698 | fprintf(stderr,"ok."); | ||
699 | |||
700 | fprintf(stderr,"\nNull bit call (LSb): "); | ||
701 | cliptest(testbuffer3,test3size,0,two,twosize); | ||
702 | fprintf(stderr,"ok."); | ||
703 | |||
704 | fprintf(stderr,"\nLarge preclipped packing (LSb): "); | ||
705 | cliptest(testbuffer2,test2size,0,three,threesize); | ||
706 | fprintf(stderr,"ok."); | ||
707 | |||
708 | fprintf(stderr,"\n32 bit preclipped packing (LSb): "); | ||
709 | oggpack_reset(&o); | ||
710 | for(i=0;i<test2size;i++) | ||
711 | oggpack_write(&o,large[i],32); | ||
712 | buffer=oggpack_get_buffer(&o); | ||
713 | bytes=oggpack_bytes(&o); | ||
714 | oggpack_readinit(&r,buffer,bytes); | ||
715 | for(i=0;i<test2size;i++){ | ||
716 | if(oggpack_look(&r,32)==-1)report("out of data. failed!"); | ||
717 | if(oggpack_look(&r,32)!=large[i]){ | ||
718 | fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i], | ||
719 | oggpack_look(&r,32),large[i]); | ||
720 | report("read incorrect value!\n"); | ||
721 | } | ||
722 | oggpack_adv(&r,32); | ||
723 | } | ||
724 | if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | ||
725 | fprintf(stderr,"ok."); | ||
726 | |||
727 | fprintf(stderr,"\nSmall unclipped packing (LSb): "); | ||
728 | cliptest(testbuffer1,test1size,7,four,foursize); | ||
729 | fprintf(stderr,"ok."); | ||
730 | |||
731 | fprintf(stderr,"\nLarge unclipped packing (LSb): "); | ||
732 | cliptest(testbuffer2,test2size,17,five,fivesize); | ||
733 | fprintf(stderr,"ok."); | ||
734 | |||
735 | fprintf(stderr,"\nSingle bit unclipped packing (LSb): "); | ||
736 | cliptest(testbuffer3,test3size,1,six,sixsize); | ||
737 | fprintf(stderr,"ok."); | ||
738 | |||
739 | fprintf(stderr,"\nTesting read past end (LSb): "); | ||
740 | oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); | ||
741 | for(i=0;i<64;i++){ | ||
742 | if(oggpack_read(&r,1)!=0){ | ||
743 | fprintf(stderr,"failed; got -1 prematurely.\n"); | ||
744 | exit(1); | ||
745 | } | ||
746 | } | ||
747 | if(oggpack_look(&r,1)!=-1 || | ||
748 | oggpack_read(&r,1)!=-1){ | ||
749 | fprintf(stderr,"failed; read past end without -1.\n"); | ||
750 | exit(1); | ||
751 | } | ||
752 | oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); | ||
753 | if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){ | ||
754 | fprintf(stderr,"failed 2; got -1 prematurely.\n"); | ||
755 | exit(1); | ||
756 | } | ||
757 | |||
758 | if(oggpack_look(&r,18)!=0 || | ||
759 | oggpack_look(&r,18)!=0){ | ||
760 | fprintf(stderr,"failed 3; got -1 prematurely.\n"); | ||
761 | exit(1); | ||
762 | } | ||
763 | if(oggpack_look(&r,19)!=-1 || | ||
764 | oggpack_look(&r,19)!=-1){ | ||
765 | fprintf(stderr,"failed; read past end without -1.\n"); | ||
766 | exit(1); | ||
767 | } | ||
768 | if(oggpack_look(&r,32)!=-1 || | ||
769 | oggpack_look(&r,32)!=-1){ | ||
770 | fprintf(stderr,"failed; read past end without -1.\n"); | ||
771 | exit(1); | ||
772 | } | ||
773 | oggpack_writeclear(&o); | ||
774 | fprintf(stderr,"ok.\n"); | ||
775 | |||
776 | /********** lazy, cut-n-paste retest with MSb packing ***********/ | ||
777 | |||
778 | /* Test read/write together */ | ||
779 | /* Later we test against pregenerated bitstreams */ | ||
780 | oggpackB_writeinit(&o); | ||
781 | |||
782 | fprintf(stderr,"\nSmall preclipped packing (MSb): "); | ||
783 | cliptestB(testbuffer1,test1size,0,oneB,onesize); | ||
784 | fprintf(stderr,"ok."); | ||
785 | |||
786 | fprintf(stderr,"\nNull bit call (MSb): "); | ||
787 | cliptestB(testbuffer3,test3size,0,twoB,twosize); | ||
788 | fprintf(stderr,"ok."); | ||
789 | |||
790 | fprintf(stderr,"\nLarge preclipped packing (MSb): "); | ||
791 | cliptestB(testbuffer2,test2size,0,threeB,threesize); | ||
792 | fprintf(stderr,"ok."); | ||
793 | |||
794 | fprintf(stderr,"\n32 bit preclipped packing (MSb): "); | ||
795 | oggpackB_reset(&o); | ||
796 | for(i=0;i<test2size;i++) | ||
797 | oggpackB_write(&o,large[i],32); | ||
798 | buffer=oggpackB_get_buffer(&o); | ||
799 | bytes=oggpackB_bytes(&o); | ||
800 | oggpackB_readinit(&r,buffer,bytes); | ||
801 | for(i=0;i<test2size;i++){ | ||
802 | if(oggpackB_look(&r,32)==-1)report("out of data. failed!"); | ||
803 | if(oggpackB_look(&r,32)!=large[i]){ | ||
804 | fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i], | ||
805 | oggpackB_look(&r,32),large[i]); | ||
806 | report("read incorrect value!\n"); | ||
807 | } | ||
808 | oggpackB_adv(&r,32); | ||
809 | } | ||
810 | if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | ||
811 | fprintf(stderr,"ok."); | ||
812 | |||
813 | fprintf(stderr,"\nSmall unclipped packing (MSb): "); | ||
814 | cliptestB(testbuffer1,test1size,7,fourB,foursize); | ||
815 | fprintf(stderr,"ok."); | ||
816 | |||
817 | fprintf(stderr,"\nLarge unclipped packing (MSb): "); | ||
818 | cliptestB(testbuffer2,test2size,17,fiveB,fivesize); | ||
819 | fprintf(stderr,"ok."); | ||
820 | |||
821 | fprintf(stderr,"\nSingle bit unclipped packing (MSb): "); | ||
822 | cliptestB(testbuffer3,test3size,1,sixB,sixsize); | ||
823 | fprintf(stderr,"ok."); | ||
824 | |||
825 | fprintf(stderr,"\nTesting read past end (MSb): "); | ||
826 | oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); | ||
827 | for(i=0;i<64;i++){ | ||
828 | if(oggpackB_read(&r,1)!=0){ | ||
829 | fprintf(stderr,"failed; got -1 prematurely.\n"); | ||
830 | exit(1); | ||
831 | } | ||
832 | } | ||
833 | if(oggpackB_look(&r,1)!=-1 || | ||
834 | oggpackB_read(&r,1)!=-1){ | ||
835 | fprintf(stderr,"failed; read past end without -1.\n"); | ||
836 | exit(1); | ||
837 | } | ||
838 | oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); | ||
839 | if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){ | ||
840 | fprintf(stderr,"failed 2; got -1 prematurely.\n"); | ||
841 | exit(1); | ||
842 | } | ||
843 | |||
844 | if(oggpackB_look(&r,18)!=0 || | ||
845 | oggpackB_look(&r,18)!=0){ | ||
846 | fprintf(stderr,"failed 3; got -1 prematurely.\n"); | ||
847 | exit(1); | ||
848 | } | ||
849 | if(oggpackB_look(&r,19)!=-1 || | ||
850 | oggpackB_look(&r,19)!=-1){ | ||
851 | fprintf(stderr,"failed; read past end without -1.\n"); | ||
852 | exit(1); | ||
853 | } | ||
854 | if(oggpackB_look(&r,32)!=-1 || | ||
855 | oggpackB_look(&r,32)!=-1){ | ||
856 | fprintf(stderr,"failed; read past end without -1.\n"); | ||
857 | exit(1); | ||
858 | } | ||
859 | oggpackB_writeclear(&o); | ||
860 | fprintf(stderr,"ok.\n\n"); | ||
861 | |||
862 | |||
863 | return(0); | ||
864 | } | ||
865 | #endif /* _V_SELFTEST */ | ||
866 | |||
867 | #undef BUFFER_INCREMENT | ||