parent
af41d7bffa
commit
a04be3e44b
|
@ -5,13 +5,13 @@
|
|||
* 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 17287 2010-06-10 13:42:06Z tterribe $
|
||||
last mod: $Id: bitwise.c 19149 2014-05-27 16:26:23Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -93,11 +93,11 @@ void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
|
|||
b->ptr=b->buffer+b->endbyte;
|
||||
}
|
||||
|
||||
value&=mask[bits];
|
||||
value&=mask[bits];
|
||||
bits+=b->endbit;
|
||||
|
||||
b->ptr[0]|=value<<b->endbit;
|
||||
|
||||
b->ptr[0]|=value<<b->endbit;
|
||||
|
||||
if(bits>=8){
|
||||
b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
|
||||
if(bits>=16){
|
||||
|
@ -136,11 +136,11 @@ void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
|
|||
b->ptr=b->buffer+b->endbyte;
|
||||
}
|
||||
|
||||
value=(value&mask[bits])<<(32-bits);
|
||||
value=(value&mask[bits])<<(32-bits);
|
||||
bits+=b->endbit;
|
||||
|
||||
b->ptr[0]|=value>>(24+b->endbit);
|
||||
|
||||
b->ptr[0]|=value>>(24+b->endbit);
|
||||
|
||||
if(bits>=8){
|
||||
b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
|
||||
if(bits>=16){
|
||||
|
@ -187,37 +187,41 @@ static void oggpack_writecopy_helper(oggpack_buffer *b,
|
|||
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);
|
||||
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);
|
||||
w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
|
||||
else
|
||||
w(b,(unsigned long)(ptr[bytes]),bits);
|
||||
w(b,(unsigned long)(ptr[bytes]),bits);
|
||||
}
|
||||
return;
|
||||
err:
|
||||
|
@ -281,11 +285,11 @@ long oggpack_look(oggpack_buffer *b,int bits){
|
|||
|
||||
ret=b->ptr[0]>>b->endbit;
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(8-b->endbit);
|
||||
ret|=b->ptr[1]<<(8-b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(16-b->endbit);
|
||||
ret|=b->ptr[2]<<(16-b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(24-b->endbit);
|
||||
ret|=b->ptr[3]<<(24-b->endbit);
|
||||
if(bits>32 && b->endbit)
|
||||
ret|=b->ptr[4]<<(32-b->endbit);
|
||||
}
|
||||
|
@ -312,11 +316,11 @@ long oggpackB_look(oggpack_buffer *b,int bits){
|
|||
|
||||
ret=b->ptr[0]<<(24+b->endbit);
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(16+b->endbit);
|
||||
ret|=b->ptr[1]<<(16+b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(8+b->endbit);
|
||||
ret|=b->ptr[2]<<(8+b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(b->endbit);
|
||||
ret|=b->ptr[3]<<(b->endbit);
|
||||
if(bits>32 && b->endbit)
|
||||
ret|=b->ptr[4]>>(8-b->endbit);
|
||||
}
|
||||
|
@ -386,11 +390,11 @@ long oggpack_read(oggpack_buffer *b,int bits){
|
|||
|
||||
ret=b->ptr[0]>>b->endbit;
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(8-b->endbit);
|
||||
ret|=b->ptr[1]<<(8-b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(16-b->endbit);
|
||||
ret|=b->ptr[2]<<(16-b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(24-b->endbit);
|
||||
ret|=b->ptr[3]<<(24-b->endbit);
|
||||
if(bits>32 && b->endbit){
|
||||
ret|=b->ptr[4]<<(32-b->endbit);
|
||||
}
|
||||
|
@ -429,11 +433,11 @@ long oggpackB_read(oggpack_buffer *b,int bits){
|
|||
|
||||
ret=b->ptr[0]<<(24+b->endbit);
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(16+b->endbit);
|
||||
ret|=b->ptr[1]<<(16+b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(8+b->endbit);
|
||||
ret|=b->ptr[2]<<(8+b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(b->endbit);
|
||||
ret|=b->ptr[3]<<(b->endbit);
|
||||
if(bits>32 && b->endbit)
|
||||
ret|=b->ptr[4]>>(8-b->endbit);
|
||||
}
|
||||
|
@ -511,7 +515,7 @@ long oggpackB_bytes(oggpack_buffer *b){
|
|||
long oggpackB_bits(oggpack_buffer *b){
|
||||
return oggpack_bits(b);
|
||||
}
|
||||
|
||||
|
||||
unsigned char *oggpack_get_buffer(oggpack_buffer *b){
|
||||
return(b->buffer);
|
||||
}
|
||||
|
@ -534,7 +538,7 @@ static int ilog(unsigned int v){
|
|||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
oggpack_buffer o;
|
||||
oggpack_buffer r;
|
||||
|
||||
|
@ -581,7 +585,7 @@ void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
|
|||
void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
|
||||
long bytes,i;
|
||||
unsigned char *buffer;
|
||||
|
||||
|
||||
oggpackB_reset(&o);
|
||||
for(i=0;i<vals;i++)
|
||||
oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
|
||||
|
@ -613,9 +617,190 @@ void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
|
|||
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};
|
||||
|
@ -761,7 +946,31 @@ int main(void){
|
|||
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 ***********/
|
||||
|
||||
|
@ -846,12 +1055,34 @@ int main(void){
|
|||
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
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
function: code raw packets into framed OggSquish stream and
|
||||
decode Ogg streams back into raw packets
|
||||
last mod: $Id: framing.c 17592 2010-11-01 20:27:54Z xiphmont $
|
||||
last mod: $Id: framing.c 18758 2013-01-08 16:29:56Z tterribe $
|
||||
|
||||
note: The CRC code is directly derived from public domain code by
|
||||
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
|
||||
|
@ -21,6 +21,7 @@
|
|||
********************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
|
@ -61,7 +62,7 @@ int ogg_page_serialno(const ogg_page *og){
|
|||
(og->header[16]<<16) |
|
||||
(og->header[17]<<24));
|
||||
}
|
||||
|
||||
|
||||
long ogg_page_pageno(const ogg_page *og){
|
||||
return(og->header[18] |
|
||||
(og->header[19]<<8) |
|
||||
|
@ -76,16 +77,16 @@ long ogg_page_pageno(const ogg_page *og){
|
|||
page, it's counted */
|
||||
|
||||
/* NOTE:
|
||||
If a page consists of a packet begun on a previous page, and a new
|
||||
packet begun (but not completed) on this page, the return will be:
|
||||
ogg_page_packets(page) ==1,
|
||||
ogg_page_continued(page) !=0
|
||||
If a page consists of a packet begun on a previous page, and a new
|
||||
packet begun (but not completed) on this page, the return will be:
|
||||
ogg_page_packets(page) ==1,
|
||||
ogg_page_continued(page) !=0
|
||||
|
||||
If a page happens to be a single packet that was begun on a
|
||||
previous page, and spans to the next page (in the case of a three or
|
||||
more page packet), the return will be:
|
||||
ogg_page_packets(page) ==0,
|
||||
ogg_page_continued(page) !=0
|
||||
If a page happens to be a single packet that was begun on a
|
||||
previous page, and spans to the next page (in the case of a three or
|
||||
more page packet), the return will be:
|
||||
ogg_page_packets(page) ==0,
|
||||
ogg_page_continued(page) !=0
|
||||
*/
|
||||
|
||||
int ogg_page_packets(const ogg_page *og){
|
||||
|
@ -205,7 +206,7 @@ int ogg_stream_init(ogg_stream_state *os,int serialno){
|
|||
return(0);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* async/delayed error detection for the ogg_stream_state */
|
||||
int ogg_stream_check(ogg_stream_state *os){
|
||||
|
@ -220,10 +221,10 @@ int ogg_stream_clear(ogg_stream_state *os){
|
|||
if(os->lacing_vals)_ogg_free(os->lacing_vals);
|
||||
if(os->granule_vals)_ogg_free(os->granule_vals);
|
||||
|
||||
memset(os,0,sizeof(*os));
|
||||
memset(os,0,sizeof(*os));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
int ogg_stream_destroy(ogg_stream_state *os){
|
||||
if(os){
|
||||
|
@ -231,44 +232,56 @@ int ogg_stream_destroy(ogg_stream_state *os){
|
|||
_ogg_free(os);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Helpers for ogg_stream_encode; this keeps the structure and
|
||||
what's happening fairly clear */
|
||||
|
||||
static int _os_body_expand(ogg_stream_state *os,int needed){
|
||||
if(os->body_storage<=os->body_fill+needed){
|
||||
static int _os_body_expand(ogg_stream_state *os,long needed){
|
||||
if(os->body_storage-needed<=os->body_fill){
|
||||
long body_storage;
|
||||
void *ret;
|
||||
ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)*
|
||||
sizeof(*os->body_data));
|
||||
if(os->body_storage>LONG_MAX-needed){
|
||||
ogg_stream_clear(os);
|
||||
return -1;
|
||||
}
|
||||
body_storage=os->body_storage+needed;
|
||||
if(body_storage<LONG_MAX-1024)body_storage+=1024;
|
||||
ret=_ogg_realloc(os->body_data,body_storage*sizeof(*os->body_data));
|
||||
if(!ret){
|
||||
ogg_stream_clear(os);
|
||||
return -1;
|
||||
}
|
||||
os->body_storage+=(needed+1024);
|
||||
os->body_storage=body_storage;
|
||||
os->body_data=ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _os_lacing_expand(ogg_stream_state *os,int needed){
|
||||
if(os->lacing_storage<=os->lacing_fill+needed){
|
||||
static int _os_lacing_expand(ogg_stream_state *os,long needed){
|
||||
if(os->lacing_storage-needed<=os->lacing_fill){
|
||||
long lacing_storage;
|
||||
void *ret;
|
||||
ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)*
|
||||
sizeof(*os->lacing_vals));
|
||||
if(os->lacing_storage>LONG_MAX-needed){
|
||||
ogg_stream_clear(os);
|
||||
return -1;
|
||||
}
|
||||
lacing_storage=os->lacing_storage+needed;
|
||||
if(lacing_storage<LONG_MAX-32)lacing_storage+=32;
|
||||
ret=_ogg_realloc(os->lacing_vals,lacing_storage*sizeof(*os->lacing_vals));
|
||||
if(!ret){
|
||||
ogg_stream_clear(os);
|
||||
return -1;
|
||||
}
|
||||
os->lacing_vals=ret;
|
||||
ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)*
|
||||
ret=_ogg_realloc(os->granule_vals,lacing_storage*
|
||||
sizeof(*os->granule_vals));
|
||||
if(!ret){
|
||||
ogg_stream_clear(os);
|
||||
return -1;
|
||||
}
|
||||
os->granule_vals=ret;
|
||||
os->lacing_storage+=(needed+32);
|
||||
os->lacing_storage=lacing_storage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -287,12 +300,12 @@ void ogg_page_checksum_set(ogg_page *og){
|
|||
og->header[23]=0;
|
||||
og->header[24]=0;
|
||||
og->header[25]=0;
|
||||
|
||||
|
||||
for(i=0;i<og->header_len;i++)
|
||||
crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
|
||||
for(i=0;i<og->body_len;i++)
|
||||
crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
|
||||
|
||||
|
||||
og->header[22]=(unsigned char)(crc_reg&0xff);
|
||||
og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
|
||||
og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
|
||||
|
@ -304,26 +317,31 @@ void ogg_page_checksum_set(ogg_page *og){
|
|||
int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
|
||||
long e_o_s, ogg_int64_t granulepos){
|
||||
|
||||
int bytes = 0, lacing_vals, i;
|
||||
long bytes = 0, lacing_vals;
|
||||
int i;
|
||||
|
||||
if(ogg_stream_check(os)) return -1;
|
||||
if(!iov) return 0;
|
||||
|
||||
for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
|
||||
|
||||
for (i = 0; i < count; ++i){
|
||||
if(iov[i].iov_len>LONG_MAX) return -1;
|
||||
if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1;
|
||||
bytes += (long)iov[i].iov_len;
|
||||
}
|
||||
lacing_vals=bytes/255+1;
|
||||
|
||||
if(os->body_returned){
|
||||
/* advance packet data according to the body_returned pointer. We
|
||||
had to keep it around to return a pointer into the buffer last
|
||||
call */
|
||||
|
||||
|
||||
os->body_fill-=os->body_returned;
|
||||
if(os->body_fill)
|
||||
memmove(os->body_data,os->body_data+os->body_returned,
|
||||
os->body_fill);
|
||||
os->body_returned=0;
|
||||
}
|
||||
|
||||
|
||||
/* make sure we have the buffer storage */
|
||||
if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals))
|
||||
return -1;
|
||||
|
@ -467,33 +485,33 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int
|
|||
pageno>>=8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* zero for computation; filled in later */
|
||||
os->header[22]=0;
|
||||
os->header[23]=0;
|
||||
os->header[24]=0;
|
||||
os->header[25]=0;
|
||||
|
||||
|
||||
/* segment table */
|
||||
os->header[26]=(unsigned char)(vals&0xff);
|
||||
for(i=0;i<vals;i++)
|
||||
bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
|
||||
|
||||
|
||||
/* set pointers in the ogg_page struct */
|
||||
og->header=os->header;
|
||||
og->header_len=os->header_fill=vals+27;
|
||||
og->body=os->body_data+os->body_returned;
|
||||
og->body_len=bytes;
|
||||
|
||||
|
||||
/* advance the lacing data and set the body_returned pointer */
|
||||
|
||||
|
||||
os->lacing_fill-=vals;
|
||||
memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
|
||||
memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
|
||||
os->body_returned+=bytes;
|
||||
|
||||
|
||||
/* calculate the checksum */
|
||||
|
||||
|
||||
ogg_page_checksum_set(og);
|
||||
|
||||
/* done */
|
||||
|
@ -512,12 +530,20 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int
|
|||
since ogg_stream_flush will flush the last page in a stream even if
|
||||
it's undersized, you almost certainly want to use ogg_stream_pageout
|
||||
(and *not* ogg_stream_flush) unless you specifically need to flush
|
||||
an page regardless of size in the middle of a stream. */
|
||||
a page regardless of size in the middle of a stream. */
|
||||
|
||||
int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
|
||||
return ogg_stream_flush_i(os,og,1,4096);
|
||||
}
|
||||
|
||||
/* Like the above, but an argument is provided to adjust the nominal
|
||||
page size for applications which are smart enough to provide their
|
||||
own delay based flushing */
|
||||
|
||||
int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){
|
||||
return ogg_stream_flush_i(os,og,1,nfill);
|
||||
}
|
||||
|
||||
/* This constructs pages from buffered packet segments. The pointers
|
||||
returned are to static buffers; do not free. The returned buffers are
|
||||
good only until the next call (using the same ogg_stream_state) */
|
||||
|
@ -533,10 +559,10 @@ int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
|
|||
return(ogg_stream_flush_i(os,og,force,4096));
|
||||
}
|
||||
|
||||
/* Like the above, but an argument is provided to adjust the nominal
|
||||
/* Like the above, but an argument is provided to adjust the nominal
|
||||
page size for applications which are smart enough to provide their
|
||||
own delay based flushing */
|
||||
|
||||
|
||||
int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){
|
||||
int force=0;
|
||||
if(ogg_stream_check(os)) return 0;
|
||||
|
@ -645,7 +671,7 @@ int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
|
|||
-n) skipped n bytes
|
||||
0) page not ready; more data (no bytes skipped)
|
||||
n) page synced at current location; page length n bytes
|
||||
|
||||
|
||||
*/
|
||||
|
||||
long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
|
||||
|
@ -654,54 +680,54 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
|
|||
long bytes=oy->fill-oy->returned;
|
||||
|
||||
if(ogg_sync_check(oy))return 0;
|
||||
|
||||
|
||||
if(oy->headerbytes==0){
|
||||
int headerbytes,i;
|
||||
if(bytes<27)return(0); /* not enough for a header */
|
||||
|
||||
|
||||
/* verify capture pattern */
|
||||
if(memcmp(page,"OggS",4))goto sync_fail;
|
||||
|
||||
|
||||
headerbytes=page[26]+27;
|
||||
if(bytes<headerbytes)return(0); /* not enough for header + seg table */
|
||||
|
||||
|
||||
/* count up body length in the segment table */
|
||||
|
||||
|
||||
for(i=0;i<page[26];i++)
|
||||
oy->bodybytes+=page[27+i];
|
||||
oy->headerbytes=headerbytes;
|
||||
}
|
||||
|
||||
|
||||
if(oy->bodybytes+oy->headerbytes>bytes)return(0);
|
||||
|
||||
|
||||
/* The whole test page is buffered. Verify the checksum */
|
||||
{
|
||||
/* Grab the checksum bytes, set the header field to zero */
|
||||
char chksum[4];
|
||||
ogg_page log;
|
||||
|
||||
|
||||
memcpy(chksum,page+22,4);
|
||||
memset(page+22,0,4);
|
||||
|
||||
|
||||
/* set up a temp page struct and recompute the checksum */
|
||||
log.header=page;
|
||||
log.header_len=oy->headerbytes;
|
||||
log.body=page+oy->headerbytes;
|
||||
log.body_len=oy->bodybytes;
|
||||
ogg_page_checksum_set(&log);
|
||||
|
||||
|
||||
/* Compare */
|
||||
if(memcmp(chksum,page+22,4)){
|
||||
/* D'oh. Mismatch! Corrupt page (or miscapture and not a page
|
||||
at all) */
|
||||
/* replace the computed checksum with the one actually read in */
|
||||
memcpy(page+22,chksum,4);
|
||||
|
||||
|
||||
/* Bad checksum. Lose sync */
|
||||
goto sync_fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* yes, have a whole page all ready to go */
|
||||
{
|
||||
unsigned char *page=oy->data+oy->returned;
|
||||
|
@ -720,12 +746,12 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
|
|||
oy->bodybytes=0;
|
||||
return(bytes);
|
||||
}
|
||||
|
||||
|
||||
sync_fail:
|
||||
|
||||
|
||||
oy->headerbytes=0;
|
||||
oy->bodybytes=0;
|
||||
|
||||
|
||||
/* search for possible capture */
|
||||
next=memchr(page+1,'O',bytes-1);
|
||||
if(!next)
|
||||
|
@ -764,7 +790,7 @@ int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
|
|||
/* need more data */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* head did not start a synced page... skipped some bytes */
|
||||
if(!oy->unsynced){
|
||||
oy->unsynced=1;
|
||||
|
@ -793,7 +819,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
|
|||
int serialno=ogg_page_serialno(og);
|
||||
long pageno=ogg_page_pageno(og);
|
||||
int segments=header[26];
|
||||
|
||||
|
||||
if(ogg_stream_check(os)) return -1;
|
||||
|
||||
/* clean up 'returned data' */
|
||||
|
@ -848,7 +874,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
|
|||
/* are we a 'continued packet' page? If so, we may need to skip
|
||||
some segments */
|
||||
if(continued){
|
||||
if(os->lacing_fill<1 ||
|
||||
if(os->lacing_fill<1 ||
|
||||
os->lacing_vals[os->lacing_fill-1]==0x400){
|
||||
bos=0;
|
||||
for(;segptr<segments;segptr++){
|
||||
|
@ -862,7 +888,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(bodysize){
|
||||
if(_os_body_expand(os,bodysize)) return -1;
|
||||
memcpy(os->body_data+os->body_fill,body,bodysize);
|
||||
|
@ -875,20 +901,20 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
|
|||
int val=header[27+segptr];
|
||||
os->lacing_vals[os->lacing_fill]=val;
|
||||
os->granule_vals[os->lacing_fill]=-1;
|
||||
|
||||
|
||||
if(bos){
|
||||
os->lacing_vals[os->lacing_fill]|=0x100;
|
||||
bos=0;
|
||||
}
|
||||
|
||||
|
||||
if(val<255)saved=os->lacing_fill;
|
||||
|
||||
|
||||
os->lacing_fill++;
|
||||
segptr++;
|
||||
|
||||
|
||||
if(val<255)os->lacing_packet=os->lacing_fill;
|
||||
}
|
||||
|
||||
|
||||
/* set the granulepos on the last granuleval of the last full packet */
|
||||
if(saved!=-1){
|
||||
os->granule_vals[saved]=granulepos;
|
||||
|
@ -1493,7 +1519,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
|
|||
/* construct a test packet */
|
||||
ogg_packet op;
|
||||
int len=pl[i];
|
||||
|
||||
|
||||
op.packet=data+inptr;
|
||||
op.bytes=len;
|
||||
op.e_o_s=(pl[i+1]<0?1:0);
|
||||
|
@ -1509,7 +1535,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
|
|||
/* retrieve any finished pages */
|
||||
{
|
||||
ogg_page og;
|
||||
|
||||
|
||||
while(ogg_stream_pageout(&os_en,&og)){
|
||||
/* We have a page. Check it carefully */
|
||||
|
||||
|
@ -1558,7 +1584,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
|
|||
if(ret==0)break;
|
||||
if(ret<0)continue;
|
||||
/* got a page. Happy happy. Verify that it's good. */
|
||||
|
||||
|
||||
fprintf(stderr,"(%d), ",pageout);
|
||||
|
||||
check_page(data+deptr,headers[pageout],&og_de);
|
||||
|
@ -1572,7 +1598,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
|
|||
while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
|
||||
ogg_stream_packetpeek(&os_de,NULL);
|
||||
ogg_stream_packetout(&os_de,&op_de); /* just catching them all */
|
||||
|
||||
|
||||
/* verify peek and out match */
|
||||
if(memcmp(&op_de,&op_de2,sizeof(op_de))){
|
||||
fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
|
||||
|
@ -1598,7 +1624,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
|
|||
}
|
||||
bosflag=1;
|
||||
depacket+=op_de.bytes;
|
||||
|
||||
|
||||
/* check eos flag */
|
||||
if(eosflag){
|
||||
fprintf(stderr,"Multiple decoded packets with eos flag!\n");
|
||||
|
@ -1745,7 +1771,7 @@ int main(void){
|
|||
10,10,10,10,10,10,10,10,
|
||||
10,10,10,10,10,10,10,50,-1};
|
||||
const int *headret[]={head1_5,head2_5,head3_5,NULL};
|
||||
|
||||
|
||||
fprintf(stderr,"testing max packet segments... ");
|
||||
test_pack(packets,headret,0,0,0);
|
||||
}
|
||||
|
@ -1754,7 +1780,7 @@ int main(void){
|
|||
/* packet that overspans over an entire page */
|
||||
const int packets[]={0,100,130049,259,255,-1};
|
||||
const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
|
||||
|
||||
|
||||
fprintf(stderr,"testing very large packets... ");
|
||||
test_pack(packets,headret,0,0,0);
|
||||
}
|
||||
|
@ -1764,7 +1790,7 @@ int main(void){
|
|||
found by Josh Coalson) */
|
||||
const int packets[]={0,100,130049,259,255,-1};
|
||||
const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
|
||||
|
||||
|
||||
fprintf(stderr,"testing continuation resync in very large packets... ");
|
||||
test_pack(packets,headret,100,2,3);
|
||||
}
|
||||
|
@ -1773,7 +1799,7 @@ int main(void){
|
|||
/* term only page. why not? */
|
||||
const int packets[]={0,100,64770,-1};
|
||||
const int *headret[]={head1_7,head2_7,head3_7,NULL};
|
||||
|
||||
|
||||
fprintf(stderr,"testing zero data page (1 nil packet)... ");
|
||||
test_pack(packets,headret,0,0,0);
|
||||
}
|
||||
|
@ -1786,13 +1812,13 @@ int main(void){
|
|||
int pl[]={0, 1,1,98,4079, 1,1,2954,2057, 76,34,912,0,234,1000,1000, 1000,300,-1};
|
||||
int inptr=0,i,j;
|
||||
ogg_page og[5];
|
||||
|
||||
|
||||
ogg_stream_reset(&os_en);
|
||||
|
||||
for(i=0;pl[i]!=-1;i++){
|
||||
ogg_packet op;
|
||||
int len=pl[i];
|
||||
|
||||
|
||||
op.packet=data+inptr;
|
||||
op.bytes=len;
|
||||
op.e_o_s=(pl[i+1]<0?1:0);
|
||||
|
@ -1840,7 +1866,7 @@ int main(void){
|
|||
ogg_stream_pagein(&os_de,&temp);
|
||||
|
||||
/* do we get the expected results/packets? */
|
||||
|
||||
|
||||
if(ogg_stream_packetout(&os_de,&test)!=1)error();
|
||||
checkpacket(&test,0,0,0);
|
||||
if(ogg_stream_packetout(&os_de,&test)!=1)error();
|
||||
|
@ -1991,13 +2017,13 @@ int main(void){
|
|||
|
||||
fprintf(stderr,"ok.\n");
|
||||
}
|
||||
|
||||
|
||||
/* Test recapture: garbage + page */
|
||||
{
|
||||
ogg_page og_de;
|
||||
fprintf(stderr,"Testing search for capture... ");
|
||||
ogg_sync_reset(&oy);
|
||||
|
||||
ogg_sync_reset(&oy);
|
||||
|
||||
/* 'garbage' */
|
||||
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
|
||||
og[1].body_len);
|
||||
|
@ -2033,7 +2059,7 @@ int main(void){
|
|||
{
|
||||
ogg_page og_de;
|
||||
fprintf(stderr,"Testing recapture... ");
|
||||
ogg_sync_reset(&oy);
|
||||
ogg_sync_reset(&oy);
|
||||
|
||||
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
|
||||
og[1].header_len);
|
||||
|
@ -2077,13 +2103,9 @@ int main(void){
|
|||
free_page(&og[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
********************************************************************
|
||||
|
||||
function: toplevel libogg include
|
||||
last mod: $Id: ogg.h 17571 2010-10-27 13:28:20Z xiphmont $
|
||||
last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OGG_H
|
||||
|
@ -161,6 +161,7 @@ extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
|
|||
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
|
||||
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
********************************************************************
|
||||
|
||||
function: #ifdef jail to whip a few platforms into the UNIX ideal.
|
||||
last mod: $Id: os_types.h 17712 2010-12-03 17:10:02Z xiphmont $
|
||||
last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OS_TYPES_H
|
||||
|
@ -24,7 +24,7 @@
|
|||
#define _ogg_realloc realloc
|
||||
#define _ogg_free free
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
|
||||
# if defined(__CYGWIN__)
|
||||
# include <stdint.h>
|
||||
|
|
Loading…
Reference in New Issue