Incremental update
authorMonty <xiphmont@xiph.org>
Wed, 19 Jan 2000 08:57:56 +0000 (08:57 +0000)
committerMonty <xiphmont@xiph.org>
Wed, 19 Jan 2000 08:57:56 +0000 (08:57 +0000)
svn path=/trunk/vorbis/; revision=235

lib/info.c
lib/infofloor.c [new file with mode: 0644]
lib/infomap.c [new file with mode: 0644]
lib/infopsy.c [new file with mode: 0644]
lib/infores.c [new file with mode: 0644]
lib/infotime.c [new file with mode: 0644]

index 765f173..1088b6b 100644 (file)
  ********************************************************************
 
  function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.14 2000/01/05 03:10:58 xiphmont Exp $
+ last mod: $Id: info.c,v 1.15 2000/01/19 08:57:55 xiphmont Exp $
 
  ********************************************************************/
 
-/* This fills in a vorbis_info structure with settings from a few
-   pre-defined encoding modes.  Also handles choosing/blowing in the
-   codebook */
+/* general handling of the header and the vorbis_info structure (and
+   substructures) */
 
 #include <stdlib.h>
 #include <string.h>
-#include "vorbis/modes.h"
+#include "vorbis/codec.h"
 #include "bitwise.h"
+#include "bookinternal.h"
+
+/* these modules were split out only to make this file more readable.
+   I don't want to expose the symbols */
+#include "infomap.c"
+
+/* helpers */
 
 static int ilog2(unsigned int v){
   int ret=0;
@@ -33,24 +39,20 @@ static int ilog2(unsigned int v){
   }
   return(ret);
 }
-  
-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);
 
-  /* handle the flat settings first */
-  memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
-  vi->user_comments=calloc(1,sizeof(char *));
-  vi->vendor=strdup("Xiphophorus libVorbis I 19991230");
+static void _v_writestring(oggpack_buffer *o,char *s){
+  while(*s){
+    _oggpack_write(o,*s++,8);
+  }
+}
 
-  return(0);
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+  while(bytes--){
+    *buf++=_oggpack_read(o,8);
+  }
 }
 
-/* convenience function */
+/* convenience functions for the interface */
 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
   vi->user_comments=realloc(vi->user_comments,
                            (vi->comments+2)*sizeof(char *));
@@ -60,16 +62,184 @@ int vorbis_info_addcomment(vorbis_info *vi,char *comment){
   return(0);
 }
 
-static void _v_writestring(oggpack_buffer *o,char *s){
-  while(*s){
-    _oggpack_write(o,*s++,8);
+int vorbis_info_addvendor(vorbis_info *vi,char *vendor){
+  if(vi->vendor)free(vi->vendor);
+  vi->vendor=strdup(vendor);
+  return(0);
+}
+  
+/* libVorbis expects modes to be submitted in an already valid
+   vorbis_info structure, but also expects some of the elements to be
+   allocated storage.  To make this easier, the Vorbis distribution
+   includes a number of modes in static storage as headers.  To
+   allocate a copy, run it through vorbis_info_dup */
+
+/* note that due to codebook size, codebooks are not fully duplicated.
+   The info structure (aside from the embedded codebook elements) will
+   be fully dupped */
+
+int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){
+  int i;
+  memcpy(dest,source,sizeof(vorbis_info));
+
+  /* also dup individual pieces that need to be allocated */
+  /* dup user comments (unlikely to have any, but for completeness */
+  if(source->comments>0){
+    dest->user_comments=calloc(source->comments+1,sizeof(char *));
+    for(i=0;i<source->comments;i++)
+      dest->user_comments[i]=strdup(source->user_comments[i]);
+  }
+  /* dup vendor */
+  if(source->vendor)
+    dest->vendor=strdup(source->vendor);
+
+  /* dup mode maps, blockflags and map types */
+  if(source->modes){
+    dest->blockflags=malloc(source->modes*sizeof(int));
+    dest->maptypes=malloc(source->modes*sizeof(int));
+    dest->maplist=calloc(source->modes,sizeof(void *));
+
+    memcpy(dest->blockflags,source->blockflags,sizeof(int)*dest->modes);
+    memcpy(dest->maptypes,source->maptypes,sizeof(int)*dest->modes);
+    for(i=0;i<source->modes;i++){
+      void *dup;
+      if(dest->maptypes[i]<0|| dest->maptypes[i]>=VI_MAPB)goto err_out;
+      if(!(dup=vorbis_map_dup_P[dest->maptypes[i]](source->maplist[i])))
+       goto err_out; 
+      dest->maplist[i]=dup;
+    }
+  }
+
+  /* dup (partially) books */
+  if(source->books){
+    dest->booklist=malloc(source->books*sizeof(codebook *));
+    for(i=0;i<source->books;i++){
+      dest->booklist[i]=calloc(1,sizeof(codebook));
+      vorbis_book_dup(dest->booklist[i],source->booklist[i]);
+    }
   }
+  /* we do *not* dup local storage */
+  dest->header=NULL;
+  dest->header1=NULL;
+  dest->header2=NULL;
+  
+  return(0);
+err_out:
+  vorbis_info_clear(dest);
+  return(-1);
 }
 
-static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
-  while(bytes--){
-    *buf++=_oggpack_read(o,8);
+void vorbis_info_clear(vorbis_info *vi){
+  int i;
+  if(vi->comments){
+    for(i=0;i<vi->comments;i++)
+      if(vi->user_comments[i])free(vi->user_comments[i]);
+    free(vi->user_comments);
   }
+  if(vi->vendor)free(vi->vendor);
+  if(vi->modes){
+    for(i=0;i<vi->modes;i++)
+      if(vi->maptypes[i]>=0 && vi->maptypes[i]<VI_MAPB)
+       vorbis_map_free_P[vi->maptypes[i]](vi->maplist[i]);
+    free(vi->maplist);
+    free(vi->maptypes);
+    free(vi->blockflags);
+  }
+  if(vi->books){
+    for(i=0;i<vi->books;i++){
+      if(vi->booklist[i]){
+       vorbis_book_clear(vi->booklist[i]);
+       free(vi->booklist[i]);
+      }
+    }
+    free(vi->booklist);
+  }
+  
+  if(vi->header)free(vi->header);
+  if(vi->header1)free(vi->header1);
+  if(vi->header2)free(vi->header2);
+
+  memset(vi,0,sizeof(vorbis_info));
+}
+
+/* Header packing/unpacking ********************************************/
+
+static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+  vi->version=_oggpack_read(opb,32);
+  if(vi->version!=0)return(-1);
+
+  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);
+
+  vi->blocksizes[0]=1<<_oggpack_read(opb,4);
+  vi->blocksizes[1]=1<<_oggpack_read(opb,4);
+  
+  if(vi->rate<1)goto err_out;
+  if(vi->channels<1)goto err_out;
+  if(vi->blocksizes[0]<8)goto err_out; 
+  if(vi->blocksizes[1]<vi->blocksizes[0])
+    goto err_out; /* doubles as EOF check */
+
+  return(0);
+ err_out:
+  vorbis_info_clear(vi);
+  return(-1);
+}
+
+static int _vorbis_unpack_comments(vorbis_info *vi,oggpack_buffer *opb){
+  int i;
+  int vendorlen=_oggpack_read(opb,32);
+  if(vendorlen<0)goto err_out;
+  vi->vendor=calloc(vendorlen+1,1);
+  _v_readstring(opb,vi->vendor,vendorlen);
+  vi->comments=_oggpack_read(opb,32);
+  if(vi->comments<0)goto err_out;
+  vi->user_comments=calloc(vi->comments+1,sizeof(char **));
+           
+  for(i=0;i<vi->comments;i++){
+    int len=_oggpack_read(opb,32);
+    if(len<0)goto err_out;
+    vi->user_comments[i]=calloc(len+1,1);
+    _v_readstring(opb,vi->user_comments[i],len);
+  }      
+  return(0);
+ err_out:
+  vorbis_info_clear(vi);
+  return(-1);
+}
+
+/* all of the real encoding details are here.  The modes, books,
+   everything */
+static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+  int i;
+
+  vi->modes=_oggpack_read(opb,16);
+  vi->blockflags=malloc(vi->modes*sizeof(int));
+  vi->maptypes=malloc(vi->modes*sizeof(int));
+  vi->maplist=calloc(vi->modes,sizeof(void *));
+
+  for(i=0;i<vi->modes;i++){
+    vi->blockflags[i]=_oggpack_read(opb,1);
+    vi->maptypes[i]=_oggpack_read(opb,8);
+    if(vi->maptypes[i]<0 || vi->maptypes[i]>VI_MAPB)goto err_out;
+    vi->maplist[i]=vorbis_map_unpack_P[vi->maptypes[i]](opb);
+    if(!vi->maplist[i])goto err_out;
+  }
+
+  vi->books=_oggpack_read(opb,16);
+  vi->booklist=calloc(vi->books,sizeof(codebook *));
+  for(i=0;i<vi->books;i++){
+    vi->booklist[i]=calloc(1,sizeof(codebook));
+    if(vorbis_book_unpack(opb,vi->booklist[i]))goto err_out;
+  }
+  return(0);
+err_out:
+  vorbis_info_clear(vi);
+  return(-1);
 }
 
 /* The Vorbis header is in three packets; the initial small packet in
@@ -77,6 +247,11 @@ static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
    with bitstream comments and a third packet that holds the
    codebook. */
 
+/* call before header in, or just to zero out uninitialized mem */
+void vorbis_info_init(vorbis_info *vi){
+  memset(vi,0,sizeof(vorbis_info));
+}
+
 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
 
   oggpack_buffer opb;
@@ -105,61 +280,24 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
          return(-1);
        }
 
-       if(_oggpack_read(&opb,32)!=0){
-         return(-1);
-       }
-       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);
-
-       vi->blocksize[0]=1<<_oggpack_read(&opb,4);
-       vi->blocksize[1]=1<<_oggpack_read(&opb,4);
-
-       vi->floororder[0]=_oggpack_read(&opb,8);
-       vi->floororder[1]=_oggpack_read(&opb,8);
-       vi->floormap[0]=_oggpack_read(&opb,16);
-       vi->floormap[1]=_oggpack_read(&opb,16);
-       vi->floorch=_oggpack_read(&opb,8);
-
-       if(vi->rate<1)return(-1);
-       if(vi->floorch<1 || vi->floorch>vi->channels)return(-1);
+       return(_vorbis_unpack_info(vi,&opb));
 
-       return(0);
       case 0x81:
        if(vi->rate==0){
-         /* um... we didn;t get the initial header */
+         /* 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);
+       return(_vorbis_unpack_comments(vi,&opb));
+
       case 0x82:
-       if(vi->rate==0){
-         /* um... we didn;t get the initial header */
+       if(vi->rate==0 || vi->vendor==NULL){
+         /* um... we didn;t get the initial header or comments yet */
          return(-1);
        }
 
-       /* not implemented quite yet */
+       return(_vorbis_unpack_books(vi,&opb));
 
-       return(0);
       default:
        /* Not a valid vorbis header type */
        return(-1);
@@ -170,49 +308,89 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
   return(-1);
 }
 
+/* pack side **********************************************************/
+
+static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
+  /* preamble */  
+  _v_writestring(opb,"vorbis");
+  _oggpack_write(opb,0x80,8);
+
+  /* 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(vi->blocksizes[0]),4);
+  _oggpack_write(opb,ilog2(vi->blocksizes[1]),4);
+  
+  return(0);
+}
+
+static int _vorbis_pack_comments(oggpack_buffer *opb,vorbis_info *vi){
+  char temp[]="Xiphophorus libVorbis I 20000114";
+
+  /* preamble */  
+  _v_writestring(opb,"vorbis");
+  _oggpack_write(opb,0x81,8);
+
+  /* vendor */
+  _oggpack_write(opb,strlen(temp),32);
+  _v_writestring(opb,temp);
+  
+  /* comments */
+
+  _oggpack_write(opb,vi->comments,32);
+  if(vi->comments){
+    int i;
+    for(i=0;i<vi->comments;i++){
+      if(vi->user_comments[i]){
+       _oggpack_write(opb,strlen(vi->user_comments[i]),32);
+       _v_writestring(opb,vi->user_comments[i]);
+      }else{
+       _oggpack_write(opb,0,32);
+      }
+    }
+  }
+
+  return(0);
+}
+static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
+  int i;
+  _v_writestring(opb,"vorbis");
+  _oggpack_write(opb,0x82,8);
+
+  _oggpack_write(opb,vi->modes,16);
+  for(i=0;i<vi->modes;i++){
+    _oggpack_write(opb,vi->blockflags[i],1);
+    _oggpack_write(opb,vi->maptypes[i],8);
+    if(vi->maptypes[i]<0 || vi->maptypes[i]>VI_MAPB)goto err_out;
+    vorbis_map_pack_P[vi->maptypes[i]](opb,vi->maplist[i]);
+  }
+
+  _oggpack_write(opb,vi->books,16);
+  for(i=0;i<vi->books;i++)
+    if(vorbis_book_pack(vi->booklist[i],opb))goto err_out;
+  return(0);
+err_out:
+  return(-1);
+} 
+
 int vorbis_info_headerout(vorbis_info *vi,
                          ogg_packet *op,
                          ogg_packet *op_comm,
                          ogg_packet *op_code){
 
   oggpack_buffer opb;
-  /* initial header:
-
-     codec id     "vorbis"
-     header id    0x80 (byte)
-     codec ver    (4 octets, lsb first: currently 0x00)
-     pcm channels (4 octets, lsb first)
-     pcm rate     (4 octets, lsb first)
-     
-     small block  (4 octets, lsb first)
-     large block  (4 octets, lsb first)
-     floor order for small block (octet)
-     floor order for large block (octet)
-     floor octaves for small block (octet)
-     floor octaves for large block (octet)
-     floorch      (4 octets, lsb first)
-   */
-
-  _oggpack_writeinit(&opb);
-  _v_writestring(&opb,"vorbis");
-  _oggpack_write(&opb,0x80,8);
-
-  _oggpack_write(&opb,0x00,32);
 
-  _oggpack_write(&opb,vi->channels,8);
-  _oggpack_write(&opb,vi->rate,32);
+  /* first header packet **********************************************/
 
-  _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(vi->blocksize[0]),4);
-  _oggpack_write(&opb,ilog2(vi->blocksize[1]),4);
-  _oggpack_write(&opb,vi->floororder[0],8);
-  _oggpack_write(&opb,vi->floororder[1],8);
-  _oggpack_write(&opb,vi->floormap[0],16);
-  _oggpack_write(&opb,vi->floormap[1],16);
-  _oggpack_write(&opb,vi->floorch,8);
+  _oggpack_writeinit(&opb);
+  if(_vorbis_pack_info(&opb,vi))goto err_out;
 
   /* build the packet */
   if(vi->header)free(vi->header);
@@ -224,43 +402,13 @@ int vorbis_info_headerout(vorbis_info *vi,
   op->e_o_s=0;
   op->frameno=0;
 
-  /* comment header:
-     codec id       "vorbis"
-     header id      0x81 (byte)
-     vendor len     (4 octets, lsb first)
-     vendor and id  (n octects as above)
-     comments       (4 octets, lsb first)
-     comment 0 len  (4 octets, lsb first)
-     comment 0 len  (n octets as above)
-     ...
-     comment n-1 len  (4 octets, lsb first)
-     comment 0-1 len  (n octets as above)
-  */
+  /* second header packet (comments) **********************************/
 
   _oggpack_reset(&opb);
   _v_writestring(&opb,"vorbis");
   _oggpack_write(&opb,0x81,8);
+  if(_vorbis_pack_comments(&opb,vi))goto err_out;
 
-  if(vi->vendor){
-    _oggpack_write(&opb,strlen(vi->vendor),32);
-    _v_writestring(&opb,vi->vendor);
-  }else{
-    _oggpack_write(&opb,0,32);
-  }
-  
-  _oggpack_write(&opb,vi->comments,32);
-  if(vi->comments){
-    int i;
-    for(i=0;i<vi->comments;i++){
-      if(vi->user_comments[i]){
-       _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
-       _v_writestring(&opb,vi->user_comments[i]);
-      }else{
-       _oggpack_write(&opb,0,32);
-      }
-    }
-  }
-  
   if(vi->header1)free(vi->header1);
   vi->header1=malloc(_oggpack_bytes(&opb));
   memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
@@ -270,14 +418,12 @@ int vorbis_info_headerout(vorbis_info *vi,
   op_comm->e_o_s=0;
   op_comm->frameno=0;
 
-  /* codebook header:
-     codec id       "vorbis"
-     header id      0x82 (byte)
-     nul so far; not encoded yet */
+  /* third header packet (modes/codebooks) ****************************/
 
   _oggpack_reset(&opb);
   _v_writestring(&opb,"vorbis");
   _oggpack_write(&opb,0x82,8);
+  if(_vorbis_pack_books(&opb,vi))goto err_out;
 
   if(vi->header2)free(vi->header2);
   vi->header2=malloc(_oggpack_bytes(&opb));
@@ -289,31 +435,12 @@ int vorbis_info_headerout(vorbis_info *vi,
   op_code->frameno=0;
 
   _oggpack_writeclear(&opb);
-
   return(0);
+ err_out:
+  _oggpack_writeclear(&opb);
+  memset(op,0,sizeof(ogg_packet));
+  memset(op_comm,0,sizeof(ogg_packet));
+  memset(op_code,0,sizeof(ogg_packet));
+  return(-1);
 }
 
-void vorbis_info_clear(vorbis_info *vi){
-  /* clear the non-flat storage before zeroing */
-
-  /* comments */
-  if(vi->user_comments){
-    char **ptr=vi->user_comments;
-    while(*ptr){
-      free(*(ptr++));
-    }
-    free(vi->user_comments);
-  }
-
-  /* vendor string */
-  if(vi->vendor)free(vi->vendor);
-
-  /* local encoding storage */
-  if(vi->header)free(vi->header);
-  if(vi->header1)free(vi->header1);
-  if(vi->header2)free(vi->header2);
-
-  memset(vi,0,sizeof(vorbis_info));
-}
-  
-
diff --git a/lib/infofloor.c b/lib/infofloor.c
new file mode 100644 (file)
index 0000000..bf92f6d
--- /dev/null
@@ -0,0 +1,95 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: pack/unpack/dup/clear the various floor backend setups
+ last mod: $Id: infofloor.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "bookinternal.h"
+
+/* calls for floor backend 0 *********************************************/
+static void *_vorbis_floor0_dup(void *source){
+  vorbis_info_floor0 *d=malloc(sizeof(vorbis_info_floor0));
+  memcpy(d,source,sizeof(vorbis_info_floor0));
+  if(d->stages){
+    d->books=malloc(sizeof(int)*d->stages);
+    memcpy(d->books,((vorbis_info_floor0 *)source)->books,
+          sizeof(int)*d->stages);
+  }
+  return(d);
+}
+
+static void _vorbis_floor0_free(void *i){
+  vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
+  if(d){
+    if(d->books)free(d->books);
+    memset(i,0,sizeof(vorbis_info_floor0));
+  }
+}
+
+static void _vorbis_floor0_pack(oggpack_buffer *opb,void *vi){
+  vorbis_info_floor0 *d=(vorbis_info_floor0 *)vi;
+  int i;
+  _oggpack_write(opb,d->order,8);
+  _oggpack_write(opb,d->rate,16);
+  _oggpack_write(opb,d->barkmap,16);
+  _oggpack_write(opb,d->stages,8);
+  for(i=0;i<d->stages;i++)
+    _oggpack_write(opb,d->books[i],8);
+}
+
+/* type is read earlier (so that we know to call this type) */
+static void *_vorbis_floor0_unpack(oggpack_buffer *opb){
+  vorbis_info_floor0 d;
+  int i;
+  d.order=_oggpack_read(opb,8);
+  d.rate=_oggpack_read(opb,16);
+  d.barkmap=_oggpack_read(opb,16);
+  d.stages=_oggpack_read(opb,8);
+  
+  if(d.order<1)return(NULL);
+  if(d.rate<1)return(NULL);
+  if(d.barkmap<1)return(NULL);
+  if(d.stages<1)return(NULL);
+
+  d.books=alloca(sizeof(int)*d.stages);
+  for(i=0;i<d.stages;i++)
+    d.books[i]=_oggpack_read(opb,8);
+  if(d.books[d.stages-1]<0)return(NULL);
+  return(_vorbis_floor0_dup(&d));
+}
+
+/* stuff em into arrays ************************************************/
+#define VI_FLOORB 1
+
+static void *(*vorbis_floor_dup_P[])(void *)={ 
+  _vorbis_floor0_dup,
+};
+
+static void (*vorbis_floor_free_P[])(void *)={ 
+  _vorbis_floor0_free,
+};
+
+static void (*vorbis_floor_pack_P[])(oggpack_buffer *,void *)={ 
+  _vorbis_floor0_pack,
+};
+
+static void *(*vorbis_floor_unpack_P[])(oggpack_buffer *)={ 
+  _vorbis_floor0_unpack,
+};
+
diff --git a/lib/infomap.c b/lib/infomap.c
new file mode 100644 (file)
index 0000000..2e7e48e
--- /dev/null
@@ -0,0 +1,128 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: pack/unpack/dup/clear the various channel mapping setups
+ last mod: $Id: infomap.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "bookinternal.h"
+
+/* these modules were split out only to make this file more readable.
+   I don't want to expose the symbols */
+#include "infotime.c"
+#include "infofloor.c"
+#include "infores.c"
+#include "infopsy.c"
+
+/* Handlers for mapping 0 *******************************************/
+static void *_vorbis_map0_dup(void *source){
+  vorbis_info_mapping0 *d=malloc(sizeof(vorbis_info_mapping0));
+  vorbis_info_mapping0 *s=(vorbis_info_mapping0 *)source;
+  memcpy(d,s,sizeof(vorbis_info_mapping0));
+
+  if(d->timetype<0  || d->timetype>=VI_TIMEB)goto err_out;
+  if(d->floortype<0 || d->floortype>=VI_FLOORB)goto err_out;
+  if(d->restype<0   || d->restype>=VI_RESB)goto err_out;
+      
+  d->time=vorbis_time_dup_P[d->timetype](s->time);
+  d->floor=vorbis_floor_dup_P[d->floortype](s->floor);
+  d->res=vorbis_res_dup_P[d->restype](s->res);
+  d->psy=vorbis_psy_dup(s->psy);
+
+  return(d);
+err_out:
+  memset(d,0,sizeof(vorbis_info_mapping0));
+  free(d);
+  return(NULL);
+}
+
+static void _vorbis_map0_free(void *i){
+  vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
+
+  if(d){
+    if(d->timetype>=0  && d->timetype<VI_TIMEB)
+      vorbis_time_free_P[d->timetype](d->time);
+    if(d->floortype>=0 && d->floortype<VI_FLOORB)
+      vorbis_floor_free_P[d->floortype](d->floor);
+    if(d->restype>=0   && d->restype<VI_RESB)
+      vorbis_res_free_P[d->restype](d->res);
+    vorbis_psy_free(d->psy);
+   
+    memset(d,0,sizeof(vorbis_info_mapping0));
+    free(d);
+  }
+}
+
+static void _vorbis_map0_pack(oggpack_buffer *opb,void *i){
+  vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
+  _oggpack_write(opb,d->timetype,8);
+  _oggpack_write(opb,d->floortype,8);
+  _oggpack_write(opb,d->restype,8);
+  
+  vorbis_time_pack_P[d->timetype](opb,d->time);
+  vorbis_floor_pack_P[d->floortype](opb,d->floor);
+  vorbis_res_pack_P[d->restype](opb,d->res);
+}
+
+static void *_vorbis_map0_unpack(oggpack_buffer *opb){
+  vorbis_info_mapping0 d;
+  memset(&d,0,sizeof(d));
+
+  d.timetype=_oggpack_read(opb,8);
+  d.floortype=_oggpack_read(opb,8);
+  d.restype=_oggpack_read(opb,8);
+
+  if(d.timetype<0  || d.timetype>=VI_TIMEB)goto err_out;
+  if(d.floortype<0 || d.floortype>=VI_FLOORB)goto err_out;
+  if(d.restype<0   || d.restype>=VI_RESB)goto err_out;
+
+  d.time=vorbis_time_unpack_P[d.timetype](opb);
+  d.floor=vorbis_floor_unpack_P[d.floortype](opb);
+  d.res=vorbis_res_unpack_P[d.restype](opb);
+  d.psy=NULL;
+
+  return _vorbis_map0_dup(&d);
+
+ err_out:
+  /* the null check protects against type out of range */
+  if(d.time)vorbis_time_free_P[d.timetype](d.time);
+  if(d.floor)vorbis_floor_free_P[d.floortype](d.floor);
+  if(d.res)vorbis_res_free_P[d.restype](d.res);
+  
+  return(NULL);
+}
+
+/* stuff em into arrays ************************************************/
+#define VI_MAPB 1
+
+static void *(*vorbis_map_dup_P[])(void *)={ 
+  _vorbis_map0_dup,
+};
+
+static void (*vorbis_map_free_P[])(void *)={ 
+  _vorbis_map0_free,
+};
+
+static void (*vorbis_map_pack_P[])(oggpack_buffer *,void *)={ 
+  _vorbis_map0_pack,
+};
+
+static void *(*vorbis_map_unpack_P[])(oggpack_buffer *)={ 
+  _vorbis_map0_unpack,
+};
+
diff --git a/lib/infopsy.c b/lib/infopsy.c
new file mode 100644 (file)
index 0000000..4471995
--- /dev/null
@@ -0,0 +1,40 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: dup/clear the psy setup
+ last mod: $Id: infopsy.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "bookinternal.h"
+
+static vorbis_info_psy *vorbis_psy_dup(vorbis_info_psy *source){
+  if(source){
+    vorbis_info_psy *d=malloc(sizeof(vorbis_info_psy));
+    memcpy(d,source,sizeof(vorbis_info_psy));
+    return(d);
+  }else
+    return(NULL);
+}
+
+static void vorbis_psy_free(vorbis_info_psy *i){
+  if(i){
+    memset(i,0,sizeof(vorbis_info_psy));
+    free(i);
+  }
+}
+
diff --git a/lib/infores.c b/lib/infores.c
new file mode 100644 (file)
index 0000000..4caa523
--- /dev/null
@@ -0,0 +1,74 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: pack/unpack/dup/clear the various residue backend setups
+ last mod: $Id: infores.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "bookinternal.h"
+
+/* handlers for residue backend 0 ***********************************/
+
+/* unfinished as of 20000118 */
+static void *_vorbis_res0_dup(void *source){
+  vorbis_info_res0 *d=malloc(sizeof(vorbis_info_res0));
+  memcpy(d,source,sizeof(vorbis_info_res0));
+  d->books=malloc(sizeof(int)*d->stages);
+  memcpy(d->books,((vorbis_info_res0 *)source)->books,
+        sizeof(int)*d->stages);
+  return(d); 
+}
+
+static void _vorbis_res0_free(void *i){
+  vorbis_info_res0 *d=(vorbis_info_res0 *)i;
+  if(d){
+    if(d->books)free(d->books);
+    memset(d,0,sizeof(vorbis_info_res0));
+    free(d);
+  }
+}
+
+/* not yet */
+static void _vorbis_res0_pack(oggpack_buffer *opb, void *vi){
+}
+
+static void *_vorbis_res0_unpack(oggpack_buffer *opb){
+  vorbis_info_floor0 d;
+  memset(&d,0,sizeof(d));
+  return(_vorbis_res0_dup(&d));
+}
+
+/* stuff em into arrays ************************************************/
+#define VI_RESB 1
+
+static void *(*vorbis_res_dup_P[])(void *)={ 
+  _vorbis_res0_dup,
+};
+
+static void (*vorbis_res_free_P[])(void *)={ 
+  _vorbis_res0_free,
+};
+
+static void (*vorbis_res_pack_P[])(oggpack_buffer *,void *)={ 
+  _vorbis_res0_pack,
+};
+
+static void *(*vorbis_res_unpack_P[])(oggpack_buffer *)={ 
+  _vorbis_res0_unpack,
+};
+
diff --git a/lib/infotime.c b/lib/infotime.c
new file mode 100644 (file)
index 0000000..a718aed
--- /dev/null
@@ -0,0 +1,59 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: pack/unpack/dup/clear the various time info storage
+ last mod: $Id: infotime.c,v 1.1 2000/01/19 08:57:56 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "vorbis/codec.h"
+#include "bitwise.h"
+#include "bookinternal.h"
+
+/* hadlers for time backend 0 (dummy) *********************************/
+static void *_vorbis_time0_dup(void *source){
+  return(calloc(1,sizeof(vorbis_info_time0)));
+}
+
+static void _vorbis_time0_free(void *i){
+  if(i)free(i);
+}
+
+static void _vorbis_time0_pack(oggpack_buffer *opb,void *i){
+}  
+
+static void *_vorbis_time0_unpack(oggpack_buffer *opb){
+  return(_vorbis_time0_dup(NULL));
+}
+
+/* stuff em into arrays ************************************************/
+#define VI_TIMEB 1
+
+static void *(*vorbis_time_dup_P[])(void *)={ 
+  &_vorbis_time0_dup,
+};
+
+static void (*vorbis_time_free_P[])(void *)={ 
+  &_vorbis_time0_free,
+};
+
+static void (*vorbis_time_pack_P[])(oggpack_buffer *,void *)={ 
+  &_vorbis_time0_pack,
+};
+
+static void *(*vorbis_time_unpack_P[])(oggpack_buffer *)={ 
+  &_vorbis_time0_unpack,
+};
+