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