The huff builder is happy.
authorMonty <xiphmont@xiph.org>
Mon, 21 Feb 2000 01:14:02 +0000 (01:14 +0000)
committerMonty <xiphmont@xiph.org>
Mon, 21 Feb 2000 01:14:02 +0000 (01:14 +0000)
Monty

svn path=/trunk/vorbis/; revision=265

vq/huffbuild.c [new file with mode: 0644]

diff --git a/vq/huffbuild.c b/vq/huffbuild.c
new file mode 100644 (file)
index 0000000..637e1d3
--- /dev/null
@@ -0,0 +1,193 @@
+/********************************************************************
+ *                                                                  *
+ * 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: hufftree builder
+ last mod: $Id: huffbuild.c,v 1.1 2000/02/21 01:14:02 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include "../vq/bookutil.h"
+
+static int nsofar=0;
+static int getval(FILE *in,int begin,int n,int group,int max){
+  double v;
+  int i;
+  long val=0;
+
+  if(nsofar>=n || get_line_value(in,&v)){
+    reset_next_value();
+    nsofar=0;
+    if(get_next_value(in,&v))
+      return(-1);
+    for(i=1;i<=begin;i++)
+      get_line_value(in,&v);
+  }
+
+  val=(int)v;
+  nsofar++;
+
+  for(i=1;i<group;i++,nsofar++)
+    if(nsofar>=n || get_line_value(in,&v))
+      return(getval(in,begin,n,group,max));
+    else
+      val = val*max+(int)v;
+  return(val);
+}
+
+static void usage(){
+  fprintf(stderr,
+         "usage:\n" 
+         "huffbuild <input>.vqd <begin,n,group>\n"
+         "   where begin,n,group is first scalar, \n"
+         "                          number of scalars of each in line,\n"
+         "                          number of scalars in a group\n"
+         "eg: huffbuild reslongaux.vqd 0,1024,4\n"
+         "produces reslongaux.vqh\n\n");
+  exit(1);
+}
+
+int main(int argc, char *argv[]){
+  char *base;
+  char *infile;
+  int i,j,k,begin,n,subn;
+  FILE *file;
+  int maxval=0;
+
+  if(argc<3)usage();
+
+  infile=strdup(argv[1]);
+  base=strdup(infile);
+  if(strrchr(base,'.'))
+    strrchr(base,'.')[0]='\0';
+
+  {
+    char *pos=strchr(argv[2],',');
+    begin=atoi(argv[2]);
+    if(!pos)
+      usage();
+    else
+      n=atoi(pos+1);
+    pos=strchr(pos+1,',');
+    if(!pos)
+      usage();
+    else
+      subn=atoi(pos+1);
+    if(n/subn*subn != n){
+      fprintf(stderr,"n must be divisible by group\n");
+      exit(1);
+    }
+  }
+
+  /* scan the file for maximum value */
+  file=fopen(infile,"r");
+  if(!file){
+    fprintf(stderr,"Could not open file %s\n",infile);
+    exit(1);
+  }
+  i=0;
+  while(1){
+    long v;
+    if(get_next_ivalue(file,&v))break;
+    if(v>maxval)maxval=v;
+
+    if(!(i++&0xff))spinnit("loading... ",i);
+  }
+  rewind(file);
+  maxval++;
+
+  {
+    long vals=pow(maxval,subn);
+    long *hist=malloc(vals*sizeof(long));
+    long *lengths=malloc(vals*sizeof(long));
+    
+    for(j=0;j<vals;j++)hist[j]=1;
+    
+    reset_next_value();
+    i/=subn;
+    while(!feof(file)){
+      long val=getval(file,begin,n,subn,maxval);
+      if(val==-1)break;
+      hist[val]++;
+      if(!(i--&0xff))spinnit("loading... ",i*subn);
+    }
+    fclose(file);
+    /* we have the probabilities, build the tree */
+    fprintf(stderr,"Building tree for %ld entries\n",vals);
+    build_tree_from_lengths(vals,hist,lengths);
+    /* save the book */
+    {
+      char *buffer=alloca(strlen(base)+5);
+      strcpy(buffer,base);
+      strcat(buffer,".vqh");
+      file=fopen(buffer,"w");
+      if(!file){
+       fprintf(stderr,"Could not open file %s\n",buffer);
+       exit(1);
+      }
+    }
+    
+    fprintf(file,
+ "/********************************************************************\n"
+ " *                                                                  *\n"
+ " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *\n"
+ " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
+ " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *\n"
+ " * PLEASE READ THESE TERMS DISTRIBUTING.                            *\n"
+ " *                                                                  *\n"
+ " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *\n"
+ " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *\n"
+ " * http://www.xiph.org/                                             *\n"
+ " *                                                                  *\n"
+ " ********************************************************************\n"
+ "\n"
+ " function: static codebook autogenerated by huff/huffbuld\n"
+ "\n"
+ " ********************************************************************/\n\n");
+
+    fprintf(file,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",base,base);
+    fprintf(file,"#include \"vorbis/codebook.h\"\n\n");
+    
+    /* first, the static vectors, then the book structure to tie it together. */
+    /* lengthlist */
+    fprintf(file,"static long _vq_lengthlist_%s[] = {\n",base);
+    for(j=0;j<vals;){
+      fprintf(file,"\t");
+      for(k=0;k<16 && j<vals;k++,j++)
+       fprintf(file,"%2ld,",lengths[j]);
+      fprintf(file,"\n");
+    }
+    fprintf(file,"};\n\n");
+    
+    /* the toplevel book */
+    fprintf(file,"static static_codebook _vq_book_%s = {\n",base);
+    fprintf(file,"\t%d, %ld, %d, %d, %d, %d,\n",
+           subn,vals,0,0,0,0);
+    fprintf(file,"\tNULL,\n");
+    fprintf(file,"\t_vq_lengthlist_%s,\n",base);
+    fprintf(file,"\tNULL,\n");
+    fprintf(file,"};\n\n");
+    
+    fprintf(file,"\n#endif\n");
+    fclose(file);
+    fprintf(stderr,"Done.                                \n\n");
+  }
+  exit(0);
+}
+
+