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