--- a/media/libogg/src/ogg_bitwise.c
+++ b/media/libogg/src/ogg_bitwise.c
@@ -1,22 +1,22 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: packing variable sized words into an octet stream
- last mod: $Id: bitwise.c 18051 2011-08-04 17:56:39Z giles $
+ last mod: $Id: bitwise.c 19149 2014-05-27 16:26:23Z giles $
********************************************************************/
/* We're 'LSb' endian; if we write a word but read individual bits,
then we'll read the lsb first */
#include <string.h>
#include <stdlib.h>
@@ -182,42 +182,46 @@ static void oggpack_writecopy_helper(ogg
long bits,
void (*w)(oggpack_buffer *,
unsigned long,
int),
int msb){
unsigned char *ptr=(unsigned char *)source;
long bytes=bits/8;
+ long pbytes=(b->endbit+bits)/8;
bits-=bytes*8;
+ /* expand storage up-front */
+ if(b->endbyte+pbytes>=b->storage){
+ void *ret;
+ if(!b->ptr) goto err;
+ if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err;
+ b->storage=b->endbyte+pbytes+BUFFER_INCREMENT;
+ ret=_ogg_realloc(b->buffer,b->storage);
+ if(!ret) goto err;
+ b->buffer=ret;
+ b->ptr=b->buffer+b->endbyte;
+ }
+
+ /* copy whole octets */
if(b->endbit){
int i;
/* unaligned copy. Do it the hard way. */
for(i=0;i<bytes;i++)
w(b,(unsigned long)(ptr[i]),8);
}else{
/* aligned block copy */
- if(b->endbyte+bytes+1>=b->storage){
- void *ret;
- if(!b->ptr) goto err;
- if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err;
- b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
- ret=_ogg_realloc(b->buffer,b->storage);
- if(!ret) goto err;
- b->buffer=ret;
- b->ptr=b->buffer+b->endbyte;
- }
-
memmove(b->ptr,source,bytes);
b->ptr+=bytes;
b->endbyte+=bytes;
*b->ptr=0;
+ }
- }
+ /* copy trailing bits */
if(bits){
if(msb)
w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
else
w(b,(unsigned long)(ptr[bytes]),bits);
}
return;
err:
@@ -608,19 +612,200 @@ void cliptestB(unsigned long *b,int vals
}else{
if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
report("read incorrect value!\n");
}
}
if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
}
+void copytest(int prefill, int copy){
+ oggpack_buffer source_write;
+ oggpack_buffer dest_write;
+ oggpack_buffer source_read;
+ oggpack_buffer dest_read;
+ unsigned char *source;
+ unsigned char *dest;
+ long source_bytes,dest_bytes;
+ int i;
+
+ oggpack_writeinit(&source_write);
+ oggpack_writeinit(&dest_write);
+
+ for(i=0;i<(prefill+copy+7)/8;i++)
+ oggpack_write(&source_write,(i^0x5a)&0xff,8);
+ source=oggpack_get_buffer(&source_write);
+ source_bytes=oggpack_bytes(&source_write);
+
+ /* prefill */
+ oggpack_writecopy(&dest_write,source,prefill);
+
+ /* check buffers; verify end byte masking */
+ dest=oggpack_get_buffer(&dest_write);
+ dest_bytes=oggpack_bytes(&dest_write);
+ if(dest_bytes!=(prefill+7)/8){
+ fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
+ exit(1);
+ }
+ oggpack_readinit(&source_read,source,source_bytes);
+ oggpack_readinit(&dest_read,dest,dest_bytes);
+
+ for(i=0;i<prefill;i+=8){
+ int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
+ int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
+ if(s!=d){
+ fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+ exit(1);
+ }
+ }
+ if(prefill<dest_bytes){
+ if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){
+ fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
+ exit(1);
+ }
+ }
+
+ /* second copy */
+ oggpack_writecopy(&dest_write,source,copy);
+
+ /* check buffers; verify end byte masking */
+ dest=oggpack_get_buffer(&dest_write);
+ dest_bytes=oggpack_bytes(&dest_write);
+ if(dest_bytes!=(copy+prefill+7)/8){
+ fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
+ exit(1);
+ }
+ oggpack_readinit(&source_read,source,source_bytes);
+ oggpack_readinit(&dest_read,dest,dest_bytes);
+
+ for(i=0;i<prefill;i+=8){
+ int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
+ int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
+ if(s!=d){
+ fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+ exit(1);
+ }
+ }
+
+ oggpack_readinit(&source_read,source,source_bytes);
+ for(i=0;i<copy;i+=8){
+ int s=oggpack_read(&source_read,copy-i<8?copy-i:8);
+ int d=oggpack_read(&dest_read,copy-i<8?copy-i:8);
+ if(s!=d){
+ fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
+ exit(1);
+ }
+ }
+
+ if(copy+prefill<dest_bytes){
+ if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){
+ fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
+ exit(1);
+ }
+ }
+
+ oggpack_writeclear(&source_write);
+ oggpack_writeclear(&dest_write);
+
+
+}
+
+void copytestB(int prefill, int copy){
+ oggpack_buffer source_write;
+ oggpack_buffer dest_write;
+ oggpack_buffer source_read;
+ oggpack_buffer dest_read;
+ unsigned char *source;
+ unsigned char *dest;
+ long source_bytes,dest_bytes;
+ int i;
+
+ oggpackB_writeinit(&source_write);
+ oggpackB_writeinit(&dest_write);
+
+ for(i=0;i<(prefill+copy+7)/8;i++)
+ oggpackB_write(&source_write,(i^0x5a)&0xff,8);
+ source=oggpackB_get_buffer(&source_write);
+ source_bytes=oggpackB_bytes(&source_write);
+
+ /* prefill */
+ oggpackB_writecopy(&dest_write,source,prefill);
+
+ /* check buffers; verify end byte masking */
+ dest=oggpackB_get_buffer(&dest_write);
+ dest_bytes=oggpackB_bytes(&dest_write);
+ if(dest_bytes!=(prefill+7)/8){
+ fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
+ exit(1);
+ }
+ oggpackB_readinit(&source_read,source,source_bytes);
+ oggpackB_readinit(&dest_read,dest,dest_bytes);
+
+ for(i=0;i<prefill;i+=8){
+ int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
+ int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
+ if(s!=d){
+ fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+ exit(1);
+ }
+ }
+ if(prefill<dest_bytes){
+ if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){
+ fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
+ exit(1);
+ }
+ }
+
+ /* second copy */
+ oggpackB_writecopy(&dest_write,source,copy);
+
+ /* check buffers; verify end byte masking */
+ dest=oggpackB_get_buffer(&dest_write);
+ dest_bytes=oggpackB_bytes(&dest_write);
+ if(dest_bytes!=(copy+prefill+7)/8){
+ fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
+ exit(1);
+ }
+ oggpackB_readinit(&source_read,source,source_bytes);
+ oggpackB_readinit(&dest_read,dest,dest_bytes);
+
+ for(i=0;i<prefill;i+=8){
+ int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
+ int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
+ if(s!=d){
+ fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+ exit(1);
+ }
+ }
+
+ oggpackB_readinit(&source_read,source,source_bytes);
+ for(i=0;i<copy;i+=8){
+ int s=oggpackB_read(&source_read,copy-i<8?copy-i:8);
+ int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8);
+ if(s!=d){
+ fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
+ exit(1);
+ }
+ }
+
+ if(copy+prefill<dest_bytes){
+ if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){
+ fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
+ exit(1);
+ }
+ }
+
+ oggpackB_writeclear(&source_write);
+ oggpackB_writeclear(&dest_write);
+
+}
+
int main(void){
unsigned char *buffer;
- long bytes,i;
+ long bytes,i,j;
static unsigned long testbuffer1[]=
{18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
int test1size=43;
static unsigned long testbuffer2[]=
{216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
1233432,534,5,346435231,14436467,7869299,76326614,167548585,
@@ -756,17 +941,41 @@ int main(void){
exit(1);
}
if(oggpack_look(&r,32)!=-1 ||
oggpack_look(&r,32)!=-1){
fprintf(stderr,"failed; read past end without -1.\n");
exit(1);
}
oggpack_writeclear(&o);
- fprintf(stderr,"ok.\n");
+ fprintf(stderr,"ok.");
+
+ /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
+
+ fprintf(stderr,"\nTesting aligned writecopies (LSb): ");
+ for(i=0;i<71;i++)
+ for(j=0;j<5;j++)
+ copytest(j*8,i);
+ for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+ for(j=0;j<5;j++)
+ copytest(j*8,i);
+ fprintf(stderr,"ok. ");
+
+ fprintf(stderr,"\nTesting unaligned writecopies (LSb): ");
+ for(i=0;i<71;i++)
+ for(j=1;j<40;j++)
+ if(j&0x7)
+ copytest(j,i);
+ for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+ for(j=1;j<40;j++)
+ if(j&0x7)
+ copytest(j,i);
+
+ fprintf(stderr,"ok. \n");
+
/********** lazy, cut-n-paste retest with MSb packing ***********/
/* Test read/write together */
/* Later we test against pregenerated bitstreams */
oggpackB_writeinit(&o);
fprintf(stderr,"\nSmall preclipped packing (MSb): ");
@@ -841,17 +1050,39 @@ int main(void){
fprintf(stderr,"failed; read past end without -1.\n");
exit(1);
}
if(oggpackB_look(&r,32)!=-1 ||
oggpackB_look(&r,32)!=-1){
fprintf(stderr,"failed; read past end without -1.\n");
exit(1);
}
+ fprintf(stderr,"ok.");
oggpackB_writeclear(&o);
- fprintf(stderr,"ok.\n\n");
+
+ /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
+
+ fprintf(stderr,"\nTesting aligned writecopies (MSb): ");
+ for(i=0;i<71;i++)
+ for(j=0;j<5;j++)
+ copytestB(j*8,i);
+ for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+ for(j=0;j<5;j++)
+ copytestB(j*8,i);
+ fprintf(stderr,"ok. ");
+ fprintf(stderr,"\nTesting unaligned writecopies (MSb): ");
+ for(i=0;i<71;i++)
+ for(j=1;j<40;j++)
+ if(j&0x7)
+ copytestB(j,i);
+ for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+ for(j=1;j<40;j++)
+ if(j&0x7)
+ copytestB(j,i);
+
+ fprintf(stderr,"ok. \n\n");
return(0);
}
#endif /* _V_SELFTEST */
#undef BUFFER_INCREMENT