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 7675 2004-09-01 00:34:39Z xiphmont $
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 const 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 const unsigned int mask8B[]=
37 {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
38 
oggpack_writeinit(oggpack_buffer * b)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 
oggpackB_writeinit(oggpack_buffer * b)46 void oggpackB_writeinit(oggpack_buffer *b){
47   oggpack_writeinit(b);
48 }
49 
oggpack_writetrunc(oggpack_buffer * b,long bits)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 
oggpackB_writetrunc(oggpack_buffer * b,long bits)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. */
oggpack_write(oggpack_buffer * b,unsigned long value,int 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]=(unsigned char)(value>>(8-b->endbit));
83     if(bits>=16){
84       b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
85       if(bits>=24){
86 	b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
87 	if(bits>=32){
88 	  if(b->endbit)
89 	    b->ptr[4]=(unsigned char)(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. */
oggpackB_write(oggpack_buffer * b,unsigned long value,int 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]=(unsigned char)(value>>(16+b->endbit));
117     if(bits>=16){
118       b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
119       if(bits>=24){
120 	b->ptr[3]=(unsigned char)(value>>(b->endbit));
121 	if(bits>=32){
122 	  if(b->endbit)
123 	    b->ptr[4]=(unsigned char)(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 
oggpack_writealign(oggpack_buffer * b)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 
oggpackB_writealign(oggpack_buffer * b)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 
oggpack_writecopy_helper(oggpack_buffer * b,void * source,long bits,void (* w)(oggpack_buffer *,unsigned long,int),int msb)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->endbyte+=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 
oggpack_writecopy(oggpack_buffer * b,void * source,long bits)187 void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
188   oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
189 }
190 
oggpackB_writecopy(oggpack_buffer * b,void * source,long bits)191 void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
192   oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
193 }
194 
oggpack_reset(oggpack_buffer * b)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 
oggpackB_reset(oggpack_buffer * b)201 void oggpackB_reset(oggpack_buffer *b){
202   oggpack_reset(b);
203 }
204 
oggpack_writeclear(oggpack_buffer * b)205 void oggpack_writeclear(oggpack_buffer *b){
206   _ogg_free(b->buffer);
207   memset(b,0,sizeof(*b));
208 }
209 
oggpackB_writeclear(oggpack_buffer * b)210 void oggpackB_writeclear(oggpack_buffer *b){
211   oggpack_writeclear(b);
212 }
213 
oggpack_readinit(oggpack_buffer * b,unsigned char * buf,int bytes)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 
oggpackB_readinit(oggpack_buffer * b,unsigned char * buf,int bytes)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 */
oggpack_look(oggpack_buffer * b,int bits)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 */
oggpackB_look(oggpack_buffer * b,int bits)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&0xffffffff)>>(m>>1))>>((m+1)>>1);
276 }
277 
oggpack_look1(oggpack_buffer * b)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 
oggpackB_look1(oggpack_buffer * b)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 
oggpack_adv(oggpack_buffer * b,int bits)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 
oggpackB_adv(oggpack_buffer * b,int bits)295 void oggpackB_adv(oggpack_buffer *b,int bits){
296   oggpack_adv(b,bits);
297 }
298 
oggpack_adv1(oggpack_buffer * b)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 
oggpackB_adv1(oggpack_buffer * b)307 void oggpackB_adv1(oggpack_buffer *b){
308   oggpack_adv1(b);
309 }
310 
311 /* bits <= 32 */
oggpack_read(oggpack_buffer * b,int bits)312 long oggpack_read(oggpack_buffer *b,int bits){
313   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=-1L;
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 */
oggpackB_read(oggpack_buffer * b,int bits)348 long oggpackB_read(oggpack_buffer *b,int bits){
349   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=-1L;
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&0xffffffffUL)>>(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 
oggpack_read1(oggpack_buffer * b)382 long oggpack_read1(oggpack_buffer *b){
383   long ret;
384 
385   if(b->endbyte>=b->storage){
386     /* not the main path */
387     ret=-1L;
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 
oggpackB_read1(oggpack_buffer * b)404 long oggpackB_read1(oggpack_buffer *b){
405   long ret;
406 
407   if(b->endbyte>=b->storage){
408     /* not the main path */
409     ret=-1L;
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 
oggpack_bytes(oggpack_buffer * b)426 long oggpack_bytes(oggpack_buffer *b){
427   return(b->endbyte+(b->endbit+7)/8);
428 }
429 
oggpack_bits(oggpack_buffer * b)430 long oggpack_bits(oggpack_buffer *b){
431   return(b->endbyte*8+b->endbit);
432 }
433 
oggpackB_bytes(oggpack_buffer * b)434 long oggpackB_bytes(oggpack_buffer *b){
435   return oggpack_bytes(b);
436 }
437 
oggpackB_bits(oggpack_buffer * b)438 long oggpackB_bits(oggpack_buffer *b){
439   return oggpack_bits(b);
440 }
441 
oggpack_get_buffer(oggpack_buffer * b)442 unsigned char *oggpack_get_buffer(oggpack_buffer *b){
443   return(b->buffer);
444 }
445 
oggpackB_get_buffer(oggpack_buffer * b)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 
ilog(unsigned int v)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 
report(char * in)468 void report(char *in){
469   fprintf(stderr,"%s",in);
470   exit(1);
471 }
472 
cliptest(unsigned long * b,int vals,int bits,int * comp,int compsize)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 
cliptestB(unsigned long * b,int vals,int bits,int * comp,int compsize)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 
main(void)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   oggpack_writeclear(&o);
691   fprintf(stderr,"ok.\n");
692 
693   /********** lazy, cut-n-paste retest with MSb packing ***********/
694 
695   /* Test read/write together */
696   /* Later we test against pregenerated bitstreams */
697   oggpackB_writeinit(&o);
698 
699   fprintf(stderr,"\nSmall preclipped packing (MSb): ");
700   cliptestB(testbuffer1,test1size,0,oneB,onesize);
701   fprintf(stderr,"ok.");
702 
703   fprintf(stderr,"\nNull bit call (MSb): ");
704   cliptestB(testbuffer3,test3size,0,twoB,twosize);
705   fprintf(stderr,"ok.");
706 
707   fprintf(stderr,"\nLarge preclipped packing (MSb): ");
708   cliptestB(testbuffer2,test2size,0,threeB,threesize);
709   fprintf(stderr,"ok.");
710 
711   fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
712   oggpackB_reset(&o);
713   for(i=0;i<test2size;i++)
714     oggpackB_write(&o,large[i],32);
715   buffer=oggpackB_get_buffer(&o);
716   bytes=oggpackB_bytes(&o);
717   oggpackB_readinit(&r,buffer,bytes);
718   for(i=0;i<test2size;i++){
719     if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
720     if(oggpackB_look(&r,32)!=large[i]){
721       fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
722 	      oggpackB_look(&r,32),large[i]);
723       report("read incorrect value!\n");
724     }
725     oggpackB_adv(&r,32);
726   }
727   if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
728   fprintf(stderr,"ok.");
729 
730   fprintf(stderr,"\nSmall unclipped packing (MSb): ");
731   cliptestB(testbuffer1,test1size,7,fourB,foursize);
732   fprintf(stderr,"ok.");
733 
734   fprintf(stderr,"\nLarge unclipped packing (MSb): ");
735   cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
736   fprintf(stderr,"ok.");
737 
738   fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
739   cliptestB(testbuffer3,test3size,1,sixB,sixsize);
740   fprintf(stderr,"ok.");
741 
742   fprintf(stderr,"\nTesting read past end (MSb): ");
743   oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8);
744   for(i=0;i<64;i++){
745     if(oggpackB_read(&r,1)!=0){
746       fprintf(stderr,"failed; got -1 prematurely.\n");
747       exit(1);
748     }
749   }
750   if(oggpackB_look(&r,1)!=-1 ||
751      oggpackB_read(&r,1)!=-1){
752       fprintf(stderr,"failed; read past end without -1.\n");
753       exit(1);
754   }
755   oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8);
756   if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
757       fprintf(stderr,"failed 2; got -1 prematurely.\n");
758       exit(1);
759   }
760 
761   if(oggpackB_look(&r,18)!=0 ||
762      oggpackB_look(&r,18)!=0){
763     fprintf(stderr,"failed 3; got -1 prematurely.\n");
764       exit(1);
765   }
766   if(oggpackB_look(&r,19)!=-1 ||
767      oggpackB_look(&r,19)!=-1){
768     fprintf(stderr,"failed; read past end without -1.\n");
769       exit(1);
770   }
771   if(oggpackB_look(&r,32)!=-1 ||
772      oggpackB_look(&r,32)!=-1){
773     fprintf(stderr,"failed; read past end without -1.\n");
774       exit(1);
775   }
776   oggpackB_writeclear(&o);
777   fprintf(stderr,"ok.\n\n");
778 
779 
780   return(0);
781 }
782 #endif  /* _V_SELFTEST */
783 
784 #undef BUFFER_INCREMENT
785