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