[xiph-commits] r16097 - in branches/vorbis-malloccheck: include/vorbis lib

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Wed Jun 10 07:01:20 PDT 2009


Author: xiphmont
Date: 2009-06-10 07:01:19 -0700 (Wed, 10 Jun 2009)
New Revision: 16097

Modified:
   branches/vorbis-malloccheck/include/vorbis/codec.h
   branches/vorbis-malloccheck/lib/block.c
   branches/vorbis-malloccheck/lib/info.c
Log:
Begin async error reporting interface; added to vorbis_comment and vorbis_info



Modified: branches/vorbis-malloccheck/include/vorbis/codec.h
===================================================================
--- branches/vorbis-malloccheck/include/vorbis/codec.h	2009-06-10 11:24:30 UTC (rev 16096)
+++ branches/vorbis-malloccheck/include/vorbis/codec.h	2009-06-10 14:01:19 UTC (rev 16097)
@@ -26,7 +26,7 @@
 #include <ogg/ogg.h>
 
 typedef struct vorbis_info{
-  int version;
+  int version;  /* < 0 indicates error state */
   int channels;
   long rate;
 
@@ -161,9 +161,10 @@
    and the streaming layer is not used */
 
 /* Vorbis PRIMITIVES: general ***************************************/
-
+  
 extern void     vorbis_info_init(vorbis_info *vi);
 extern void     vorbis_info_clear(vorbis_info *vi);
+extern int      vorbis_info_check(vorbis_info *vi);
 extern int      vorbis_info_blocksize(vorbis_info *vi,int zo);
 extern void     vorbis_comment_init(vorbis_comment *vc);
 extern void     vorbis_comment_add(vorbis_comment *vc, const char *comment);
@@ -172,6 +173,7 @@
 extern char    *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count);
 extern int      vorbis_comment_query_count(vorbis_comment *vc, const char *tag);
 extern void     vorbis_comment_clear(vorbis_comment *vc);
+  extern int      vorbis_comment_check(vorbis_comment *vc);
 
 extern int      vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
 extern int      vorbis_block_clear(vorbis_block *vb);
@@ -234,6 +236,8 @@
 #define OV_EBADPACKET -136
 #define OV_EBADLINK   -137
 #define OV_ENOSEEK    -138
+#define OV_ESTACK     -139
+#define OV_EHEAP      -140
 
 #ifdef __cplusplus
 }

Modified: branches/vorbis-malloccheck/lib/block.c
===================================================================
--- branches/vorbis-malloccheck/lib/block.c	2009-06-10 11:24:30 UTC (rev 16096)
+++ branches/vorbis-malloccheck/lib/block.c	2009-06-10 14:01:19 UTC (rev 16097)
@@ -91,7 +91,7 @@
   vb->vd=v;
   vb->localalloc=0;
   vb->localstore=NULL;
-  if(v->analysisp){
+  if(v->analysisp>0){
     vorbis_block_internal *vbi=
       vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
     vbi->ampmax=-9999;

Modified: branches/vorbis-malloccheck/lib/info.c
===================================================================
--- branches/vorbis-malloccheck/lib/info.c	2009-06-10 11:24:30 UTC (rev 16096)
+++ branches/vorbis-malloccheck/lib/info.c	2009-06-10 14:01:19 UTC (rev 16097)
@@ -31,8 +31,8 @@
 #include "misc.h"
 #include "os.h"
 
-#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.2.2rc1"
-#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20090604"
+#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.2.3pre"
+#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20090610"
 
 /* helpers */
 static int ilog2(unsigned int v){
@@ -46,7 +46,6 @@
 }
 
 static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
-
   while(bytes--){
     oggpack_write(o,*s++,8);
   }
@@ -59,27 +58,49 @@
 }
 
 void vorbis_comment_init(vorbis_comment *vc){
-  memset(vc,0,sizeof(*vc));
+  if(vc)
+    memset(vc,0,sizeof(*vc));
 }
 
 void vorbis_comment_add(vorbis_comment *vc,const char *comment){
-  vc->user_comments=_ogg_realloc(vc->user_comments,
-                            (vc->comments+2)*sizeof(*vc->user_comments));
-  vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
-                                  (vc->comments+2)*sizeof(*vc->comment_lengths));
-  vc->comment_lengths[vc->comments]=strlen(comment);
-  vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1);
-  strcpy(vc->user_comments[vc->comments], comment);
-  vc->comments++;
-  vc->user_comments[vc->comments]=NULL;
+  if(vc && vc->comments>=0){
+    void *ret =_ogg_realloc(vc->user_comments,
+				   (vc->comments+2)*sizeof(*vc->user_comments));
+    if(!ret)goto err;
+    vc->user_comments=ret;
+
+    ret=_ogg_realloc(vc->comment_lengths,
+		     (vc->comments+2)*sizeof(*vc->comment_lengths));
+    if(!ret)goto err;
+    vc->comment_lengths=ret;
+    vc->comment_lengths[vc->comments]=strlen(comment);
+
+    ret=_ogg_malloc(vc->comment_lengths[vc->comments]+1);
+    if(!ret)goto err;
+    vc->user_comments[vc->comments]=ret;
+    strcpy(vc->user_comments[vc->comments], comment);
+    vc->comments++;
+    vc->user_comments[vc->comments]=NULL;
+  }
+  return;
+ err:
+  vorbis_comment_clear(vc);
+  vc->comments=OV_EHEAP;
 }
 
 void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){
-  char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
-  strcpy(comment, tag);
-  strcat(comment, "=");
-  strcat(comment, contents);
-  vorbis_comment_add(vc, comment);
+  if(vc && vc->comments>=0 && tag && contents){
+    char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
+    if(comment==NULL){
+      vorbis_comment_clear(vc);
+      vc->comments=OV_ESTACK;
+    }else{
+      strcpy(comment, tag);
+      strcat(comment, "=");
+      strcat(comment, contents);
+      vorbis_comment_add(vc, comment);
+    }
+  }
 }
 
 /* This is more or less the same as strncasecmp - but that doesn't exist
@@ -100,17 +121,22 @@
   int taglen = strlen(tag)+1; /* +1 for the = we append */
   char *fulltag = alloca(taglen+ 1);
 
-  strcpy(fulltag, tag);
-  strcat(fulltag, "=");
-  
-  for(i=0;i<vc->comments;i++){
-    if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
-      if(count == found)
-        /* We return a pointer to the data, not a copy */
-              return vc->user_comments[i] + taglen;
-      else
-        found++;
+  if(fulltag){
+    strcpy(fulltag, tag);
+    strcat(fulltag, "=");
+    
+    for(i=0;i<vc->comments;i++){
+      if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
+	if(count == found)
+	  /* We return a pointer to the data, not a copy */
+	  return vc->user_comments[i] + taglen;
+	else
+	  found++;
+      }
     }
+  }else{
+    vorbis_comment_clear(vc);
+    vc->comments=OV_ESTACK;
   }
   return NULL; /* didn't find anything */
 }
@@ -119,14 +145,21 @@
   int i,count=0;
   int taglen = strlen(tag)+1; /* +1 for the = we append */
   char *fulltag = alloca(taglen+1);
-  strcpy(fulltag,tag);
-  strcat(fulltag, "=");
 
-  for(i=0;i<vc->comments;i++){
-    if(!tagcompare(vc->user_comments[i], fulltag, taglen))
-      count++;
+  if(fulltag){
+    strcpy(fulltag,tag);
+    strcat(fulltag, "=");
+    
+    for(i=0;i<vc->comments;i++){
+      if(!tagcompare(vc->user_comments[i], fulltag, taglen))
+	count++;
+    }
+    
+  }else{
+    vorbis_comment_clear(vc);
+    vc->comments=OV_ESTACK;
   }
-
+  
   return count;
 }
 
@@ -144,119 +177,156 @@
   }
 }
 
+int vorbis_comment_check(vorbis_comment *vc){
+  return (vc ? (vc->comments<0 ? vc->comments:0) : OV_EFAULT);
+}
+
 /* blocksize 0 is guaranteed to be short, 1 is guaranteed to be long.
    They may be equal, but short will never ge greater than long */
 int vorbis_info_blocksize(vorbis_info *vi,int zo){
-  codec_setup_info *ci = vi->codec_setup;
-  return ci ? ci->blocksizes[zo] : -1;
+  if(vi && vi->version>=0){
+    codec_setup_info *ci = vi->codec_setup;
+    return ci ? ci->blocksizes[zo] : -1;
+  }
+  return -1;
 }
 
 /* used by synthesis, which has a full, alloced vi */
 void vorbis_info_init(vorbis_info *vi){
-  memset(vi,0,sizeof(*vi));
-  vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
+  if(vi){
+    memset(vi,0,sizeof(*vi));
+    vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
+    if(!vi->codec_setup){
+      vi->version = OV_EHEAP;
+    }
+  }
 }
 
 void vorbis_info_clear(vorbis_info *vi){
-  codec_setup_info     *ci=vi->codec_setup;
-  int i;
-
-  if(ci){
-
-    for(i=0;i<ci->modes;i++)
-      if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
-
-    for(i=0;i<ci->maps;i++) /* unpack does the range checking */
-      if(ci->map_param[i]) /* this may be cleaning up an aborted
-                              unpack, in which case the below type
-                              cannot be trusted */
-        _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
-
-    for(i=0;i<ci->floors;i++) /* unpack does the range checking */
-      if(ci->floor_param[i]) /* this may be cleaning up an aborted
-                                unpack, in which case the below type
-                                cannot be trusted */
-        _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+  if(vi){
+    codec_setup_info     *ci=vi->codec_setup;
+    int i;
     
-    for(i=0;i<ci->residues;i++) /* unpack does the range checking */
-      if(ci->residue_param[i]) /* this may be cleaning up an aborted
-                                  unpack, in which case the below type
-                                  cannot be trusted */
-        _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
-    
-    for(i=0;i<ci->books;i++){
-      if(ci->book_param[i]){
-        /* knows if the book was not alloced */
-        vorbis_staticbook_destroy(ci->book_param[i]);
+    if(ci){
+      
+      for(i=0;i<ci->modes;i++)
+	if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
+      
+      for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+	if(ci->map_param[i]) /* this may be cleaning up an aborted
+				unpack, in which case the below type
+				cannot be trusted */
+	  _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
+      
+      for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+	if(ci->floor_param[i]) /* this may be cleaning up an aborted
+				  unpack, in which case the below type
+				  cannot be trusted */
+	  _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+      
+      for(i=0;i<ci->residues;i++) /* unpack does the range checking */
+	if(ci->residue_param[i]) /* this may be cleaning up an aborted
+				    unpack, in which case the below type
+				    cannot be trusted */
+	  _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
+      
+      for(i=0;i<ci->books;i++){
+	if(ci->book_param[i]){
+	  /* knows if the book was not alloced */
+	  vorbis_staticbook_destroy(ci->book_param[i]);
+	}
+	if(ci->fullbooks)
+	  vorbis_book_clear(ci->fullbooks+i);
       }
       if(ci->fullbooks)
-        vorbis_book_clear(ci->fullbooks+i);
+        _ogg_free(ci->fullbooks);
+      
+      for(i=0;i<ci->psys;i++)
+	_vi_psy_free(ci->psy_param[i]);
+      
+      _ogg_free(ci);
     }
-    if(ci->fullbooks)
-        _ogg_free(ci->fullbooks);
     
-    for(i=0;i<ci->psys;i++)
-      _vi_psy_free(ci->psy_param[i]);
-
-    _ogg_free(ci);
+    memset(vi,0,sizeof(*vi));
   }
+}
 
-  memset(vi,0,sizeof(*vi));
+int vorbis_info_check(vorbis_info *vi){
+  return(vi ? (vi->version>=0?0:vi->version) : OV_EFAULT);
 }
 
 /* Header packing/unpacking ********************************************/
 
 static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
-  codec_setup_info     *ci=vi->codec_setup;
-  if(!ci)return(OV_EFAULT);
-
-  vi->version=oggpack_read(opb,32);
-  if(vi->version!=0)return(OV_EVERSION);
-
-  vi->channels=oggpack_read(opb,8);
-  vi->rate=oggpack_read(opb,32);
-
-  vi->bitrate_upper=oggpack_read(opb,32);
-  vi->bitrate_nominal=oggpack_read(opb,32);
-  vi->bitrate_lower=oggpack_read(opb,32);
-
-  ci->blocksizes[0]=1<<oggpack_read(opb,4);
-  ci->blocksizes[1]=1<<oggpack_read(opb,4);
-  
-  if(vi->rate<1)goto err_out;
-  if(vi->channels<1)goto err_out;
-  if(ci->blocksizes[0]<64)goto err_out; 
-  if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
-  if(ci->blocksizes[1]>8192)goto err_out;
-
-  if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
-
-  return(0);
- err_out:
-  vorbis_info_clear(vi);
-  return(OV_EBADHEADER);
+  if(vi && opb){
+    codec_setup_info     *ci=vi->codec_setup;
+    if(vi->version<0)return vi->version;
+    if(!ci)return(OV_EFAULT);
+    
+    vi->version=oggpack_read(opb,32);
+    if(vi->version!=0)return(OV_EVERSION);
+    
+    vi->channels=oggpack_read(opb,8);
+    vi->rate=oggpack_read(opb,32);
+    
+    vi->bitrate_upper=oggpack_read(opb,32);
+    vi->bitrate_nominal=oggpack_read(opb,32);
+    vi->bitrate_lower=oggpack_read(opb,32);
+    
+    ci->blocksizes[0]=1<<oggpack_read(opb,4);
+    ci->blocksizes[1]=1<<oggpack_read(opb,4);
+    
+    if(vi->rate<1)goto err_out;
+    if(vi->channels<1)goto err_out;
+    if(ci->blocksizes[0]<64)goto err_out; 
+    if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
+    if(ci->blocksizes[1]>8192)goto err_out;
+    
+    if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+    
+    return(0);
+  err_out:
+    vorbis_info_clear(vi);
+    vi->version=OV_EBADHEADER;
+    return(vi->version=OV_EBADHEADER);
+  }
+  return(OV_EFAULT);
 }
 
 static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
   int i;
+  int ret=OV_EBADHEADER;
   int vendorlen=oggpack_read(opb,32);
   if(vendorlen<0)goto err_out;
   if(vendorlen+8>opb->storage)goto err_out;
   vc->vendor=_ogg_calloc(vendorlen+1,1);
+  if(!vc->vendor){
+    ret=OV_EHEAP;
+    goto err_out;
+  }
   _v_readstring(opb,vc->vendor,vendorlen);
   i=oggpack_read(opb,32);
   if(i<0)goto err_out;
   if(4*i+oggpack_bytes(opb)>opb->storage)goto err_out;
   vc->comments=i;
+
   vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
   vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
-            
+  if(!vc->user_comments || !vc->comment_lengths){
+    ret=OV_EHEAP;
+    goto err_out;
+  }
+
   for(i=0;i<vc->comments;i++){
     int len=oggpack_read(opb,32);
     if(len<0)goto err_out;
     if(len+oggpack_bytes(opb)>opb->storage)goto err_out;
     vc->comment_lengths[i]=len;
     vc->user_comments[i]=_ogg_calloc(len+1,1);
+    if(!vc->user_comments[i]){
+      ret=OV_EHEAP;
+      goto err_out;
+    }
     _v_readstring(opb,vc->user_comments[i],len);
   }          
   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
@@ -264,87 +334,106 @@
   return(0);
  err_out:
   vorbis_comment_clear(vc);
-  return(OV_EBADHEADER);
+  vc->comments= -1;
+  return(ret);
 }
 
 /* all of the real encoding details are here.  The modes, books,
    everything */
 static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
-  codec_setup_info     *ci=vi->codec_setup;
-  int i;
-  if(!ci)return(OV_EFAULT);
+  if(vi){
+    codec_setup_info     *ci=vi->codec_setup;
+    int i;
+    int ret=OV_EBADHEADER;
 
-  /* codebooks */
-  ci->books=oggpack_read(opb,8)+1;
-  /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/
-  for(i=0;i<ci->books;i++){
-    ci->book_param[i]=_ogg_calloc(1,sizeof(*ci->book_param[i]));
-    if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
-  }
+    if(vi->version<0)return(vi->version);
+    if(!ci)return(OV_EFAULT);
 
-  /* time backend settings; hooks are unused */
-  {
-    int times=oggpack_read(opb,6)+1;
-    for(i=0;i<times;i++){
-      int test=oggpack_read(opb,16);
-      if(test<0 || test>=VI_TIMEB)goto err_out;
+    /* codebooks */
+    ci->books=oggpack_read(opb,8)+1;
+    /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/
+    for(i=0;i<ci->books;i++){
+      ci->book_param[i]=_ogg_calloc(1,sizeof(*ci->book_param[i]));
+      if(!ci->book_param[i]){
+	ret=OV_EHEAP;
+	goto err_out;
+      }
+      if((ret=vorbis_staticbook_unpack(opb,ci->book_param[i])))goto err_out;
     }
+    
+    /* time backend settings; hooks are unused */
+    {
+      int times=oggpack_read(opb,6)+1;
+      for(i=0;i<times;i++){
+	int test=oggpack_read(opb,16);
+	if(test<0 || test>=VI_TIMEB)goto err_out;
+      }
+    }
+    
+    /* floor backend settings */
+    ci->floors=oggpack_read(opb,6)+1;
+    /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/
+    /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
+    for(i=0;i<ci->floors;i++){
+      ci->floor_type[i]=oggpack_read(opb,16);
+      if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
+      ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+      if(!ci->floor_param[i])goto err_out;
+    }
+    
+    /* residue backend settings */
+    ci->residues=oggpack_read(opb,6)+1;
+    /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/
+    /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
+    for(i=0;i<ci->residues;i++){
+      ci->residue_type[i]=oggpack_read(opb,16);
+      if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
+      ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
+      if(!ci->residue_param[i])goto err_out;
+    }
+    
+    /* map backend settings */
+    ci->maps=oggpack_read(opb,6)+1;
+    /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/
+    /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
+    for(i=0;i<ci->maps;i++){
+      ci->map_type[i]=oggpack_read(opb,16);
+      if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
+      ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
+      if(!ci->map_param[i])goto err_out;
+    }
+    
+    /* mode settings */
+    ci->modes=oggpack_read(opb,6)+1;
+    /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
+    for(i=0;i<ci->modes;i++){
+      ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
+      if(!ci->mode_param[i]){
+	ret=OV_EHEAP;
+	goto err_out;
+      }
+      ci->mode_param[i]->blockflag=oggpack_read(opb,1);
+      ci->mode_param[i]->windowtype=oggpack_read(opb,16);
+      ci->mode_param[i]->transformtype=oggpack_read(opb,16);
+      ci->mode_param[i]->mapping=oggpack_read(opb,8);
+      
+      if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+      if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+      if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
+    }
+    
+    if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+    
+    return(0);
+  err_out:
+    if(vi->version<0)ret=vi->version; /* hack to return error state
+					 from unpack functions called
+					 through dispatch table */
+    vorbis_info_clear(vi);
+    vi->version=ret;
+    return(ret);
   }
-
-  /* floor backend settings */
-  ci->floors=oggpack_read(opb,6)+1;
-  /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/
-  /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
-  for(i=0;i<ci->floors;i++){
-    ci->floor_type[i]=oggpack_read(opb,16);
-    if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
-    ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
-    if(!ci->floor_param[i])goto err_out;
-  }
-
-  /* residue backend settings */
-  ci->residues=oggpack_read(opb,6)+1;
-  /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/
-  /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
-  for(i=0;i<ci->residues;i++){
-    ci->residue_type[i]=oggpack_read(opb,16);
-    if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
-    ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
-    if(!ci->residue_param[i])goto err_out;
-  }
-
-  /* map backend settings */
-  ci->maps=oggpack_read(opb,6)+1;
-  /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/
-  /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
-  for(i=0;i<ci->maps;i++){
-    ci->map_type[i]=oggpack_read(opb,16);
-    if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
-    ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
-    if(!ci->map_param[i])goto err_out;
-  }
-  
-  /* mode settings */
-  ci->modes=oggpack_read(opb,6)+1;
-  /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
-  for(i=0;i<ci->modes;i++){
-    ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
-    ci->mode_param[i]->blockflag=oggpack_read(opb,1);
-    ci->mode_param[i]->windowtype=oggpack_read(opb,16);
-    ci->mode_param[i]->transformtype=oggpack_read(opb,16);
-    ci->mode_param[i]->mapping=oggpack_read(opb,8);
-
-    if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
-    if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
-    if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
-  }
-  
-  if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
-
-  return(0);
- err_out:
-  vorbis_info_clear(vi);
-  return(OV_EBADHEADER);
+  return(OV_EFAULT);
 }
 
 /* Is this packet a vorbis ID header? */
@@ -436,27 +525,30 @@
 /* pack side **********************************************************/
 
 static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
-  codec_setup_info     *ci=vi->codec_setup;
-  if(!ci)return(OV_EFAULT);
-
-  /* preamble */  
-  oggpack_write(opb,0x01,8);
-  _v_writestring(opb,"vorbis", 6);
-
-  /* basic information about the stream */
-  oggpack_write(opb,0x00,32);
-  oggpack_write(opb,vi->channels,8);
-  oggpack_write(opb,vi->rate,32);
-
-  oggpack_write(opb,vi->bitrate_upper,32);
-  oggpack_write(opb,vi->bitrate_nominal,32);
-  oggpack_write(opb,vi->bitrate_lower,32);
-
-  oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
-  oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
-  oggpack_write(opb,1,1);
-
-  return(0);
+  if(opb && vi){
+    codec_setup_info     *ci=vi->codec_setup;
+    if(vi->version<0)return(vi->version);
+    if(!ci)return(OV_EFAULT);
+    
+    /* preamble */  
+    oggpack_write(opb,0x01,8);
+    _v_writestring(opb,"vorbis", 6);
+    
+    /* basic information about the stream */
+    oggpack_write(opb,0x00,32);
+    oggpack_write(opb,vi->channels,8);
+    oggpack_write(opb,vi->rate,32);
+    
+    oggpack_write(opb,vi->bitrate_upper,32);
+    oggpack_write(opb,vi->bitrate_nominal,32);
+    oggpack_write(opb,vi->bitrate_lower,32);
+    
+    oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
+    oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
+    oggpack_write(opb,1,1);
+    return(oggpack_writecheck(opb)?OV_EHEAP:0);
+  }
+  return OV_EFAULT;
 }
 
 static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
@@ -486,83 +578,99 @@
   }
   oggpack_write(opb,1,1);
 
-  return(0);
+  return(oggpack_writecheck(opb)?OV_EHEAP:0);
 }
  
 static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
-  codec_setup_info     *ci=vi->codec_setup;
-  int i;
-  if(!ci)return(OV_EFAULT);
+  int ret=OV_EFAULT;
+  if(opb && vi){
+    codec_setup_info     *ci=vi->codec_setup;
+    int i;
+    if(vi->version<0)return(vi->version);
+    if(!ci)goto err_out;
+    
+    oggpack_write(opb,0x05,8);
+    _v_writestring(opb,"vorbis", 6);
+    
+    /* books */
+    oggpack_write(opb,ci->books-1,8);
+    for(i=0;i<ci->books;i++)
+      if((ret=vorbis_staticbook_pack(ci->book_param[i],opb)))goto err_out;
 
-  oggpack_write(opb,0x05,8);
-  _v_writestring(opb,"vorbis", 6);
+    /* times; hook placeholders */
+    oggpack_write(opb,0,6);
+    oggpack_write(opb,0,16);
+    
+    /* floors */
+    oggpack_write(opb,ci->floors-1,6);
+    for(i=0;i<ci->floors;i++){
+      oggpack_write(opb,ci->floor_type[i],16);
+      if(_floor_P[ci->floor_type[i]]->pack){
+	_floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
+      }else{
+	ret=OV_EFAULT;
+	goto err_out;
+      }
+    }
+    
+    /* residues */
+    oggpack_write(opb,ci->residues-1,6);
+    for(i=0;i<ci->residues;i++){
+      oggpack_write(opb,ci->residue_type[i],16);
+      _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
+    }
 
-  /* books */
-  oggpack_write(opb,ci->books-1,8);
-  for(i=0;i<ci->books;i++)
-    if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
+    /* maps */
+    oggpack_write(opb,ci->maps-1,6);
+    for(i=0;i<ci->maps;i++){
+      oggpack_write(opb,ci->map_type[i],16);
+      _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
+    }
 
-  /* times; hook placeholders */
-  oggpack_write(opb,0,6);
-  oggpack_write(opb,0,16);
-
-  /* floors */
-  oggpack_write(opb,ci->floors-1,6);
-  for(i=0;i<ci->floors;i++){
-    oggpack_write(opb,ci->floor_type[i],16);
-    if(_floor_P[ci->floor_type[i]]->pack)
-      _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
-    else
-      goto err_out;
+    /* modes */
+    oggpack_write(opb,ci->modes-1,6);
+    for(i=0;i<ci->modes;i++){
+      oggpack_write(opb,ci->mode_param[i]->blockflag,1);
+      oggpack_write(opb,ci->mode_param[i]->windowtype,16);
+      oggpack_write(opb,ci->mode_param[i]->transformtype,16);
+      oggpack_write(opb,ci->mode_param[i]->mapping,8);
+    }
+    oggpack_write(opb,1,1);
+    
+    return(oggpack_writecheck(opb)?OV_EHEAP:0);
   }
-
-  /* residues */
-  oggpack_write(opb,ci->residues-1,6);
-  for(i=0;i<ci->residues;i++){
-    oggpack_write(opb,ci->residue_type[i],16);
-    _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
-  }
-
-  /* maps */
-  oggpack_write(opb,ci->maps-1,6);
-  for(i=0;i<ci->maps;i++){
-    oggpack_write(opb,ci->map_type[i],16);
-    _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
-  }
-
-  /* modes */
-  oggpack_write(opb,ci->modes-1,6);
-  for(i=0;i<ci->modes;i++){
-    oggpack_write(opb,ci->mode_param[i]->blockflag,1);
-    oggpack_write(opb,ci->mode_param[i]->windowtype,16);
-    oggpack_write(opb,ci->mode_param[i]->transformtype,16);
-    oggpack_write(opb,ci->mode_param[i]->mapping,8);
-  }
-  oggpack_write(opb,1,1);
-
-  return(0);
 err_out:
-  return(-1);
+  return(ret);
 } 
 
 int vorbis_commentheader_out(vorbis_comment *vc,
-                                          ogg_packet *op){
+			     ogg_packet *op){
 
-  oggpack_buffer opb;
+  if(op){
+    oggpack_buffer opb;
+    int ret;
 
-  oggpack_writeinit(&opb);
-  if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL;
-
-  op->packet = _ogg_malloc(oggpack_bytes(&opb));
-  memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
-
-  op->bytes=oggpack_bytes(&opb);
-  op->b_o_s=0;
-  op->e_o_s=0;
-  op->granulepos=0;
-  op->packetno=1;
-
-  return 0;
+    oggpack_writeinit(&opb);
+    if((ret=_vorbis_pack_comment(&opb,vc)))return(ret);
+    
+    op->packet = _ogg_malloc(oggpack_bytes(&opb));
+    if(!op->packet){
+      oggpack_writeclear(&opb);
+      memset(op,0,sizeof(*op));
+      return OV_EHEAP;
+    }
+    memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
+    
+    op->bytes=oggpack_bytes(&opb);
+    op->b_o_s=0;
+    op->e_o_s=0;
+    op->granulepos=0;
+    op->packetno=1;
+    oggpack_writeclear(&opb);
+    
+    return 0;
+  }
+  return OV_EFAULT;
 }
 
 int vorbis_analysis_headerout(vorbis_dsp_state *v,
@@ -570,84 +678,97 @@
                               ogg_packet *op,
                               ogg_packet *op_comm,
                               ogg_packet *op_code){
-  int ret=OV_EIMPL;
-  vorbis_info *vi=v->vi;
-  oggpack_buffer opb;
-  private_state *b=v->backend_state;
-
-  if(!b){
-    ret=OV_EFAULT;
-    goto err_out;
-  }
-
-  /* first header packet **********************************************/
-
-  oggpack_writeinit(&opb);
-  if(_vorbis_pack_info(&opb,vi))goto err_out;
-
-  /* build the packet */
-  if(b->header)_ogg_free(b->header);
-  b->header=_ogg_malloc(oggpack_bytes(&opb));
-  memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
-  op->packet=b->header;
-  op->bytes=oggpack_bytes(&opb);
-  op->b_o_s=1;
-  op->e_o_s=0;
-  op->granulepos=0;
-  op->packetno=0;
-
-  /* second header packet (comments) **********************************/
-
-  oggpack_reset(&opb);
-  if(_vorbis_pack_comment(&opb,vc))goto err_out;
-
-  if(b->header1)_ogg_free(b->header1);
-  b->header1=_ogg_malloc(oggpack_bytes(&opb));
-  memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
-  op_comm->packet=b->header1;
-  op_comm->bytes=oggpack_bytes(&opb);
-  op_comm->b_o_s=0;
-  op_comm->e_o_s=0;
-  op_comm->granulepos=0;
-  op_comm->packetno=1;
-
-  /* third header packet (modes/codebooks) ****************************/
-
-  oggpack_reset(&opb);
-  if(_vorbis_pack_books(&opb,vi))goto err_out;
-
-  if(b->header2)_ogg_free(b->header2);
-  b->header2=_ogg_malloc(oggpack_bytes(&opb));
-  memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
-  op_code->packet=b->header2;
-  op_code->bytes=oggpack_bytes(&opb);
-  op_code->b_o_s=0;
-  op_code->e_o_s=0;
-  op_code->granulepos=0;
-  op_code->packetno=2;
-
-  oggpack_writeclear(&opb);
-  return(0);
- err_out:
-  oggpack_writeclear(&opb);
-  memset(op,0,sizeof(*op));
-  memset(op_comm,0,sizeof(*op_comm));
-  memset(op_code,0,sizeof(*op_code));
-
-  if(b){
+  if(v){
+    vorbis_info *vi=v->vi;
+    oggpack_buffer opb;
+    private_state *b=v->backend_state;
+    int ret=0;
+  
+    if(!vc || !b || !op || !op_comm || !op_code) goto err_out;
+    
+    /* first header packet **********************************************/
+    
+    oggpack_writeinit(&opb);
+    if((ret=_vorbis_pack_info(&opb,vi)))goto err_out;
+    
+    /* build the packet */
     if(b->header)_ogg_free(b->header);
+    b->header=_ogg_malloc(oggpack_bytes(&opb));
+    if(!b->header){
+      ret=OV_EHEAP;
+      goto err_out;
+    }
+    memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
+    op->packet=b->header;
+    op->bytes=oggpack_bytes(&opb);
+    op->b_o_s=1;
+    op->e_o_s=0;
+    op->granulepos=0;
+    op->packetno=0;
+    
+    /* second header packet (comments) **********************************/
+    
+    oggpack_reset(&opb);
+    if((ret=_vorbis_pack_comment(&opb,vc)))goto err_out;
     if(b->header1)_ogg_free(b->header1);
+    b->header1=_ogg_malloc(oggpack_bytes(&opb));
+    if(!b->header1){
+      ret=OV_EHEAP;
+      goto err_out;
+    }
+    memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
+    op_comm->packet=b->header1;
+    op_comm->bytes=oggpack_bytes(&opb);
+    op_comm->b_o_s=0;
+    op_comm->e_o_s=0;
+    op_comm->granulepos=0;
+    op_comm->packetno=1;
+    
+    /* third header packet (modes/codebooks) ****************************/
+    
+    oggpack_reset(&opb);
+    if((ret=_vorbis_pack_books(&opb,vi)))goto err_out;
+    
     if(b->header2)_ogg_free(b->header2);
-    b->header=NULL;
-    b->header1=NULL;
-    b->header2=NULL;
+    b->header2=_ogg_malloc(oggpack_bytes(&opb));
+    if(!b->header2){
+      ret=OV_EHEAP;
+      goto err_out;
+    }
+    memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
+    op_code->packet=b->header2;
+    op_code->bytes=oggpack_bytes(&opb);
+    op_code->b_o_s=0;
+    op_code->e_o_s=0;
+    op_code->granulepos=0;
+    op_code->packetno=2;
+    
+    oggpack_writeclear(&opb);
+    return(0);
+  err_out:
+    oggpack_writeclear(&opb);
+    memset(op,0,sizeof(*op));
+    memset(op_comm,0,sizeof(*op_comm));
+    memset(op_code,0,sizeof(*op_code));
+    
+    if(b){
+      if(b->header)_ogg_free(b->header);
+      if(b->header1)_ogg_free(b->header1);
+      if(b->header2)_ogg_free(b->header2);
+      b->header=NULL;
+      b->header1=NULL;
+      b->header2=NULL;
+    }
+    return(ret);
   }
-  return(ret);
+
+  return(OV_EFAULT);
 }
 
 double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
-  if(granulepos>=0)
-    return((double)granulepos/v->vi->rate);
+  if(v && v->vi && v->vi->version>=0)
+    if(granulepos>=0)
+      return((double)granulepos/v->vi->rate);
   return(-1);
 }
 



More information about the commits mailing list