Update tizen 2.0 beta source
[external/libvorbis.git] / vq / run.c
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: utility main for loading and operating on codebooks
14  last mod: $Id: run.c 16037 2009-05-26 21:10:58Z xiphmont $
15
16  ********************************************************************/
17
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <math.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <fcntl.h>
27
28 #include "bookutil.h"
29
30 /* command line:
31    utilname [-i] +|* input_book.vqh [+|* input_book.vqh] 
32             input_data.vqd [input_data.vqd]
33
34    produces output data on stdout
35    (may also take input data from stdin)
36
37  */
38
39 extern void process_preprocess(codebook **b,char *basename);
40 extern void process_postprocess(codebook **b,char *basename);
41 extern void process_vector(codebook **b,int *addmul, int inter,float *a,int n);
42 extern void process_usage(void);
43
44 int main(int argc,char *argv[]){
45   char *basename;
46   codebook **b=_ogg_calloc(1,sizeof(codebook *));
47   int *addmul=_ogg_calloc(1,sizeof(int));
48   int books=0;
49   int input=0;
50   int interleave=0;
51   int j;
52   int start=0;
53   int num=-1;
54   argv++;
55
56   if(*argv==NULL){
57     process_usage();
58     exit(1);
59   }
60
61   /* yes, this is evil.  However, it's very convenient to parse file
62      extentions */
63
64   while(*argv){
65     if(*argv[0]=='-'){
66       /* option */
67       if(argv[0][1]=='s'){
68         /* subvector */
69         if(sscanf(argv[1],"%d,%d",&start,&num)!=2){
70           num= -1;
71           if(sscanf(argv[1],"%d",&start)!=1){
72             fprintf(stderr,"Syntax error using -s\n");
73             exit(1);
74           }
75         }
76         argv+=2;
77       }
78       if(argv[0][1]=='i'){
79         /* interleave */
80         interleave=1;
81         argv+=1;
82       }
83     }else{
84       /* input file.  What kind? */
85       char *dot;
86       char *ext=NULL;
87       char *name=strdup(*argv++);
88       dot=strrchr(name,'.');
89       if(dot)
90         ext=dot+1;
91       else
92         ext="";
93
94       /* codebook */
95       if(!strcmp(ext,"vqh")){
96         int multp=0;
97         if(input){
98           fprintf(stderr,"specify all input data (.vqd) files following\n"
99                   "codebook header (.vqh) files\n");
100           exit(1);
101         }
102         /* is it additive or multiplicative? */
103         if(name[0]=='*'){
104           multp=1;
105           name++;
106         }
107         if(name[0]=='+')name++;
108
109         basename=strrchr(name,'/');
110         if(basename)
111           basename=strdup(basename)+1;
112         else
113           basename=strdup(name);
114         dot=strrchr(basename,'.');
115         if(dot)*dot='\0';
116
117         b=_ogg_realloc(b,sizeof(codebook *)*(books+2));
118         b[books]=codebook_load(name);
119         addmul=_ogg_realloc(addmul,sizeof(int)*(books+1));
120         addmul[books++]=multp;
121         b[books]=NULL;
122       }
123
124       /* data file */
125       if(!strcmp(ext,"vqd")){
126         int cols;
127         long lines=0;
128         char *line;
129         float *vec;
130         FILE *in=fopen(name,"r");
131         if(!in){
132           fprintf(stderr,"Could not open input file %s\n",name);
133           exit(1);
134         }
135
136         if(!input){
137           process_preprocess(b,basename);
138           input++;
139         }
140
141         reset_next_value();
142         line=setup_line(in);
143         /* count cols before we start reading */
144         {
145           char *temp=line;
146           while(*temp==' ')temp++;
147           for(cols=0;*temp;cols++){
148             while(*temp>32)temp++;
149             while(*temp==' ')temp++;
150           }
151         }
152         vec=alloca(cols*sizeof(float));
153         while(line){
154           lines++;
155           for(j=0;j<cols;j++)
156             if(get_line_value(in,vec+j)){
157               fprintf(stderr,"Too few columns on line %ld in data file\n",lines);
158               exit(1);
159             }
160           /* ignores -s for now */
161           process_vector(b,addmul,interleave,vec,cols);
162
163           line=setup_line(in);
164         }
165         fclose(in);
166       }
167     }
168   }
169
170   /* take any data from stdin */
171   {
172     struct stat st;
173     if(fstat(STDIN_FILENO,&st)==-1){
174       fprintf(stderr,"Could not stat STDIN\n");
175       exit(1);
176     }
177     if((S_IFIFO|S_IFREG|S_IFSOCK)&st.st_mode){
178       int cols;
179       char *line;
180       long lines=0;
181       float *vec;
182       if(!input){
183         process_preprocess(b,basename);
184         input++;
185       }
186       
187       line=setup_line(stdin);
188       /* count cols before we start reading */
189       {
190         char *temp=line;
191         while(*temp==' ')temp++;
192         for(cols=0;*temp;cols++){
193           while(*temp>32)temp++;
194           while(*temp==' ')temp++;
195         }
196       }
197       vec=alloca(cols*sizeof(float));
198       while(line){
199         lines++;
200         for(j=0;j<cols;j++)
201           if(get_line_value(stdin,vec+j)){
202             fprintf(stderr,"Too few columns on line %ld in data file\n",lines);
203             exit(1);
204           }
205         /* ignores -s for now */
206         process_vector(b,addmul,interleave,vec,cols);
207         
208         line=setup_line(stdin);
209       }
210     }
211   }
212
213   process_postprocess(b,basename);
214
215   return 0;
216 }