tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ogg_bitwise.c (30633B)


      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-2014             *
      9 * by the Xiph.Org Foundation http://www.xiph.org/                  *
     10 *                                                                  *
     11 ********************************************************************
     12 
     13  function: packing variable sized words into an octet stream
     14 
     15 ********************************************************************/
     16 
     17 /* We're 'LSb' endian; if we write a word but read individual bits,
     18   then we'll read the lsb first */
     19 
     20 #include <string.h>
     21 #include <stdlib.h>
     22 #include <limits.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  if (!b->buffer)
     43    return;
     44  b->buffer[0]='\0';
     45  b->storage=BUFFER_INCREMENT;
     46 }
     47 
     48 void oggpackB_writeinit(oggpack_buffer *b){
     49  oggpack_writeinit(b);
     50 }
     51 
     52 int oggpack_writecheck(oggpack_buffer *b){
     53  if(!b->ptr || !b->storage)return -1;
     54  return 0;
     55 }
     56 
     57 int oggpackB_writecheck(oggpack_buffer *b){
     58  return oggpack_writecheck(b);
     59 }
     60 
     61 void oggpack_writetrunc(oggpack_buffer *b,long bits){
     62  long bytes=bits>>3;
     63  if(b->ptr){
     64    bits-=bytes*8;
     65    b->ptr=b->buffer+bytes;
     66    b->endbit=bits;
     67    b->endbyte=bytes;
     68    *b->ptr&=mask[bits];
     69  }
     70 }
     71 
     72 void oggpackB_writetrunc(oggpack_buffer *b,long bits){
     73  long bytes=bits>>3;
     74  if(b->ptr){
     75    bits-=bytes*8;
     76    b->ptr=b->buffer+bytes;
     77    b->endbit=bits;
     78    b->endbyte=bytes;
     79    *b->ptr&=mask8B[bits];
     80  }
     81 }
     82 
     83 /* Takes only up to 32 bits. */
     84 void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
     85  if(bits<0 || bits>32) goto err;
     86  if(b->endbyte>=b->storage-4){
     87    void *ret;
     88    if(!b->ptr)return;
     89    if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
     90    ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
     91    if(!ret) goto err;
     92    b->buffer=ret;
     93    b->storage+=BUFFER_INCREMENT;
     94    b->ptr=b->buffer+b->endbyte;
     95  }
     96 
     97  value&=mask[bits];
     98  bits+=b->endbit;
     99 
    100  b->ptr[0]|=value<<b->endbit;
    101 
    102  if(bits>=8){
    103    b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
    104    if(bits>=16){
    105      b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
    106      if(bits>=24){
    107        b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
    108        if(bits>=32){
    109          if(b->endbit)
    110            b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
    111          else
    112            b->ptr[4]=0;
    113        }
    114      }
    115    }
    116  }
    117 
    118  b->endbyte+=bits/8;
    119  b->ptr+=bits/8;
    120  b->endbit=bits&7;
    121  return;
    122 err:
    123  oggpack_writeclear(b);
    124 }
    125 
    126 /* Takes only up to 32 bits. */
    127 void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
    128  if(bits<0 || bits>32) goto err;
    129  if(b->endbyte>=b->storage-4){
    130    void *ret;
    131    if(!b->ptr)return;
    132    if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
    133    ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
    134    if(!ret) goto err;
    135    b->buffer=ret;
    136    b->storage+=BUFFER_INCREMENT;
    137    b->ptr=b->buffer+b->endbyte;
    138  }
    139 
    140  value=(value&mask[bits])<<(32-bits);
    141  bits+=b->endbit;
    142 
    143  b->ptr[0]|=value>>(24+b->endbit);
    144 
    145  if(bits>=8){
    146    b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
    147    if(bits>=16){
    148      b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
    149      if(bits>=24){
    150        b->ptr[3]=(unsigned char)(value>>(b->endbit));
    151        if(bits>=32){
    152          if(b->endbit)
    153            b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
    154          else
    155            b->ptr[4]=0;
    156        }
    157      }
    158    }
    159  }
    160 
    161  b->endbyte+=bits/8;
    162  b->ptr+=bits/8;
    163  b->endbit=bits&7;
    164  return;
    165 err:
    166  oggpack_writeclear(b);
    167 }
    168 
    169 void oggpack_writealign(oggpack_buffer *b){
    170  int bits=8-b->endbit;
    171  if(bits<8)
    172    oggpack_write(b,0,bits);
    173 }
    174 
    175 void oggpackB_writealign(oggpack_buffer *b){
    176  int bits=8-b->endbit;
    177  if(bits<8)
    178    oggpackB_write(b,0,bits);
    179 }
    180 
    181 static void oggpack_writecopy_helper(oggpack_buffer *b,
    182                                     void *source,
    183                                     long bits,
    184                                     void (*w)(oggpack_buffer *,
    185                                               unsigned long,
    186                                               int),
    187                                     int msb){
    188  unsigned char *ptr=(unsigned char *)source;
    189 
    190  long bytes=bits/8;
    191  long pbytes=(b->endbit+bits)/8;
    192  bits-=bytes*8;
    193 
    194  /* expand storage up-front */
    195  if(b->endbyte+pbytes>=b->storage){
    196    void *ret;
    197    if(!b->ptr) goto err;
    198    if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err;
    199    b->storage=b->endbyte+pbytes+BUFFER_INCREMENT;
    200    ret=_ogg_realloc(b->buffer,b->storage);
    201    if(!ret) goto err;
    202    b->buffer=ret;
    203    b->ptr=b->buffer+b->endbyte;
    204  }
    205 
    206  /* copy whole octets */
    207  if(b->endbit){
    208    int i;
    209    /* unaligned copy.  Do it the hard way. */
    210    for(i=0;i<bytes;i++)
    211      w(b,(unsigned long)(ptr[i]),8);
    212  }else{
    213    /* aligned block copy */
    214    memmove(b->ptr,source,bytes);
    215    b->ptr+=bytes;
    216    b->endbyte+=bytes;
    217    *b->ptr=0;
    218  }
    219 
    220  /* copy trailing bits */
    221  if(bits){
    222    if(msb)
    223      w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
    224    else
    225      w(b,(unsigned long)(ptr[bytes]),bits);
    226  }
    227  return;
    228 err:
    229  oggpack_writeclear(b);
    230 }
    231 
    232 void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
    233  oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
    234 }
    235 
    236 void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
    237  oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
    238 }
    239 
    240 void oggpack_reset(oggpack_buffer *b){
    241  if(!b->ptr)return;
    242  b->ptr=b->buffer;
    243  b->buffer[0]=0;
    244  b->endbit=b->endbyte=0;
    245 }
    246 
    247 void oggpackB_reset(oggpack_buffer *b){
    248  oggpack_reset(b);
    249 }
    250 
    251 void oggpack_writeclear(oggpack_buffer *b){
    252  if(b->buffer)_ogg_free(b->buffer);
    253  memset(b,0,sizeof(*b));
    254 }
    255 
    256 void oggpackB_writeclear(oggpack_buffer *b){
    257  oggpack_writeclear(b);
    258 }
    259 
    260 void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
    261  memset(b,0,sizeof(*b));
    262  b->buffer=b->ptr=buf;
    263  b->storage=bytes;
    264 }
    265 
    266 void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
    267  oggpack_readinit(b,buf,bytes);
    268 }
    269 
    270 /* Read in bits without advancing the bitptr; bits <= 32 */
    271 long oggpack_look(oggpack_buffer *b,int bits){
    272  unsigned long ret;
    273  unsigned long m;
    274 
    275  if(bits<0 || bits>32) return -1;
    276  m=mask[bits];
    277  bits+=b->endbit;
    278 
    279  if(b->endbyte >= b->storage-4){
    280    /* not the main path */
    281    if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
    282    /* special case to avoid reading b->ptr[0], which might be past the end of
    283        the buffer; also skips some useless accounting */
    284    else if(!bits)return(0L);
    285  }
    286 
    287  ret=b->ptr[0]>>b->endbit;
    288  if(bits>8){
    289    ret|=(unsigned long)b->ptr[1]<<(8-b->endbit);
    290    if(bits>16){
    291      ret|=(unsigned long)b->ptr[2]<<(16-b->endbit);
    292      if(bits>24){
    293        ret|=(unsigned long)b->ptr[3]<<(24-b->endbit);
    294        if(bits>32 && b->endbit)
    295          ret|=(unsigned long)b->ptr[4]<<(32-b->endbit);
    296      }
    297    }
    298  }
    299  return(m&ret);
    300 }
    301 
    302 /* Read in bits without advancing the bitptr; bits <= 32 */
    303 long oggpackB_look(oggpack_buffer *b,int bits){
    304  unsigned long ret;
    305  int m=32-bits;
    306 
    307  if(m<0 || m>32) return -1;
    308  bits+=b->endbit;
    309 
    310  if(b->endbyte >= b->storage-4){
    311    /* not the main path */
    312    if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
    313    /* special case to avoid reading b->ptr[0], which might be past the end of
    314        the buffer; also skips some useless accounting */
    315    else if(!bits)return(0L);
    316  }
    317 
    318  ret=(unsigned long)b->ptr[0]<<(24+b->endbit);
    319  if(bits>8){
    320    ret|=(unsigned long)b->ptr[1]<<(16+b->endbit);
    321    if(bits>16){
    322      ret|=(unsigned long)b->ptr[2]<<(8+b->endbit);
    323      if(bits>24){
    324        ret|=(unsigned long)b->ptr[3]<<(b->endbit);
    325        if(bits>32 && b->endbit)
    326          ret|=b->ptr[4]>>(8-b->endbit);
    327      }
    328    }
    329  }
    330  return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
    331 }
    332 
    333 long oggpack_look1(oggpack_buffer *b){
    334  if(b->endbyte>=b->storage)return(-1);
    335  return((b->ptr[0]>>b->endbit)&1);
    336 }
    337 
    338 long oggpackB_look1(oggpack_buffer *b){
    339  if(b->endbyte>=b->storage)return(-1);
    340  return((b->ptr[0]>>(7-b->endbit))&1);
    341 }
    342 
    343 void oggpack_adv(oggpack_buffer *b,int bits){
    344  bits+=b->endbit;
    345 
    346  if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
    347 
    348  b->ptr+=bits/8;
    349  b->endbyte+=bits/8;
    350  b->endbit=bits&7;
    351  return;
    352 
    353 overflow:
    354  b->ptr=NULL;
    355  b->endbyte=b->storage;
    356  b->endbit=1;
    357 }
    358 
    359 void oggpackB_adv(oggpack_buffer *b,int bits){
    360  oggpack_adv(b,bits);
    361 }
    362 
    363 void oggpack_adv1(oggpack_buffer *b){
    364  if(++(b->endbit)>7){
    365    b->endbit=0;
    366    b->ptr++;
    367    b->endbyte++;
    368  }
    369 }
    370 
    371 void oggpackB_adv1(oggpack_buffer *b){
    372  oggpack_adv1(b);
    373 }
    374 
    375 /* bits <= 32 */
    376 long oggpack_read(oggpack_buffer *b,int bits){
    377  long ret;
    378  unsigned long m;
    379 
    380  if(bits<0 || bits>32) goto err;
    381  m=mask[bits];
    382  bits+=b->endbit;
    383 
    384  if(b->endbyte >= b->storage-4){
    385    /* not the main path */
    386    if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
    387    /* special case to avoid reading b->ptr[0], which might be past the end of
    388        the buffer; also skips some useless accounting */
    389    else if(!bits)return(0L);
    390  }
    391 
    392  ret=b->ptr[0]>>b->endbit;
    393  if(bits>8){
    394    ret|=(unsigned long)b->ptr[1]<<(8-b->endbit);
    395    if(bits>16){
    396      ret|=(unsigned long)b->ptr[2]<<(16-b->endbit);
    397      if(bits>24){
    398        ret|=(unsigned long)b->ptr[3]<<(24-b->endbit);
    399        if(bits>32 && b->endbit){
    400          ret|=(unsigned long)b->ptr[4]<<(32-b->endbit);
    401        }
    402      }
    403    }
    404  }
    405  ret&=m;
    406  b->ptr+=bits/8;
    407  b->endbyte+=bits/8;
    408  b->endbit=bits&7;
    409  return ret;
    410 
    411 overflow:
    412 err:
    413  b->ptr=NULL;
    414  b->endbyte=b->storage;
    415  b->endbit=1;
    416  return -1L;
    417 }
    418 
    419 /* bits <= 32 */
    420 long oggpackB_read(oggpack_buffer *b,int bits){
    421  long ret;
    422  long m=32-bits;
    423 
    424  if(m<0 || m>32) goto err;
    425  bits+=b->endbit;
    426 
    427  if(b->endbyte+4>=b->storage){
    428    /* not the main path */
    429    if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
    430    /* special case to avoid reading b->ptr[0], which might be past the end of
    431        the buffer; also skips some useless accounting */
    432    else if(!bits)return(0L);
    433  }
    434 
    435  ret=(unsigned long)b->ptr[0]<<(24+b->endbit);
    436  if(bits>8){
    437    ret|=(unsigned long)b->ptr[1]<<(16+b->endbit);
    438    if(bits>16){
    439      ret|=(unsigned long)b->ptr[2]<<(8+b->endbit);
    440      if(bits>24){
    441        ret|=(unsigned long)b->ptr[3]<<(b->endbit);
    442        if(bits>32 && b->endbit)
    443          ret|=b->ptr[4]>>(8-b->endbit);
    444      }
    445    }
    446  }
    447  ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
    448 
    449  b->ptr+=bits/8;
    450  b->endbyte+=bits/8;
    451  b->endbit=bits&7;
    452  return ret;
    453 
    454 overflow:
    455 err:
    456  b->ptr=NULL;
    457  b->endbyte=b->storage;
    458  b->endbit=1;
    459  return -1L;
    460 }
    461 
    462 long oggpack_read1(oggpack_buffer *b){
    463  long ret;
    464 
    465  if(b->endbyte >= b->storage) goto overflow;
    466  ret=(b->ptr[0]>>b->endbit)&1;
    467 
    468  b->endbit++;
    469  if(b->endbit>7){
    470    b->endbit=0;
    471    b->ptr++;
    472    b->endbyte++;
    473  }
    474  return ret;
    475 
    476 overflow:
    477  b->ptr=NULL;
    478  b->endbyte=b->storage;
    479  b->endbit=1;
    480  return -1L;
    481 }
    482 
    483 long oggpackB_read1(oggpack_buffer *b){
    484  long ret;
    485 
    486  if(b->endbyte >= b->storage) goto overflow;
    487  ret=(b->ptr[0]>>(7-b->endbit))&1;
    488 
    489  b->endbit++;
    490  if(b->endbit>7){
    491    b->endbit=0;
    492    b->ptr++;
    493    b->endbyte++;
    494  }
    495  return ret;
    496 
    497 overflow:
    498  b->ptr=NULL;
    499  b->endbyte=b->storage;
    500  b->endbit=1;
    501  return -1L;
    502 }
    503 
    504 long oggpack_bytes(oggpack_buffer *b){
    505  return(b->endbyte+(b->endbit+7)/8);
    506 }
    507 
    508 long oggpack_bits(oggpack_buffer *b){
    509  return(b->endbyte*8+b->endbit);
    510 }
    511 
    512 long oggpackB_bytes(oggpack_buffer *b){
    513  return oggpack_bytes(b);
    514 }
    515 
    516 long oggpackB_bits(oggpack_buffer *b){
    517  return oggpack_bits(b);
    518 }
    519 
    520 unsigned char *oggpack_get_buffer(oggpack_buffer *b){
    521  return(b->buffer);
    522 }
    523 
    524 unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
    525  return oggpack_get_buffer(b);
    526 }
    527 
    528 /* Self test of the bitwise routines; everything else is based on
    529   them, so they damned well better be solid. */
    530 
    531 #ifdef _V_SELFTEST
    532 #include <stdio.h>
    533 
    534 static int ilog(unsigned int v){
    535  int ret=0;
    536  while(v){
    537    ret++;
    538    v>>=1;
    539  }
    540  return(ret);
    541 }
    542 
    543 oggpack_buffer o;
    544 oggpack_buffer r;
    545 
    546 void report(char *in){
    547  fprintf(stderr,"%s",in);
    548  exit(1);
    549 }
    550 
    551 void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
    552  long bytes,i;
    553  unsigned char *buffer;
    554 
    555  oggpack_reset(&o);
    556  for(i=0;i<vals;i++)
    557    oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
    558  buffer=oggpack_get_buffer(&o);
    559  bytes=oggpack_bytes(&o);
    560  if(bytes!=compsize)report("wrong number of bytes!\n");
    561  for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
    562    for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
    563    report("wrote incorrect value!\n");
    564  }
    565  oggpack_readinit(&r,buffer,bytes);
    566  for(i=0;i<vals;i++){
    567    int tbit=bits?bits:ilog(b[i]);
    568    if(oggpack_look(&r,tbit)==-1)
    569      report("out of data!\n");
    570    if((unsigned long)oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
    571      report("looked at incorrect value!\n");
    572    if(tbit==1)
    573      if((unsigned long)oggpack_look1(&r)!=(b[i]&mask[tbit]))
    574        report("looked at single bit incorrect value!\n");
    575    if(tbit==1){
    576      if((unsigned long)oggpack_read1(&r)!=(b[i]&mask[tbit]))
    577        report("read incorrect single bit value!\n");
    578    }else{
    579      if((unsigned long)oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
    580 report("read incorrect value!\n");
    581    }
    582  }
    583  if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
    584 }
    585 
    586 void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
    587  long bytes,i;
    588  unsigned char *buffer;
    589 
    590  oggpackB_reset(&o);
    591  for(i=0;i<vals;i++)
    592    oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
    593  buffer=oggpackB_get_buffer(&o);
    594  bytes=oggpackB_bytes(&o);
    595  if(bytes!=compsize)report("wrong number of bytes!\n");
    596  for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
    597    for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
    598    report("wrote incorrect value!\n");
    599  }
    600  oggpackB_readinit(&r,buffer,bytes);
    601  for(i=0;i<vals;i++){
    602    int tbit=bits?bits:ilog(b[i]);
    603    if(oggpackB_look(&r,tbit)==-1)
    604      report("out of data!\n");
    605    if((unsigned long)oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
    606      report("looked at incorrect value!\n");
    607    if(tbit==1)
    608      if((unsigned long)oggpackB_look1(&r)!=(b[i]&mask[tbit]))
    609        report("looked at single bit incorrect value!\n");
    610    if(tbit==1){
    611      if((unsigned long)oggpackB_read1(&r)!=(b[i]&mask[tbit]))
    612        report("read incorrect single bit value!\n");
    613    }else{
    614    if((unsigned long)oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
    615      report("read incorrect value!\n");
    616    }
    617  }
    618  if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
    619 }
    620 
    621 void copytest(int prefill, int copy){
    622  oggpack_buffer source_write;
    623  oggpack_buffer dest_write;
    624  oggpack_buffer source_read;
    625  oggpack_buffer dest_read;
    626  unsigned char *source;
    627  unsigned char *dest;
    628  long source_bytes,dest_bytes;
    629  int i;
    630 
    631  oggpack_writeinit(&source_write);
    632  oggpack_writeinit(&dest_write);
    633 
    634  for(i=0;i<(prefill+copy+7)/8;i++)
    635    oggpack_write(&source_write,(i^0x5a)&0xff,8);
    636  source=oggpack_get_buffer(&source_write);
    637  source_bytes=oggpack_bytes(&source_write);
    638 
    639  /* prefill */
    640  oggpack_writecopy(&dest_write,source,prefill);
    641 
    642  /* check buffers; verify end byte masking */
    643  dest=oggpack_get_buffer(&dest_write);
    644  dest_bytes=oggpack_bytes(&dest_write);
    645  if(dest_bytes!=(prefill+7)/8){
    646    fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
    647    exit(1);
    648  }
    649  oggpack_readinit(&source_read,source,source_bytes);
    650  oggpack_readinit(&dest_read,dest,dest_bytes);
    651 
    652  for(i=0;i<prefill;i+=8){
    653    int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
    654    int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
    655    if(s!=d){
    656      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
    657      exit(1);
    658    }
    659  }
    660  if(prefill<dest_bytes){
    661    if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){
    662      fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
    663      exit(1);
    664    }
    665  }
    666 
    667  /* second copy */
    668  oggpack_writecopy(&dest_write,source,copy);
    669 
    670  /* check buffers; verify end byte masking */
    671  dest=oggpack_get_buffer(&dest_write);
    672  dest_bytes=oggpack_bytes(&dest_write);
    673  if(dest_bytes!=(copy+prefill+7)/8){
    674    fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
    675    exit(1);
    676  }
    677  oggpack_readinit(&source_read,source,source_bytes);
    678  oggpack_readinit(&dest_read,dest,dest_bytes);
    679 
    680  for(i=0;i<prefill;i+=8){
    681    int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
    682    int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
    683    if(s!=d){
    684      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
    685      exit(1);
    686    }
    687  }
    688 
    689  oggpack_readinit(&source_read,source,source_bytes);
    690  for(i=0;i<copy;i+=8){
    691    int s=oggpack_read(&source_read,copy-i<8?copy-i:8);
    692    int d=oggpack_read(&dest_read,copy-i<8?copy-i:8);
    693    if(s!=d){
    694      fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
    695      exit(1);
    696    }
    697  }
    698 
    699  if(copy+prefill<dest_bytes){
    700    if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){
    701      fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
    702      exit(1);
    703    }
    704  }
    705 
    706  oggpack_writeclear(&source_write);
    707  oggpack_writeclear(&dest_write);
    708 
    709 
    710 }
    711 
    712 void copytestB(int prefill, int copy){
    713  oggpack_buffer source_write;
    714  oggpack_buffer dest_write;
    715  oggpack_buffer source_read;
    716  oggpack_buffer dest_read;
    717  unsigned char *source;
    718  unsigned char *dest;
    719  long source_bytes,dest_bytes;
    720  int i;
    721 
    722  oggpackB_writeinit(&source_write);
    723  oggpackB_writeinit(&dest_write);
    724 
    725  for(i=0;i<(prefill+copy+7)/8;i++)
    726    oggpackB_write(&source_write,(i^0x5a)&0xff,8);
    727  source=oggpackB_get_buffer(&source_write);
    728  source_bytes=oggpackB_bytes(&source_write);
    729 
    730  /* prefill */
    731  oggpackB_writecopy(&dest_write,source,prefill);
    732 
    733  /* check buffers; verify end byte masking */
    734  dest=oggpackB_get_buffer(&dest_write);
    735  dest_bytes=oggpackB_bytes(&dest_write);
    736  if(dest_bytes!=(prefill+7)/8){
    737    fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
    738    exit(1);
    739  }
    740  oggpackB_readinit(&source_read,source,source_bytes);
    741  oggpackB_readinit(&dest_read,dest,dest_bytes);
    742 
    743  for(i=0;i<prefill;i+=8){
    744    int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
    745    int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
    746    if(s!=d){
    747      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
    748      exit(1);
    749    }
    750  }
    751  if(prefill<dest_bytes){
    752    if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){
    753      fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
    754      exit(1);
    755    }
    756  }
    757 
    758  /* second copy */
    759  oggpackB_writecopy(&dest_write,source,copy);
    760 
    761  /* check buffers; verify end byte masking */
    762  dest=oggpackB_get_buffer(&dest_write);
    763  dest_bytes=oggpackB_bytes(&dest_write);
    764  if(dest_bytes!=(copy+prefill+7)/8){
    765    fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
    766    exit(1);
    767  }
    768  oggpackB_readinit(&source_read,source,source_bytes);
    769  oggpackB_readinit(&dest_read,dest,dest_bytes);
    770 
    771  for(i=0;i<prefill;i+=8){
    772    int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
    773    int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
    774    if(s!=d){
    775      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
    776      exit(1);
    777    }
    778  }
    779 
    780  oggpackB_readinit(&source_read,source,source_bytes);
    781  for(i=0;i<copy;i+=8){
    782    int s=oggpackB_read(&source_read,copy-i<8?copy-i:8);
    783    int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8);
    784    if(s!=d){
    785      fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
    786      exit(1);
    787    }
    788  }
    789 
    790  if(copy+prefill<dest_bytes){
    791    if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){
    792      fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
    793      exit(1);
    794    }
    795  }
    796 
    797  oggpackB_writeclear(&source_write);
    798  oggpackB_writeclear(&dest_write);
    799 
    800 }
    801 
    802 int main(void){
    803  unsigned char *buffer;
    804  long bytes,i,j;
    805  static unsigned long testbuffer1[]=
    806    {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
    807       567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
    808  int test1size=43;
    809 
    810  static unsigned long testbuffer2[]=
    811    {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
    812       1233432,534,5,346435231,14436467,7869299,76326614,167548585,
    813       85525151,0,12321,1,349528352};
    814  int test2size=21;
    815 
    816  static unsigned long testbuffer3[]=
    817    {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,
    818       0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
    819  int test3size=56;
    820 
    821  static unsigned long large[]=
    822    {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
    823       1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
    824       85525151,0,12321,1,2146528352};
    825 
    826  int onesize=33;
    827  static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
    828                    34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
    829                    223,4};
    830  static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
    831                       8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
    832                       245,251,128};
    833 
    834  int twosize=6;
    835  static int two[6]={61,255,255,251,231,29};
    836  static int twoB[6]={247,63,255,253,249,120};
    837 
    838  int threesize=54;
    839  static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
    840                      142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
    841                      58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
    842                      100,52,4,14,18,86,77,1};
    843  static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
    844                         130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
    845                         233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
    846                         200,20,254,4,58,106,176,144,0};
    847 
    848  int foursize=38;
    849  static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
    850                     132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
    851                     28,2,133,0,1};
    852  static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
    853                        1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
    854                        129,10,4,32};
    855 
    856  int fivesize=45;
    857  static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
    858                     241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
    859                     84,75,159,2,1,0,132,192,8,0,0,18,22};
    860  static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
    861                        124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
    862                        172,150,169,129,79,128,0,6,4,32,0,27,9,0};
    863 
    864  int sixsize=7;
    865  static int six[7]={17,177,170,242,169,19,148};
    866  static int sixB[7]={136,141,85,79,149,200,41};
    867 
    868  /* Test read/write together */
    869  /* Later we test against pregenerated bitstreams */
    870  oggpack_writeinit(&o);
    871 
    872  fprintf(stderr,"\nSmall preclipped packing (LSb): ");
    873  cliptest(testbuffer1,test1size,0,one,onesize);
    874  fprintf(stderr,"ok.");
    875 
    876  fprintf(stderr,"\nNull bit call (LSb): ");
    877  cliptest(testbuffer3,test3size,0,two,twosize);
    878  fprintf(stderr,"ok.");
    879 
    880  fprintf(stderr,"\nLarge preclipped packing (LSb): ");
    881  cliptest(testbuffer2,test2size,0,three,threesize);
    882  fprintf(stderr,"ok.");
    883 
    884  fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
    885  oggpack_reset(&o);
    886  for(i=0;i<test2size;i++)
    887    oggpack_write(&o,large[i],32);
    888  buffer=oggpack_get_buffer(&o);
    889  bytes=oggpack_bytes(&o);
    890  oggpack_readinit(&r,buffer,bytes);
    891  for(i=0;i<test2size;i++){
    892    if(oggpack_look(&r,32)==-1)report("out of data. failed!");
    893    if((unsigned long)oggpack_look(&r,32)!=large[i]){
    894      fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpack_look(&r,32),large[i],
    895              oggpack_look(&r,32),large[i]);
    896      report("read incorrect value!\n");
    897    }
    898    oggpack_adv(&r,32);
    899  }
    900  if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
    901  fprintf(stderr,"ok.");
    902 
    903  fprintf(stderr,"\nSmall unclipped packing (LSb): ");
    904  cliptest(testbuffer1,test1size,7,four,foursize);
    905  fprintf(stderr,"ok.");
    906 
    907  fprintf(stderr,"\nLarge unclipped packing (LSb): ");
    908  cliptest(testbuffer2,test2size,17,five,fivesize);
    909  fprintf(stderr,"ok.");
    910 
    911  fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
    912  cliptest(testbuffer3,test3size,1,six,sixsize);
    913  fprintf(stderr,"ok.");
    914 
    915  fprintf(stderr,"\nTesting read past end (LSb): ");
    916  oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
    917  for(i=0;i<64;i++){
    918    if(oggpack_read(&r,1)!=0){
    919      fprintf(stderr,"failed; got -1 prematurely.\n");
    920      exit(1);
    921    }
    922  }
    923  if(oggpack_look(&r,1)!=-1 ||
    924     oggpack_read(&r,1)!=-1){
    925      fprintf(stderr,"failed; read past end without -1.\n");
    926      exit(1);
    927  }
    928  oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
    929  if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
    930      fprintf(stderr,"failed 2; got -1 prematurely.\n");
    931      exit(1);
    932  }
    933 
    934  if(oggpack_look(&r,18)!=0 ||
    935     oggpack_look(&r,18)!=0){
    936    fprintf(stderr,"failed 3; got -1 prematurely.\n");
    937      exit(1);
    938  }
    939  if(oggpack_look(&r,19)!=-1 ||
    940     oggpack_look(&r,19)!=-1){
    941    fprintf(stderr,"failed; read past end without -1.\n");
    942      exit(1);
    943  }
    944  if(oggpack_look(&r,32)!=-1 ||
    945     oggpack_look(&r,32)!=-1){
    946    fprintf(stderr,"failed; read past end without -1.\n");
    947      exit(1);
    948  }
    949  oggpack_writeclear(&o);
    950  fprintf(stderr,"ok.");
    951 
    952  /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
    953 
    954  fprintf(stderr,"\nTesting aligned writecopies (LSb): ");
    955  for(i=0;i<71;i++)
    956    for(j=0;j<5;j++)
    957      copytest(j*8,i);
    958  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
    959    for(j=0;j<5;j++)
    960      copytest(j*8,i);
    961  fprintf(stderr,"ok.      ");
    962 
    963  fprintf(stderr,"\nTesting unaligned writecopies (LSb): ");
    964  for(i=0;i<71;i++)
    965    for(j=1;j<40;j++)
    966      if(j&0x7)
    967        copytest(j,i);
    968  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
    969    for(j=1;j<40;j++)
    970      if(j&0x7)
    971        copytest(j,i);
    972  
    973  fprintf(stderr,"ok.      \n");
    974 
    975 
    976  /********** lazy, cut-n-paste retest with MSb packing ***********/
    977 
    978  /* Test read/write together */
    979  /* Later we test against pregenerated bitstreams */
    980  oggpackB_writeinit(&o);
    981 
    982  fprintf(stderr,"\nSmall preclipped packing (MSb): ");
    983  cliptestB(testbuffer1,test1size,0,oneB,onesize);
    984  fprintf(stderr,"ok.");
    985 
    986  fprintf(stderr,"\nNull bit call (MSb): ");
    987  cliptestB(testbuffer3,test3size,0,twoB,twosize);
    988  fprintf(stderr,"ok.");
    989 
    990  fprintf(stderr,"\nLarge preclipped packing (MSb): ");
    991  cliptestB(testbuffer2,test2size,0,threeB,threesize);
    992  fprintf(stderr,"ok.");
    993 
    994  fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
    995  oggpackB_reset(&o);
    996  for(i=0;i<test2size;i++)
    997    oggpackB_write(&o,large[i],32);
    998  buffer=oggpackB_get_buffer(&o);
    999  bytes=oggpackB_bytes(&o);
   1000  oggpackB_readinit(&r,buffer,bytes);
   1001  for(i=0;i<test2size;i++){
   1002    if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
   1003    if((unsigned long)oggpackB_look(&r,32)!=large[i]){
   1004      fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpackB_look(&r,32),large[i],
   1005              oggpackB_look(&r,32),large[i]);
   1006      report("read incorrect value!\n");
   1007    }
   1008    oggpackB_adv(&r,32);
   1009  }
   1010  if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
   1011  fprintf(stderr,"ok.");
   1012 
   1013  fprintf(stderr,"\nSmall unclipped packing (MSb): ");
   1014  cliptestB(testbuffer1,test1size,7,fourB,foursize);
   1015  fprintf(stderr,"ok.");
   1016 
   1017  fprintf(stderr,"\nLarge unclipped packing (MSb): ");
   1018  cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
   1019  fprintf(stderr,"ok.");
   1020 
   1021  fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
   1022  cliptestB(testbuffer3,test3size,1,sixB,sixsize);
   1023  fprintf(stderr,"ok.");
   1024 
   1025  fprintf(stderr,"\nTesting read past end (MSb): ");
   1026  oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
   1027  for(i=0;i<64;i++){
   1028    if(oggpackB_read(&r,1)!=0){
   1029      fprintf(stderr,"failed; got -1 prematurely.\n");
   1030      exit(1);
   1031    }
   1032  }
   1033  if(oggpackB_look(&r,1)!=-1 ||
   1034     oggpackB_read(&r,1)!=-1){
   1035      fprintf(stderr,"failed; read past end without -1.\n");
   1036      exit(1);
   1037  }
   1038  oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
   1039  if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
   1040      fprintf(stderr,"failed 2; got -1 prematurely.\n");
   1041      exit(1);
   1042  }
   1043 
   1044  if(oggpackB_look(&r,18)!=0 ||
   1045     oggpackB_look(&r,18)!=0){
   1046    fprintf(stderr,"failed 3; got -1 prematurely.\n");
   1047      exit(1);
   1048  }
   1049  if(oggpackB_look(&r,19)!=-1 ||
   1050     oggpackB_look(&r,19)!=-1){
   1051    fprintf(stderr,"failed; read past end without -1.\n");
   1052      exit(1);
   1053  }
   1054  if(oggpackB_look(&r,32)!=-1 ||
   1055     oggpackB_look(&r,32)!=-1){
   1056    fprintf(stderr,"failed; read past end without -1.\n");
   1057      exit(1);
   1058  }
   1059  fprintf(stderr,"ok.");
   1060  oggpackB_writeclear(&o);
   1061 
   1062  /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
   1063 
   1064  fprintf(stderr,"\nTesting aligned writecopies (MSb): ");
   1065  for(i=0;i<71;i++)
   1066    for(j=0;j<5;j++)
   1067      copytestB(j*8,i);
   1068  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
   1069    for(j=0;j<5;j++)
   1070      copytestB(j*8,i);
   1071  fprintf(stderr,"ok.      ");
   1072 
   1073  fprintf(stderr,"\nTesting unaligned writecopies (MSb): ");
   1074  for(i=0;i<71;i++)
   1075    for(j=1;j<40;j++)
   1076      if(j&0x7)
   1077        copytestB(j,i);
   1078  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
   1079    for(j=1;j<40;j++)
   1080      if(j&0x7)
   1081        copytestB(j,i);
   1082  
   1083  fprintf(stderr,"ok.      \n\n");
   1084 
   1085  return(0);
   1086 }
   1087 #endif  /* _V_SELFTEST */
   1088 
   1089 #undef BUFFER_INCREMENT