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