Home | History | Annotate | Download | only in vq
      1 /********************************************************************
      2  *                                                                  *
      3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
      4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
      5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
      6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
      7  *                                                                  *
      8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
      9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
     10  *                                                                  *
     11  ********************************************************************
     12 
     13  function: hufftree builder
     14  last mod: $Id: huffbuild.c 16959 2010-03-10 16:03:11Z xiphmont $
     15 
     16  ********************************************************************/
     17 
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <math.h>
     21 #include <stdio.h>
     22 #include "bookutil.h"
     23 
     24 static int nsofar=0;
     25 static int getval(FILE *in,int begin,int n,int group,int max){
     26   float v;
     27   int i;
     28   long val=0;
     29 
     30   if(nsofar>=n || get_line_value(in,&v)){
     31     reset_next_value();
     32     nsofar=0;
     33     if(get_next_value(in,&v))
     34       return(-1);
     35     for(i=1;i<=begin;i++)
     36       get_line_value(in,&v);
     37   }
     38 
     39   val=(int)v;
     40   nsofar++;
     41 
     42   for(i=1;i<group;i++,nsofar++)
     43     if(nsofar>=n || get_line_value(in,&v))
     44       return(getval(in,begin,n,group,max));
     45     else
     46       val = val*max+(int)v;
     47   return(val);
     48 }
     49 
     50 static void usage(){
     51   fprintf(stderr,
     52           "usage:\n"
     53           "huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
     54           "   where begin,n,group is first scalar, \n"
     55           "                          number of scalars of each in line,\n"
     56           "                          number of scalars in a group\n"
     57           "eg: huffbuild reslongaux.vqd 0,1024,4\n"
     58           "produces reslongaux.vqh\n\n");
     59   exit(1);
     60 }
     61 
     62 int main(int argc, char *argv[]){
     63   char *base;
     64   char *infile;
     65   int i,j,k,begin,n,subn,guard=1;
     66   FILE *file;
     67   int maxval=0;
     68   int loval=0;
     69 
     70   if(argc<3)usage();
     71   if(argc==4)guard=0;
     72 
     73   infile=strdup(argv[1]);
     74   base=strdup(infile);
     75   if(strrchr(base,'.'))
     76     strrchr(base,'.')[0]='\0';
     77 
     78   {
     79     char *pos=strchr(argv[2],',');
     80     char *dpos=strchr(argv[2],'-');
     81     if(dpos){
     82       loval=atoi(argv[2]);
     83       maxval=atoi(dpos+1);
     84       subn=1;
     85       begin=0;
     86     }else{
     87       begin=atoi(argv[2]);
     88       if(!pos)
     89         usage();
     90       else
     91         n=atoi(pos+1);
     92       pos=strchr(pos+1,',');
     93       if(!pos)
     94         usage();
     95       else
     96         subn=atoi(pos+1);
     97       if(n/subn*subn != n){
     98         fprintf(stderr,"n must be divisible by group\n");
     99         exit(1);
    100       }
    101     }
    102   }
    103 
    104   /* scan the file for maximum value */
    105   file=fopen(infile,"r");
    106   if(!file){
    107     fprintf(stderr,"Could not open file %s\n",infile);
    108     if(!maxval)
    109       exit(1);
    110     else
    111       fprintf(stderr,"  making untrained books.\n");
    112 
    113   }
    114 
    115   if(!maxval){
    116     i=0;
    117     while(1){
    118       long v;
    119       if(get_next_ivalue(file,&v))break;
    120       if(v>maxval)maxval=v;
    121 
    122       if(!(i++&0xff))spinnit("loading... ",i);
    123     }
    124     rewind(file);
    125     maxval++;
    126   }
    127 
    128   {
    129     long vals=pow(maxval,subn);
    130     long *hist=_ogg_calloc(vals,sizeof(long));
    131     long *lengths=_ogg_calloc(vals,sizeof(long));
    132 
    133     for(j=loval;j<vals;j++)hist[j]=guard;
    134 
    135     if(file){
    136       reset_next_value();
    137       i/=subn;
    138       while(!feof(file)){
    139         long val=getval(file,begin,n,subn,maxval);
    140         if(val==-1 || val>=vals)break;
    141         hist[val]++;
    142         if(!(i--&0xff))spinnit("loading... ",i*subn);
    143       }
    144       fclose(file);
    145     }
    146 
    147     /* we have the probabilities, build the tree */
    148     fprintf(stderr,"Building tree for %ld entries\n",vals);
    149     build_tree_from_lengths0(vals,hist,lengths);
    150 
    151     /* save the book */
    152     {
    153       char *buffer=alloca(strlen(base)+5);
    154       strcpy(buffer,base);
    155       strcat(buffer,".vqh");
    156       file=fopen(buffer,"w");
    157       if(!file){
    158         fprintf(stderr,"Could not open file %s\n",buffer);
    159         exit(1);
    160       }
    161     }
    162 
    163     /* first, the static vectors, then the book structure to tie it together. */
    164     /* lengthlist */
    165     fprintf(file,"static const long _huff_lengthlist_%s[] = {\n",base);
    166     for(j=0;j<vals;){
    167       fprintf(file,"\t");
    168       for(k=0;k<16 && j<vals;k++,j++)
    169         fprintf(file,"%2ld,",lengths[j]);
    170       fprintf(file,"\n");
    171     }
    172     fprintf(file,"};\n\n");
    173 
    174     /* the toplevel book */
    175     fprintf(file,"static const static_codebook _huff_book_%s = {\n",base);
    176     fprintf(file,"\t%d, %ld,\n",subn,vals);
    177     fprintf(file,"\t(long *)_huff_lengthlist_%s,\n",base);
    178     fprintf(file,"\t0, 0, 0, 0, 0,\n");
    179     fprintf(file,"\tNULL,\n");
    180 
    181     fprintf(file,"\t0\n};\n\n");
    182 
    183     fclose(file);
    184     fprintf(stderr,"Done.                                \n\n");
    185   }
    186   exit(0);
    187 }
    188 
    189 
    190 
    191 
    192 
    193 
    194 
    195 
    196 
    197 
    198 
    199