From 42ec2370c0a1e47b5f2f8745f7d98fdda089ec1d Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 4 Oct 1999 18:02:43 +0000 Subject: [PATCH] Info struct needs initializer so that we know if we've not gotten the initial header (*never* let a bad bitstream crash us!) Monty svn path=/trunk/vorbis/; revision=137 --- lib/codec.h | 25 +++++------ lib/info.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 131 insertions(+), 35 deletions(-) diff --git a/lib/codec.h b/lib/codec.h index 8f8c622..82eb1ba 100644 --- a/lib/codec.h +++ b/lib/codec.h @@ -80,7 +80,7 @@ typedef struct vorbis_info{ int version; char **user_comments; - int max_comment; + int comments; char *vendor; int smallblock; @@ -291,17 +291,18 @@ extern int ogg_page_pageno(ogg_page *og); /* Vorbis PRIMITIVES: general ***************************************/ -extern int vorbis_info_clear(vorbis_info *vi); -extern int vorbis_info_modeset(vorbis_info *vi, int mode); -extern int vorbis_info_addcomment(vorbis_info *vi, char *comment); -extern int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op); -extern int vorbis_info_headerout(vorbis_info *vi, - ogg_packet *op, - ogg_packet *op_comm, - ogg_packet *op_code); - -extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); -extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_info_init(vorbis_info *vi); +extern int vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_modeset(vorbis_info *vi, int mode); +extern int vorbis_info_addcomment(vorbis_info *vi, char *comment); +extern int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op); +extern int vorbis_info_headerout(vorbis_info *vi, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); /* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); diff --git a/lib/info.c b/lib/info.c index ee74ba2..e8b96bb 100644 --- a/lib/info.c +++ b/lib/info.c @@ -14,7 +14,7 @@ function: maintain the info structure, info <-> header packets author: Monty modifications by: Monty - last modification date: Oct 03 1999 + last modification date: Oct 04 1999 ********************************************************************/ @@ -27,6 +27,10 @@ #include "modes.h" #include "bitwise.h" +void vorbis_info_init(vorbis_info *vi){ + memset(vi,0,sizeof(vorbis_info)); +} + /* one test mode for now; temporary of course */ int vorbis_info_modeset(vorbis_info *vi, int mode){ if(mode<0 || mode>predef_mode_max)return(-1); @@ -42,26 +46,23 @@ int vorbis_info_modeset(vorbis_info *vi, int mode){ /* convenience function */ int vorbis_info_add_comment(vorbis_info *vi,char *comment){ vi->user_comments=realloc(vi->user_comments, - (vi->max_comment+2)*sizeof(char *)); - vi->user_comments[vi->max_comment]=strdup(comment); - vi->max_comment++; - vi->user_comments[vi->max_comment]=NULL; + (vi->comments+1)*sizeof(char *)); + vi->user_comments[vi->comments]=strdup(comment); + vi->comments++; + vi->user_comments[vi->comments]=NULL; return(0); } -static int _v_writestring(oggpack_buffer *o,char *s){ +static void _v_writestring(oggpack_buffer *o,char *s){ while(*s){ _oggpack_write(o,*s++,8); } } -static char *_v_readstring(oggpack_buffer *o,int bytes){ - char *ret=calloc(bytes+1,1); - char *ptr=ret; +static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ while(bytes--){ - *ptr++=_oggpack_read(o,8); + *buf++=_oggpack_read(o,8); } - return(ret); } /* The Vorbis header is in three packets; the initial small packet in @@ -71,6 +72,84 @@ static char *_v_readstring(oggpack_buffer *o,int bytes){ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){ + oggpack_buffer opb; + + if(op){ + _oggpack_readinit(&opb,op->packet,op->bytes); + + /* Which of the three types of header is this? */ + /* Also verify header-ness, vorbis */ + { + char buffer[6]; + int type; + memset(buffer,0,6); + _v_readstring(&opb,buffer,6); + if(memcmp(buffer,"vorbis",6)){ + /* not a vorbis header */ + return(-1); + } + switch(_oggpack_read(&opb,8)){ + case 0: + if(!op->b_o_s){ + /* Not the initial packet */ + return(-1); + } + if(vi->rate!=0){ + /* previously initialized info header */ + return(-1); + } + + vi->channels=_oggpack_read(&opb,32); + vi->rate=_oggpack_read(&opb,32); + vi->smallblock=_oggpack_read(&opb,32); + vi->largeblock=_oggpack_read(&opb,32); + vi->envelopesa=_oggpack_read(&opb,32); + vi->envelopech=_oggpack_read(&opb,16); + vi->floororder=_oggpack_read(&opb,8); + vi->flooroctaves=_oggpack_read(&opb,8); + vi->floorch=_oggpack_read(&opb,16); + + return(0); + case 1: + if(vi->rate==0){ + /* um... we didn;t get the initial header */ + return(-1); + } + { + int vendorlen=_oggpack_read(&opb,32); + vi->vendor=calloc(vendorlen+1,1); + _v_readstring(&opb,vi->vendor,vendorlen); + } + { + int i; + vi->comments=_oggpack_read(&opb,32); + vi->user_comments=calloc(vi->comments+1,sizeof(char **)); + + for(i=0;i<=vi->comments;i++){ + int len=_oggpack_read(&opb,32); + vi->user_comments[i]=calloc(len+1,1); + _v_readstring(&opb,vi->user_comments[i],len); + } + } + + return(0); + case 2: + if(vi->rate==0){ + /* um... we didn;t get the initial header */ + return(-1); + } + + /* not implemented quite yet */ + + return(0); + default: + /* Not a valid vorbis header type */ + return(-1); + break; + } + } + } + return(-1); } int vorbis_info_headerout(vorbis_info *vi, @@ -82,6 +161,7 @@ int vorbis_info_headerout(vorbis_info *vi, /* initial header: codec id "vorbis" + header id 0 (byte) codec ver (4 octets, lsb first: currently 0x00) pcm channels (4 octets, lsb first) pcm rate (4 octets, lsb first) @@ -96,7 +176,9 @@ int vorbis_info_headerout(vorbis_info *vi, */ _oggpack_writeinit(&opb); - _v_writestring(&obp,"vorbis"); + _v_writestring(&opb,"vorbis"); + _oggpack_write(&opb,0x00,8); + _oggpack_write(&opb,0x00,32); _oggpack_write(&opb,vi->channels,32); @@ -104,14 +186,14 @@ int vorbis_info_headerout(vorbis_info *vi, _oggpack_write(&opb,vi->smallblock,32); _oggpack_write(&opb,vi->largeblock,32); _oggpack_write(&opb,vi->envelopesa,32); - _oggpack_write(&opb,vi->envelopech,32); + _oggpack_write(&opb,vi->envelopech,16); _oggpack_write(&opb,vi->floororder,8); _oggpack_write(&opb,vi->flooroctaves,8); - _oggpack_write(&opb,vi->floorch,32); + _oggpack_write(&opb,vi->floorch,16); /* build the packet */ if(vi->header)free(vi->header); - vi->header=memcpy(opb.buffer,_oggpack_bytes(&opb)); + memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb)); op->packet=vi->header; op->bytes=_oggpack_bytes(&opb); op->b_o_s=1; @@ -119,6 +201,8 @@ int vorbis_info_headerout(vorbis_info *vi, op->frameno=0; /* comment header: + codec id "vorbis" + header id 1 (byte) vendor len (4 octets, lsb first) vendor and id (n octects as above) comments (4 octets, lsb first) @@ -130,20 +214,23 @@ int vorbis_info_headerout(vorbis_info *vi, */ _oggpack_reset(&opb); + _v_writestring(&opb,"vorbis"); + _oggpack_write(&opb,0x01,8); + if(vi->vendor){ _oggpack_write(&opb,strlen(vi->vendor),32); - _oggpack_write(&opb,vi->vendor,strlen(vi->vendor)); + _v_writestring(&opb,vi->vendor); }else{ _oggpack_write(&opb,0,32); } - _oggpack_write(&opb,vi->max_comment,32); - if(vi->max_comment){ + _oggpack_write(&opb,vi->comments,32); + if(vi->comments){ int i; - for(i=0;i<=vi->max_comment;i++){ + for(i=0;icomments;i++){ if(vi->user_comments[i]){ _oggpack_write(&opb,strlen(vi->user_comments[i]),32); - _oggpack_write(&opb,vi->user_comments[i],strlen(vi->user_comments[i])); + _v_writestring(&opb,vi->user_comments[i]); }else{ _oggpack_write(&opb,0,32); } @@ -151,7 +238,7 @@ int vorbis_info_headerout(vorbis_info *vi, } if(vi->header1)free(vi->header1); - vi->header1=memcpy(opb.buffer,_oggpack_bytes(&opb)); + memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb)); op_comm->packet=vi->header1; op_comm->bytes=_oggpack_bytes(&opb); op_comm->b_o_s=0; @@ -159,16 +246,24 @@ int vorbis_info_headerout(vorbis_info *vi, op_comm->frameno=0; /* codebook header: + codec id "vorbis" + header id 2 (byte) nul so far; not encoded yet */ + _oggpack_reset(&opb); + _v_writestring(&opb,"vorbis"); + _oggpack_write(&opb,0x02,8); + if(vi->header2)free(vi->header2); - vi->header2=NULL; + memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb)); op_code->packet=vi->header2; - op_code->bytes=0; + op_code->bytes=_oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->frameno=0; + _oggpack_writefree(&opb); + return(0); } -- 2.7.4