diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ogg/bitwise.c | 315 | ||||
-rw-r--r-- | drivers/ogg/framing.c | 202 | ||||
-rw-r--r-- | drivers/ogg/ogg.h | 3 | ||||
-rw-r--r-- | drivers/ogg/os_types.h | 4 |
4 files changed, 389 insertions, 135 deletions
diff --git a/drivers/ogg/bitwise.c b/drivers/ogg/bitwise.c index 3d02198094..145901d185 100644 --- a/drivers/ogg/bitwise.c +++ b/drivers/ogg/bitwise.c @@ -5,13 +5,13 @@ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: packing variable sized words into an octet stream - last mod: $Id: bitwise.c 17287 2010-06-10 13:42:06Z tterribe $ + last mod: $Id: bitwise.c 19149 2014-05-27 16:26:23Z giles $ ********************************************************************/ @@ -93,11 +93,11 @@ void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ b->ptr=b->buffer+b->endbyte; } - value&=mask[bits]; + value&=mask[bits]; bits+=b->endbit; - b->ptr[0]|=value<<b->endbit; - + b->ptr[0]|=value<<b->endbit; + if(bits>=8){ b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); if(bits>=16){ @@ -136,11 +136,11 @@ void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ b->ptr=b->buffer+b->endbyte; } - value=(value&mask[bits])<<(32-bits); + value=(value&mask[bits])<<(32-bits); bits+=b->endbit; - b->ptr[0]|=value>>(24+b->endbit); - + b->ptr[0]|=value>>(24+b->endbit); + if(bits>=8){ b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); if(bits>=16){ @@ -187,37 +187,41 @@ static void oggpack_writecopy_helper(oggpack_buffer *b, unsigned char *ptr=(unsigned char *)source; long bytes=bits/8; + long pbytes=(b->endbit+bits)/8; bits-=bytes*8; + /* expand storage up-front */ + if(b->endbyte+pbytes>=b->storage){ + void *ret; + if(!b->ptr) goto err; + if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err; + b->storage=b->endbyte+pbytes+BUFFER_INCREMENT; + ret=_ogg_realloc(b->buffer,b->storage); + if(!ret) goto err; + b->buffer=ret; + b->ptr=b->buffer+b->endbyte; + } + + /* copy whole octets */ if(b->endbit){ int i; /* unaligned copy. Do it the hard way. */ for(i=0;i<bytes;i++) - w(b,(unsigned long)(ptr[i]),8); + w(b,(unsigned long)(ptr[i]),8); }else{ /* aligned block copy */ - if(b->endbyte+bytes+1>=b->storage){ - void *ret; - if(!b->ptr) goto err; - if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err; - b->storage=b->endbyte+bytes+BUFFER_INCREMENT; - ret=_ogg_realloc(b->buffer,b->storage); - if(!ret) goto err; - b->buffer=ret; - b->ptr=b->buffer+b->endbyte; - } - memmove(b->ptr,source,bytes); b->ptr+=bytes; b->endbyte+=bytes; *b->ptr=0; - } + + /* copy trailing bits */ if(bits){ if(msb) - w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); + w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); else - w(b,(unsigned long)(ptr[bytes]),bits); + w(b,(unsigned long)(ptr[bytes]),bits); } return; err: @@ -281,11 +285,11 @@ long oggpack_look(oggpack_buffer *b,int bits){ ret=b->ptr[0]>>b->endbit; if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); + ret|=b->ptr[1]<<(8-b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); + ret|=b->ptr[2]<<(16-b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); + ret|=b->ptr[3]<<(24-b->endbit); if(bits>32 && b->endbit) ret|=b->ptr[4]<<(32-b->endbit); } @@ -312,11 +316,11 @@ long oggpackB_look(oggpack_buffer *b,int bits){ ret=b->ptr[0]<<(24+b->endbit); if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); + ret|=b->ptr[1]<<(16+b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); + ret|=b->ptr[2]<<(8+b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); + ret|=b->ptr[3]<<(b->endbit); if(bits>32 && b->endbit) ret|=b->ptr[4]>>(8-b->endbit); } @@ -386,11 +390,11 @@ long oggpack_read(oggpack_buffer *b,int bits){ ret=b->ptr[0]>>b->endbit; if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); + ret|=b->ptr[1]<<(8-b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); + ret|=b->ptr[2]<<(16-b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); + ret|=b->ptr[3]<<(24-b->endbit); if(bits>32 && b->endbit){ ret|=b->ptr[4]<<(32-b->endbit); } @@ -429,11 +433,11 @@ long oggpackB_read(oggpack_buffer *b,int bits){ ret=b->ptr[0]<<(24+b->endbit); if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); + ret|=b->ptr[1]<<(16+b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); + ret|=b->ptr[2]<<(8+b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); + ret|=b->ptr[3]<<(b->endbit); if(bits>32 && b->endbit) ret|=b->ptr[4]>>(8-b->endbit); } @@ -511,7 +515,7 @@ long oggpackB_bytes(oggpack_buffer *b){ long oggpackB_bits(oggpack_buffer *b){ return oggpack_bits(b); } - + unsigned char *oggpack_get_buffer(oggpack_buffer *b){ return(b->buffer); } @@ -534,7 +538,7 @@ static int ilog(unsigned int v){ } return(ret); } - + oggpack_buffer o; oggpack_buffer r; @@ -581,7 +585,7 @@ void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ long bytes,i; unsigned char *buffer; - + oggpackB_reset(&o); for(i=0;i<vals;i++) oggpackB_write(&o,b[i],bits?bits:ilog(b[i])); @@ -613,9 +617,190 @@ void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); } +void copytest(int prefill, int copy){ + oggpack_buffer source_write; + oggpack_buffer dest_write; + oggpack_buffer source_read; + oggpack_buffer dest_read; + unsigned char *source; + unsigned char *dest; + long source_bytes,dest_bytes; + int i; + + oggpack_writeinit(&source_write); + oggpack_writeinit(&dest_write); + + for(i=0;i<(prefill+copy+7)/8;i++) + oggpack_write(&source_write,(i^0x5a)&0xff,8); + source=oggpack_get_buffer(&source_write); + source_bytes=oggpack_bytes(&source_write); + + /* prefill */ + oggpack_writecopy(&dest_write,source,prefill); + + /* check buffers; verify end byte masking */ + dest=oggpack_get_buffer(&dest_write); + dest_bytes=oggpack_bytes(&dest_write); + if(dest_bytes!=(prefill+7)/8){ + fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8); + exit(1); + } + oggpack_readinit(&source_read,source,source_bytes); + oggpack_readinit(&dest_read,dest,dest_bytes); + + for(i=0;i<prefill;i+=8){ + int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8); + int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8); + if(s!=d){ + fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); + exit(1); + } + } + if(prefill<dest_bytes){ + if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){ + fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill); + exit(1); + } + } + + /* second copy */ + oggpack_writecopy(&dest_write,source,copy); + + /* check buffers; verify end byte masking */ + dest=oggpack_get_buffer(&dest_write); + dest_bytes=oggpack_bytes(&dest_write); + if(dest_bytes!=(copy+prefill+7)/8){ + fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8); + exit(1); + } + oggpack_readinit(&source_read,source,source_bytes); + oggpack_readinit(&dest_read,dest,dest_bytes); + + for(i=0;i<prefill;i+=8){ + int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8); + int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8); + if(s!=d){ + fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); + exit(1); + } + } + + oggpack_readinit(&source_read,source,source_bytes); + for(i=0;i<copy;i+=8){ + int s=oggpack_read(&source_read,copy-i<8?copy-i:8); + int d=oggpack_read(&dest_read,copy-i<8?copy-i:8); + if(s!=d){ + fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d); + exit(1); + } + } + + if(copy+prefill<dest_bytes){ + if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){ + fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy); + exit(1); + } + } + + oggpack_writeclear(&source_write); + oggpack_writeclear(&dest_write); + + +} + +void copytestB(int prefill, int copy){ + oggpack_buffer source_write; + oggpack_buffer dest_write; + oggpack_buffer source_read; + oggpack_buffer dest_read; + unsigned char *source; + unsigned char *dest; + long source_bytes,dest_bytes; + int i; + + oggpackB_writeinit(&source_write); + oggpackB_writeinit(&dest_write); + + for(i=0;i<(prefill+copy+7)/8;i++) + oggpackB_write(&source_write,(i^0x5a)&0xff,8); + source=oggpackB_get_buffer(&source_write); + source_bytes=oggpackB_bytes(&source_write); + + /* prefill */ + oggpackB_writecopy(&dest_write,source,prefill); + + /* check buffers; verify end byte masking */ + dest=oggpackB_get_buffer(&dest_write); + dest_bytes=oggpackB_bytes(&dest_write); + if(dest_bytes!=(prefill+7)/8){ + fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8); + exit(1); + } + oggpackB_readinit(&source_read,source,source_bytes); + oggpackB_readinit(&dest_read,dest,dest_bytes); + + for(i=0;i<prefill;i+=8){ + int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8); + int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8); + if(s!=d){ + fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); + exit(1); + } + } + if(prefill<dest_bytes){ + if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){ + fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill); + exit(1); + } + } + + /* second copy */ + oggpackB_writecopy(&dest_write,source,copy); + + /* check buffers; verify end byte masking */ + dest=oggpackB_get_buffer(&dest_write); + dest_bytes=oggpackB_bytes(&dest_write); + if(dest_bytes!=(copy+prefill+7)/8){ + fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8); + exit(1); + } + oggpackB_readinit(&source_read,source,source_bytes); + oggpackB_readinit(&dest_read,dest,dest_bytes); + + for(i=0;i<prefill;i+=8){ + int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8); + int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8); + if(s!=d){ + fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); + exit(1); + } + } + + oggpackB_readinit(&source_read,source,source_bytes); + for(i=0;i<copy;i+=8){ + int s=oggpackB_read(&source_read,copy-i<8?copy-i:8); + int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8); + if(s!=d){ + fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d); + exit(1); + } + } + + if(copy+prefill<dest_bytes){ + if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){ + fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy); + exit(1); + } + } + + oggpackB_writeclear(&source_write); + oggpackB_writeclear(&dest_write); + +} + int main(void){ unsigned char *buffer; - long bytes,i; + long bytes,i,j; static unsigned long testbuffer1[]= {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; @@ -761,7 +946,31 @@ int main(void){ exit(1); } oggpack_writeclear(&o); - fprintf(stderr,"ok.\n"); + fprintf(stderr,"ok."); + + /* this is partly glassbox; we're mostly concerned about the allocation boundaries */ + + fprintf(stderr,"\nTesting aligned writecopies (LSb): "); + for(i=0;i<71;i++) + for(j=0;j<5;j++) + copytest(j*8,i); + for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) + for(j=0;j<5;j++) + copytest(j*8,i); + fprintf(stderr,"ok. "); + + fprintf(stderr,"\nTesting unaligned writecopies (LSb): "); + for(i=0;i<71;i++) + for(j=1;j<40;j++) + if(j&0x7) + copytest(j,i); + for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) + for(j=1;j<40;j++) + if(j&0x7) + copytest(j,i); + + fprintf(stderr,"ok. \n"); + /********** lazy, cut-n-paste retest with MSb packing ***********/ @@ -846,12 +1055,34 @@ int main(void){ fprintf(stderr,"failed; read past end without -1.\n"); exit(1); } + fprintf(stderr,"ok."); oggpackB_writeclear(&o); - fprintf(stderr,"ok.\n\n"); + /* this is partly glassbox; we're mostly concerned about the allocation boundaries */ + + fprintf(stderr,"\nTesting aligned writecopies (MSb): "); + for(i=0;i<71;i++) + for(j=0;j<5;j++) + copytestB(j*8,i); + for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) + for(j=0;j<5;j++) + copytestB(j*8,i); + fprintf(stderr,"ok. "); + + fprintf(stderr,"\nTesting unaligned writecopies (MSb): "); + for(i=0;i<71;i++) + for(j=1;j<40;j++) + if(j&0x7) + copytestB(j,i); + for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) + for(j=1;j<40;j++) + if(j&0x7) + copytestB(j,i); + + fprintf(stderr,"ok. \n\n"); return(0); -} +} #endif /* _V_SELFTEST */ #undef BUFFER_INCREMENT diff --git a/drivers/ogg/framing.c b/drivers/ogg/framing.c index 25f0e88dbc..3a2f0a6058 100644 --- a/drivers/ogg/framing.c +++ b/drivers/ogg/framing.c @@ -12,7 +12,7 @@ function: code raw packets into framed OggSquish stream and decode Ogg streams back into raw packets - last mod: $Id: framing.c 17592 2010-11-01 20:27:54Z xiphmont $ + last mod: $Id: framing.c 18758 2013-01-08 16:29:56Z tterribe $ note: The CRC code is directly derived from public domain code by Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html @@ -21,6 +21,7 @@ ********************************************************************/ #include <stdlib.h> +#include <limits.h> #include <string.h> #include <ogg/ogg.h> @@ -61,7 +62,7 @@ int ogg_page_serialno(const ogg_page *og){ (og->header[16]<<16) | (og->header[17]<<24)); } - + long ogg_page_pageno(const ogg_page *og){ return(og->header[18] | (og->header[19]<<8) | @@ -76,16 +77,16 @@ long ogg_page_pageno(const ogg_page *og){ page, it's counted */ /* NOTE: -If a page consists of a packet begun on a previous page, and a new -packet begun (but not completed) on this page, the return will be: - ogg_page_packets(page) ==1, - ogg_page_continued(page) !=0 - -If a page 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 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 */ int ogg_page_packets(const ogg_page *og){ @@ -205,7 +206,7 @@ int ogg_stream_init(ogg_stream_state *os,int serialno){ return(0); } return(-1); -} +} /* async/delayed error detection for the ogg_stream_state */ int ogg_stream_check(ogg_stream_state *os){ @@ -220,10 +221,10 @@ int ogg_stream_clear(ogg_stream_state *os){ if(os->lacing_vals)_ogg_free(os->lacing_vals); if(os->granule_vals)_ogg_free(os->granule_vals); - memset(os,0,sizeof(*os)); + memset(os,0,sizeof(*os)); } return(0); -} +} int ogg_stream_destroy(ogg_stream_state *os){ if(os){ @@ -231,44 +232,56 @@ int ogg_stream_destroy(ogg_stream_state *os){ _ogg_free(os); } return(0); -} +} /* Helpers for ogg_stream_encode; this keeps the structure and what's happening fairly clear */ -static int _os_body_expand(ogg_stream_state *os,int needed){ - if(os->body_storage<=os->body_fill+needed){ +static int _os_body_expand(ogg_stream_state *os,long needed){ + if(os->body_storage-needed<=os->body_fill){ + long body_storage; void *ret; - ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)* - sizeof(*os->body_data)); + if(os->body_storage>LONG_MAX-needed){ + ogg_stream_clear(os); + return -1; + } + body_storage=os->body_storage+needed; + if(body_storage<LONG_MAX-1024)body_storage+=1024; + ret=_ogg_realloc(os->body_data,body_storage*sizeof(*os->body_data)); if(!ret){ ogg_stream_clear(os); return -1; } - os->body_storage+=(needed+1024); + os->body_storage=body_storage; os->body_data=ret; } return 0; } -static int _os_lacing_expand(ogg_stream_state *os,int needed){ - if(os->lacing_storage<=os->lacing_fill+needed){ +static int _os_lacing_expand(ogg_stream_state *os,long needed){ + if(os->lacing_storage-needed<=os->lacing_fill){ + long lacing_storage; void *ret; - ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)* - sizeof(*os->lacing_vals)); + if(os->lacing_storage>LONG_MAX-needed){ + ogg_stream_clear(os); + return -1; + } + lacing_storage=os->lacing_storage+needed; + if(lacing_storage<LONG_MAX-32)lacing_storage+=32; + ret=_ogg_realloc(os->lacing_vals,lacing_storage*sizeof(*os->lacing_vals)); if(!ret){ ogg_stream_clear(os); return -1; } os->lacing_vals=ret; - ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)* + ret=_ogg_realloc(os->granule_vals,lacing_storage* sizeof(*os->granule_vals)); if(!ret){ ogg_stream_clear(os); return -1; } os->granule_vals=ret; - os->lacing_storage+=(needed+32); + os->lacing_storage=lacing_storage; } return 0; } @@ -287,12 +300,12 @@ void ogg_page_checksum_set(ogg_page *og){ og->header[23]=0; og->header[24]=0; og->header[25]=0; - + for(i=0;i<og->header_len;i++) crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]]; for(i=0;i<og->body_len;i++) crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]]; - + og->header[22]=(unsigned char)(crc_reg&0xff); og->header[23]=(unsigned char)((crc_reg>>8)&0xff); og->header[24]=(unsigned char)((crc_reg>>16)&0xff); @@ -304,26 +317,31 @@ void ogg_page_checksum_set(ogg_page *og){ int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count, long e_o_s, ogg_int64_t granulepos){ - int bytes = 0, lacing_vals, i; + long bytes = 0, lacing_vals; + int i; if(ogg_stream_check(os)) return -1; if(!iov) return 0; - - for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len; + + for (i = 0; i < count; ++i){ + if(iov[i].iov_len>LONG_MAX) return -1; + if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1; + bytes += (long)iov[i].iov_len; + } lacing_vals=bytes/255+1; if(os->body_returned){ /* advance packet data according to the body_returned pointer. We had to keep it around to return a pointer into the buffer last call */ - + os->body_fill-=os->body_returned; if(os->body_fill) memmove(os->body_data,os->body_data+os->body_returned, os->body_fill); os->body_returned=0; } - + /* make sure we have the buffer storage */ if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals)) return -1; @@ -467,33 +485,33 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int pageno>>=8; } } - + /* zero for computation; filled in later */ os->header[22]=0; os->header[23]=0; os->header[24]=0; os->header[25]=0; - + /* segment table */ os->header[26]=(unsigned char)(vals&0xff); for(i=0;i<vals;i++) bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff); - + /* set pointers in the ogg_page struct */ og->header=os->header; og->header_len=os->header_fill=vals+27; og->body=os->body_data+os->body_returned; og->body_len=bytes; - + /* advance the lacing data and set the body_returned pointer */ - + os->lacing_fill-=vals; memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals)); memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals)); os->body_returned+=bytes; - + /* calculate the checksum */ - + ogg_page_checksum_set(og); /* done */ @@ -512,12 +530,20 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int since ogg_stream_flush will flush the last page in a stream even if it's undersized, you almost certainly want to use ogg_stream_pageout (and *not* ogg_stream_flush) unless you specifically need to flush - an page regardless of size in the middle of a stream. */ + a page regardless of size in the middle of a stream. */ int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ return ogg_stream_flush_i(os,og,1,4096); } +/* Like the above, but an argument is provided to adjust the nominal + page size for applications which are smart enough to provide their + own delay based flushing */ + +int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){ + return ogg_stream_flush_i(os,og,1,nfill); +} + /* This constructs pages from buffered packet segments. The pointers returned are to static buffers; do not free. The returned buffers are good only until the next call (using the same ogg_stream_state) */ @@ -533,10 +559,10 @@ int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){ return(ogg_stream_flush_i(os,og,force,4096)); } -/* Like the above, but an argument is provided to adjust the nominal +/* Like the above, but an argument is provided to adjust the nominal page size for applications which are smart enough to provide their own delay based flushing */ - + int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){ int force=0; if(ogg_stream_check(os)) return 0; @@ -645,7 +671,7 @@ int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ -n) skipped n bytes 0) page not ready; more data (no bytes skipped) n) page synced at current location; page length n bytes - + */ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ @@ -654,54 +680,54 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ long bytes=oy->fill-oy->returned; if(ogg_sync_check(oy))return 0; - + if(oy->headerbytes==0){ int headerbytes,i; if(bytes<27)return(0); /* not enough for a header */ - + /* verify capture pattern */ if(memcmp(page,"OggS",4))goto sync_fail; - + headerbytes=page[26]+27; if(bytes<headerbytes)return(0); /* not enough for header + seg table */ - + /* count up body length in the segment table */ - + for(i=0;i<page[26];i++) oy->bodybytes+=page[27+i]; oy->headerbytes=headerbytes; } - + if(oy->bodybytes+oy->headerbytes>bytes)return(0); - + /* The whole test page is buffered. Verify the checksum */ { /* Grab the checksum bytes, set the header field to zero */ char chksum[4]; ogg_page log; - + memcpy(chksum,page+22,4); memset(page+22,0,4); - + /* set up a temp page struct and recompute the checksum */ log.header=page; log.header_len=oy->headerbytes; log.body=page+oy->headerbytes; log.body_len=oy->bodybytes; ogg_page_checksum_set(&log); - + /* Compare */ if(memcmp(chksum,page+22,4)){ /* D'oh. Mismatch! Corrupt page (or miscapture and not a page at all) */ /* replace the computed checksum with the one actually read in */ memcpy(page+22,chksum,4); - + /* Bad checksum. Lose sync */ goto sync_fail; } } - + /* yes, have a whole page all ready to go */ { unsigned char *page=oy->data+oy->returned; @@ -720,12 +746,12 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ oy->bodybytes=0; return(bytes); } - + sync_fail: - + oy->headerbytes=0; oy->bodybytes=0; - + /* search for possible capture */ next=memchr(page+1,'O',bytes-1); if(!next) @@ -764,7 +790,7 @@ int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ /* need more data */ return(0); } - + /* head did not start a synced page... skipped some bytes */ if(!oy->unsynced){ oy->unsynced=1; @@ -793,7 +819,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ int serialno=ogg_page_serialno(og); long pageno=ogg_page_pageno(og); int segments=header[26]; - + if(ogg_stream_check(os)) return -1; /* clean up 'returned data' */ @@ -848,7 +874,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ /* are we a 'continued packet' page? If so, we may need to skip some segments */ if(continued){ - if(os->lacing_fill<1 || + if(os->lacing_fill<1 || os->lacing_vals[os->lacing_fill-1]==0x400){ bos=0; for(;segptr<segments;segptr++){ @@ -862,7 +888,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ } } } - + if(bodysize){ if(_os_body_expand(os,bodysize)) return -1; memcpy(os->body_data+os->body_fill,body,bodysize); @@ -875,20 +901,20 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ int val=header[27+segptr]; os->lacing_vals[os->lacing_fill]=val; os->granule_vals[os->lacing_fill]=-1; - + if(bos){ os->lacing_vals[os->lacing_fill]|=0x100; bos=0; } - + if(val<255)saved=os->lacing_fill; - + os->lacing_fill++; segptr++; - + if(val<255)os->lacing_packet=os->lacing_fill; } - + /* set the granulepos on the last granuleval of the last full packet */ if(saved!=-1){ os->granule_vals[saved]=granulepos; @@ -1493,7 +1519,7 @@ void test_pack(const int *pl, const int **headers, int byteskip, /* construct a test packet */ ogg_packet op; int len=pl[i]; - + op.packet=data+inptr; op.bytes=len; op.e_o_s=(pl[i+1]<0?1:0); @@ -1509,7 +1535,7 @@ void test_pack(const int *pl, const int **headers, int byteskip, /* retrieve any finished pages */ { ogg_page og; - + while(ogg_stream_pageout(&os_en,&og)){ /* We have a page. Check it carefully */ @@ -1558,7 +1584,7 @@ void test_pack(const int *pl, const int **headers, int byteskip, if(ret==0)break; if(ret<0)continue; /* got a page. Happy happy. Verify that it's good. */ - + fprintf(stderr,"(%d), ",pageout); check_page(data+deptr,headers[pageout],&og_de); @@ -1572,7 +1598,7 @@ void test_pack(const int *pl, const int **headers, int byteskip, while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ ogg_stream_packetpeek(&os_de,NULL); ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ - + /* verify peek and out match */ if(memcmp(&op_de,&op_de2,sizeof(op_de))){ fprintf(stderr,"packetout != packetpeek! pos=%ld\n", @@ -1598,7 +1624,7 @@ void test_pack(const int *pl, const int **headers, int byteskip, } bosflag=1; depacket+=op_de.bytes; - + /* check eos flag */ if(eosflag){ fprintf(stderr,"Multiple decoded packets with eos flag!\n"); @@ -1745,7 +1771,7 @@ int main(void){ 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,50,-1}; const int *headret[]={head1_5,head2_5,head3_5,NULL}; - + fprintf(stderr,"testing max packet segments... "); test_pack(packets,headret,0,0,0); } @@ -1754,7 +1780,7 @@ int main(void){ /* packet that overspans over an entire page */ const int packets[]={0,100,130049,259,255,-1}; const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; - + fprintf(stderr,"testing very large packets... "); test_pack(packets,headret,0,0,0); } @@ -1764,7 +1790,7 @@ int main(void){ found by Josh Coalson) */ const int packets[]={0,100,130049,259,255,-1}; const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; - + fprintf(stderr,"testing continuation resync in very large packets... "); test_pack(packets,headret,100,2,3); } @@ -1773,7 +1799,7 @@ int main(void){ /* term only page. why not? */ const int packets[]={0,100,64770,-1}; const int *headret[]={head1_7,head2_7,head3_7,NULL}; - + fprintf(stderr,"testing zero data page (1 nil packet)... "); test_pack(packets,headret,0,0,0); } @@ -1786,13 +1812,13 @@ int main(void){ int pl[]={0, 1,1,98,4079, 1,1,2954,2057, 76,34,912,0,234,1000,1000, 1000,300,-1}; int inptr=0,i,j; ogg_page og[5]; - + ogg_stream_reset(&os_en); for(i=0;pl[i]!=-1;i++){ ogg_packet op; int len=pl[i]; - + op.packet=data+inptr; op.bytes=len; op.e_o_s=(pl[i+1]<0?1:0); @@ -1840,7 +1866,7 @@ int main(void){ ogg_stream_pagein(&os_de,&temp); /* do we get the expected results/packets? */ - + if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,0,0,0); if(ogg_stream_packetout(&os_de,&test)!=1)error(); @@ -1991,13 +2017,13 @@ int main(void){ fprintf(stderr,"ok.\n"); } - + /* Test recapture: garbage + page */ { ogg_page og_de; fprintf(stderr,"Testing search for capture... "); - ogg_sync_reset(&oy); - + ogg_sync_reset(&oy); + /* 'garbage' */ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); @@ -2033,7 +2059,7 @@ int main(void){ { ogg_page og_de; fprintf(stderr,"Testing recapture... "); - ogg_sync_reset(&oy); + ogg_sync_reset(&oy); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, og[1].header_len); @@ -2077,13 +2103,9 @@ int main(void){ free_page(&og[i]); } } - } + } return(0); } #endif - - - - diff --git a/drivers/ogg/ogg.h b/drivers/ogg/ogg.h index cea5c16edc..cea4ebed75 100644 --- a/drivers/ogg/ogg.h +++ b/drivers/ogg/ogg.h @@ -11,7 +11,7 @@ ******************************************************************** function: toplevel libogg include - last mod: $Id: ogg.h 17571 2010-10-27 13:28:20Z xiphmont $ + last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $ ********************************************************************/ #ifndef _OGG_H @@ -161,6 +161,7 @@ extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); /* Ogg BITSTREAM PRIMITIVES: decoding **************************/ diff --git a/drivers/ogg/os_types.h b/drivers/ogg/os_types.h index d6691b703d..8bf82107e5 100644 --- a/drivers/ogg/os_types.h +++ b/drivers/ogg/os_types.h @@ -11,7 +11,7 @@ ******************************************************************** function: #ifdef jail to whip a few platforms into the UNIX ideal. - last mod: $Id: os_types.h 17712 2010-12-03 17:10:02Z xiphmont $ + last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $ ********************************************************************/ #ifndef _OS_TYPES_H @@ -24,7 +24,7 @@ #define _ogg_realloc realloc #define _ogg_free free -#if defined(_WIN32) +#if defined(_WIN32) # if defined(__CYGWIN__) # include <stdint.h> |