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