bugfixes for new functionality
[platform/upstream/libvorbis.git] / vq / build.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
6  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
7  *                                                                  *
8  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *
9  * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: utility main for building codebooks from training sets
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Dec 15 1999
18
19  ********************************************************************/
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <string.h>
25 #include <errno.h>
26 #include "vqgen.h"
27
28 static char *linebuffer=NULL;
29 static int  lbufsize=0;
30 static char *rline(FILE *in,FILE *out){
31   long sofar=0;
32   if(feof(in))return NULL;
33
34   while(1){
35     int gotline=0;
36
37     while(!gotline){
38       if(sofar>=lbufsize){
39         if(!lbufsize){  
40           lbufsize=1024;
41           linebuffer=malloc(lbufsize);
42         }else{
43           lbufsize*=2;
44           linebuffer=realloc(linebuffer,lbufsize);
45         }
46       }
47       {
48         long c=fgetc(in);
49         switch(c){
50         case '\n':
51         case EOF:
52           gotline=1;
53           break;
54         default:
55           linebuffer[sofar++]=c;
56           linebuffer[sofar]='\0';
57           break;
58         }
59       }
60     }
61     
62     if(linebuffer[0]=='#'){
63       sofar=0;
64     }else{
65       return(linebuffer);
66     }
67   }
68 }
69
70 /* command line:
71    buildvq file
72 */
73
74 int main(int argc,char *argv[]){
75   vqgen v;
76   vqbook b;
77   quant_meta q;
78   long *quantlist=NULL;
79
80   int entries=-1,dim=-1,aux=-1;
81   FILE *out=NULL;
82   FILE *in=NULL;
83   char *line,*name;
84   long i,j,k;
85
86   if(argv[1]==NULL){
87     fprintf(stderr,"Need a trained data set on the command line.\n");
88     exit(1);
89   }
90
91   {
92     char *ptr;
93     char *filename=strdup(argv[1]);
94
95     in=fopen(filename,"r");
96     if(!in){
97       fprintf(stderr,"Could not open input file %s\n",filename);
98       exit(1);
99     }
100     
101     ptr=strrchr(filename,'-');
102     if(ptr){
103       *ptr='\0';
104       name=strdup(filename);
105       sprintf(ptr,".vqh");
106     }else{
107       name=strdup(filename);
108       strcat(filename,".vqh");
109     }
110
111     out=fopen(filename,"w");
112     if(out==NULL){
113       fprintf(stderr,"Unable to open %s for writing\n",filename);
114       exit(1);
115     }
116   }
117
118   /* suck in the trained book */
119
120   /* read book type, but it doesn't matter */
121   line=rline(in,out);
122   
123   line=rline(in,out);
124   if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){
125     fprintf(stderr,"Syntax error reading book file\n");
126     exit(1);
127   }
128   
129   /* just use it to allocate mem */
130   vqgen_init(&v,dim,0,entries,NULL,NULL);
131   
132   /* quant */
133   line=rline(in,out);
134   if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
135             &q.quant,&q.sequencep)!=4){
136     fprintf(stderr,"Syntax error reading book file\n");
137     exit(1);
138   }
139   
140   /* quantized entries */
141   /* save quant data; we don't want to requantize later as our method
142      is currently imperfect wrt repeated application */
143   i=0;
144   quantlist=malloc(sizeof(long)*v.elements*v.entries);
145   for(j=0;j<entries;j++){
146     double a;
147     for(k=0;k<dim;k++){
148       line=rline(in,out);
149       sscanf(line,"%lf",&a);
150       v.entrylist[i]=a;
151       quantlist[i++]=rint(a);
152     }
153   }    
154   
155   /* ignore bias */
156   for(j=0;j<entries;j++)line=rline(in,out);
157   free(v.bias);
158   v.bias=NULL;
159   
160   /* training points */
161   {
162     double *b=alloca(sizeof(double)*(dim+aux));
163     i=0;
164     v.entries=0; /* hack to avoid reseeding */
165     while(1){
166       for(k=0;k<dim+aux;k++){
167         line=rline(in,out);
168         if(!line)break;
169         sscanf(line,"%lf",b+k);
170       }
171       if(feof(in))break;
172       vqgen_addpoint(&v,b,NULL);
173     }
174     v.entries=entries;
175   }
176   
177   fclose(in);
178   vqgen_unquantize(&v,&q);
179
180   /* build the book */
181   vqsp_book(&v,&b,quantlist);
182
183   /* save the book in C header form */
184   fprintf(out,
185  "/********************************************************************\n"
186  " *                                                                  *\n"
187  " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *\n"
188  " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
189  " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *\n"
190  " * PLEASE READ THESE TERMS DISTRIBUTING.                            *\n"
191  " *                                                                  *\n"
192  " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *\n"
193  " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *\n"
194  " * http://www.xiph.org/                                             *\n"
195  " *                                                                  *\n"
196  " ********************************************************************\n"
197  "\n"
198  " function: static codebook autogenerated by vq/vqbuild\n"
199  "\n"
200  " ********************************************************************/\n\n");
201
202   fprintf(out,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",name,name);
203   fprintf(out,"#include \"vqgen.h\"\n\n");
204
205   /* first, the static vectors, then the book structure to tie it together. */
206   /* quantlist */
207   fprintf(out,"static long _vq_quantlist_%s[] = {\n",name);
208   i=0;
209   for(j=0;j<entries;j++){
210     fprintf(out,"\t");
211     for(k=0;k<dim;k++)
212       fprintf(out,"%ld, ",b.quantlist[i++]);
213     fprintf(out,"\n");
214   }
215   fprintf(out,"};\n\n");
216
217   /* codelist */
218   fprintf(out,"static long _vq_codelist_%s[] = {\n",name);
219   for(j=0;j<entries;j++){
220     fprintf(out,"\t%ld,\n",b.codelist[j]);
221   }
222   fprintf(out,"};\n\n");
223
224   /* lengthlist */
225   fprintf(out,"static long _vq_lengthlist_%s[] = {\n",name);
226   for(j=0;j<entries;j++){
227     fprintf(out,"\t%ld,\n",b.lengthlist[j]);
228   }
229   fprintf(out,"};\n\n");
230
231   /* ptr0 */
232   fprintf(out,"static long _vq_ptr0_%s[] = {\n",name);
233   for(j=0;j<b.aux;j++){
234     fprintf(out,"\t%ld,\n",b.ptr0[j]);
235   }
236   fprintf(out,"};\n\n");
237
238   /* ptr1 */
239   fprintf(out,"static long _vq_ptr1_%s[] = {\n",name);
240   for(j=0;j<b.aux;j++){
241     fprintf(out,"\t%ld,\n",b.ptr1[j]);
242   }
243   fprintf(out,"};\n\n");
244
245   /* n */
246   fprintf(out,"static double _vq_n_%s[] = {\n",name);
247   i=0;
248   for(j=0;j<b.aux;j++){
249     fprintf(out,"\t");
250     for(k=0;k<dim;k++)
251       fprintf(out,"%g,",b.n[i++]);
252     fprintf(out,"\n");
253   }
254   fprintf(out,"};\n\n");
255
256   /* c */
257   fprintf(out,"static double _vq_c_%s[] = {\n",name);
258   for(j=0;j<b.aux;j++){
259     fprintf(out,"\t%g,\n",b.c[j]);
260   }
261   fprintf(out,"};\n\n");
262
263   /* tie it all together */
264   fprintf(out,"static vqbook _vq_book_%s = {\n",name);
265   fprintf(out,"\t%ld, %ld, %ld, %ld, %d, %d,\n",
266           b.dim,b.entries,q.min,q.delta,q.quant,q.sequencep);
267   fprintf(out,"\t0,\n"); /* valuelist */
268   fprintf(out,"\t_vq_quantlist_%s,\n",name);
269   fprintf(out,"\t_vq_codelist_%s,\n",name);
270   fprintf(out,"\t_vq_lengthlist_%s,\n",name);
271   fprintf(out,"\t_vq_ptr0_%s,\n",name);
272   fprintf(out,"\t_vq_ptr1_%s,\n",name);
273   fprintf(out,"\t_vq_n_%s,\n",name);
274   fprintf(out,"\t_vq_c_%s,\n",name);
275   fprintf(out,"\t%ld, %ld };\n\n",b.aux,b.aux);
276
277   fprintf(out,"\n#endif\n");
278   fclose(out);
279   exit(0);
280 }