Merging the postbeta2 branch onto the mainline.
[platform/upstream/libvorbis.git] / vq / residuesplit.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: residue backend 0 partitioner/classifier
15  last mod: $Id: residuesplit.c,v 1.5 2000/10/12 03:13:02 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <math.h>
22 #include <stdio.h>
23 #include "../vq/bookutil.h"
24 #include "../lib/sharedbook.h"
25
26 /* does not guard against invalid settings; eg, a subn of 16 and a
27    subgroup request of 32.  Max subn of 128 */
28 static void _testhack(float *vec,int n,float *entropy){
29   int i,j=0;
30   float max=0.;
31   float temp[128];
32
33   /* setup */
34   for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
35
36   /* handle case subgrp==1 outside */
37   for(i=0;i<n;i++)
38     if(temp[i]>max)max=temp[i];
39
40   for(i=0;i<n;i++)temp[i]=rint(temp[i]);
41
42   while(1){
43     entropy[j]=max;
44     n>>=1;
45     j++;
46
47     if(n<=0)break;
48     for(i=0;i<n;i++){
49       temp[i]+=temp[i+n];
50     }
51     max=0.;
52     for(i=0;i<n;i++)
53       if(temp[i]>max)max=temp[i];
54   }
55 }
56
57 static FILE *of;
58 static FILE **or;
59
60 /* we evaluate the the entropy measure for each interleaved subgroup */
61 /* This is currently a bit specific to/hardwired for mapping 0; things
62    will need to change in the future when we get real multichannel
63    mappings */
64 int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn){
65   long i,j;
66   float entropy[8];
67   int aux;
68
69   for(i=0;i<=n-subn;i+=subn){
70     float max=0.;
71
72     _testhack(res+i,subn,entropy);
73     for(j=0;j<subn;j++)
74       if(fabs(res[i+j])>max)max=fabs(res[i+j]);
75
76     for(j=0;j<parts-1;j++)
77       if(entropy[subgrp[j]]<=ebound[j] &&
78          max<=mbound[j])
79         break;
80     aux=j;
81     
82     fprintf(of,"%d, ",aux);
83     
84     for(j=0;j<subn;j++)
85       fprintf(or[aux],"%g, ",res[j+i]);
86     
87     fprintf(or[aux],"\n");
88   }
89
90   fprintf(of,"\n");
91
92   return(0);
93 }
94
95 static int getline(FILE *in,float *vec,int begin,int n){
96   int i,next=0;
97
98   reset_next_value();
99   if(get_next_value(in,vec))return(0);
100   if(begin){
101     for(i=1;i<begin;i++)
102       get_line_value(in,vec);
103     next=0;
104   }else{
105     next=1;
106   }
107
108   for(i=next;i<n;i++)
109     if(get_line_value(in,vec+i)){
110       fprintf(stderr,"ran out of columns in input data\n");
111       exit(1);
112     }
113   
114   return(1);
115 }
116
117 static void usage(){
118   fprintf(stderr,
119           "usage:\n" 
120           "residuesplit <res> <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
121           "   where begin,n,group is first scalar, \n"
122           "                          number of scalars of each in line,\n"
123           "                          number of scalars in a group\n"
124           "         ent is the maximum entropy value allowed for membership in a group\n"
125           "         peak is the maximum amplitude value allowed for membership in a group\n"
126           "         subn is the maximum entropy value allowed for membership in a group\n"
127                    
128           "eg: residuesplit mask.vqd floor.vqd 0,1024,16 res 0,.5,16 3,1.5,8 \n"
129           "produces resaux.vqd and res_0...n.vqd\n\n");
130   exit(1);
131 }
132
133 int main(int argc, char *argv[]){
134   char *buffer;
135   char *base;
136   int i,parts,begin,n,subn,*subgrp;
137   FILE *res;
138   float *ebound,*mbound,*vec;
139   long c=0;
140   if(argc<5)usage();
141
142   base=strdup(argv[3]);
143   buffer=alloca(strlen(base)+20);
144   {
145     char *pos=strchr(argv[2],',');
146     begin=atoi(argv[2]);
147     if(!pos)
148       usage();
149     else
150       n=atoi(pos+1);
151     pos=strchr(pos+1,',');
152     if(!pos)
153       usage();
154     else
155       subn=atoi(pos+1);
156     if(n/subn*subn != n){
157       fprintf(stderr,"n must be divisible by group\n");
158       exit(1);
159     }
160   }
161
162   /* how many parts?... */
163   parts=argc-3;
164   
165   ebound=malloc(sizeof(float)*parts);
166   mbound=malloc(sizeof(float)*parts);
167   subgrp=malloc(sizeof(int)*parts);
168   
169   for(i=0;i<parts-1;i++){
170     char *pos=strchr(argv[4+i],',');
171     if(*argv[4+i]==',')
172       ebound[i]=1e50;
173     else
174       ebound[i]=atof(argv[4+i]);
175
176     if(!pos){
177       mbound[i]=1e50;
178       subgrp[i]=_ilog(subn)-1;
179      }else{
180        if(*(pos+1)==',')
181          mbound[i]=1e50;
182        else
183          mbound[i]=atof(pos+1);
184        pos=strchr(pos+1,',');
185        
186        if(!pos){
187          subgrp[i]=_ilog(subn)-1;
188        }else{
189          subgrp[i]=_ilog(atoi(pos+1))-1;
190        }
191      }
192   }
193
194   ebound[i]=1e50;
195   mbound[i]=1e50;
196   subgrp[i]=_ilog(subn)-1;
197
198   res=fopen(argv[1],"r");
199   if(!res){
200     fprintf(stderr,"Could not open file %s\n",argv[1]);
201     exit(1);
202   }
203
204   or=alloca(parts*sizeof(FILE*));
205   sprintf(buffer,"%saux.vqd",base);
206   of=fopen(buffer,"w");
207   if(!of){
208     fprintf(stderr,"Could not open file %s for writing\n",buffer);
209     exit(1);
210   }
211   for(i=0;i<parts;i++){
212     sprintf(buffer,"%s_%d.vqd",base,i);
213     or[i]=fopen(buffer,"w");
214     if(!or[i]){
215       fprintf(stderr,"Could not open file %s for writing\n",buffer);
216       exit(1);
217     }
218   }
219   
220   vec=malloc(sizeof(float)*n);
221   /* get the input line by line and process it */
222   while(!feof(res)){
223     if(getline(res,vec,begin,n))
224       quantaux(vec,n,ebound,mbound,subgrp,parts,subn);
225     c++;
226     if(!(c&0xf)){
227       spinnit("kB so far...",(int)(ftell(res)/1024));
228     }
229   }
230   fclose(res);
231   fclose(of);
232   for(i=0;i<parts;i++)
233     fclose(or[i]);
234   fprintf(stderr,"\rDone                         \n");
235   return(0);
236 }
237
238
239
240