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