ref: e876447b7570808a97cbad6193b33c8af41552fe
parent: f75bbcdd45358ac00fdf07d0107c87390b28c4cb
author: mischief <mischief@offblast.org>
date: Fri Sep 28 13:28:51 EDT 2018
audio/libogg: sync to ogg v1.3.3 this corresponds to upstream git commit 4380566a44b8d5e85ad511c9c17eb04197863ec5.
--- a/sys/src/cmd/audio/libogg/bitwise.c
+++ b/sys/src/cmd/audio/libogg/bitwise.c
@@ -1,17 +1,17 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * 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-2002 *
+ * 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,v 1.13 2002/07/11 09:09:08 xiphmont Exp $
+ last mod: $Id$
********************************************************************/
@@ -20,11 +20,12 @@
#include <string.h>
#include <stdlib.h>
+#include <limits.h>
#include <ogg/ogg.h>
#define BUFFER_INCREMENT 256
-static unsigned long mask[]=
+static const unsigned long mask[]=
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
@@ -33,6 +34,9 @@
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
0x3fffffff,0x7fffffff,0xffffffff };
+static const unsigned int mask8B[]=
+{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
+
void oggpack_writeinit(oggpack_buffer *b){
memset(b,0,sizeof(*b));
b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT);
@@ -40,15 +44,127 @@
b->storage=BUFFER_INCREMENT;
}
+void oggpackB_writeinit(oggpack_buffer *b){
+ oggpack_writeinit(b);
+}
+
+int oggpack_writecheck(oggpack_buffer *b){
+ if(!b->ptr || !b->storage)return -1;
+ return 0;
+}
+
+int oggpackB_writecheck(oggpack_buffer *b){
+ return oggpack_writecheck(b);
+}
+
void oggpack_writetrunc(oggpack_buffer *b,long bits){
long bytes=bits>>3;
- bits-=bytes*8;
- b->ptr=b->buffer+bytes;
- b->endbit=bits;
- b->endbyte=bytes;
- *b->ptr|=mask[bits];
+ if(b->ptr){
+ bits-=bytes*8;
+ b->ptr=b->buffer+bytes;
+ b->endbit=bits;
+ b->endbyte=bytes;
+ *b->ptr&=mask[bits];
+ }
}
+void oggpackB_writetrunc(oggpack_buffer *b,long bits){
+ long bytes=bits>>3;
+ if(b->ptr){
+ bits-=bytes*8;
+ b->ptr=b->buffer+bytes;
+ b->endbit=bits;
+ b->endbyte=bytes;
+ *b->ptr&=mask8B[bits];
+ }
+}
+
+/* Takes only up to 32 bits. */
+void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
+ if(bits<0 || bits>32) goto err;
+ if(b->endbyte>=b->storage-4){
+ void *ret;
+ if(!b->ptr)return;
+ if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
+ ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
+ if(!ret) goto err;
+ b->buffer=ret;
+ b->storage+=BUFFER_INCREMENT;
+ b->ptr=b->buffer+b->endbyte;
+ }
+
+ value&=mask[bits];
+ bits+=b->endbit;
+
+ b->ptr[0]|=value<<b->endbit;
+
+ if(bits>=8){
+ b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
+ if(bits>=16){
+ b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
+ if(bits>=24){
+ b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
+ if(bits>=32){
+ if(b->endbit)
+ b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
+ else
+ b->ptr[4]=0;
+ }
+ }
+ }
+ }
+
+ b->endbyte+=bits/8;
+ b->ptr+=bits/8;
+ b->endbit=bits&7;
+ return;
+ err:
+ oggpack_writeclear(b);
+}
+
+/* Takes only up to 32 bits. */
+void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
+ if(bits<0 || bits>32) goto err;
+ if(b->endbyte>=b->storage-4){
+ void *ret;
+ if(!b->ptr)return;
+ if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
+ ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
+ if(!ret) goto err;
+ b->buffer=ret;
+ b->storage+=BUFFER_INCREMENT;
+ b->ptr=b->buffer+b->endbyte;
+ }
+
+ value=(value&mask[bits])<<(32-bits);
+ bits+=b->endbit;
+
+ b->ptr[0]|=value>>(24+b->endbit);
+
+ if(bits>=8){
+ b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
+ if(bits>=16){
+ b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
+ if(bits>=24){
+ b->ptr[3]=(unsigned char)(value>>(b->endbit));
+ if(bits>=32){
+ if(b->endbit)
+ b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
+ else
+ b->ptr[4]=0;
+ }
+ }
+ }
+ }
+
+ b->endbyte+=bits/8;
+ b->ptr+=bits/8;
+ b->endbit=bits&7;
+ return;
+ err:
+ oggpack_writeclear(b);
+}
+
void oggpack_writealign(oggpack_buffer *b){
int bits=8-b->endbit;
if(bits<8)
@@ -55,46 +171,91 @@
oggpack_write(b,0,bits);
}
-void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
+void oggpackB_writealign(oggpack_buffer *b){
+ int bits=8-b->endbit;
+ if(bits<8)
+ oggpackB_write(b,0,bits);
+}
+
+static void oggpack_writecopy_helper(oggpack_buffer *b,
+ void *source,
+ 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++)
- oggpack_write(b,(long)(ptr[i]),8);
+ w(b,(unsigned long)(ptr[i]),8);
}else{
/* aligned block copy */
- if(b->endbyte+bytes+1>=b->storage){
- b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
- b->buffer=_ogg_realloc(b->buffer,b->storage);
- b->ptr=b->buffer+b->endbyte;
- }
-
memmove(b->ptr,source,bytes);
b->ptr+=bytes;
- b->buffer+=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);
}
- if(bits)
- oggpack_write(b,(long)(ptr[bytes]),bits);
+ return;
+ err:
+ oggpack_writeclear(b);
}
+void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
+ oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
+}
+
+void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
+ oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
+}
+
void oggpack_reset(oggpack_buffer *b){
+ if(!b->ptr)return;
b->ptr=b->buffer;
b->buffer[0]=0;
b->endbit=b->endbyte=0;
}
+void oggpackB_reset(oggpack_buffer *b){
+ oggpack_reset(b);
+}
+
void oggpack_writeclear(oggpack_buffer *b){
- _ogg_free(b->buffer);
+ if(b->buffer)_ogg_free(b->buffer);
memset(b,0,sizeof(*b));
}
+void oggpackB_writeclear(oggpack_buffer *b){
+ oggpack_writeclear(b);
+}
+
void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
memset(b,0,sizeof(*b));
b->buffer=b->ptr=buf;
@@ -101,65 +262,71 @@
b->storage=bytes;
}
-/* Takes only up to 32 bits. */
-void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
- if(b->endbyte+4>=b->storage){
- b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
- b->storage+=BUFFER_INCREMENT;
- b->ptr=b->buffer+b->endbyte;
- }
+void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
+ oggpack_readinit(b,buf,bytes);
+}
- value&=mask[bits];
+/* Read in bits without advancing the bitptr; bits <= 32 */
+long oggpack_look(oggpack_buffer *b,int bits){
+ unsigned long ret;
+ unsigned long m;
+
+ if(bits<0 || bits>32) return -1;
+ m=mask[bits];
bits+=b->endbit;
- b->ptr[0]|=value<<b->endbit;
-
- if(bits>=8){
- b->ptr[1]=value>>(8-b->endbit);
- if(bits>=16){
- b->ptr[2]=value>>(16-b->endbit);
- if(bits>=24){
- b->ptr[3]=value>>(24-b->endbit);
- if(bits>=32){
- if(b->endbit)
- b->ptr[4]=value>>(32-b->endbit);
- else
- b->ptr[4]=0;
- }
+ if(b->endbyte >= b->storage-4){
+ /* not the main path */
+ if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
+ /* special case to avoid reading b->ptr[0], which might be past the end of
+ the buffer; also skips some useless accounting */
+ else if(!bits)return(0L);
+ }
+
+ ret=b->ptr[0]>>b->endbit;
+ if(bits>8){
+ ret|=b->ptr[1]<<(8-b->endbit);
+ if(bits>16){
+ ret|=b->ptr[2]<<(16-b->endbit);
+ if(bits>24){
+ ret|=b->ptr[3]<<(24-b->endbit);
+ if(bits>32 && b->endbit)
+ ret|=b->ptr[4]<<(32-b->endbit);
}
}
}
-
- b->endbyte+=bits/8;
- b->ptr+=bits/8;
- b->endbit=bits&7;
+ return(m&ret);
}
/* Read in bits without advancing the bitptr; bits <= 32 */
-long oggpack_look(oggpack_buffer *b,int bits){
+long oggpackB_look(oggpack_buffer *b,int bits){
unsigned long ret;
- unsigned long m=mask[bits];
+ int m=32-bits;
+ if(m<0 || m>32) return -1;
bits+=b->endbit;
- if(b->endbyte+4>=b->storage){
+ if(b->endbyte >= b->storage-4){
/* not the main path */
- if(b->endbyte*8+bits>b->storage*8)return(-1);
+ if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
+ /* special case to avoid reading b->ptr[0], which might be past the end of
+ the buffer; also skips some useless accounting */
+ else if(!bits)return(0L);
}
-
- ret=b->ptr[0]>>b->endbit;
+
+ ret=b->ptr[0]<<(24+b->endbit);
if(bits>8){
- ret|=b->ptr[1]<<(8-b->endbit);
+ ret|=b->ptr[1]<<(16+b->endbit);
if(bits>16){
- ret|=b->ptr[2]<<(16-b->endbit);
+ ret|=b->ptr[2]<<(8+b->endbit);
if(bits>24){
- ret|=b->ptr[3]<<(24-b->endbit);
- if(bits>32 && b->endbit)
- ret|=b->ptr[4]<<(32-b->endbit);
+ ret|=b->ptr[3]<<(b->endbit);
+ if(bits>32 && b->endbit)
+ ret|=b->ptr[4]>>(8-b->endbit);
}
}
}
- return(m&ret);
+ return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
}
long oggpack_look1(oggpack_buffer *b){
@@ -167,13 +334,31 @@
return((b->ptr[0]>>b->endbit)&1);
}
+long oggpackB_look1(oggpack_buffer *b){
+ if(b->endbyte>=b->storage)return(-1);
+ return((b->ptr[0]>>(7-b->endbit))&1);
+}
+
void oggpack_adv(oggpack_buffer *b,int bits){
bits+=b->endbit;
+
+ if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
+
b->ptr+=bits/8;
b->endbyte+=bits/8;
b->endbit=bits&7;
+ return;
+
+ overflow:
+ b->ptr=NULL;
+ b->endbyte=b->storage;
+ b->endbit=1;
}
+void oggpackB_adv(oggpack_buffer *b,int bits){
+ oggpack_adv(b,bits);
+}
+
void oggpack_adv1(oggpack_buffer *b){
if(++(b->endbit)>7){
b->endbit=0;
@@ -182,55 +367,124 @@
}
}
+void oggpackB_adv1(oggpack_buffer *b){
+ oggpack_adv1(b);
+}
+
/* bits <= 32 */
long oggpack_read(oggpack_buffer *b,int bits){
- unsigned long ret;
- unsigned long m=mask[bits];
+ long ret;
+ unsigned long m;
+ if(bits<0 || bits>32) goto err;
+ m=mask[bits];
bits+=b->endbit;
- if(b->endbyte+4>=b->storage){
+ if(b->endbyte >= b->storage-4){
/* not the main path */
- ret=-1UL;
- if(b->endbyte*8+bits>b->storage*8)goto overflow;
+ if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
+ /* special case to avoid reading b->ptr[0], which might be past the end of
+ the buffer; also skips some useless accounting */
+ else if(!bits)return(0L);
}
-
+
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);
- if(bits>32 && b->endbit){
- ret|=b->ptr[4]<<(32-b->endbit);
- }
+ ret|=b->ptr[3]<<(24-b->endbit);
+ if(bits>32 && b->endbit){
+ ret|=b->ptr[4]<<(32-b->endbit);
+ }
}
}
}
ret&=m;
-
+ b->ptr+=bits/8;
+ b->endbyte+=bits/8;
+ b->endbit=bits&7;
+ return ret;
+
overflow:
+ err:
+ b->ptr=NULL;
+ b->endbyte=b->storage;
+ b->endbit=1;
+ return -1L;
+}
+/* bits <= 32 */
+long oggpackB_read(oggpack_buffer *b,int bits){
+ long ret;
+ long m=32-bits;
+
+ if(m<0 || m>32) goto err;
+ bits+=b->endbit;
+
+ if(b->endbyte+4>=b->storage){
+ /* not the main path */
+ if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
+ /* special case to avoid reading b->ptr[0], which might be past the end of
+ the buffer; also skips some useless accounting */
+ else if(!bits)return(0L);
+ }
+
+ ret=b->ptr[0]<<(24+b->endbit);
+ if(bits>8){
+ ret|=b->ptr[1]<<(16+b->endbit);
+ if(bits>16){
+ ret|=b->ptr[2]<<(8+b->endbit);
+ if(bits>24){
+ ret|=b->ptr[3]<<(b->endbit);
+ if(bits>32 && b->endbit)
+ ret|=b->ptr[4]>>(8-b->endbit);
+ }
+ }
+ }
+ ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
+
b->ptr+=bits/8;
b->endbyte+=bits/8;
b->endbit=bits&7;
- return(ret);
+ return ret;
+
+ overflow:
+ err:
+ b->ptr=NULL;
+ b->endbyte=b->storage;
+ b->endbit=1;
+ return -1L;
}
long oggpack_read1(oggpack_buffer *b){
- unsigned long ret;
-
- if(b->endbyte>=b->storage){
- /* not the main path */
- ret=-1UL;
- goto overflow;
- }
+ long ret;
+ if(b->endbyte >= b->storage) goto overflow;
ret=(b->ptr[0]>>b->endbit)&1;
-
+
+ b->endbit++;
+ if(b->endbit>7){
+ b->endbit=0;
+ b->ptr++;
+ b->endbyte++;
+ }
+ return ret;
+
overflow:
+ b->ptr=NULL;
+ b->endbyte=b->storage;
+ b->endbit=1;
+ return -1L;
+}
+long oggpackB_read1(oggpack_buffer *b){
+ long ret;
+
+ if(b->endbyte >= b->storage) goto overflow;
+ ret=(b->ptr[0]>>(7-b->endbit))&1;
+
b->endbit++;
if(b->endbit>7){
b->endbit=0;
@@ -237,7 +491,13 @@
b->ptr++;
b->endbyte++;
}
- return(ret);
+ return ret;
+
+ overflow:
+ b->ptr=NULL;
+ b->endbyte=b->storage;
+ b->endbit=1;
+ return -1L;
}
long oggpack_bytes(oggpack_buffer *b){
@@ -248,10 +508,22 @@
return(b->endbyte*8+b->endbit);
}
+long oggpackB_bytes(oggpack_buffer *b){
+ return oggpack_bytes(b);
+}
+
+long oggpackB_bits(oggpack_buffer *b){
+ return oggpack_bits(b);
+}
+
unsigned char *oggpack_get_buffer(oggpack_buffer *b){
return(b->buffer);
}
+unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
+ return oggpack_get_buffer(b);
+}
+
/* Self test of the bitwise routines; everything else is based on
them, so they damned well better be solid. */
@@ -266,7 +538,7 @@
}
return(ret);
}
-
+
oggpack_buffer o;
oggpack_buffer r;
@@ -298,10 +570,10 @@
report("looked at incorrect value!\n");
if(tbit==1)
if(oggpack_look1(&r)!=(b[i]&mask[tbit]))
- report("looked at single bit incorrect value!\n");
+ report("looked at single bit incorrect value!\n");
if(tbit==1){
if(oggpack_read1(&r)!=(b[i]&mask[tbit]))
- report("read incorrect single bit value!\n");
+ report("read incorrect single bit value!\n");
}else{
if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
report("read incorrect value!\n");
@@ -310,9 +582,225 @@
if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
}
+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]));
+ buffer=oggpackB_get_buffer(&o);
+ bytes=oggpackB_bytes(&o);
+ if(bytes!=compsize)report("wrong number of bytes!\n");
+ for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
+ for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
+ report("wrote incorrect value!\n");
+ }
+ oggpackB_readinit(&r,buffer,bytes);
+ for(i=0;i<vals;i++){
+ int tbit=bits?bits:ilog(b[i]);
+ if(oggpackB_look(&r,tbit)==-1)
+ report("out of data!\n");
+ if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
+ report("looked at incorrect value!\n");
+ if(tbit==1)
+ if(oggpackB_look1(&r)!=(b[i]&mask[tbit]))
+ report("looked at single bit incorrect value!\n");
+ if(tbit==1){
+ if(oggpackB_read1(&r)!=(b[i]&mask[tbit]))
+ report("read incorrect single bit value!\n");
+ }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};
@@ -324,60 +812,75 @@
85525151,0,12321,1,349528352};
int test2size=21;
- static unsigned long large[]=
- {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
- 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
- 85525151,0,12321,1,2146528352};
-
static unsigned long testbuffer3[]=
{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,
0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
int test3size=56;
+ static unsigned long large[]=
+ {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
+ 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
+ 85525151,0,12321,1,2146528352};
+
int onesize=33;
- static int one[]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
+ static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
223,4};
+ static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
+ 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
+ 245,251,128};
int twosize=6;
- static int two[]={61,255,255,251,231,29};
+ static int two[6]={61,255,255,251,231,29};
+ static int twoB[6]={247,63,255,253,249,120};
int threesize=54;
- static int three[]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
+ static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
100,52,4,14,18,86,77,1};
+ static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
+ 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
+ 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
+ 200,20,254,4,58,106,176,144,0};
int foursize=38;
- static int four[]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
+ static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
28,2,133,0,1};
+ static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
+ 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
+ 129,10,4,32};
int fivesize=45;
- static int five[]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
+ static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
84,75,159,2,1,0,132,192,8,0,0,18,22};
+ static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
+ 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
+ 172,150,169,129,79,128,0,6,4,32,0,27,9,0};
int sixsize=7;
- static int six[]={17,177,170,242,169,19,148};
+ static int six[7]={17,177,170,242,169,19,148};
+ static int sixB[7]={136,141,85,79,149,200,41};
/* Test read/write together */
/* Later we test against pregenerated bitstreams */
oggpack_writeinit(&o);
- fprintf(stderr,"\nSmall preclipped packing: ");
+ fprintf(stderr,"\nSmall preclipped packing (LSb): ");
cliptest(testbuffer1,test1size,0,one,onesize);
fprintf(stderr,"ok.");
- fprintf(stderr,"\nNull bit call: ");
+ fprintf(stderr,"\nNull bit call (LSb): ");
cliptest(testbuffer3,test3size,0,two,twosize);
fprintf(stderr,"ok.");
- fprintf(stderr,"\nLarge preclipped packing: ");
+ fprintf(stderr,"\nLarge preclipped packing (LSb): ");
cliptest(testbuffer2,test2size,0,three,threesize);
fprintf(stderr,"ok.");
- fprintf(stderr,"\n32 bit preclipped packing: ");
+ fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
oggpack_reset(&o);
for(i=0;i<test2size;i++)
oggpack_write(&o,large[i],32);
@@ -388,7 +891,7 @@
if(oggpack_look(&r,32)==-1)report("out of data. failed!");
if(oggpack_look(&r,32)!=large[i]){
fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i],
- oggpack_look(&r,32),large[i]);
+ oggpack_look(&r,32),large[i]);
report("read incorrect value!\n");
}
oggpack_adv(&r,32);
@@ -396,20 +899,20 @@
if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
fprintf(stderr,"ok.");
- fprintf(stderr,"\nSmall unclipped packing: ");
+ fprintf(stderr,"\nSmall unclipped packing (LSb): ");
cliptest(testbuffer1,test1size,7,four,foursize);
fprintf(stderr,"ok.");
- fprintf(stderr,"\nLarge unclipped packing: ");
+ fprintf(stderr,"\nLarge unclipped packing (LSb): ");
cliptest(testbuffer2,test2size,17,five,fivesize);
fprintf(stderr,"ok.");
- fprintf(stderr,"\nSingle bit unclipped packing: ");
+ fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
cliptest(testbuffer3,test3size,1,six,sixsize);
fprintf(stderr,"ok.");
- fprintf(stderr,"\nTesting read past end: ");
- oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8);
+ fprintf(stderr,"\nTesting read past end (LSb): ");
+ oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
for(i=0;i<64;i++){
if(oggpack_read(&r,1)!=0){
fprintf(stderr,"failed; got -1 prematurely.\n");
@@ -421,7 +924,7 @@
fprintf(stderr,"failed; read past end without -1.\n");
exit(1);
}
- oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8);
+ oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
fprintf(stderr,"failed 2; got -1 prematurely.\n");
exit(1);
@@ -442,11 +945,144 @@
fprintf(stderr,"failed; read past end without -1.\n");
exit(1);
}
- fprintf(stderr,"ok.\n\n");
+ oggpack_writeclear(&o);
+ 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): ");
+ cliptestB(testbuffer1,test1size,0,oneB,onesize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nNull bit call (MSb): ");
+ cliptestB(testbuffer3,test3size,0,twoB,twosize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nLarge preclipped packing (MSb): ");
+ cliptestB(testbuffer2,test2size,0,threeB,threesize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
+ oggpackB_reset(&o);
+ for(i=0;i<test2size;i++)
+ oggpackB_write(&o,large[i],32);
+ buffer=oggpackB_get_buffer(&o);
+ bytes=oggpackB_bytes(&o);
+ oggpackB_readinit(&r,buffer,bytes);
+ for(i=0;i<test2size;i++){
+ if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
+ if(oggpackB_look(&r,32)!=large[i]){
+ fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
+ oggpackB_look(&r,32),large[i]);
+ report("read incorrect value!\n");
+ }
+ oggpackB_adv(&r,32);
+ }
+ if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nSmall unclipped packing (MSb): ");
+ cliptestB(testbuffer1,test1size,7,fourB,foursize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nLarge unclipped packing (MSb): ");
+ cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
+ cliptestB(testbuffer3,test3size,1,sixB,sixsize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nTesting read past end (MSb): ");
+ oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
+ for(i=0;i<64;i++){
+ if(oggpackB_read(&r,1)!=0){
+ fprintf(stderr,"failed; got -1 prematurely.\n");
+ exit(1);
+ }
+ }
+ if(oggpackB_look(&r,1)!=-1 ||
+ oggpackB_read(&r,1)!=-1){
+ fprintf(stderr,"failed; read past end without -1.\n");
+ exit(1);
+ }
+ oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
+ if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
+ fprintf(stderr,"failed 2; got -1 prematurely.\n");
+ exit(1);
+ }
+
+ if(oggpackB_look(&r,18)!=0 ||
+ oggpackB_look(&r,18)!=0){
+ fprintf(stderr,"failed 3; got -1 prematurely.\n");
+ exit(1);
+ }
+ if(oggpackB_look(&r,19)!=-1 ||
+ oggpackB_look(&r,19)!=-1){
+ 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);
+
+ /* 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
--- a/sys/src/cmd/audio/libogg/framing.c
+++ b/sys/src/cmd/audio/libogg/framing.c
@@ -1,18 +1,18 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * 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-2002 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
- function: code raw [Vorbis] packets into framed OggSquish stream and
+ function: code raw packets into framed OggSquish stream and
decode Ogg streams back into raw packets
- last mod: $Id: framing.c,v 1.22 2002/07/11 09:09:08 xiphmont Exp $
+ last mod: $Id$
note: The CRC code is directly derived from public domain code by
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
@@ -21,28 +21,29 @@
********************************************************************/
#include <stdlib.h>
+#include <limits.h>
#include <string.h>
#include <ogg/ogg.h>
/* A complete description of Ogg framing exists in docs/framing.html */
-int ogg_page_version(ogg_page *og){
+int ogg_page_version(const ogg_page *og){
return((int)(og->header[4]));
}
-int ogg_page_continued(ogg_page *og){
+int ogg_page_continued(const ogg_page *og){
return((int)(og->header[5]&0x01));
}
-int ogg_page_bos(ogg_page *og){
+int ogg_page_bos(const ogg_page *og){
return((int)(og->header[5]&0x02));
}
-int ogg_page_eos(ogg_page *og){
+int ogg_page_eos(const ogg_page *og){
return((int)(og->header[5]&0x04));
}
-ogg_int64_t ogg_page_granulepos(ogg_page *og){
+ogg_int64_t ogg_page_granulepos(const ogg_page *og){
unsigned char *page=og->header;
ogg_int64_t granulepos=page[13]&(0xff);
granulepos= (granulepos<<8)|(page[12]&0xff);
@@ -55,18 +56,18 @@
return(granulepos);
}
-int ogg_page_serialno(ogg_page *og){
+int ogg_page_serialno(const ogg_page *og){
return(og->header[14] |
- (og->header[15]<<8) |
- (og->header[16]<<16) |
- (og->header[17]<<24));
+ (og->header[15]<<8) |
+ (og->header[16]<<16) |
+ (og->header[17]<<24));
}
-
-long ogg_page_pageno(ogg_page *og){
+
+long ogg_page_pageno(const ogg_page *og){
return(og->header[18] |
- (og->header[19]<<8) |
- (og->header[20]<<16) |
- (og->header[21]<<24));
+ (og->header[19]<<8) |
+ (og->header[20]<<16) |
+ (og->header[21]<<24));
}
@@ -76,19 +77,19 @@
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(ogg_page *og){
+int ogg_page_packets(const ogg_page *og){
int i,n=og->header[26],count=0;
for(i=0;i<n;i++)
if(og->header[27+i]<255)count++;
@@ -108,9 +109,9 @@
for (i=0; i<8; i++)
if (r & 0x80000000UL)
r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
- polynomial, although we use an
- unreflected alg and an init/final
- of 0, not 0xffffffff */
+ polynomial, although we use an
+ unreflected alg and an init/final
+ of 0, not 0xffffffff */
else
r<<=1;
return (r & 0xffffffffUL);
@@ -117,7 +118,7 @@
}
#endif
-static ogg_uint32_t crc_lookup[256]={
+static const ogg_uint32_t crc_lookup[256]={
0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
@@ -189,19 +190,30 @@
if(os){
memset(os,0,sizeof(*os));
os->body_storage=16*1024;
- os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
-
os->lacing_storage=1024;
+
+ os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
+ if(!os->body_data || !os->lacing_vals || !os->granule_vals){
+ ogg_stream_clear(os);
+ return -1;
+ }
+
os->serialno=serialno;
return(0);
}
return(-1);
-}
+}
+/* async/delayed error detection for the ogg_stream_state */
+int ogg_stream_check(ogg_stream_state *os){
+ if(!os || !os->body_data) return -1;
+ return 0;
+}
+
/* _clear does not free os, only the non-flat storage within */
int ogg_stream_clear(ogg_stream_state *os){
if(os){
@@ -209,10 +221,10 @@
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){
@@ -220,29 +232,63 @@
_ogg_free(os);
}
return(0);
-}
+}
/* Helpers for ogg_stream_encode; this keeps the structure and
what's happening fairly clear */
-static void _os_body_expand(ogg_stream_state *os,int needed){
- if(os->body_storage<=os->body_fill+needed){
- os->body_storage+=(needed+1024);
- os->body_data=_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data));
+static int _os_body_expand(ogg_stream_state *os,long needed){
+ if(os->body_storage-needed<=os->body_fill){
+ long body_storage;
+ void *ret;
+ 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=body_storage;
+ os->body_data=ret;
}
+ return 0;
}
-static void _os_lacing_expand(ogg_stream_state *os,int needed){
- if(os->lacing_storage<=os->lacing_fill+needed){
- os->lacing_storage+=(needed+32);
- os->lacing_vals=_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals));
- os->granule_vals=_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals));
+static int _os_lacing_expand(ogg_stream_state *os,long needed){
+ if(os->lacing_storage-needed<=os->lacing_fill){
+ long lacing_storage;
+ void *ret;
+ 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,lacing_storage*
+ sizeof(*os->granule_vals));
+ if(!ret){
+ ogg_stream_clear(os);
+ return -1;
+ }
+ os->granule_vals=ret;
+ os->lacing_storage=lacing_storage;
}
+ return 0;
}
/* checksum the page */
/* Direct table CRC; note that this will be faster in the future if we
- perform the checksum silmultaneously with other copies */
+ perform the checksum simultaneously with other copies */
void ogg_page_checksum_set(ogg_page *og){
if(og){
@@ -254,38 +300,51 @@
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]=crc_reg&0xff;
- og->header[23]=(crc_reg>>8)&0xff;
- og->header[24]=(crc_reg>>16)&0xff;
- og->header[25]=(crc_reg>>24)&0xff;
+
+ 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);
+ og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
}
}
/* submit data to the internal buffer of the framing engine */
-int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
- int lacing_vals=op->bytes/255+1,i;
+int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
+ long e_o_s, ogg_int64_t granulepos){
+ long bytes = 0, lacing_vals;
+ int i;
+
+ if(ogg_stream_check(os)) return -1;
+ if(!iov) return 0;
+
+ 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_fill);
os->body_returned=0;
}
-
+
/* make sure we have the buffer storage */
- _os_body_expand(os,op->bytes);
- _os_lacing_expand(os,lacing_vals);
+ if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals))
+ return -1;
/* Copy in the submitted packet. Yes, the copy is a waste; this is
the liability of overly clean abstraction for the time being. It
@@ -292,8 +351,10 @@
will actually be fairly easy to eliminate the extra copy in the
future */
- memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
- os->body_fill+=op->bytes;
+ for (i = 0; i < count; ++i) {
+ memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len);
+ os->body_fill += (int)iov[i].iov_len;
+ }
/* Store lacing vals for this packet */
for(i=0;i<lacing_vals-1;i++){
@@ -300,8 +361,8 @@
os->lacing_vals[os->lacing_fill+i]=255;
os->granule_vals[os->lacing_fill+i]=os->granulepos;
}
- os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
- os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
+ os->lacing_vals[os->lacing_fill+i]=bytes%255;
+ os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
/* flag the first segment as the beginning of the packet */
os->lacing_vals[os->lacing_fill]|= 0x100;
@@ -311,38 +372,35 @@
/* for the sake of completeness */
os->packetno++;
- if(op->e_o_s)os->e_o_s=1;
+ if(e_o_s)os->e_o_s=1;
return(0);
}
-/* This will flush remaining packets into a page (returning nonzero),
- even if there is not enough data to trigger a flush normally
- (undersized page). If there are no packets or partial packets to
- flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will
- try to flush a normal sized page like ogg_stream_pageout; a call to
- ogg_stream_flush does not gurantee that all packets have flushed.
- Only a return value of 0 from ogg_stream_flush indicates all packet
- data is flushed into pages.
+int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
+ ogg_iovec_t iov;
+ iov.iov_base = op->packet;
+ iov.iov_len = op->bytes;
+ return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos);
+}
- ogg_stream_page 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 need to flush an undersized
- page in the middle of a stream for some reason. */
-
-int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
+/* Conditionally flush a page; force==0 will only flush nominal-size
+ pages, force==1 forces us to flush a page regardless of page size
+ so long as there's any data available at all. */
+static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){
int i;
int vals=0;
int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
int bytes=0;
long acc=0;
- ogg_int64_t granule_pos=os->granule_vals[0];
+ ogg_int64_t granule_pos=-1;
- if(maxvals==0)return(0);
-
+ if(ogg_stream_check(os)) return(0);
+ if(maxvals==0) return(0);
+
/* construct a page */
/* decide how many segments to include */
-
+
/* If this is the initial header case, the first page must only include
the initial header packet */
if(os->b_o_s==0){ /* 'initial header page' case */
@@ -349,24 +407,46 @@
granule_pos=0;
for(vals=0;vals<maxvals;vals++){
if((os->lacing_vals[vals]&0x0ff)<255){
- vals++;
- break;
+ vals++;
+ break;
}
}
}else{
+
+ /* The extra packets_done, packet_just_done logic here attempts to do two things:
+ 1) Don't unneccessarily span pages.
+ 2) Unless necessary, don't flush pages if there are less than four packets on
+ them; this expands page size to reduce unneccessary overhead if incoming packets
+ are large.
+ These are not necessary behaviors, just 'always better than naive flushing'
+ without requiring an application to explicitly request a specific optimized
+ behavior. We'll want an explicit behavior setup pathway eventually as well. */
+
+ int packets_done=0;
+ int packet_just_done=0;
for(vals=0;vals<maxvals;vals++){
- if(acc>4096)break;
+ if(acc>nfill && packet_just_done>=4){
+ force=1;
+ break;
+ }
acc+=os->lacing_vals[vals]&0x0ff;
- granule_pos=os->granule_vals[vals];
+ if((os->lacing_vals[vals]&0xff)<255){
+ granule_pos=os->granule_vals[vals];
+ packet_just_done=++packets_done;
+ }else
+ packet_just_done=0;
}
+ if(vals==255)force=1;
}
-
+
+ if(!force) return(0);
+
/* construct the header in temp storage */
memcpy(os->header,"OggS",4);
-
+
/* stream structure version */
os->header[4]=0x00;
-
+
/* continued packet flag? */
os->header[5]=0x00;
if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
@@ -378,7 +458,7 @@
/* 64 bits of PCM position */
for(i=6;i<14;i++){
- os->header[i]=(granule_pos&0xff);
+ os->header[i]=(unsigned char)(granule_pos&0xff);
granule_pos>>=8;
}
@@ -386,7 +466,7 @@
{
long serialno=os->serialno;
for(i=14;i<18;i++){
- os->header[i]=(serialno&0xff);
+ os->header[i]=(unsigned char)(serialno&0xff);
serialno>>=8;
}
}
@@ -394,44 +474,44 @@
/* 32 bits of page counter (we have both counter and page header
because this val can roll over) */
if(os->pageno==-1)os->pageno=0; /* because someone called
- stream_reset; this would be a
- strange thing to do in an
- encode stream, but it has
- plausible uses */
+ stream_reset; this would be a
+ strange thing to do in an
+ encode stream, but it has
+ plausible uses */
{
long pageno=os->pageno++;
for(i=18;i<22;i++){
- os->header[i]=(pageno&0xff);
+ os->header[i]=(unsigned char)(pageno&0xff);
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]=vals&0xff;
+ os->header[26]=(unsigned char)(vals&0xff);
for(i=0;i<vals;i++)
- bytes+=os->header[i+27]=(os->lacing_vals[i]&0xff);
-
+ 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 */
@@ -438,26 +518,64 @@
return(1);
}
+/* This will flush remaining packets into a page (returning nonzero),
+ even if there is not enough data to trigger a flush normally
+ (undersized page). If there are no packets or partial packets to
+ flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will
+ try to flush a normal sized page like ogg_stream_pageout; a call to
+ ogg_stream_flush does not guarantee that all packets have flushed.
+ Only a return value of 0 from ogg_stream_flush indicates all packet
+ data is flushed into pages.
+ 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
+ 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) */
int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
+ int force=0;
+ if(ogg_stream_check(os)) return 0;
if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
- os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */
- os->lacing_fill>=255 || /* 'segment table full' case */
- (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */
-
- return(ogg_stream_flush(os,og));
- }
-
- /* not enough data to construct a page and not end of stream */
- return(0);
+ (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */
+ force=1;
+
+ return(ogg_stream_flush_i(os,og,force,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_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){
+ int force=0;
+ if(ogg_stream_check(os)) return 0;
+
+ if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
+ (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */
+ force=1;
+
+ return(ogg_stream_flush_i(os,og,force,nfill));
+}
+
int ogg_stream_eos(ogg_stream_state *os){
+ if(ogg_stream_check(os)) return 1;
return os->e_o_s;
}
@@ -474,12 +592,12 @@
ogg_stream_pagein() along with the appropriate
ogg_stream_state* (ie, matching serialno). We then get raw
packets out calling ogg_stream_packetout() with a
- ogg_stream_state. See the 'frame-prog.txt' docs for details and
- example code. */
+ ogg_stream_state. */
/* initialize the struct to a known state */
int ogg_sync_init(ogg_sync_state *oy){
if(oy){
+ oy->storage = -1; /* used as a readiness flag */
memset(oy,0,sizeof(*oy));
}
return(0);
@@ -489,7 +607,7 @@
int ogg_sync_clear(ogg_sync_state *oy){
if(oy){
if(oy->data)_ogg_free(oy->data);
- ogg_sync_init(oy);
+ memset(oy,0,sizeof(*oy));
}
return(0);
}
@@ -502,7 +620,13 @@
return(0);
}
+int ogg_sync_check(ogg_sync_state *oy){
+ if(oy->storage<0) return -1;
+ return 0;
+}
+
char *ogg_sync_buffer(ogg_sync_state *oy, long size){
+ if(ogg_sync_check(oy)) return NULL;
/* first, clear out any space that has been previously returned */
if(oy->returned){
@@ -515,11 +639,17 @@
if(size>oy->storage-oy->fill){
/* We need to extend the internal buffer */
long newsize=size+oy->fill+4096; /* an extra page to be nice */
+ void *ret;
if(oy->data)
- oy->data=_ogg_realloc(oy->data,newsize);
+ ret=_ogg_realloc(oy->data,newsize);
else
- oy->data=_ogg_malloc(newsize);
+ ret=_ogg_malloc(newsize);
+ if(!ret){
+ ogg_sync_clear(oy);
+ return NULL;
+ }
+ oy->data=ret;
oy->storage=newsize;
}
@@ -528,7 +658,8 @@
}
int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
- if(oy->fill+bytes>oy->storage)return(-1);
+ if(ogg_sync_check(oy))return -1;
+ if(oy->fill+bytes>oy->storage)return -1;
oy->fill+=bytes;
return(0);
}
@@ -540,7 +671,7 @@
-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){
@@ -547,35 +678,37 @@
unsigned char *page=oy->data+oy->returned;
unsigned char *next;
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;
@@ -582,19 +715,19 @@
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) */
+ 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;
@@ -613,23 +746,23 @@
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)
next=oy->data+oy->fill;
- oy->returned=next-oy->data;
- return(-(next-page));
+ oy->returned=(int)(next-oy->data);
+ return((long)-(next-page));
}
/* sync the stream and get a page. Keep trying until we find a page.
- Supress 'sync errors' after reporting the first.
+ Suppress 'sync errors' after reporting the first.
return values:
-1) recapture (hole in data)
@@ -641,11 +774,13 @@
int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
+ if(ogg_sync_check(oy))return 0;
+
/* all we need to do is verify a page at the head of the stream
buffer. If it doesn't verify, we look for the next potential
frame */
- while(1){
+ for(;;){
long ret=ogg_sync_pageseek(oy,og);
if(ret>0){
/* have a page */
@@ -655,7 +790,7 @@
/* need more data */
return(0);
}
-
+
/* head did not start a synced page... skipped some bytes */
if(!oy->unsynced){
oy->unsynced=1;
@@ -684,7 +819,9 @@
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' */
{
long lr=os->lacing_returned;
@@ -694,7 +831,7 @@
if(br){
os->body_fill-=br;
if(os->body_fill)
- memmove(os->body_data,os->body_data+br,os->body_fill);
+ memmove(os->body_data,os->body_data+br,os->body_fill);
os->body_returned=0;
}
@@ -701,10 +838,10 @@
if(lr){
/* segment table */
if(os->lacing_fill-lr){
- memmove(os->lacing_vals,os->lacing_vals+lr,
- (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
- memmove(os->granule_vals,os->granule_vals+lr,
- (os->lacing_fill-lr)*sizeof(*os->granule_vals));
+ memmove(os->lacing_vals,os->lacing_vals+lr,
+ (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
+ memmove(os->granule_vals,os->granule_vals+lr,
+ (os->lacing_fill-lr)*sizeof(*os->granule_vals));
}
os->lacing_fill-=lr;
os->lacing_packet-=lr;
@@ -716,7 +853,7 @@
if(serialno!=os->serialno)return(-1);
if(version>0)return(-1);
- _os_lacing_expand(os,segments+1);
+ if(_os_lacing_expand(os,segments+1)) return -1;
/* are we in sequence? */
if(pageno!=os->pageno){
@@ -732,25 +869,29 @@
os->lacing_vals[os->lacing_fill++]=0x400;
os->lacing_packet++;
}
+ }
- /* are we a 'continued packet' page? If so, we'll need to skip
- some segments */
- if(continued){
+ /* are we a 'continued packet' page? If so, we may need to skip
+ some segments */
+ if(continued){
+ if(os->lacing_fill<1 ||
+ (os->lacing_vals[os->lacing_fill-1]&0xff)<255 ||
+ os->lacing_vals[os->lacing_fill-1]==0x400){
bos=0;
for(;segptr<segments;segptr++){
- int val=header[27+segptr];
- body+=val;
- bodysize-=val;
- if(val<255){
- segptr++;
- break;
- }
+ int val=header[27+segptr];
+ body+=val;
+ bodysize-=val;
+ if(val<255){
+ segptr++;
+ break;
+ }
}
}
}
-
+
if(bodysize){
- _os_body_expand(os,bodysize);
+ if(_os_body_expand(os,bodysize)) return -1;
memcpy(os->body_data+os->body_fill,body,bodysize);
os->body_fill+=bodysize;
}
@@ -761,20 +902,20 @@
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;
+ 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;
@@ -795,6 +936,8 @@
/* clear things to an initial state. Good to call, eg, before seeking */
int ogg_sync_reset(ogg_sync_state *oy){
+ if(ogg_sync_check(oy))return -1;
+
oy->fill=0;
oy->returned=0;
oy->unsynced=0;
@@ -804,6 +947,8 @@
}
int ogg_stream_reset(ogg_stream_state *os){
+ if(ogg_stream_check(os)) return -1;
+
os->body_fill=0;
os->body_returned=0;
@@ -823,6 +968,7 @@
}
int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
+ if(ogg_stream_check(os)) return -1;
ogg_stream_reset(os);
os->serialno=serialno;
return(0);
@@ -853,7 +999,7 @@
/* Gather the whole packet. We'll have no holes or a partial packet */
{
int size=os->lacing_vals[ptr]&0xff;
- int bytes=size;
+ long bytes=size;
int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
@@ -883,10 +1029,12 @@
}
int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
+ if(ogg_stream_check(os)) return 0;
return _packetout(os,op,1);
}
int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
+ if(ogg_stream_check(os)) return 0;
return _packetout(os,op,0);
}
@@ -901,17 +1049,17 @@
ogg_stream_state os_en, os_de;
ogg_sync_state oy;
-void checkpacket(ogg_packet *op,int len, int no, int pos){
+void checkpacket(ogg_packet *op,long len, int no, long pos){
long j;
static int sequence=0;
static int lastno=0;
if(op->bytes!=len){
- fprintf(stderr,"incorrect packet length!\n");
+ fprintf(stderr,"incorrect packet length (%ld != %ld)!\n",op->bytes,len);
exit(1);
}
if(op->granulepos!=pos){
- fprintf(stderr,"incorrect packet position!\n");
+ fprintf(stderr,"incorrect packet granpos (%ld != %ld)!\n",(long)op->granulepos,pos);
exit(1);
}
@@ -927,7 +1075,7 @@
lastno=no;
if(op->packetno!=sequence){
fprintf(stderr,"incorrect packet sequence %ld != %d\n",
- (long)(op->packetno),sequence);
+ (long)(op->packetno),sequence);
exit(1);
}
@@ -935,7 +1083,7 @@
for(j=0;j<op->bytes;j++)
if(op->packet[j]!=((j+no)&0xff)){
fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
- j,op->packet[j],(j+no)&0xff);
+ j,op->packet[j],(j+no)&0xff);
exit(1);
}
}
@@ -946,7 +1094,7 @@
for(j=0;j<og->body_len;j++)
if(og->body[j]!=data[j]){
fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
- j,data[j],og->body[j]);
+ j,data[j],og->body[j]);
exit(1);
}
@@ -955,7 +1103,7 @@
if(og->header[j]!=header[j]){
fprintf(stderr,"header content mismatch at pos %ld:\n",j);
for(j=0;j<header[26]+27;j++)
- fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
+ fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
fprintf(stderr,"\n");
exit(1);
}
@@ -962,7 +1110,7 @@
}
if(og->header_len!=header[26]+27){
fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
- og->header_len,header[26]+27);
+ og->header_len,header[26]+27);
exit(1);
}
}
@@ -971,21 +1119,21 @@
int j;
fprintf(stderr,"\nHEADER:\n");
fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n",
- og->header[0],og->header[1],og->header[2],og->header[3],
- (int)og->header[4],(int)og->header[5]);
+ og->header[0],og->header[1],og->header[2],og->header[3],
+ (int)og->header[4],(int)og->header[5]);
fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n",
- (og->header[9]<<24)|(og->header[8]<<16)|
- (og->header[7]<<8)|og->header[6],
- (og->header[17]<<24)|(og->header[16]<<16)|
- (og->header[15]<<8)|og->header[14],
- ((long)(og->header[21])<<24)|(og->header[20]<<16)|
- (og->header[19]<<8)|og->header[18]);
+ (og->header[9]<<24)|(og->header[8]<<16)|
+ (og->header[7]<<8)|og->header[6],
+ (og->header[17]<<24)|(og->header[16]<<16)|
+ (og->header[15]<<8)|og->header[14],
+ ((long)(og->header[21])<<24)|(og->header[20]<<16)|
+ (og->header[19]<<8)|og->header[18]);
fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (",
- (int)og->header[22],(int)og->header[23],
- (int)og->header[24],(int)og->header[25],
- (int)og->header[26]);
+ (int)og->header[22],(int)og->header[23],
+ (int)og->header[24],(int)og->header[25],
+ (int)og->header[26]);
for(j=27;j<og->header_len;j++)
fprintf(stderr,"%d ",(int)og->header[j]);
@@ -1002,6 +1150,11 @@
og->body=temp;
}
+void free_page(ogg_page *og){
+ _ogg_free (og->header);
+ _ogg_free (og->body);
+}
+
void error(void){
fprintf(stderr,"error!\n");
exit(1);
@@ -1009,191 +1162,367 @@
/* 17 only */
const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0x15,0xed,0xec,0x91,
- 1,
- 17};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0x15,0xed,0xec,0x91,
+ 1,
+ 17};
/* 17, 254, 255, 256, 500, 510, 600 byte, pad */
const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0x59,0x10,0x6c,0x2c,
- 1,
- 17};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0x59,0x10,0x6c,0x2c,
+ 1,
+ 17};
const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x89,0x33,0x85,0xce,
- 13,
- 254,255,0,255,1,255,245,255,255,0,
- 255,255,90};
+ 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x89,0x33,0x85,0xce,
+ 13,
+ 254,255,0,255,1,255,245,255,255,0,
+ 255,255,90};
/* nil packets; beginning,middle,end */
const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x5c,0x3f,0x66,0xcb,
- 17,
- 17,254,255,0,0,255,1,0,255,245,255,255,0,
- 255,255,90,0};
+ 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x5c,0x3f,0x66,0xcb,
+ 17,
+ 17,254,255,0,0,255,1,0,255,245,255,255,0,
+ 255,255,90,0};
/* large initial packet */
const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0x01,0x27,0x31,0xaa,
- 18,
- 255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,10};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0x01,0x27,0x31,0xaa,
+ 18,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,10};
const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x7f,0x4e,0x8a,0xd2,
- 4,
- 255,4,255,0};
+ 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x7f,0x4e,0x8a,0xd2,
+ 4,
+ 255,4,255,0};
/* continuing packet test */
const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x34,0x24,0xd5,0x29,
- 17,
- 255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255};
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0xf8,0x3c,0x19,0x79,
+ 255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255};
const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
- 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0xc8,0xc3,0xcb,0xed,
- 5,
- 10,255,4,255,0};
+ 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0x38,0xe6,0xb6,0x28,
+ 6,
+ 255,220,255,4,255,0};
+/* spill expansion test */
+const int head1_4b[] = {0x4f,0x67,0x67,0x53,0,0x02,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
+
+const int head2_4b[] = {0x4f,0x67,0x67,0x53,0,0x00,
+ 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0xce,0x8f,0x17,0x1a,
+ 23,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,10,255,4,255,0,0};
+
+
+const int head3_4b[] = {0x4f,0x67,0x67,0x53,0,0x04,
+ 0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0x9b,0xb2,0x50,0xa1,
+ 1,
+ 0};
+
/* page with the 255 segment limit */
const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0xed,0x2a,0x2e,0xa7,
- 255,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10};
+ 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0xed,0x2a,0x2e,0xa7,
+ 255,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10};
const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0x6c,0x3b,0x82,0x3d,
- 1,
- 50};
+ 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0x6c,0x3b,0x82,0x3d,
+ 1,
+ 50};
/* packet that overspans over an entire page */
const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x3c,0xd9,0x4d,0x3f,
- 17,
- 100,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255};
+ 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x68,0x22,0x7c,0x3d,
+ 255,
+ 100,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255};
const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
- 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0xbd,0xd5,0xb5,0x8b,
- 17,
- 255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255};
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0xf4,0x87,0xba,0xf3,
+ 255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255};
const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
- 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,3,0,0,0,
- 0xef,0xdd,0x88,0xde,
- 7,
- 255,255,75,255,4,255,0};
+ 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,3,0,0,0,
+ 0xf7,0x2f,0x6c,0x60,
+ 5,
+ 254,255,4,255,0};
/* packet that overspans over an entire page */
const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0,0,0,0,
+ 0xff,0x7b,0x23,0x17,
+ 1,
+ 0};
const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x3c,0xd9,0x4d,0x3f,
- 17,
- 100,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255};
+ 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,1,0,0,0,
+ 0x68,0x22,0x7c,0x3d,
+ 255,
+ 100,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255};
const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
- 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0xd4,0xe0,0x60,0xe5,
- 1,0};
+ 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,2,0,0,0,
+ 0xd4,0xe0,0x60,0xe5,
+ 1,
+ 0};
-void test_pack(const int *pl, const int **headers){
+int compare_packet(const ogg_packet *op1, const ogg_packet *op2){
+ if(op1->packet!=op2->packet){
+ fprintf(stderr,"op1->packet != op2->packet\n");
+ return(1);
+ }
+ if(op1->bytes!=op2->bytes){
+ fprintf(stderr,"op1->bytes != op2->bytes\n");
+ return(1);
+ }
+ if(op1->b_o_s!=op2->b_o_s){
+ fprintf(stderr,"op1->b_o_s != op2->b_o_s\n");
+ return(1);
+ }
+ if(op1->e_o_s!=op2->e_o_s){
+ fprintf(stderr,"op1->e_o_s != op2->e_o_s\n");
+ return(1);
+ }
+ if(op1->granulepos!=op2->granulepos){
+ fprintf(stderr,"op1->granulepos != op2->granulepos\n");
+ return(1);
+ }
+ if(op1->packetno!=op2->packetno){
+ fprintf(stderr,"op1->packetno != op2->packetno\n");
+ return(1);
+ }
+ return(0);
+}
+
+void test_pack(const int *pl, const int **headers, int byteskip,
+ int pageskip, int packetskip){
unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */
long inptr=0;
long outptr=0;
@@ -1200,14 +1529,19 @@
long deptr=0;
long depacket=0;
long granule_pos=7,pageno=0;
- int i,j,packets,pageout=0;
+ int i,j,packets,pageout=pageskip;
int eosflag=0;
int bosflag=0;
+ int byteskipcount=0;
+
ogg_stream_reset(&os_en);
ogg_stream_reset(&os_de);
ogg_sync_reset(&oy);
+ for(packets=0;packets<packetskip;packets++)
+ depacket+=pl[packets];
+
for(packets=0;;packets++)if(pl[packets]==-1)break;
for(i=0;i<packets;i++){
@@ -1214,7 +1548,7 @@
/* 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);
@@ -1230,88 +1564,111 @@
/* retrieve any finished pages */
{
ogg_page og;
-
+
while(ogg_stream_pageout(&os_en,&og)){
- /* We have a page. Check it carefully */
+ /* We have a page. Check it carefully */
- fprintf(stderr,"%ld, ",pageno);
+ fprintf(stderr,"%ld, ",pageno);
- if(headers[pageno]==NULL){
- fprintf(stderr,"coded too many pages!\n");
- exit(1);
- }
+ if(headers[pageno]==NULL){
+ fprintf(stderr,"coded too many pages!\n");
+ exit(1);
+ }
- check_page(data+outptr,headers[pageno],&og);
+ check_page(data+outptr,headers[pageno],&og);
- outptr+=og.body_len;
- pageno++;
+ outptr+=og.body_len;
+ pageno++;
+ if(pageskip){
+ bosflag=1;
+ pageskip--;
+ deptr+=og.body_len;
+ }
- /* have a complete page; submit it to sync/decode */
+ /* have a complete page; submit it to sync/decode */
- {
- ogg_page og_de;
- ogg_packet op_de,op_de2;
- char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
- memcpy(buf,og.header,og.header_len);
- memcpy(buf+og.header_len,og.body,og.body_len);
- ogg_sync_wrote(&oy,og.header_len+og.body_len);
+ {
+ ogg_page og_de;
+ ogg_packet op_de,op_de2;
+ char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
+ char *next=buf;
+ byteskipcount+=og.header_len;
+ if(byteskipcount>byteskip){
+ memcpy(next,og.header,byteskipcount-byteskip);
+ next+=byteskipcount-byteskip;
+ byteskipcount=byteskip;
+ }
- while(ogg_sync_pageout(&oy,&og_de)>0){
- /* got a page. Happy happy. Verify that it's good. */
-
- check_page(data+deptr,headers[pageout],&og_de);
- deptr+=og_de.body_len;
- pageout++;
+ byteskipcount+=og.body_len;
+ if(byteskipcount>byteskip){
+ memcpy(next,og.body,byteskipcount-byteskip);
+ next+=byteskipcount-byteskip;
+ byteskipcount=byteskip;
+ }
- /* submit it to deconstitution */
- ogg_stream_pagein(&os_de,&og_de);
+ ogg_sync_wrote(&oy,next-buf);
- /* packets out? */
- 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",
- depacket);
- exit(1);
- }
+ while(1){
+ int ret=ogg_sync_pageout(&oy,&og_de);
+ if(ret==0)break;
+ if(ret<0)continue;
+ /* got a page. Happy happy. Verify that it's good. */
- /* verify the packet! */
- /* check data */
- if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
- fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
- depacket);
- exit(1);
- }
- /* check bos flag */
- if(bosflag==0 && op_de.b_o_s==0){
- fprintf(stderr,"b_o_s flag not set on packet!\n");
- exit(1);
- }
- if(bosflag && op_de.b_o_s){
- fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
- exit(1);
- }
- bosflag=1;
- depacket+=op_de.bytes;
-
- /* check eos flag */
- if(eosflag){
- fprintf(stderr,"Multiple decoded packets with eos flag!\n");
- exit(1);
- }
+ fprintf(stderr,"(%d), ",pageout);
- if(op_de.e_o_s)eosflag=1;
+ check_page(data+deptr,headers[pageout],&og_de);
+ deptr+=og_de.body_len;
+ pageout++;
- /* check granulepos flag */
- if(op_de.granulepos!=-1){
- fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
- }
- }
- }
- }
+ /* submit it to deconstitution */
+ ogg_stream_pagein(&os_de,&og_de);
+
+ /* packets out? */
+ 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(compare_packet(&op_de,&op_de2)){
+ fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
+ depacket);
+ exit(1);
+ }
+
+ /* verify the packet! */
+ /* check data */
+ if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
+ fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
+ depacket);
+ exit(1);
+ }
+ /* check bos flag */
+ if(bosflag==0 && op_de.b_o_s==0){
+ fprintf(stderr,"b_o_s flag not set on packet!\n");
+ exit(1);
+ }
+ if(bosflag && op_de.b_o_s){
+ fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
+ exit(1);
+ }
+ bosflag=1;
+ depacket+=op_de.bytes;
+
+ /* check eos flag */
+ if(eosflag){
+ fprintf(stderr,"Multiple decoded packets with eos flag!\n");
+ exit(1);
+ }
+
+ if(op_de.e_o_s)eosflag=1;
+
+ /* check granulepos flag */
+ if(op_de.granulepos!=-1){
+ fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
+ }
+ }
+ }
+ }
}
}
}
@@ -1356,9 +1713,9 @@
/* 17 only */
const int packets[]={17, -1};
const int *headret[]={head1_0,NULL};
-
+
fprintf(stderr,"testing single page encoding... ");
- test_pack(packets,headret);
+ test_pack(packets,headret,0,0,0);
}
{
@@ -1365,9 +1722,9 @@
/* 17, 254, 255, 256, 500, 510, 600 byte, pad */
const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
const int *headret[]={head1_1,head2_1,NULL};
-
+
fprintf(stderr,"testing basic page encoding... ");
- test_pack(packets,headret);
+ test_pack(packets,headret,0,0,0);
}
{
@@ -1374,9 +1731,9 @@
/* nil packets; beginning,middle,end */
const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
const int *headret[]={head1_2,head2_2,NULL};
-
+
fprintf(stderr,"testing basic nil packets... ");
- test_pack(packets,headret);
+ test_pack(packets,headret,0,0,0);
}
{
@@ -1383,77 +1740,97 @@
/* large initial packet */
const int packets[]={4345,259,255,-1};
const int *headret[]={head1_3,head2_3,NULL};
-
+
fprintf(stderr,"testing initial-packet lacing > 4k... ");
- test_pack(packets,headret);
+ test_pack(packets,headret,0,0,0);
}
{
- /* continuing packet test */
- const int packets[]={0,4345,259,255,-1};
+ /* continuing packet test; with page spill expansion, we have to
+ overflow the lacing table. */
+ const int packets[]={0,65500,259,255,-1};
const int *headret[]={head1_4,head2_4,head3_4,NULL};
-
+
fprintf(stderr,"testing single packet page span... ");
- test_pack(packets,headret);
+ test_pack(packets,headret,0,0,0);
}
+ {
+ /* spill expand packet test */
+ const int packets[]={0,4345,259,255,0,0,-1};
+ const int *headret[]={head1_4b,head2_4b,head3_4b,NULL};
+
+ fprintf(stderr,"testing page spill expansion... ");
+ test_pack(packets,headret,0,0,0);
+ }
+
/* page with the 255 segment limit */
{
const int packets[]={0,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,50,-1};
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,
+ 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);
+ test_pack(packets,headret,0,0,0);
}
{
/* packet that overspans over an entire page */
- const int packets[]={0,100,9000,259,255,-1};
+ 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);
+ test_pack(packets,headret,0,0,0);
}
{
+ /* test for the libogg 1.1.1 resync in large continuation bug
+ 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);
+ }
+
+ {
/* term only page. why not? */
- const int packets[]={0,100,4080,-1};
+ 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);
+ test_pack(packets,headret,0,0,0);
}
@@ -1461,16 +1838,16 @@
{
/* build a bunch of pages for testing */
unsigned char *data=_ogg_malloc(1024*1024);
- int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
+ 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);
@@ -1485,8 +1862,8 @@
/* retrieve finished pages */
for(i=0;i<5;i++){
if(ogg_stream_pageout(&os_en,&og[i])==0){
- fprintf(stderr,"Too few pages output building sync tests!\n");
- exit(1);
+ fprintf(stderr,"Too few pages output building sync tests!\n");
+ exit(1);
}
copy_page(&og[i]);
}
@@ -1501,11 +1878,11 @@
ogg_sync_reset(&oy);
ogg_stream_reset(&os_de);
for(i=0;i<5;i++){
- memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
- og[i].header_len);
- ogg_sync_wrote(&oy,og[i].header_len);
- memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
- ogg_sync_wrote(&oy,og[i].body_len);
+ memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
+ og[i].header_len);
+ ogg_sync_wrote(&oy,og[i].header_len);
+ memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
+ ogg_sync_wrote(&oy,og[i].body_len);
}
ogg_sync_pageout(&oy,&temp);
@@ -1518,21 +1895,25 @@
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();
- checkpacket(&test,100,1,-1);
+ checkpacket(&test,1,1,-1);
if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,4079,2,3000);
+ checkpacket(&test,1,2,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,98,3,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,4079,4,5000);
if(ogg_stream_packetout(&os_de,&test)!=-1){
- fprintf(stderr,"Error: loss of page did not return error\n");
- exit(1);
+ fprintf(stderr,"Error: loss of page did not return error\n");
+ exit(1);
}
if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,76,5,-1);
+ checkpacket(&test,76,9,-1);
if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,34,6,-1);
+ checkpacket(&test,34,10,-1);
fprintf(stderr,"ok.\n");
}
@@ -1546,11 +1927,11 @@
ogg_sync_reset(&oy);
ogg_stream_reset(&os_de);
for(i=0;i<5;i++){
- memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
- og[i].header_len);
- ogg_sync_wrote(&oy,og[i].header_len);
- memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
- ogg_sync_wrote(&oy,og[i].body_len);
+ memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
+ og[i].header_len);
+ ogg_sync_wrote(&oy,og[i].header_len);
+ memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
+ ogg_sync_wrote(&oy,og[i].body_len);
}
ogg_sync_pageout(&oy,&temp);
@@ -1565,24 +1946,34 @@
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();
- checkpacket(&test,100,1,-1);
+ checkpacket(&test,1,1,-1);
if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,4079,2,3000);
+ checkpacket(&test,1,2,-1);
if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,2956,3,4000);
+ checkpacket(&test,98,3,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,4079,4,5000);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,1,5,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,1,6,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,2954,7,-1);
+ if(ogg_stream_packetout(&os_de,&test)!=1)error();
+ checkpacket(&test,2057,8,9000);
if(ogg_stream_packetout(&os_de,&test)!=-1){
- fprintf(stderr,"Error: loss of page did not return error\n");
- exit(1);
+ fprintf(stderr,"Error: loss of page did not return error\n");
+ exit(1);
}
if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,300,13,14000);
+ checkpacket(&test,300,17,18000);
fprintf(stderr,"ok.\n");
}
-
+
/* the rest only test sync */
{
ogg_page og_de;
@@ -1590,38 +1981,38 @@
fprintf(stderr,"Testing sync on partial inputs... ");
ogg_sync_reset(&oy);
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- 3);
+ 3);
ogg_sync_wrote(&oy,3);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
+
/* Test fractional page inputs: incomplete fixed header */
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
- 20);
+ 20);
ogg_sync_wrote(&oy,20);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
+
/* Test fractional page inputs: incomplete header */
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
- 5);
+ 5);
ogg_sync_wrote(&oy,5);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
+
/* Test fractional page inputs: incomplete body */
-
+
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
- og[1].header_len-28);
+ og[1].header_len-28);
ogg_sync_wrote(&oy,og[1].header_len-28);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
+
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
ogg_sync_wrote(&oy,1000);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
+
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
- og[1].body_len-1000);
+ og[1].body_len-1000);
ogg_sync_wrote(&oy,og[1].body_len-1000);
if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
+
fprintf(stderr,"ok.\n");
}
@@ -1629,54 +2020,54 @@
{
ogg_page og_de;
fprintf(stderr,"Testing sync on 1+partial inputs... ");
- ogg_sync_reset(&oy);
+ ogg_sync_reset(&oy);
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- og[1].header_len);
+ og[1].header_len);
ogg_sync_wrote(&oy,og[1].header_len);
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
+ og[1].body_len);
ogg_sync_wrote(&oy,og[1].body_len);
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- 20);
+ 20);
ogg_sync_wrote(&oy,20);
if(ogg_sync_pageout(&oy,&og_de)<=0)error();
if(ogg_sync_pageout(&oy,&og_de)>0)error();
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
- og[1].header_len-20);
+ og[1].header_len-20);
ogg_sync_wrote(&oy,og[1].header_len-20);
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
+ og[1].body_len);
ogg_sync_wrote(&oy,og[1].body_len);
if(ogg_sync_pageout(&oy,&og_de)<=0)error();
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);
+ og[1].body_len);
ogg_sync_wrote(&oy,og[1].body_len);
memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- og[1].header_len);
+ og[1].header_len);
ogg_sync_wrote(&oy,og[1].header_len);
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
+ og[1].body_len);
ogg_sync_wrote(&oy,og[1].body_len);
memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
- 20);
+ 20);
ogg_sync_wrote(&oy,20);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
if(ogg_sync_pageout(&oy,&og_de)<=0)error();
@@ -1683,10 +2074,10 @@
if(ogg_sync_pageout(&oy,&og_de)>0)error();
memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
- og[2].header_len-20);
+ og[2].header_len-20);
ogg_sync_wrote(&oy,og[2].header_len-20);
memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
- og[2].body_len);
+ og[2].body_len);
ogg_sync_wrote(&oy,og[2].body_len);
if(ogg_sync_pageout(&oy,&og_de)<=0)error();
@@ -1697,36 +2088,36 @@
{
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);
+ og[1].header_len);
ogg_sync_wrote(&oy,og[1].header_len);
memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
+ og[1].body_len);
ogg_sync_wrote(&oy,og[1].body_len);
memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
- og[2].header_len);
+ og[2].header_len);
ogg_sync_wrote(&oy,og[2].header_len);
memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
- og[2].header_len);
+ og[2].header_len);
ogg_sync_wrote(&oy,og[2].header_len);
if(ogg_sync_pageout(&oy,&og_de)<=0)error();
memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
- og[2].body_len-5);
+ og[2].body_len-5);
ogg_sync_wrote(&oy,og[2].body_len-5);
memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
- og[3].header_len);
+ og[3].header_len);
ogg_sync_wrote(&oy,og[3].header_len);
memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
- og[3].body_len);
+ og[3].body_len);
ogg_sync_wrote(&oy,og[3].body_len);
if(ogg_sync_pageout(&oy,&og_de)>0)error();
@@ -1734,13 +2125,16 @@
fprintf(stderr,"ok.\n");
}
- }
+ /* Free page data that was previously copied */
+ {
+ for(i=0;i<5;i++){
+ free_page(&og[i]);
+ }
+ }
+ }
+
return(0);
}
#endif
-
-
-
-
--- a/sys/src/cmd/audio/libogg/mkfile
+++ b/sys/src/cmd/audio/libogg/mkfile
@@ -1,7 +1,7 @@
</$objtype/mkfile
CC=pcc
-CFLAGS=-I. -c
+CFLAGS=-I. -c
LIB=libogg.a$O
OFILES=\
@@ -12,14 +12,9 @@
ogg/ogg.h\
ogg/os_types.h\
-UPDATE=\
- mkfile\
- $HFILES\
- ${OFILES:%.$O=%.c}\
- ${LIB:/$objtype/%=/386/%}\
-
</sys/src/cmd/mklib
nuke:V:
mk clean
rm -f libogg.a[$OS]
+
--- a/sys/src/cmd/audio/libogg/ogg/config_types.h
+++ /dev/null
@@ -1,10 +1,0 @@
-#ifndef __CONFIG_TYPES_H__
-#define __CONFIG_TYPES_H__
-
-/* these are filled in by configure */
-typedef int16_t ogg_int16_t;
-typedef int32_t ogg_int32_t;
-typedef u_int32_t ogg_uint32_t;
-typedef int64_t ogg_int64_t;
-
-#endif
--- a/sys/src/cmd/audio/libogg/ogg/ogg.h
+++ b/sys/src/cmd/audio/libogg/ogg/ogg.h
@@ -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-2002 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: toplevel libogg include
- last mod: $Id: ogg.h,v 1.18 2002/07/13 10:28:33 giles Exp $
+ last mod: $Id$
********************************************************************/
#ifndef _OGG_H
@@ -23,9 +23,15 @@
#pragma lib "/sys/src/cmd/audio/libogg/libogg.a$O"
+#include <stddef.h>
#include <ogg/os_types.h>
typedef struct {
+ void *iov_base;
+ size_t iov_len;
+} ogg_iovec_t;
+
+typedef struct {
long endbyte;
int endbit;
@@ -55,8 +61,8 @@
int *lacing_vals; /* The values that will go to the segment table */
ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
- this way, but it is simple coupled to the
- lacing fifo */
+ this way, but it is simple coupled to the
+ lacing fifo */
long lacing_storage;
long lacing_fill;
long lacing_packet;
@@ -71,10 +77,10 @@
of a logical bitstream */
long serialno;
long pageno;
- ogg_int64_t packetno; /* sequence number for decode; the framing
+ ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
- (which is in a seperate abstraction
+ (which is in a separate abstraction
layer) also knows about the gap */
ogg_int64_t granulepos;
@@ -90,12 +96,12 @@
long e_o_s;
ogg_int64_t granulepos;
-
+
ogg_int64_t packetno; /* sequence number for decode; the framing
- knows where there's a hole in the data,
- but we need coupling so that the codec
- (which is in a seperate abstraction
- layer) also knows about the gap */
+ knows where there's a hole in the data,
+ but we need coupling so that the codec
+ (which is in a separate abstraction
+ layer) also knows about the gap */
} ogg_packet;
typedef struct {
@@ -112,6 +118,7 @@
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
extern void oggpack_writeinit(oggpack_buffer *b);
+extern int oggpack_writecheck(oggpack_buffer *b);
extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
extern void oggpack_writealign(oggpack_buffer *b);
extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
@@ -129,11 +136,34 @@
extern long oggpack_bits(oggpack_buffer *b);
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
+extern void oggpackB_writeinit(oggpack_buffer *b);
+extern int oggpackB_writecheck(oggpack_buffer *b);
+extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
+extern void oggpackB_writealign(oggpack_buffer *b);
+extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void oggpackB_reset(oggpack_buffer *b);
+extern void oggpackB_writeclear(oggpack_buffer *b);
+extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long oggpackB_look(oggpack_buffer *b,int bits);
+extern long oggpackB_look1(oggpack_buffer *b);
+extern void oggpackB_adv(oggpack_buffer *b,int bits);
+extern void oggpackB_adv1(oggpack_buffer *b);
+extern long oggpackB_read(oggpack_buffer *b,int bits);
+extern long oggpackB_read1(oggpack_buffer *b);
+extern long oggpackB_bytes(oggpack_buffer *b);
+extern long oggpackB_bits(oggpack_buffer *b);
+extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
+
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
+ int count, long e_o_s, ogg_int64_t granulepos);
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 **************************/
@@ -140,7 +170,8 @@
extern int ogg_sync_init(ogg_sync_state *oy);
extern int ogg_sync_clear(ogg_sync_state *oy);
extern int ogg_sync_reset(ogg_sync_state *oy);
-extern int ogg_sync_destroy(ogg_sync_state *oy);
+extern int ogg_sync_destroy(ogg_sync_state *oy);
+extern int ogg_sync_check(ogg_sync_state *oy);
extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
@@ -157,18 +188,19 @@
extern int ogg_stream_reset(ogg_stream_state *os);
extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
extern int ogg_stream_destroy(ogg_stream_state *os);
+extern int ogg_stream_check(ogg_stream_state *os);
extern int ogg_stream_eos(ogg_stream_state *os);
extern void ogg_page_checksum_set(ogg_page *og);
-extern int ogg_page_version(ogg_page *og);
-extern int ogg_page_continued(ogg_page *og);
-extern int ogg_page_bos(ogg_page *og);
-extern int ogg_page_eos(ogg_page *og);
-extern ogg_int64_t ogg_page_granulepos(ogg_page *og);
-extern int ogg_page_serialno(ogg_page *og);
-extern long ogg_page_pageno(ogg_page *og);
-extern int ogg_page_packets(ogg_page *og);
+extern int ogg_page_version(const ogg_page *og);
+extern int ogg_page_continued(const ogg_page *og);
+extern int ogg_page_bos(const ogg_page *og);
+extern int ogg_page_eos(const ogg_page *og);
+extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
+extern int ogg_page_serialno(const ogg_page *og);
+extern long ogg_page_pageno(const ogg_page *og);
+extern int ogg_page_packets(const ogg_page *og);
extern void ogg_packet_clear(ogg_packet *op);
@@ -178,9 +210,3 @@
#endif
#endif /* _OGG_H */
-
-
-
-
-
-
--- a/sys/src/cmd/audio/libogg/ogg/os_types.h
+++ b/sys/src/cmd/audio/libogg/ogg/os_types.h
@@ -9,6 +9,7 @@
#define _ogg_free free
typedef short ogg_int16_t;
+typedef unsigned short ogg_uint16_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;