Home | History | Annotate | Download | only in Tremolo
      1 /************************************************************************
      2  * Copyright (C) 2002-2009, Xiph.org Foundation
      3  * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  *     * Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  *     * Redistributions in binary form must reproduce the above
     13  * copyright notice, this list of conditions and the following disclaimer
     14  * in the documentation and/or other materials provided with the
     15  * distribution.
     16  *     * Neither the names of the Xiph.org Foundation nor Pinknoise
     17  * Productions Ltd nor the names of its contributors may be used to
     18  * endorse or promote products derived from this software without
     19  * specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  ************************************************************************
     33 
     34   function: packing variable sized words into an octet stream
     35 
     36  ************************************************************************/
     37 
     38 /* We're 'LSb' endian; if we write a word but read individual bits,
     39    then we'll read the lsb first */
     40 
     41 #include <string.h>
     42 #include <stdlib.h>
     43 #include "misc.h"
     44 #include "ogg.h"
     45 
     46 #include <stdio.h>
     47 
     48 
     49 #if !defined(ARM_LITTLE_ENDIAN) || defined(_V_BIT_TEST)
     50 static unsigned long mask[]=
     51 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
     52  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
     53  0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
     54  0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
     55  0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
     56  0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
     57  0x3fffffff,0x7fffffff,0xffffffff };
     58 #endif
     59 
     60 #ifdef ARM_LITTLE_ENDIAN
     61 
     62 #ifdef DEBUGGING_BITWISE
     63 extern void oggpack_readinitARM(oggpack_buffer *b,ogg_reference *r);
     64 
     65 void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
     66     oggpack_readinitARM(b,r);
     67     //fprintf(stderr, "Init: buffer=(%d,%x,%d,%d) %08x%08x\n",
     68     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
     69     //        b->ptr[1], b->ptr[0]);
     70     //fflush(stderr);
     71 }
     72 
     73 extern long oggpack_lookARM(oggpack_buffer *b,int bits);
     74 
     75 long oggpack_look(oggpack_buffer *b,int bits){
     76     long l;
     77 
     78     //fprintf(stderr, "PreLook: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
     79     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
     80     //        b->ptr[1], b->ptr[0], bits);
     81     //fflush(stderr);
     82     l = oggpack_lookARM(b,bits);
     83     //fprintf(stderr, "Look: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
     84     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
     85     //        b->ptr[1], b->ptr[0], bits, l);
     86     //fflush(stderr);
     87 
     88     return l;
     89 }
     90 
     91 extern void oggpack_advARM(oggpack_buffer *b,int bits);
     92 
     93 void oggpack_adv(oggpack_buffer *b,int bits){
     94     //fprintf(stderr, "Adv before: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
     95     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
     96     //        b->ptr[1], b->ptr[0],bits);
     97     //fflush(stderr);
     98     oggpack_advARM(b,bits);
     99     //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %08x%08x\n",
    100     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
    101     //        b->ptr[1], b->ptr[0]);
    102     //fflush(stderr);
    103 }
    104 
    105 extern long oggpack_readARM(oggpack_buffer *b,int bits);
    106 
    107 /* bits <= 32 */
    108 long oggpack_read(oggpack_buffer *b,int bits){
    109     long l;
    110 
    111     //fprintf(stderr, "PreRead: buffer=(%d,%x,%d,%d) %08x%08x (%d bits)\n",
    112     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
    113     //        b->ptr[1], b->ptr[0], bits);
    114     //fflush(stderr);
    115     l = oggpack_readARM(b,bits);
    116     //fprintf(stderr, "Read: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
    117     //       b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
    118     //       b->ptr[1], b->ptr[0], bits, l);
    119     //fflush(stderr);
    120 
    121     return l;
    122 }
    123 #endif
    124 
    125 int oggpack_eop(oggpack_buffer *b){
    126   int ret;
    127   if(b->bitsLeftInSegment<0)ret= -1;
    128   else ret = 0;
    129   //fprintf(stderr, "EOP %d\n", ret);
    130   //fflush(stderr);
    131   return ret;
    132 }
    133 
    134 long oggpack_bytes(oggpack_buffer *b){
    135   long ret;
    136   if(b->bitsLeftInSegment<0) ret = b->count+b->head->length;
    137   else ret = b->count + b->head->length - (b->bitsLeftInSegment)/8;
    138   //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
    139   //        b->count, b->head->length, b->bitsLeftInSegment);
    140   //fflush(stderr);
    141   return ret;
    142 }
    143 
    144 long oggpack_bits(oggpack_buffer *b){
    145   long ret;
    146   if(b->bitsLeftInSegment<0) ret=(b->count+b->head->length)*8;
    147   else ret = b->count*8 + b->head->length*8 - b->bitsLeftInSegment;
    148   //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
    149   //        b->count, b->head->length, b->bitsLeftInSegment);
    150   //fflush(stderr);
    151   return ret;
    152 }
    153 
    154 #else
    155 
    156 /* spans forward, skipping as many bytes as headend is negative; if
    157    headend is zero, simply finds next byte.  If we're up to the end
    158    of the buffer, leaves headend at zero.  If we've read past the end,
    159    halt the decode process. */
    160 
    161 static void _span(oggpack_buffer *b){
    162   while(b->headend-(b->headbit>>3)<1){
    163     b->headend-=b->headbit>>3;
    164     b->headbit&=0x7;
    165 
    166     if(b->head && b->head->next){
    167       b->count+=b->head->length;
    168       b->head=b->head->next;
    169 
    170       if(b->headend+b->head->length>0)
    171 	b->headptr=b->head->buffer->data+b->head->begin-b->headend;
    172 
    173       b->headend+=b->head->length;
    174     }else{
    175       /* we've either met the end of decode, or gone past it. halt
    176 	 only if we're past */
    177       if(b->headend*8<b->headbit)
    178 	/* read has fallen off the end */
    179 	b->headend=-1;
    180         break;
    181     }
    182   }
    183 }
    184 
    185 void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
    186   memset(b,0,sizeof(*b));
    187 
    188   b->tail=b->head=r;
    189   b->count=0;
    190   if (b->head && r->length) {
    191     b->headptr=b->head->buffer->data+b->head->begin;
    192     b->headend=b->head->length;
    193   } else {
    194     b->headptr=0;
    195     b->headend=0;
    196   }
    197   _span(b);
    198 
    199   //fprintf(stderr,
    200   //        "Init: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x\n",
    201   //        b->headbit, b->headptr, b->headend, b->count,
    202   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
    203   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0]);
    204   //fflush(stderr);
    205 }
    206 
    207 #define _lookspan()   while(!end){\
    208                         head=head->next;\
    209                         if(!head) return -1;\
    210                         ptr=head->buffer->data + head->begin;\
    211                         end=head->length;\
    212                       }
    213 
    214 /* Read in bits without advancing the bitptr; bits <= 32 */
    215 long oggpack_look(oggpack_buffer *b,int bits){
    216   unsigned long m=mask[bits];
    217   unsigned long ret = 0;
    218   int BITS = bits;
    219 
    220   if (!b->headptr) return 0;
    221 
    222   bits+=b->headbit;
    223 
    224   if(bits >= b->headend<<3){
    225     int            end=b->headend;
    226     unsigned char *ptr=b->headptr;
    227     ogg_reference *head=b->head;
    228 
    229     if(end<0)return 0;
    230     if (!head || !end)return 0;
    231 
    232     if(bits){
    233       _lookspan();
    234       ret=*ptr++>>b->headbit;
    235       if(bits>8){
    236         --end;
    237         _lookspan();
    238         ret|=*ptr++<<(8-b->headbit);
    239         if(bits>16){
    240           --end;
    241           _lookspan();
    242           ret|=*ptr++<<(16-b->headbit);
    243           if(bits>24){
    244             --end;
    245             _lookspan();
    246             ret|=*ptr++<<(24-b->headbit);
    247             if(bits>32 && b->headbit){
    248               --end;
    249               _lookspan();
    250               ret|=*ptr<<(32-b->headbit);
    251             }
    252           }
    253         }
    254       }
    255     }
    256 
    257   }else{
    258 
    259     /* make this a switch jump-table */
    260     ret=b->headptr[0]>>b->headbit;
    261     if(bits>8){
    262       ret|=b->headptr[1]<<(8-b->headbit);
    263       if(bits>16){
    264         ret|=b->headptr[2]<<(16-b->headbit);
    265         if(bits>24){
    266           ret|=b->headptr[3]<<(24-b->headbit);
    267           if(bits>32 && b->headbit)
    268             ret|=b->headptr[4]<<(32-b->headbit);
    269         }
    270       }
    271     }
    272   }
    273 
    274   ret&=m;
    275   //fprintf(stderr,
    276   //        "Look: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits) return=%x\n",
    277   //        b->headbit, b->headptr, b->headend, b->count,
    278   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
    279   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
    280   //        BITS, ret);
    281   //fflush(stderr);
    282   return ret;
    283 }
    284 
    285 /* limited to 32 at a time */
    286 void oggpack_adv(oggpack_buffer *b,int bits){
    287     int BITS=bits;
    288   bits+=b->headbit;
    289   b->headbit=bits&7;
    290   b->headend-=(bits>>3);
    291   b->headptr+=(bits>>3);
    292   if(b->headend<1)_span(b);
    293   //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
    294   //        b->headbit, b->headptr, b->headend,b->count,
    295   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
    296   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
    297   //        BITS);
    298   //fflush(stderr);
    299 }
    300 
    301 int oggpack_eop(oggpack_buffer *b){
    302   int ret;
    303   if(b->headend<0)ret= -1;
    304   else ret = 0;
    305   //fprintf(stderr, "EOP %d\n", ret);
    306   //fflush(stderr);
    307   return ret;
    308 }
    309 
    310 long oggpack_bytes(oggpack_buffer *b){
    311   long ret;
    312   if(b->headend<0) ret = b->count+b->head->length;
    313   ret = b->count + b->head->length-b->headend + (b->headbit+7)/8;
    314   //fprintf(stderr, "Bytes: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bytes)\n",
    315   //        b->headbit, b->headptr, b->headend, b->count,
    316   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
    317   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
    318   //        ret);
    319   //fflush(stderr);
    320   return ret;
    321 }
    322 
    323 long oggpack_bits(oggpack_buffer *b){
    324   long ret;
    325   if(b->headend<0) ret = (b->count+b->head->length)*8;
    326   else ret = (b->count + b->head->length-b->headend)*8 + b->headbit;
    327   //fprintf(stderr, "Bits: buffer=(%x,%x,%x) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
    328   //        b->headbit, b->headptr, b->headend,
    329   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
    330   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
    331   //        ret);
    332   //fflush(stderr);
    333   return ret;
    334 }
    335 
    336 /* bits <= 32 */
    337 long oggpack_read(oggpack_buffer *b,int bits){
    338   long ret=oggpack_look(b,bits);
    339   oggpack_adv(b,bits);
    340   return(ret);
    341 }
    342 
    343 #endif
    344 
    345 /* Self test of the bitwise routines; everything else is based on
    346    them, so they damned well better be solid. */
    347 
    348 #ifdef _V_BIT_TEST
    349 #include <string.h>
    350 #include <stdlib.h>
    351 #include <stdio.h>
    352 #include "framing.c"
    353 
    354 static int ilog(unsigned long v){
    355   int ret=0;
    356   while(v){
    357     ret++;
    358     v>>=1;
    359   }
    360   return(ret);
    361 }
    362 
    363 oggpack_buffer r;
    364 oggpack_buffer o;
    365 ogg_buffer_state *bs;
    366 ogg_reference *or;
    367 #define TESTWORDS 256
    368 
    369 void report(char *in){
    370   fprintf(stderr,"%s",in);
    371   exit(1);
    372 }
    373 
    374 int getbyte(ogg_reference *or,int position){
    375   while(or && position>=or->length){
    376     position-=or->length;
    377     or=or->next;
    378     if(or==NULL){
    379       fprintf(stderr,"\n\tERROR: getbyte ran off end of buffer.\n");
    380       exit(1);
    381     }
    382   }
    383 
    384   if((position+or->begin)&1)
    385     return (or->buffer->data[(position+or->begin)>>1])&0xff;
    386   else
    387     return (or->buffer->data[(position+or->begin)>>1]>>8)&0xff;
    388 }
    389 
    390 void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
    391   long i,bitcount=0;
    392   ogg_reference *or=ogg_buffer_alloc(bs,64);
    393   for(i=0;i<compsize;i++)
    394     or->buffer->data[i]= comp[i];
    395   or->length=i;
    396 
    397   oggpack_readinit(&r,or);
    398   for(i=0;i<vals;i++){
    399     unsigned long test;
    400     int tbit=bits?bits:ilog(b[i]);
    401     if((test=oggpack_look(&r,tbit))==0xffffffff)
    402       report("out of data!\n");
    403     if(test!=(b[i]&mask[tbit])){
    404       fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
    405       report("looked at incorrect value!\n");
    406     }
    407     if((test=oggpack_read(&r,tbit))==0xffffffff){
    408       report("premature end of data when reading!\n");
    409     }
    410     if(test!=(b[i]&mask[tbit])){
    411       fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
    412       report("read incorrect value!\n");
    413     }
    414     bitcount+=tbit;
    415 
    416     if(bitcount!=oggpack_bits(&r))
    417       report("wrong number of bits while reading!\n");
    418     if((bitcount+7)/8!=oggpack_bytes(&r))
    419       report("wrong number of bytes while reading!\n");
    420 
    421   }
    422   if(oggpack_bytes(&r)!=(bitcount+7)/8){
    423       fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), (bitcount+7)/8);
    424       report("leftover bytes after read!\n");
    425   }
    426   ogg_buffer_release(or);
    427 }
    428 
    429 void _end_verify(int count){
    430   int i;
    431 
    432   /* are the proper number of bits left over? */
    433   int leftover=count*8-oggpack_bits(&o);
    434   if(leftover>7)
    435     report("\nERROR: too many bits reported left over.\n");
    436 
    437   /* does reading to exactly byte alignment *not* trip EOF? */
    438   if(oggpack_read(&o,leftover)==-1)
    439     report("\nERROR: read to but not past exact end tripped EOF.\n");
    440   if(oggpack_bits(&o)!=count*8)
    441     report("\nERROR: read to but not past exact end reported bad bitcount.\n");
    442 
    443   /* does EOF trip properly after a single additional bit? */
    444   if(oggpack_read(&o,1)!=-1)
    445     report("\nERROR: read past exact end did not trip EOF.\n");
    446   if(oggpack_bits(&o)!=count*8)
    447     report("\nERROR: read past exact end reported bad bitcount.\n");
    448 
    449   /* does EOF stay set over additional bit reads? */
    450   for(i=0;i<=32;i++){
    451     if(oggpack_read(&o,i)!=-1)
    452       report("\nERROR: EOF did not stay set on stream.\n");
    453     if(oggpack_bits(&o)!=count*8)
    454       report("\nERROR: read past exact end reported bad bitcount.\n");
    455   }
    456 }
    457 
    458 void _end_verify2(int count){
    459   int i;
    460 
    461   /* are the proper number of bits left over? */
    462   int leftover=count*8-oggpack_bits(&o);
    463   if(leftover>7)
    464     report("\nERROR: too many bits reported left over.\n");
    465 
    466   /* does reading to exactly byte alignment *not* trip EOF? */
    467   oggpack_adv(&o,leftover);
    468 #ifdef ARM_LITTLE_ENDIAN
    469     if(o.bitsLeftInSegment!=0)
    470 #else
    471   if(o.headend!=0)
    472 #endif
    473     report("\nERROR: read to but not past exact end tripped EOF.\n");
    474   if(oggpack_bits(&o)!=count*8)
    475     report("\nERROR: read to but not past exact end reported bad bitcount.\n");
    476 
    477   /* does EOF trip properly after a single additional bit? */
    478   oggpack_adv(&o,1);
    479 #ifdef ARM_LITTLE_ENDIAN
    480     if(o.bitsLeftInSegment>=0)
    481 #else
    482   if(o.headend>=0)
    483 #endif
    484     report("\nERROR: read past exact end did not trip EOF.\n");
    485   if(oggpack_bits(&o)!=count*8)
    486     report("\nERROR: read past exact end reported bad bitcount.\n");
    487 
    488   /* does EOF stay set over additional bit reads? */
    489   for(i=0;i<=32;i++){
    490     oggpack_adv(&o,i);
    491 #ifdef ARM_LITTLE_ENDIAN
    492     if(o.bitsLeftInSegment>=0)
    493 #else
    494     if(o.headend>=0)
    495 #endif
    496       report("\nERROR: EOF did not stay set on stream.\n");
    497     if(oggpack_bits(&o)!=count*8)
    498       report("\nERROR: read past exact end reported bad bitcount.\n");
    499   }
    500 }
    501 
    502 long ogg_buffer_length(ogg_reference *or){
    503   int count=0;
    504   while(or){
    505     count+=or->length;
    506     or=or->next;
    507   }
    508   return count;
    509 }
    510 
    511 ogg_reference *ogg_buffer_extend(ogg_reference *or,long bytes){
    512   if(or){
    513     while(or->next){
    514       or=or->next;
    515     }
    516     or->next=ogg_buffer_alloc(or->buffer->ptr.owner,bytes);
    517     return(or->next);
    518   }
    519   return 0;
    520 }
    521 
    522 void ogg_buffer_posttruncate(ogg_reference *or,long pos){
    523   /* walk to the point where we want to begin truncate */
    524   while(or && pos>or->length){
    525     pos-=or->length;
    526     or=or->next;
    527   }
    528   if(or){
    529     ogg_buffer_release(or->next);
    530     or->next=0;
    531     or->length=pos;
    532   }
    533 }
    534 
    535 int main(void){
    536   long i;
    537   static unsigned long testbuffer1[]=
    538     {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
    539        567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
    540   int test1size=43;
    541 
    542   static unsigned long testbuffer2[]=
    543     {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
    544        1233432,534,5,346435231,14436467,7869299,76326614,167548585,
    545        85525151,0,12321,1,349528352};
    546   int test2size=21;
    547 
    548   static unsigned long testbuffer3[]=
    549     {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,
    550        0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
    551   int test3size=56;
    552 
    553   static unsigned long large[]=
    554     {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
    555        1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
    556        85525151,0,12321,1,2146528352};
    557 
    558   int onesize=33;
    559   static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
    560                     34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
    561                     223,4};
    562 
    563   int twosize=6;
    564   static int two[6]={61,255,255,251,231,29};
    565 
    566   int threesize=54;
    567   static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
    568                       142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
    569                       58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
    570                       100,52,4,14,18,86,77,1};
    571 
    572   int foursize=38;
    573   static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
    574                      132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
    575                      28,2,133,0,1};
    576 
    577   int fivesize=45;
    578   static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
    579                      241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
    580                      84,75,159,2,1,0,132,192,8,0,0,18,22};
    581 
    582   int sixsize=7;
    583   static int six[7]={17,177,170,242,169,19,148};
    584 
    585   /* Test read/write together */
    586   /* Later we test against pregenerated bitstreams */
    587   bs=ogg_buffer_create();
    588 
    589   fprintf(stderr,"\nSmall preclipped packing (LSb): ");
    590   cliptest(testbuffer1,test1size,0,one,onesize);
    591   fprintf(stderr,"ok.");
    592 
    593   fprintf(stderr,"\nNull bit call (LSb): ");
    594   cliptest(testbuffer3,test3size,0,two,twosize);
    595   fprintf(stderr,"ok.");
    596 
    597   fprintf(stderr,"\nLarge preclipped packing (LSb): ");
    598   cliptest(testbuffer2,test2size,0,three,threesize);
    599   fprintf(stderr,"ok.");
    600 
    601   fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
    602 
    603   or=ogg_buffer_alloc(bs,128);
    604   for(i=0;i<test2size;i++){
    605     or->buffer->data[i*4]  = large[i]&0xff;
    606     or->buffer->data[i*4+1]  = (large[i]>>8)&0xff;
    607     or->buffer->data[i*4+2]  = (large[i]>>16)&0xff;
    608     or->buffer->data[i*4+3]  = (large[i]>>24)&0xff;
    609   }
    610   or->length=test2size*4;
    611   oggpack_readinit(&r,or);
    612   for(i=0;i<test2size;i++){
    613     unsigned long test;
    614     if((test=oggpack_look(&r,32))==0xffffffffUL)report("out of data. failed!");
    615     if(test!=large[i]){
    616       fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
    617               test,large[i]);
    618       report("read incorrect value!\n");
    619     }
    620     oggpack_adv(&r,32);
    621   }
    622   ogg_buffer_release(or);
    623   if(oggpack_bytes(&r)!=test2size*4){
    624     fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), test2size*4);
    625     report("leftover bytes after read!\n");
    626   }
    627   fprintf(stderr,"ok.");
    628 
    629   fprintf(stderr,"\nSmall unclipped packing (LSb): ");
    630   cliptest(testbuffer1,test1size,7,four,foursize);
    631   fprintf(stderr,"ok.");
    632 
    633   fprintf(stderr,"\nLarge unclipped packing (LSb): ");
    634   cliptest(testbuffer2,test2size,17,five,fivesize);
    635   fprintf(stderr,"ok.");
    636 
    637   fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
    638   cliptest(testbuffer3,test3size,1,six,sixsize);
    639   fprintf(stderr,"ok.");
    640 
    641   fprintf(stderr,"\nTesting read past end (LSb): ");
    642   {
    643     unsigned char dda[]={0,0,0,0};
    644     ogg_buffer lob={dda,8,0,{0}};
    645     ogg_reference lor={&lob,0,8,0};
    646 
    647     oggpack_readinit(&r,&lor);
    648     for(i=0;i<64;i++){
    649       if(oggpack_read(&r,1)<0){
    650         fprintf(stderr,"failed; got -1 prematurely.\n");
    651         exit(1);
    652       }
    653     }
    654     if(oggpack_look(&r,1)!=-1 ||
    655        oggpack_read(&r,1)!=-1){
    656       fprintf(stderr,"failed; read past end without -1.\n");
    657       exit(1);
    658     }
    659   }
    660   {
    661     unsigned char dda[]={0,0,0,0};
    662     ogg_buffer lob={dda,8,0,{0}};
    663     ogg_reference lor={&lob,0,8,0};
    664     unsigned long test;
    665 
    666     oggpack_readinit(&r,&lor);
    667     if((test=oggpack_read(&r,30))==0xffffffffUL ||
    668        (test=oggpack_read(&r,16))==0xffffffffUL){
    669       fprintf(stderr,"failed 2; got -1 prematurely.\n");
    670       exit(1);
    671     }
    672 
    673     if((test=oggpack_look(&r,18))==0xffffffffUL){
    674       fprintf(stderr,"failed 3; got -1 prematurely.\n");
    675       exit(1);
    676     }
    677     if((test=oggpack_look(&r,19))!=0xffffffffUL){
    678       fprintf(stderr,"failed; read past end without -1.\n");
    679       exit(1);
    680     }
    681     if((test=oggpack_look(&r,32))!=0xffffffffUL){
    682       fprintf(stderr,"failed; read past end without -1.\n");
    683       exit(1);
    684     }
    685   }
    686   fprintf(stderr,"ok.\n");
    687 
    688   /* now the scary shit: randomized testing */
    689 
    690   for(i=0;i<10000;i++){
    691     long j,count=0,count2=0,bitcount=0;
    692     unsigned long values[TESTWORDS];
    693     int len[TESTWORDS];
    694     unsigned char flat[4*TESTWORDS]; /* max possible needed size */
    695 
    696     memset(flat,0,sizeof(flat));
    697     fprintf(stderr,"\rRandomized testing (LSb)... (%ld)   ",10000-i);
    698 
    699     /* generate a list of words and lengths */
    700     /* write the required number of bits out to packbuffer */
    701     {
    702       long word=0;
    703       long bit=0;
    704       int k;
    705 
    706       for(j=0;j<TESTWORDS;j++){
    707 	values[j]=rand();
    708 	len[j]=(rand()%33);
    709 
    710 	for(k=0;k<len[j];k++){
    711 	  flat[word] |= ((values[j]>>k)&0x1)<<bit;
    712 	  bit++;
    713 	  bitcount++;
    714 	  if(bit>7){
    715 	    bit=0;
    716 	    word++;
    717 	  }
    718 	}
    719       }
    720     }
    721     count2=(bitcount+7)>>3;
    722 
    723     /* construct random-length buffer chain from flat vector; random
    724        byte starting offset within the length of the vector */
    725     {
    726       ogg_reference *or=NULL,*orl=NULL;
    727       long pos=0;
    728 
    729       /* build buffer chain */
    730       while(count2){
    731         int ilen=(rand()%32),k;
    732         int ibegin=(rand()%32);
    733 
    734 
    735         if(ilen>count2)ilen=count2;
    736 
    737         if(or)
    738           orl=ogg_buffer_extend(orl,64);
    739         else
    740           or=orl=ogg_buffer_alloc(bs,64);
    741 
    742         orl->length=ilen;
    743         orl->begin=ibegin;
    744 
    745 	for(k=0;k<ilen;k++)
    746 	  orl->buffer->data[ibegin++]= flat[pos++];
    747 
    748         count2-=ilen;
    749       }
    750 
    751       if(ogg_buffer_length(or)!=(bitcount+7)/8){
    752         fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
    753         exit(1);
    754       }
    755 
    756 
    757       {
    758         int begin=0; //=(rand()%TESTWORDS);
    759         int ilen=(rand()%(TESTWORDS-begin));
    760         int bitoffset,bitcount=0;
    761         unsigned long temp;
    762 
    763         for(j=0;j<begin;j++)
    764           bitcount+=len[j];
    765         or=ogg_buffer_pretruncate(or,bitcount/8);
    766         bitoffset=bitcount%=8;
    767         for(;j<begin+ilen;j++)
    768           bitcount+=len[j];
    769         ogg_buffer_posttruncate(or,((bitcount+7)/8));
    770 
    771         if((count=ogg_buffer_length(or))!=(bitcount+7)/8){
    772           fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
    773           exit(1);
    774         }
    775 
    776         oggpack_readinit(&o,or);
    777 
    778         /* verify bit count */
    779         if(oggpack_bits(&o)!=0){
    780           fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
    781           exit(1);
    782         }
    783         if(oggpack_bytes(&o)!=0){
    784           fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
    785           exit(1);
    786         }
    787 
    788         bitcount=bitoffset;
    789         oggpack_read(&o,bitoffset);
    790 
    791         /* read and compare to original list */
    792         for(j=begin;j<begin+ilen;j++){
    793 	  temp=oggpack_read(&o,len[j]);
    794           if(temp==0xffffffffUL){
    795             fprintf(stderr,"\nERROR: End of stream too soon! word: %ld,%d\n",
    796                     j-begin,ilen);
    797             exit(1);
    798           }
    799           if(temp!=(values[j]&mask[len[j]])){
    800             fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n"
    801 ,
    802                     values[j]&mask[len[j]],temp,j-begin,len[j]);
    803             exit(1);
    804           }
    805           bitcount+=len[j];
    806           if(oggpack_bits(&o)!=bitcount){
    807             fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
    808                     bitcount,oggpack_bits(&o));
    809             exit(1);
    810           }
    811           if(oggpack_bytes(&o)!=(bitcount+7)/8){
    812             fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
    813                     (bitcount+7)/8,oggpack_bytes(&o));
    814             exit(1);
    815           }
    816 
    817         }
    818         _end_verify(count);
    819 
    820         /* look/adv version */
    821         oggpack_readinit(&o,or);
    822         bitcount=bitoffset;
    823         oggpack_adv(&o,bitoffset);
    824 
    825         /* read and compare to original list */
    826         for(j=begin;j<begin+ilen;j++){
    827 	  temp=oggpack_look(&o,len[j]);
    828 
    829           if(temp==0xffffffffUL){
    830             fprintf(stderr,"\nERROR: End of stream too soon! word: %ld\n",
    831                     j-begin);
    832             exit(1);
    833           }
    834           if(temp!=(values[j]&mask[len[j]])){
    835             fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n"
    836 ,
    837                     values[j]&mask[len[j]],temp,j-begin,len[j]);
    838             exit(1);
    839           }
    840 	  oggpack_adv(&o,len[j]);
    841           bitcount+=len[j];
    842           if(oggpack_bits(&o)!=bitcount){
    843             fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
    844                     bitcount,oggpack_bits(&o));
    845             exit(1);
    846           }
    847           if(oggpack_bytes(&o)!=(bitcount+7)/8){
    848             fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
    849                     (bitcount+7)/8,oggpack_bytes(&o));
    850             exit(1);
    851           }
    852 
    853         }
    854         _end_verify2(count);
    855 
    856       }
    857       ogg_buffer_release(or);
    858     }
    859   }
    860   fprintf(stderr,"\rRandomized testing (LSb)... ok.   \n");
    861 
    862   return(0);
    863 }
    864 
    865 #ifdef _WIN32_WCE
    866 int WinMain(void){
    867     return main();
    868 }
    869 #endif
    870 
    871 #endif
    872