• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
getval(FILE * in,int begin,int n,int group,int max)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 
usage()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 
main(int argc,char * argv[])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