]> git.jsancho.org Git - lugaru.git/blob - libvorbis-1.0.1/vq/latticebuild.c
Simplified web browser launching on Linux.
[lugaru.git] / libvorbis-1.0.1 / vq / latticebuild.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 XIPHOPHORUS Company http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12
13  function: utility main for building codebooks from lattice descriptions
14  last mod: $Id: latticebuild.c,v 1.12 2001/12/20 01:00:39 segher Exp $
15
16  ********************************************************************/
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <math.h>
21 #include <string.h>
22 #include <errno.h>
23 #include "bookutil.h"
24
25 /* The purpose of this util is just to finish packaging the
26    description into a static codebook.  It used to count hits for a
27    histogram, but I've divorced that out to add some flexibility (it
28    currently generates an equal probability codebook) 
29
30    command line:
31    latticebuild description.vql
32
33    the lattice description file contains two lines:
34
35    <n> <dim> <multiplicitavep> <sequentialp>
36    <value_0> <value_1> <value_2> ... <value_n-1>
37    
38    a threshmap (or pigeonmap) struct is generated by latticehint;
39    there are fun tricks one can do with the threshmap and cascades,
40    but the utils don't know them...
41
42    entropy encoding is done by feeding an entry list collected from a
43    training set and feeding it to latticetune along with the book.
44
45    latticebuild produces a codebook on stdout */
46
47 static int ilog(unsigned int v){
48   int ret=0;
49   while(v){
50     ret++;
51     v>>=1;
52   }
53   return(ret);
54 }
55
56 int main(int argc,char *argv[]){
57   codebook b;
58   static_codebook c;
59   double *quantlist;
60   long *hits;
61
62   int entries=-1,dim=-1,quantvals=-1,addmul=-1,sequencep=0;
63   FILE *in=NULL;
64   char *line,*name;
65   long i,j;
66
67   memset(&b,0,sizeof(b));
68   memset(&c,0,sizeof(c));
69
70   if(argv[1]==NULL){
71     fprintf(stderr,"Need a lattice description file on the command line.\n");
72     exit(1);
73   }
74
75   {
76     char *ptr;
77     char *filename=_ogg_calloc(strlen(argv[1])+4,1);
78
79     strcpy(filename,argv[1]);
80     in=fopen(filename,"r");
81     if(!in){
82       fprintf(stderr,"Could not open input file %s\n",filename);
83       exit(1);
84     }
85     
86     ptr=strrchr(filename,'.');
87     if(ptr){
88       *ptr='\0';
89       name=strdup(filename);
90     }else{
91       name=strdup(filename);
92     }
93
94   }
95   
96   /* read the description */
97   line=get_line(in);
98   if(sscanf(line,"%d %d %d %d",&quantvals,&dim,&addmul,&sequencep)!=4){
99     if(sscanf(line,"%d %d %d",&quantvals,&dim,&addmul)!=3){
100       fprintf(stderr,"Syntax error reading description file (line 1)\n");
101       exit(1);
102     }
103   }
104   entries=pow(quantvals,dim);
105   c.dim=dim;
106   c.entries=entries;
107   c.lengthlist=_ogg_malloc(entries*sizeof(long));
108   c.maptype=1;
109   c.q_sequencep=sequencep;
110   c.quantlist=_ogg_calloc(quantvals,sizeof(long));
111
112   quantlist=_ogg_malloc(sizeof(double)*c.dim*c.entries);
113   hits=_ogg_malloc(c.entries*sizeof(long));
114   for(j=0;j<entries;j++)hits[j]=1;
115   for(j=0;j<entries;j++)c.lengthlist[j]=1;
116
117   reset_next_value();
118   line=setup_line(in);
119   for(j=0;j<quantvals;j++){ 
120     char *temp;
121     if(!line || sscanf(line,"%lf",quantlist+j)!=1){
122       fprintf(stderr,"Ran out of data on line 2 of description file\n");
123       exit(1);
124     }
125     temp=strchr(line,',');
126     if(!temp)temp=strchr(line,' ');
127     if(temp)temp++;
128     line=temp;
129   }
130
131   /* gen a real quant list from the more easily human-grokked input */
132   {
133     double min=quantlist[0];
134     double mindel=-1;
135     int fac=1;
136     for(j=1;j<quantvals;j++)if(quantlist[j]<min)min=quantlist[j];
137     for(j=0;j<quantvals;j++)
138       for(i=j+1;i<quantvals;i++)
139         if(mindel==-1 || fabs(quantlist[j]-quantlist[i])<mindel)
140           mindel=fabs(quantlist[j]-quantlist[i]);
141
142     j=0;
143     while(j<quantvals){
144       for(j=0;j<quantvals;j++){
145         double test=fac*(quantlist[j]-min)/mindel;
146         if( fabs(rint(test)-test)>.00001f) break;
147       }
148       if(fac>100)break;
149       if(j<quantvals)fac++;
150     }
151
152     mindel/=fac;
153     fprintf(stderr,"min=%g mindel=%g\n",min,mindel);
154
155     c.q_min=_float32_pack(min);
156     c.q_delta=_float32_pack(mindel);
157     c.q_quant=0;
158
159     min=_float32_unpack(c.q_min);
160     mindel=_float32_unpack(c.q_delta);
161     for(j=0;j<quantvals;j++){
162       c.quantlist[j]=rint((quantlist[j]-min)/mindel);
163       if(ilog(c.quantlist[j])>c.q_quant)c.q_quant=ilog(c.quantlist[j]);
164     }
165   }
166
167   /* build the [default] codeword lengths */
168   memset(c.lengthlist,0,sizeof(long)*entries);
169   for(i=0;i<entries;i++)hits[i]=1;
170   build_tree_from_lengths(entries,hits,c.lengthlist);
171
172   /* save the book in C header form */
173   write_codebook(stdout,name,&c);
174   fprintf(stderr,"\r                                                     "
175           "\nDone.\n");
176   exit(0);
177 }