Allow cascade and metric utilities to take more than one codebook
[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.6 2000/01/07 12:11:33 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 input_book.vqh 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,double *a);
42 extern void process_usage(void);
43
44 int main(int argc,char *argv[]){
45   char *name;
46   char *basename;
47   double *a=NULL;
48   codebook **b=calloc(1,sizeof(codebook *));
49   int books=0;
50   int input=0;
51   argv++;
52
53   if(*argv==NULL){
54     process_usage();
55     exit(1);
56   }
57
58   /* yes, this is evil.  However, it's very convenient to parse file
59      extentions */
60
61   while(*argv){
62     if(*argv[0]=='-'){
63       /* option */
64
65
66
67     }else{
68       /* input file.  What kind? */
69       char *dot;
70       char *ext=NULL;
71       char *name=strdup(*argv++);
72       dot=strchr(name,'.');
73       if(dot)
74         ext=dot+1;
75       else
76         ext="";
77
78       /* codebook */
79       if(!strcmp(ext,"vqh")){
80         if(input){
81           fprintf(stderr,"specify all input data (.vqd) files following\n"
82                   "codebook header (.vqh) files\n");
83           exit(1);
84         }
85
86         basename=strrchr(name,'/');
87         if(basename)
88           basename=strdup(basename);
89         else
90           basename=strdup(name);
91         dot=strchr(basename,'.');
92         if(dot)*dot='\0';
93
94         b=realloc(b,sizeof(codebook *)*(books+2));
95         b[books++]=codebook_load(name);
96         b[books]=NULL;
97         if(!a)a=malloc(sizeof(double)*b[books-1]->dim);
98       }
99
100       /* data file */
101       if(!strcmp(ext,"vqd")){
102         FILE *in=fopen(name,"r");
103         if(!in){
104           fprintf(stderr,"Could not open input file %s\n",name);
105           exit(1);
106         }
107
108         if(!input){
109           process_preprocess(b,basename);
110           input++;
111         }
112
113         reset_next_value();
114
115         while(get_vector(*b,in,a)!=-1)
116           process_vector(b,a);
117
118         fclose(in);
119       }
120     }
121   }
122
123   /* take any data from stdin */
124   {
125     struct stat st;
126     if(fstat(STDIN_FILENO,&st)==-1){
127       fprintf(stderr,"Could not stat STDIN\n");
128       exit(1);
129     }
130     if((S_IFIFO|S_IFREG|S_IFSOCK)&st.st_mode){
131       if(!input){
132         process_preprocess(b,basename);
133         input++;
134       }
135       
136       reset_next_value();
137       while(get_vector(*b,stdin,a)!=-1)
138         process_vector(b,a);
139     }
140   }
141
142   process_postprocess(b,basename);
143
144   return 0;
145 }