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