blob: bcdf153a39c2760618b7981e26aee13d04412eaa [file] [log] [blame]
Gloria Wang0f6f2522010-02-04 13:58:20 -08001/********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
4 * *
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. *
8 * *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
11 * *
12 ********************************************************************
13
14 function: packing variable sized words into an octet stream
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 "misc.h"
24#include "ogg.h"
25
26#include <stdio.h>
27
28
29#if !defined(ARM_LITTLE_ENDIAN) || defined(_V_BIT_TEST)
30static unsigned long mask[]=
31{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
32 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
33 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
34 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
35 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
36 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
37 0x3fffffff,0x7fffffff,0xffffffff };
38#endif
39
40#ifdef ARM_LITTLE_ENDIAN
41
42#ifdef DEBUGGING_BITWISE
43extern void oggpack_readinitARM(oggpack_buffer *b,ogg_reference *r);
44
45void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
46 oggpack_readinitARM(b,r);
47 //fprintf(stderr, "Init: buffer=(%d,%x,%d,%d) %08x%08x\n",
48 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
49 // b->ptr[1], b->ptr[0]);
50 //fflush(stderr);
51}
52
53extern long oggpack_lookARM(oggpack_buffer *b,int bits);
54
55long oggpack_look(oggpack_buffer *b,int bits){
56 long l;
57
58 //fprintf(stderr, "PreLook: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
59 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
60 // b->ptr[1], b->ptr[0], bits);
61 //fflush(stderr);
62 l = oggpack_lookARM(b,bits);
63 //fprintf(stderr, "Look: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
64 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
65 // b->ptr[1], b->ptr[0], bits, l);
66 //fflush(stderr);
67
68 return l;
69}
70
71extern void oggpack_advARM(oggpack_buffer *b,int bits);
72
73void oggpack_adv(oggpack_buffer *b,int bits){
74 //fprintf(stderr, "Adv before: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
75 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
76 // b->ptr[1], b->ptr[0],bits);
77 //fflush(stderr);
78 oggpack_advARM(b,bits);
79 //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %08x%08x\n",
80 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
81 // b->ptr[1], b->ptr[0]);
82 //fflush(stderr);
83}
84
85extern long oggpack_readARM(oggpack_buffer *b,int bits);
86
87/* bits <= 32 */
88long oggpack_read(oggpack_buffer *b,int bits){
89 long l;
90
91 //fprintf(stderr, "PreRead: buffer=(%d,%x,%d,%d) %08x%08x (%d bits)\n",
92 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
93 // b->ptr[1], b->ptr[0], bits);
94 //fflush(stderr);
95 l = oggpack_readARM(b,bits);
96 //fprintf(stderr, "Read: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
97 // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
98 // b->ptr[1], b->ptr[0], bits, l);
99 //fflush(stderr);
100
101 return l;
102}
103#endif
104
105int oggpack_eop(oggpack_buffer *b){
106 int ret;
107 if(b->bitsLeftInSegment<0)ret= -1;
108 else ret = 0;
109 //fprintf(stderr, "EOP %d\n", ret);
110 //fflush(stderr);
111 return ret;
112}
113
114long oggpack_bytes(oggpack_buffer *b){
115 long ret;
116 if(b->bitsLeftInSegment<0) ret = b->count+b->head->length;
117 else ret = b->count + b->head->length - (b->bitsLeftInSegment)/8;
118 //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
119 // b->count, b->head->length, b->bitsLeftInSegment);
120 //fflush(stderr);
121 return ret;
122}
123
124long oggpack_bits(oggpack_buffer *b){
125 long ret;
126 if(b->bitsLeftInSegment<0) ret=(b->count+b->head->length)*8;
127 else ret = b->count*8 + b->head->length*8 - b->bitsLeftInSegment;
128 //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
129 // b->count, b->head->length, b->bitsLeftInSegment);
130 //fflush(stderr);
131 return ret;
132}
133
134#else
135
136/* spans forward, skipping as many bytes as headend is negative; if
137 headend is zero, simply finds next byte. If we're up to the end
138 of the buffer, leaves headend at zero. If we've read past the end,
139 halt the decode process. */
140
141static void _span(oggpack_buffer *b){
142 while(b->headend-(b->headbit>>3)<1){
143 b->headend-=b->headbit>>3;
144 b->headbit&=0x7;
145
146 if(b->head && b->head->next){
147 b->count+=b->head->length;
148 b->head=b->head->next;
149
150 if(b->headend+b->head->length>0)
151 b->headptr=b->head->buffer->data+b->head->begin-b->headend;
152
153 b->headend+=b->head->length;
154 }else{
155 /* we've either met the end of decode, or gone past it. halt
156 only if we're past */
157 if(b->headend*8<b->headbit)
158 /* read has fallen off the end */
159 b->headend=-1;
160 break;
161 }
162 }
163}
164
165void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
166 memset(b,0,sizeof(*b));
167
168 b->tail=b->head=r;
169 b->count=0;
170 if (b->head) {
171 b->headptr=b->head->buffer->data+b->head->begin;
172 b->headend=b->head->length;
173 } else {
174 b->headptr=0;
175 b->headend=0;
176 }
177 _span(b);
178
179 //fprintf(stderr,
180 // "Init: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x\n",
181 // b->headbit, b->headptr, b->headend, b->count,
182 // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
183 // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0]);
184 //fflush(stderr);
185}
186
187#define _lookspan() while(!end){\
188 head=head->next;\
189 if(!head) return -1;\
190 ptr=head->buffer->data + head->begin;\
191 end=head->length;\
192 }
193
194/* Read in bits without advancing the bitptr; bits <= 32 */
195long oggpack_look(oggpack_buffer *b,int bits){
196 unsigned long m=mask[bits];
197 unsigned long ret;
198 int BITS = bits;
199
200 bits+=b->headbit;
201
202 if(bits >= b->headend<<3){
203 int end=b->headend;
204 unsigned char *ptr=b->headptr;
205 ogg_reference *head=b->head;
206
207 if(end<0)return -1;
208 if (!head || !end)return -1;
209
210 if(bits){
211 _lookspan();
212 ret=*ptr++>>b->headbit;
213 if(bits>8){
214 --end;
215 _lookspan();
216 ret|=*ptr++<<(8-b->headbit);
217 if(bits>16){
218 --end;
219 _lookspan();
220 ret|=*ptr++<<(16-b->headbit);
221 if(bits>24){
222 --end;
223 _lookspan();
224 ret|=*ptr++<<(24-b->headbit);
225 if(bits>32 && b->headbit){
226 --end;
227 _lookspan();
228 ret|=*ptr<<(32-b->headbit);
229 }
230 }
231 }
232 }
233 }
234
235 }else{
236
237 /* make this a switch jump-table */
238 ret=b->headptr[0]>>b->headbit;
239 if(bits>8){
240 ret|=b->headptr[1]<<(8-b->headbit);
241 if(bits>16){
242 ret|=b->headptr[2]<<(16-b->headbit);
243 if(bits>24){
244 ret|=b->headptr[3]<<(24-b->headbit);
245 if(bits>32 && b->headbit)
246 ret|=b->headptr[4]<<(32-b->headbit);
247 }
248 }
249 }
250 }
251
252 ret&=m;
253 //fprintf(stderr,
254 // "Look: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits) return=%x\n",
255 // b->headbit, b->headptr, b->headend, b->count,
256 // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
257 // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
258 // BITS, ret);
259 //fflush(stderr);
260 return ret;
261}
262
263/* limited to 32 at a time */
264void oggpack_adv(oggpack_buffer *b,int bits){
265 int BITS=bits;
266 bits+=b->headbit;
267 b->headbit=bits&7;
268 b->headend-=(bits>>3);
269 b->headptr+=(bits>>3);
270 if(b->headend<1)_span(b);
271 //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
272 // b->headbit, b->headptr, b->headend,b->count,
273 // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
274 // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
275 // BITS);
276 //fflush(stderr);
277}
278
279int oggpack_eop(oggpack_buffer *b){
280 int ret;
281 if(b->headend<0)ret= -1;
282 else ret = 0;
283 //fprintf(stderr, "EOP %d\n", ret);
284 //fflush(stderr);
285 return ret;
286}
287
288long oggpack_bytes(oggpack_buffer *b){
289 long ret;
290 if(b->headend<0) ret = b->count+b->head->length;
291 ret = b->count + b->head->length-b->headend + (b->headbit+7)/8;
292 //fprintf(stderr, "Bytes: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bytes)\n",
293 // b->headbit, b->headptr, b->headend, b->count,
294 // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
295 // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
296 // ret);
297 //fflush(stderr);
298 return ret;
299}
300
301long oggpack_bits(oggpack_buffer *b){
302 long ret;
303 if(b->headend<0) ret = (b->count+b->head->length)*8;
304 else ret = (b->count + b->head->length-b->headend)*8 + b->headbit;
305 //fprintf(stderr, "Bits: buffer=(%x,%x,%x) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
306 // b->headbit, b->headptr, b->headend,
307 // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
308 // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
309 // ret);
310 //fflush(stderr);
311 return ret;
312}
313
314/* bits <= 32 */
315long oggpack_read(oggpack_buffer *b,int bits){
316 long ret=oggpack_look(b,bits);
317 oggpack_adv(b,bits);
318 return(ret);
319}
320
321#endif
322
323/* Self test of the bitwise routines; everything else is based on
324 them, so they damned well better be solid. */
325
326#ifdef _V_BIT_TEST
327#include <string.h>
328#include <stdlib.h>
329#include <stdio.h>
330#include "framing.c"
331
332static int ilog(unsigned long v){
333 int ret=0;
334 while(v){
335 ret++;
336 v>>=1;
337 }
338 return(ret);
339}
340
341oggpack_buffer r;
342oggpack_buffer o;
343ogg_buffer_state *bs;
344ogg_reference *or;
345#define TESTWORDS 256
346
347void report(char *in){
348 fprintf(stderr,"%s",in);
349 exit(1);
350}
351
352int getbyte(ogg_reference *or,int position){
353 while(or && position>=or->length){
354 position-=or->length;
355 or=or->next;
356 if(or==NULL){
357 fprintf(stderr,"\n\tERROR: getbyte ran off end of buffer.\n");
358 exit(1);
359 }
360 }
361
362 if((position+or->begin)&1)
363 return (or->buffer->data[(position+or->begin)>>1])&0xff;
364 else
365 return (or->buffer->data[(position+or->begin)>>1]>>8)&0xff;
366}
367
368void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
369 long i,bitcount=0;
370 ogg_reference *or=ogg_buffer_alloc(bs,64);
371 for(i=0;i<compsize;i++)
372 or->buffer->data[i]= comp[i];
373 or->length=i;
374
375 oggpack_readinit(&r,or);
376 for(i=0;i<vals;i++){
377 unsigned long test;
378 int tbit=bits?bits:ilog(b[i]);
379 if((test=oggpack_look(&r,tbit))==0xffffffff)
380 report("out of data!\n");
381 if(test!=(b[i]&mask[tbit])){
382 fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
383 report("looked at incorrect value!\n");
384 }
385 if((test=oggpack_read(&r,tbit))==0xffffffff){
386 report("premature end of data when reading!\n");
387 }
388 if(test!=(b[i]&mask[tbit])){
389 fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
390 report("read incorrect value!\n");
391 }
392 bitcount+=tbit;
393
394 if(bitcount!=oggpack_bits(&r))
395 report("wrong number of bits while reading!\n");
396 if((bitcount+7)/8!=oggpack_bytes(&r))
397 report("wrong number of bytes while reading!\n");
398
399 }
400 if(oggpack_bytes(&r)!=(bitcount+7)/8){
401 fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), (bitcount+7)/8);
402 report("leftover bytes after read!\n");
403 }
404 ogg_buffer_release(or);
405}
406
407void _end_verify(int count){
408 int i;
409
410 /* are the proper number of bits left over? */
411 int leftover=count*8-oggpack_bits(&o);
412 if(leftover>7)
413 report("\nERROR: too many bits reported left over.\n");
414
415 /* does reading to exactly byte alignment *not* trip EOF? */
416 if(oggpack_read(&o,leftover)==-1)
417 report("\nERROR: read to but not past exact end tripped EOF.\n");
418 if(oggpack_bits(&o)!=count*8)
419 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
420
421 /* does EOF trip properly after a single additional bit? */
422 if(oggpack_read(&o,1)!=-1)
423 report("\nERROR: read past exact end did not trip EOF.\n");
424 if(oggpack_bits(&o)!=count*8)
425 report("\nERROR: read past exact end reported bad bitcount.\n");
426
427 /* does EOF stay set over additional bit reads? */
428 for(i=0;i<=32;i++){
429 if(oggpack_read(&o,i)!=-1)
430 report("\nERROR: EOF did not stay set on stream.\n");
431 if(oggpack_bits(&o)!=count*8)
432 report("\nERROR: read past exact end reported bad bitcount.\n");
433 }
434}
435
436void _end_verify2(int count){
437 int i;
438
439 /* are the proper number of bits left over? */
440 int leftover=count*8-oggpack_bits(&o);
441 if(leftover>7)
442 report("\nERROR: too many bits reported left over.\n");
443
444 /* does reading to exactly byte alignment *not* trip EOF? */
445 oggpack_adv(&o,leftover);
446#ifdef ARM_LITTLE_ENDIAN
447 if(o.bitsLeftInSegment!=0)
448#else
449 if(o.headend!=0)
450#endif
451 report("\nERROR: read to but not past exact end tripped EOF.\n");
452 if(oggpack_bits(&o)!=count*8)
453 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
454
455 /* does EOF trip properly after a single additional bit? */
456 oggpack_adv(&o,1);
457#ifdef ARM_LITTLE_ENDIAN
458 if(o.bitsLeftInSegment>=0)
459#else
460 if(o.headend>=0)
461#endif
462 report("\nERROR: read past exact end did not trip EOF.\n");
463 if(oggpack_bits(&o)!=count*8)
464 report("\nERROR: read past exact end reported bad bitcount.\n");
465
466 /* does EOF stay set over additional bit reads? */
467 for(i=0;i<=32;i++){
468 oggpack_adv(&o,i);
469#ifdef ARM_LITTLE_ENDIAN
470 if(o.bitsLeftInSegment>=0)
471#else
472 if(o.headend>=0)
473#endif
474 report("\nERROR: EOF did not stay set on stream.\n");
475 if(oggpack_bits(&o)!=count*8)
476 report("\nERROR: read past exact end reported bad bitcount.\n");
477 }
478}
479
480long ogg_buffer_length(ogg_reference *or){
481 int count=0;
482 while(or){
483 count+=or->length;
484 or=or->next;
485 }
486 return count;
487}
488
489ogg_reference *ogg_buffer_extend(ogg_reference *or,long bytes){
490 if(or){
491 while(or->next){
492 or=or->next;
493 }
494 or->next=ogg_buffer_alloc(or->buffer->ptr.owner,bytes);
495 return(or->next);
496 }
497 return 0;
498}
499
500void ogg_buffer_posttruncate(ogg_reference *or,long pos){
501 /* walk to the point where we want to begin truncate */
502 while(or && pos>or->length){
503 pos-=or->length;
504 or=or->next;
505 }
506 if(or){
507 ogg_buffer_release(or->next);
508 or->next=0;
509 or->length=pos;
510 }
511}
512
513int main(void){
514 long i;
515 static unsigned long testbuffer1[]=
516 {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
517 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
518 int test1size=43;
519
520 static unsigned long testbuffer2[]=
521 {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
522 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
523 85525151,0,12321,1,349528352};
524 int test2size=21;
525
526 static unsigned long testbuffer3[]=
527 {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,
528 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
529 int test3size=56;
530
531 static unsigned long large[]=
532 {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
533 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
534 85525151,0,12321,1,2146528352};
535
536 int onesize=33;
537 static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
538 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
539 223,4};
540
541 int twosize=6;
542 static int two[6]={61,255,255,251,231,29};
543
544 int threesize=54;
545 static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
546 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
547 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
548 100,52,4,14,18,86,77,1};
549
550 int foursize=38;
551 static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
552 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
553 28,2,133,0,1};
554
555 int fivesize=45;
556 static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
557 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
558 84,75,159,2,1,0,132,192,8,0,0,18,22};
559
560 int sixsize=7;
561 static int six[7]={17,177,170,242,169,19,148};
562
563 /* Test read/write together */
564 /* Later we test against pregenerated bitstreams */
565 bs=ogg_buffer_create();
566
567 fprintf(stderr,"\nSmall preclipped packing (LSb): ");
568 cliptest(testbuffer1,test1size,0,one,onesize);
569 fprintf(stderr,"ok.");
570
571 fprintf(stderr,"\nNull bit call (LSb): ");
572 cliptest(testbuffer3,test3size,0,two,twosize);
573 fprintf(stderr,"ok.");
574
575 fprintf(stderr,"\nLarge preclipped packing (LSb): ");
576 cliptest(testbuffer2,test2size,0,three,threesize);
577 fprintf(stderr,"ok.");
578
579 fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
580
581 or=ogg_buffer_alloc(bs,128);
582 for(i=0;i<test2size;i++){
583 or->buffer->data[i*4] = large[i]&0xff;
584 or->buffer->data[i*4+1] = (large[i]>>8)&0xff;
585 or->buffer->data[i*4+2] = (large[i]>>16)&0xff;
586 or->buffer->data[i*4+3] = (large[i]>>24)&0xff;
587 }
588 or->length=test2size*4;
589 oggpack_readinit(&r,or);
590 for(i=0;i<test2size;i++){
591 unsigned long test;
592 if((test=oggpack_look(&r,32))==0xffffffffUL)report("out of data. failed!");
593 if(test!=large[i]){
594 fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
595 test,large[i]);
596 report("read incorrect value!\n");
597 }
598 oggpack_adv(&r,32);
599 }
600 ogg_buffer_release(or);
601 if(oggpack_bytes(&r)!=test2size*4){
602 fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), test2size*4);
603 report("leftover bytes after read!\n");
604 }
605 fprintf(stderr,"ok.");
606
607 fprintf(stderr,"\nSmall unclipped packing (LSb): ");
608 cliptest(testbuffer1,test1size,7,four,foursize);
609 fprintf(stderr,"ok.");
610
611 fprintf(stderr,"\nLarge unclipped packing (LSb): ");
612 cliptest(testbuffer2,test2size,17,five,fivesize);
613 fprintf(stderr,"ok.");
614
615 fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
616 cliptest(testbuffer3,test3size,1,six,sixsize);
617 fprintf(stderr,"ok.");
618
619 fprintf(stderr,"\nTesting read past end (LSb): ");
620 {
621 unsigned char dda[]={0,0,0,0};
622 ogg_buffer lob={dda,8,0,{0}};
623 ogg_reference lor={&lob,0,8,0};
624
625 oggpack_readinit(&r,&lor);
626 for(i=0;i<64;i++){
627 if(oggpack_read(&r,1)<0){
628 fprintf(stderr,"failed; got -1 prematurely.\n");
629 exit(1);
630 }
631 }
632 if(oggpack_look(&r,1)!=-1 ||
633 oggpack_read(&r,1)!=-1){
634 fprintf(stderr,"failed; read past end without -1.\n");
635 exit(1);
636 }
637 }
638 {
639 unsigned char dda[]={0,0,0,0};
640 ogg_buffer lob={dda,8,0,{0}};
641 ogg_reference lor={&lob,0,8,0};
642 unsigned long test;
643
644 oggpack_readinit(&r,&lor);
645 if((test=oggpack_read(&r,30))==0xffffffffUL ||
646 (test=oggpack_read(&r,16))==0xffffffffUL){
647 fprintf(stderr,"failed 2; got -1 prematurely.\n");
648 exit(1);
649 }
650
651 if((test=oggpack_look(&r,18))==0xffffffffUL){
652 fprintf(stderr,"failed 3; got -1 prematurely.\n");
653 exit(1);
654 }
655 if((test=oggpack_look(&r,19))!=0xffffffffUL){
656 fprintf(stderr,"failed; read past end without -1.\n");
657 exit(1);
658 }
659 if((test=oggpack_look(&r,32))!=0xffffffffUL){
660 fprintf(stderr,"failed; read past end without -1.\n");
661 exit(1);
662 }
663 }
664 fprintf(stderr,"ok.\n");
665
666 /* now the scary shit: randomized testing */
667
668 for(i=0;i<10000;i++){
669 long j,count=0,count2=0,bitcount=0;
670 unsigned long values[TESTWORDS];
671 int len[TESTWORDS];
672 unsigned char flat[4*TESTWORDS]; /* max possible needed size */
673
674 memset(flat,0,sizeof(flat));
675 fprintf(stderr,"\rRandomized testing (LSb)... (%ld) ",10000-i);
676
677 /* generate a list of words and lengths */
678 /* write the required number of bits out to packbuffer */
679 {
680 long word=0;
681 long bit=0;
682 int k;
683
684 for(j=0;j<TESTWORDS;j++){
685 values[j]=rand();
686 len[j]=(rand()%33);
687
688 for(k=0;k<len[j];k++){
689 flat[word] |= ((values[j]>>k)&0x1)<<bit;
690 bit++;
691 bitcount++;
692 if(bit>7){
693 bit=0;
694 word++;
695 }
696 }
697 }
698 }
699 count2=(bitcount+7)>>3;
700
701 /* construct random-length buffer chain from flat vector; random
702 byte starting offset within the length of the vector */
703 {
704 ogg_reference *or=NULL,*orl=NULL;
705 long pos=0;
706
707 /* build buffer chain */
708 while(count2){
709 int ilen=(rand()%32),k;
710 int ibegin=(rand()%32);
711
712
713 if(ilen>count2)ilen=count2;
714
715 if(or)
716 orl=ogg_buffer_extend(orl,64);
717 else
718 or=orl=ogg_buffer_alloc(bs,64);
719
720 orl->length=ilen;
721 orl->begin=ibegin;
722
723 for(k=0;k<ilen;k++)
724 orl->buffer->data[ibegin++]= flat[pos++];
725
726 count2-=ilen;
727 }
728
729 if(ogg_buffer_length(or)!=(bitcount+7)/8){
730 fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
731 exit(1);
732 }
733
734
735 {
736 int begin=0; //=(rand()%TESTWORDS);
737 int ilen=(rand()%(TESTWORDS-begin));
738 int bitoffset,bitcount=0;
739 unsigned long temp;
740
741 for(j=0;j<begin;j++)
742 bitcount+=len[j];
743 or=ogg_buffer_pretruncate(or,bitcount/8);
744 bitoffset=bitcount%=8;
745 for(;j<begin+ilen;j++)
746 bitcount+=len[j];
747 ogg_buffer_posttruncate(or,((bitcount+7)/8));
748
749 if((count=ogg_buffer_length(or))!=(bitcount+7)/8){
750 fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
751 exit(1);
752 }
753
754 oggpack_readinit(&o,or);
755
756 /* verify bit count */
757 if(oggpack_bits(&o)!=0){
758 fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
759 exit(1);
760 }
761 if(oggpack_bytes(&o)!=0){
762 fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
763 exit(1);
764 }
765
766 bitcount=bitoffset;
767 oggpack_read(&o,bitoffset);
768
769 /* read and compare to original list */
770 for(j=begin;j<begin+ilen;j++){
771 temp=oggpack_read(&o,len[j]);
772 if(temp==0xffffffffUL){
773 fprintf(stderr,"\nERROR: End of stream too soon! word: %ld,%d\n",
774 j-begin,ilen);
775 exit(1);
776 }
777 if(temp!=(values[j]&mask[len[j]])){
778 fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n"
779,
780 values[j]&mask[len[j]],temp,j-begin,len[j]);
781 exit(1);
782 }
783 bitcount+=len[j];
784 if(oggpack_bits(&o)!=bitcount){
785 fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
786 bitcount,oggpack_bits(&o));
787 exit(1);
788 }
789 if(oggpack_bytes(&o)!=(bitcount+7)/8){
790 fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
791 (bitcount+7)/8,oggpack_bytes(&o));
792 exit(1);
793 }
794
795 }
796 _end_verify(count);
797
798 /* look/adv version */
799 oggpack_readinit(&o,or);
800 bitcount=bitoffset;
801 oggpack_adv(&o,bitoffset);
802
803 /* read and compare to original list */
804 for(j=begin;j<begin+ilen;j++){
805 temp=oggpack_look(&o,len[j]);
806
807 if(temp==0xffffffffUL){
808 fprintf(stderr,"\nERROR: End of stream too soon! word: %ld\n",
809 j-begin);
810 exit(1);
811 }
812 if(temp!=(values[j]&mask[len[j]])){
813 fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n"
814,
815 values[j]&mask[len[j]],temp,j-begin,len[j]);
816 exit(1);
817 }
818 oggpack_adv(&o,len[j]);
819 bitcount+=len[j];
820 if(oggpack_bits(&o)!=bitcount){
821 fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
822 bitcount,oggpack_bits(&o));
823 exit(1);
824 }
825 if(oggpack_bytes(&o)!=(bitcount+7)/8){
826 fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
827 (bitcount+7)/8,oggpack_bytes(&o));
828 exit(1);
829 }
830
831 }
832 _end_verify2(count);
833
834 }
835 ogg_buffer_release(or);
836 }
837 }
838 fprintf(stderr,"\rRandomized testing (LSb)... ok. \n");
839
840 return(0);
841}
842
843#ifdef _WIN32_WCE
844int WinMain(void){
845 return main();
846}
847#endif
848
849#endif