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