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