examples/SFExamples/oggvorbiscodec/src/libvorbis/vq/huffbuild.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: hufftree builder
00014  last mod: $Id: huffbuild.c 7187 2004-07-20 07:24:27Z xiphmont $
00015 
00016  ********************************************************************/
00017 
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <math.h>
00021 #include <stdio.h>
00022 #include "bookutil.h"
00023 
00024 static int nsofar=0;
00025 static int getval(FILE *in,int begin,int n,int group,int max){
00026   float v;
00027   int i;
00028   long val=0;
00029 
00030   if(nsofar>=n || get_line_value(in,&v)){
00031     reset_next_value();
00032     nsofar=0;
00033     if(get_next_value(in,&v))
00034       return(-1);
00035     for(i=1;i<=begin;i++)
00036       get_line_value(in,&v);
00037   }
00038 
00039   val=(int)v;
00040   nsofar++;
00041 
00042   for(i=1;i<group;i++,nsofar++)
00043     if(nsofar>=n || get_line_value(in,&v))
00044       return(getval(in,begin,n,group,max));
00045     else
00046       val = val*max+(int)v;
00047   return(val);
00048 }
00049 
00050 static void usage(){
00051   fprintf(stderr,
00052           "usage:\n" 
00053           "huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
00054           "   where begin,n,group is first scalar, \n"
00055           "                          number of scalars of each in line,\n"
00056           "                          number of scalars in a group\n"
00057           "eg: huffbuild reslongaux.vqd 0,1024,4\n"
00058           "produces reslongaux.vqh\n\n");
00059   exit(1);
00060 }
00061 
00062 int main(int argc, char *argv[]){
00063   char *base;
00064   char *infile;
00065   int i,j,k,begin,n,subn,guard=1;
00066   FILE *file;
00067   int maxval=0;
00068   int loval=0;
00069 
00070   if(argc<3)usage();
00071   if(argc==4)guard=0;
00072 
00073   infile=strdup(argv[1]);
00074   base=strdup(infile);
00075   if(strrchr(base,'.'))
00076     strrchr(base,'.')[0]='\0';
00077 
00078   {
00079     char *pos=strchr(argv[2],',');
00080     char *dpos=strchr(argv[2],'-');
00081     if(dpos){
00082       loval=atoi(argv[2]);
00083       maxval=atoi(dpos+1);
00084       subn=1;
00085       begin=0;
00086     }else{
00087       begin=atoi(argv[2]);
00088       if(!pos)
00089         usage();
00090       else
00091         n=atoi(pos+1);
00092       pos=strchr(pos+1,',');
00093       if(!pos)
00094         usage();
00095       else
00096         subn=atoi(pos+1);
00097       if(n/subn*subn != n){
00098         fprintf(stderr,"n must be divisible by group\n");
00099         exit(1);
00100       }
00101     }
00102   }
00103 
00104   /* scan the file for maximum value */
00105   file=fopen(infile,"r");
00106   if(!file){
00107     fprintf(stderr,"Could not open file %s\n",infile);
00108     if(!maxval)
00109       exit(1);
00110     else
00111       fprintf(stderr,"  making untrained books.\n");
00112 
00113   }
00114 
00115   if(!maxval){
00116     i=0;
00117     while(1){
00118       long v;
00119       if(get_next_ivalue(file,&v))break;
00120       if(v>maxval)maxval=v;
00121       
00122       if(!(i++&0xff))spinnit("loading... ",i);
00123     }
00124     rewind(file);
00125     maxval++;
00126   }
00127 
00128   {
00129     long vals=pow(maxval,subn);
00130     long *hist=_ogg_calloc(vals,sizeof(long));
00131     long *lengths=_ogg_calloc(vals,sizeof(long));
00132     
00133     for(j=loval;j<vals;j++)hist[j]=guard;
00134     
00135     if(file){
00136       reset_next_value();
00137       i/=subn;
00138       while(!feof(file)){
00139         long val=getval(file,begin,n,subn,maxval);
00140         if(val==-1 || val>=vals)break;
00141         hist[val]++;
00142         if(!(i--&0xff))spinnit("loading... ",i*subn);
00143       }
00144       fclose(file);
00145     }
00146  
00147     /* we have the probabilities, build the tree */
00148     fprintf(stderr,"Building tree for %ld entries\n",vals);
00149     build_tree_from_lengths0(vals,hist,lengths);
00150 
00151     /* save the book */
00152     {
00153       char *buffer=alloca(strlen(base)+5);
00154       strcpy(buffer,base);
00155       strcat(buffer,".vqh");
00156       file=fopen(buffer,"w");
00157       if(!file){
00158         fprintf(stderr,"Could not open file %s\n",buffer);
00159         exit(1);
00160       }
00161     }
00162     
00163     /* first, the static vectors, then the book structure to tie it together. */
00164     /* lengthlist */
00165     fprintf(file,"static long _huff_lengthlist_%s[] = {\n",base);
00166     for(j=0;j<vals;){
00167       fprintf(file,"\t");
00168       for(k=0;k<16 && j<vals;k++,j++)
00169         fprintf(file,"%2ld,",lengths[j]);
00170       fprintf(file,"\n");
00171     }
00172     fprintf(file,"};\n\n");
00173     
00174     /* the toplevel book */
00175     fprintf(file,"static static_codebook _huff_book_%s = {\n",base);
00176     fprintf(file,"\t%d, %ld,\n",subn,vals);
00177     fprintf(file,"\t_huff_lengthlist_%s,\n",base);
00178     fprintf(file,"\t0, 0, 0, 0, 0,\n");
00179     fprintf(file,"\tNULL,\n");
00180 
00181     fprintf(file,"\tNULL,\n");
00182     fprintf(file,"\tNULL,\n");
00183     fprintf(file,"\tNULL,\n");
00184     fprintf(file,"\t0\n};\n\n");
00185     
00186     fclose(file);
00187     fprintf(stderr,"Done.                                \n\n");
00188   }
00189   exit(0);
00190 }
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 

Generated by  doxygen 1.6.2