[xiph-commits] r14811 - in trunk/vorbis: doc examples lib

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Mon Apr 28 14:42:52 PDT 2008


Author: xiphmont
Date: 2008-04-28 14:42:52 -0700 (Mon, 28 Apr 2008)
New Revision: 14811

Modified:
   trunk/vorbis/doc/Vorbis_I_spec.pdf
   trunk/vorbis/examples/decoder_example.c
   trunk/vorbis/lib/block.c
   trunk/vorbis/lib/sharedbook.c
Log:
Additional bulletproofing to hufftree decoding; reject underpopulated 
trees up-front.



Modified: trunk/vorbis/doc/Vorbis_I_spec.pdf
===================================================================
(Binary files differ)

Modified: trunk/vorbis/examples/decoder_example.c
===================================================================
--- trunk/vorbis/examples/decoder_example.c	2008-04-28 03:27:06 UTC (rev 14810)
+++ trunk/vorbis/examples/decoder_example.c	2008-04-28 21:42:52 UTC (rev 14811)
@@ -198,108 +198,111 @@
 
     /* OK, got and parsed all three headers. Initialize the Vorbis
        packet->PCM decoder. */
-    vorbis_synthesis_init(&vd,&vi); /* central decode state */
-    vorbis_block_init(&vd,&vb);     /* local state for most of the decode
-				       so multiple block decodes can
-				       proceed in parallel.  We could init
-				       multiple vorbis_block structures
-				       for vd here */
-    
-    /* The rest is just a straight decode loop until end of stream */
-    while(!eos){
+    if(vorbis_synthesis_init(&vd,&vi)==0){ /* central decode state */
+      vorbis_block_init(&vd,&vb);          /* local state for most of the decode
+					      so multiple block decodes can
+					      proceed in parallel.  We could init
+					      multiple vorbis_block structures
+					      for vd here */
+      
+      /* The rest is just a straight decode loop until end of stream */
       while(!eos){
-	int result=ogg_sync_pageout(&oy,&og);
-	if(result==0)break; /* need more data */
-	if(result<0){ /* missing or corrupt data at this page position */
-	  fprintf(stderr,"Corrupt or missing data in bitstream; "
-		  "continuing...\n");
-	}else{
-	  ogg_stream_pagein(&os,&og); /* can safely ignore errors at
-					 this point */
-	  while(1){
-	    result=ogg_stream_packetout(&os,&op);
-
-	    if(result==0)break; /* need more data */
-	    if(result<0){ /* missing or corrupt data at this page position */
-	      /* no reason to complain; already complained above */
-	    }else{
-	      /* we have a packet.  Decode it */
-	      float **pcm;
-	      int samples;
+	while(!eos){
+	  int result=ogg_sync_pageout(&oy,&og);
+	  if(result==0)break; /* need more data */
+	  if(result<0){ /* missing or corrupt data at this page position */
+	    fprintf(stderr,"Corrupt or missing data in bitstream; "
+		    "continuing...\n");
+	  }else{
+	    ogg_stream_pagein(&os,&og); /* can safely ignore errors at
+					   this point */
+	    while(1){
+	      result=ogg_stream_packetout(&os,&op);
 	      
-	      if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
-		vorbis_synthesis_blockin(&vd,&vb);
-	      /* 
-		 
-	      **pcm is a multichannel float vector.  In stereo, for
-	      example, pcm[0] is left, and pcm[1] is right.  samples is
-	      the size of each channel.  Convert the float values
-	      (-1.<=range<=1.) to whatever PCM format and write it out */
-	      
-	      while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){
-		int j;
-		int clipflag=0;
-		int bout=(samples<convsize?samples:convsize);
+	      if(result==0)break; /* need more data */
+	      if(result<0){ /* missing or corrupt data at this page position */
+		/* no reason to complain; already complained above */
+	      }else{
+		/* we have a packet.  Decode it */
+		float **pcm;
+		int samples;
 		
-		/* convert floats to 16 bit signed ints (host order) and
-		   interleave */
-		for(i=0;i<vi.channels;i++){
-		  ogg_int16_t *ptr=convbuffer+i;
-		  float  *mono=pcm[i];
-		  for(j=0;j<bout;j++){
+		if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
+		  vorbis_synthesis_blockin(&vd,&vb);
+		/* 
+		   
+		**pcm is a multichannel float vector.  In stereo, for
+		example, pcm[0] is left, and pcm[1] is right.  samples is
+		the size of each channel.  Convert the float values
+		(-1.<=range<=1.) to whatever PCM format and write it out */
+		
+		while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){
+		  int j;
+		  int clipflag=0;
+		  int bout=(samples<convsize?samples:convsize);
+		  
+		  /* convert floats to 16 bit signed ints (host order) and
+		     interleave */
+		  for(i=0;i<vi.channels;i++){
+		    ogg_int16_t *ptr=convbuffer+i;
+		    float  *mono=pcm[i];
+		    for(j=0;j<bout;j++){
 #if 1
-		    int val=mono[j]*32767.f;
+		      int val=mono[j]*32767.f;
 #else /* optional dither */
-		    int val=mono[j]*32767.f+drand48()-0.5f;
+		      int val=mono[j]*32767.f+drand48()-0.5f;
 #endif
-		    /* might as well guard against clipping */
-		    if(val>32767){
-		      val=32767;
-		      clipflag=1;
+		      /* might as well guard against clipping */
+		      if(val>32767){
+			val=32767;
+			clipflag=1;
+		      }
+		      if(val<-32768){
+			val=-32768;
+			clipflag=1;
+		      }
+		      *ptr=val;
+		      ptr+=vi.channels;
 		    }
-		    if(val<-32768){
-		      val=-32768;
-		      clipflag=1;
-		    }
-		    *ptr=val;
-		    ptr+=vi.channels;
 		  }
-		}
-		
-		if(clipflag)
-		  fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence));
-		
-		
-		fwrite(convbuffer,2*vi.channels,bout,stdout);
-		
-		vorbis_synthesis_read(&vd,bout); /* tell libvorbis how
-						   many samples we
-						   actually consumed */
-	      }	    
+		  
+		  if(clipflag)
+		    fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence));
+		  
+		  
+		  fwrite(convbuffer,2*vi.channels,bout,stdout);
+		  
+		  vorbis_synthesis_read(&vd,bout); /* tell libvorbis how
+						      many samples we
+						      actually consumed */
+		}	    
+	      }
 	    }
+	    if(ogg_page_eos(&og))eos=1;
 	  }
-	  if(ogg_page_eos(&og))eos=1;
 	}
+	if(!eos){
+	  buffer=ogg_sync_buffer(&oy,4096);
+	  bytes=fread(buffer,1,4096,stdin);
+	  ogg_sync_wrote(&oy,bytes);
+	  if(bytes==0)eos=1;
+	}
       }
-      if(!eos){
-	buffer=ogg_sync_buffer(&oy,4096);
-	bytes=fread(buffer,1,4096,stdin);
-	ogg_sync_wrote(&oy,bytes);
-	if(bytes==0)eos=1;
-      }
+      
+      /* ogg_page and ogg_packet structs always point to storage in
+	 libvorbis.  They're never freed or manipulated directly */
+      
+      vorbis_block_clear(&vb);
+      vorbis_dsp_clear(&vd);
+    }else{
+      fprintf(stderr,"Error: Corrupt header during playback initialization.\n");
     }
-    
+
     /* clean up this logical bitstream; before exit we see if we're
        followed by another [chained] */
-
+    
     ogg_stream_clear(&os);
-  
-    /* ogg_page and ogg_packet structs always point to storage in
-       libvorbis.  They're never freed or manipulated directly */
-    
-    vorbis_block_clear(&vb);
-    vorbis_dsp_clear(&vd);
-	vorbis_comment_clear(&vc);
+    vorbis_comment_clear(&vc);
     vorbis_info_clear(&vi);  /* must be called last */
   }
 

Modified: trunk/vorbis/lib/block.c
===================================================================
--- trunk/vorbis/lib/block.c	2008-04-28 03:27:06 UTC (rev 14810)
+++ trunk/vorbis/lib/block.c	2008-04-28 21:42:52 UTC (rev 14811)
@@ -235,7 +235,8 @@
     if(!ci->fullbooks){
       ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
       for(i=0;i<ci->books;i++){
-	vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
+	if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
+	  return -1;
 	/* decode codebooks are now standalone after init */
 	vorbis_staticbook_destroy(ci->book_param[i]);
 	ci->book_param[i]=NULL;
@@ -694,9 +695,11 @@
 }
 
 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
-  if(_vds_shared_init(v,vi,0)) return 1;
+  if(_vds_shared_init(v,vi,0)){
+    vorbis_dsp_clear(v);
+    return 1;
+  }
   vorbis_synthesis_restart(v);
-
   return 0;
 }
 

Modified: trunk/vorbis/lib/sharedbook.c
===================================================================
--- trunk/vorbis/lib/sharedbook.c	2008-04-28 03:27:06 UTC (rev 14810)
+++ trunk/vorbis/lib/sharedbook.c	2008-04-28 21:42:52 UTC (rev 14811)
@@ -124,7 +124,14 @@
     }else
       if(sparsecount==0)count++;
   }
-    
+  
+  /* sanity check the huffman tree; an underpopulated tree must be rejected. */
+  for(i=1;i<33;i++)
+    if(marker[i] & (0xffffffffUL>>(32-i))){
+      _ogg_free(r);
+      return(NULL);
+    }
+
   /* bitreverse the words because our bitwise packer/unpacker is LSb
      endian */
   for(i=0,count=0;i<n;i++){



More information about the commits mailing list