summaryrefslogtreecommitdiffhomepage
path: root/vorbis/vq/huffbuild.c
diff options
context:
space:
mode:
Diffstat (limited to 'vorbis/vq/huffbuild.c')
-rw-r--r--vorbis/vq/huffbuild.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/vorbis/vq/huffbuild.c b/vorbis/vq/huffbuild.c
new file mode 100644
index 0000000..014c81c
--- /dev/null
+++ b/vorbis/vq/huffbuild.c
@@ -0,0 +1,197 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: hufftree builder
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include "bookutil.h"
+
+static int nsofar=0;
+static int getval(FILE *in,int begin,int n,int group,int max){
+ float 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>|<lorange-hirange> [noguard]\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,guard=1;
+ FILE *file;
+ int maxval=0;
+ int loval=0;
+
+ if(argc<3)usage();
+ if(argc==4)guard=0;
+
+ infile=strdup(argv[1]);
+ base=strdup(infile);
+ if(strrchr(base,'.'))
+ strrchr(base,'.')[0]='\0';
+
+ {
+ char *pos=strchr(argv[2],',');
+ char *dpos=strchr(argv[2],'-');
+ if(dpos){
+ loval=atoi(argv[2]);
+ maxval=atoi(dpos+1);
+ subn=1;
+ begin=0;
+ }else{
+ 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);
+ if(!maxval)
+ exit(1);
+ else
+ fprintf(stderr," making untrained books.\n");
+
+ }
+
+ if(!maxval){
+ 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=_ogg_calloc(vals,sizeof(long));
+ long *lengths=_ogg_calloc(vals,sizeof(long));
+
+ for(j=loval;j<vals;j++)hist[j]=guard;
+
+ if(file){
+ reset_next_value();
+ i/=subn;
+ while(!feof(file)){
+ long val=getval(file,begin,n,subn,maxval);
+ if(val==-1 || val>=vals)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_lengths0(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);
+ }
+ }
+
+ /* first, the static vectors, then the book structure to tie it together. */
+ /* lengthlist */
+ fprintf(file,"static const char _huff_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 const static_codebook _huff_book_%s = {\n",base);
+ fprintf(file,"\t%d, %ld,\n",subn,vals);
+ fprintf(file,"\t(char *)_huff_lengthlist_%s,\n",base);
+ fprintf(file,"\t0, 0, 0, 0, 0,\n");
+ fprintf(file,"\tNULL,\n");
+
+ fprintf(file,"\t0\n};\n\n");
+
+ fclose(file);
+ fprintf(stderr,"Done. \n\n");
+ }
+ exit(0);
+}
+
+
+
+
+
+
+
+
+
+
+