summaryrefslogtreecommitdiff
path: root/media/libogg/src/ogg_framing.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libogg/src/ogg_framing.c')
-rw-r--r--media/libogg/src/ogg_framing.c215
1 files changed, 109 insertions, 106 deletions
diff --git a/media/libogg/src/ogg_framing.c b/media/libogg/src/ogg_framing.c
index 3a2f0a6058..724d116d7f 100644
--- a/media/libogg/src/ogg_framing.c
+++ b/media/libogg/src/ogg_framing.c
@@ -5,14 +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-2018 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: code raw packets into framed OggSquish stream and
decode Ogg streams back into raw packets
- 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
@@ -20,6 +19,10 @@
********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <limits.h>
#include <string.h>
@@ -45,7 +48,7 @@ int ogg_page_eos(const 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);
+ ogg_uint64_t granulepos=page[13]&(0xff);
granulepos= (granulepos<<8)|(page[12]&0xff);
granulepos= (granulepos<<8)|(page[11]&0xff);
granulepos= (granulepos<<8)|(page[10]&0xff);
@@ -53,21 +56,21 @@ ogg_int64_t ogg_page_granulepos(const ogg_page *og){
granulepos= (granulepos<<8)|(page[8]&0xff);
granulepos= (granulepos<<8)|(page[7]&0xff);
granulepos= (granulepos<<8)|(page[6]&0xff);
- return(granulepos);
+ return((ogg_int64_t)granulepos);
}
int ogg_page_serialno(const ogg_page *og){
- return(og->header[14] |
- (og->header[15]<<8) |
- (og->header[16]<<16) |
- (og->header[17]<<24));
+ return((int)((ogg_uint32_t)og->header[14]) |
+ ((ogg_uint32_t)og->header[15]<<8) |
+ ((ogg_uint32_t)og->header[16]<<16) |
+ ((ogg_uint32_t)og->header[17]<<24));
}
long ogg_page_pageno(const ogg_page *og){
- return(og->header[18] |
- (og->header[19]<<8) |
- (og->header[20]<<16) |
- (og->header[21]<<24));
+ return((long)((ogg_uint32_t)og->header[18]) |
+ ((ogg_uint32_t)og->header[19]<<8) |
+ ((ogg_uint32_t)og->header[20]<<16) |
+ ((ogg_uint32_t)og->header[21]<<24));
}
@@ -99,90 +102,31 @@ int ogg_page_packets(const ogg_page *og){
#if 0
/* helper to initialize lookup for direct-table CRC (illustrative; we
- use the static init below) */
-
-static ogg_uint32_t _ogg_crc_entry(unsigned long index){
- int i;
- unsigned long r;
-
- r = index << 24;
- 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 */
- else
- r<<=1;
- return (r & 0xffffffffUL);
+ use the static init in crctable.h) */
+
+static void _ogg_crc_init(){
+ int i, j;
+ ogg_uint32_t polynomial, crc;
+ polynomial = 0x04c11db7; /* The same as the ethernet generator
+ polynomial, although we use an
+ unreflected alg and an init/final
+ of 0, not 0xffffffff */
+ for (i = 0; i <= 0xFF; i++){
+ crc = i << 24;
+
+ for (j = 0; j < 8; j++)
+ crc = (crc << 1) ^ (crc & (1 << 31) ? polynomial : 0);
+
+ crc_lookup[0][i] = crc;
+ }
+
+ for (i = 0; i <= 0xFF; i++)
+ for (j = 1; j < 8; j++)
+ crc_lookup[j][i] = crc_lookup[0][(crc_lookup[j - 1][i] >> 24) & 0xFF] ^ (crc_lookup[j - 1][i] << 8);
}
#endif
-static const ogg_uint32_t crc_lookup[256]={
- 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
- 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
- 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
- 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
- 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
- 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
- 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
- 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
- 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
- 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
- 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
- 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
- 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
- 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
- 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
- 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
- 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
- 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
- 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
- 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
- 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
- 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
- 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
- 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
- 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
- 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
- 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
- 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
- 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
- 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
- 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
- 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
- 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
- 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
- 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
- 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
- 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
- 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
- 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
- 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
- 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
- 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
- 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
- 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
- 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
- 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
- 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
- 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
- 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
- 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
- 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
- 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
- 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
- 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
- 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
- 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
- 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
- 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
- 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
- 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
- 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
- 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
- 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
- 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
+#include "crctable.h"
/* init the encode/decode logical stream state */
@@ -290,10 +234,27 @@ static int _os_lacing_expand(ogg_stream_state *os,long needed){
/* Direct table CRC; note that this will be faster in the future if we
perform the checksum simultaneously with other copies */
+static ogg_uint32_t _os_update_crc(ogg_uint32_t crc, unsigned char *buffer, int size){
+ while (size>=8){
+ crc^=((ogg_uint32_t)buffer[0]<<24)|((ogg_uint32_t)buffer[1]<<16)|((ogg_uint32_t)buffer[2]<<8)|((ogg_uint32_t)buffer[3]);
+
+ crc=crc_lookup[7][ crc>>24 ]^crc_lookup[6][(crc>>16)&0xFF]^
+ crc_lookup[5][(crc>> 8)&0xFF]^crc_lookup[4][ crc &0xFF]^
+ crc_lookup[3][buffer[4] ]^crc_lookup[2][buffer[5] ]^
+ crc_lookup[1][buffer[6] ]^crc_lookup[0][buffer[7] ];
+
+ buffer+=8;
+ size-=8;
+ }
+
+ while (size--)
+ crc=(crc<<8)^crc_lookup[0][((crc >> 24)&0xff)^*buffer++];
+ return crc;
+}
+
void ogg_page_checksum_set(ogg_page *og){
if(og){
ogg_uint32_t crc_reg=0;
- int i;
/* safety; needed for API behavior, but not framing code */
og->header[22]=0;
@@ -301,10 +262,8 @@ void ogg_page_checksum_set(ogg_page *og){
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]];
+ crc_reg=_os_update_crc(crc_reg,og->header,og->header_len);
+ crc_reg=_os_update_crc(crc_reg,og->body,og->body_len);
og->header[22]=(unsigned char)(crc_reg&0xff);
og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
@@ -414,9 +373,9 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int
}else{
/* The extra packets_done, packet_just_done logic here attempts to do two things:
- 1) Don't unneccessarily span pages.
+ 1) Don't unnecessarily 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
+ them; this expands page size to reduce unnecessary 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
@@ -638,9 +597,14 @@ char *ogg_sync_buffer(ogg_sync_state *oy, long size){
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 */
+ long newsize;
void *ret;
+ if(size>INT_MAX-4096-oy->fill){
+ ogg_sync_clear(oy);
+ return NULL;
+ }
+ newsize=size+oy->fill+4096; /* an extra page to be nice */
if(oy->data)
ret=_ogg_realloc(oy->data,newsize);
else
@@ -723,16 +687,15 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
/* replace the computed checksum with the one actually read in */
memcpy(page+22,chksum,4);
+#ifndef DISABLE_CRC
/* Bad checksum. Lose sync */
goto sync_fail;
+#endif
}
}
/* yes, have a whole page all ready to go */
{
- unsigned char *page=oy->data+oy->returned;
- long bytes;
-
if(og){
og->header=page;
og->header_len=oy->headerbytes;
@@ -875,6 +838,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
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++){
@@ -1492,6 +1456,34 @@ const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
1,
0};
+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 */
@@ -1577,7 +1569,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
byteskipcount=byteskip;
}
- ogg_sync_wrote(&oy,next-buf);
+ ogg_sync_wrote(&oy,(long)(next-buf));
while(1){
int ret=ogg_sync_pageout(&oy,&og_de);
@@ -1600,7 +1592,7 @@ void test_pack(const int *pl, const int **headers, int byteskip,
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))){
+ if(compare_packet(&op_de,&op_de2)){
fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
depacket);
exit(1);
@@ -1785,6 +1777,7 @@ int main(void){
test_pack(packets,headret,0,0,0);
}
+#ifndef DISABLE_CRC
{
/* test for the libogg 1.1.1 resync in large continuation bug
found by Josh Coalson) */
@@ -1794,6 +1787,9 @@ int main(void){
fprintf(stderr,"testing continuation resync in very large packets... ");
test_pack(packets,headret,100,2,3);
}
+#else
+ fprintf(stderr,"Skipping continuation resync test due to --disable-crc\n");
+#endif
{
/* term only page. why not? */
@@ -2055,6 +2051,7 @@ int main(void){
fprintf(stderr,"ok.\n");
}
+#ifndef DISABLE_CRC
/* Test recapture: page + garbage + page */
{
ogg_page og_de;
@@ -2096,6 +2093,9 @@ int main(void){
fprintf(stderr,"ok.\n");
}
+#else
+ fprintf(stderr,"Skipping recapture test due to --disable-crc\n");
+#endif
/* Free page data that was previously copied */
{
@@ -2104,6 +2104,9 @@ int main(void){
}
}
}
+ ogg_sync_clear(&oy);
+ ogg_stream_clear(&os_en);
+ ogg_stream_clear(&os_de);
return(0);
}