dc728f2c46c91eb271bdddd76dccb529993bb573
[platform/upstream/libvorbis.git] / vq / huffbuild.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: hufftree builder
15  last mod: $Id: huffbuild.c,v 1.4 2000/07/12 09:36:17 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
25 static int nsofar=0;
26 static int getval(FILE *in,int begin,int n,int group,int max){
27   double v;
28   int i;
29   long val=0;
30
31   if(nsofar>=n || get_line_value(in,&v)){
32     reset_next_value();
33     nsofar=0;
34     if(get_next_value(in,&v))
35       return(-1);
36     for(i=1;i<=begin;i++)
37       get_line_value(in,&v);
38   }
39
40   val=(int)v;
41   nsofar++;
42
43   for(i=1;i<group;i++,nsofar++)
44     if(nsofar>=n || get_line_value(in,&v))
45       return(getval(in,begin,n,group,max));
46     else
47       val = val*max+(int)v;
48   return(val);
49 }
50
51 static void usage(){
52   fprintf(stderr,
53           "usage:\n" 
54           "huffbuild <input>.vqd <begin,n,group> [noguard]\n"
55           "   where begin,n,group is first scalar, \n"
56           "                          number of scalars of each in line,\n"
57           "                          number of scalars in a group\n"
58           "eg: huffbuild reslongaux.vqd 0,1024,4\n"
59           "produces reslongaux.vqh\n\n");
60   exit(1);
61 }
62
63 int main(int argc, char *argv[]){
64   char *base;
65   char *infile;
66   int i,j,k,begin,n,subn,guard=1;
67   FILE *file;
68   int maxval=0;
69
70   if(argc<3)usage();
71   if(argc==4)guard=0;
72
73   infile=strdup(argv[1]);
74   base=strdup(infile);
75   if(strrchr(base,'.'))
76     strrchr(base,'.')[0]='\0';
77
78   {
79     char *pos=strchr(argv[2],',');
80     begin=atoi(argv[2]);
81     if(!pos)
82       usage();
83     else
84       n=atoi(pos+1);
85     pos=strchr(pos+1,',');
86     if(!pos)
87       usage();
88     else
89       subn=atoi(pos+1);
90     if(n/subn*subn != n){
91       fprintf(stderr,"n must be divisible by group\n");
92       exit(1);
93     }
94   }
95
96   /* scan the file for maximum value */
97   file=fopen(infile,"r");
98   if(!file){
99     fprintf(stderr,"Could not open file %s\n",infile);
100     exit(1);
101   }
102   i=0;
103   while(1){
104     long v;
105     if(get_next_ivalue(file,&v))break;
106     if(v>maxval)maxval=v;
107
108     if(!(i++&0xff))spinnit("loading... ",i);
109   }
110   rewind(file);
111   maxval++;
112
113   {
114     long vals=pow(maxval,subn);
115     long *hist=malloc(vals*sizeof(long));
116     long *lengths=malloc(vals*sizeof(long));
117     
118     for(j=0;j<vals;j++)hist[j]=guard;
119     
120     reset_next_value();
121     i/=subn;
122     while(!feof(file)){
123       long val=getval(file,begin,n,subn,maxval);
124       if(val==-1)break;
125       hist[val]++;
126       if(!(i--&0xff))spinnit("loading... ",i*subn);
127     }
128     fclose(file);
129  
130     /* we have the probabilities, build the tree */
131     fprintf(stderr,"Building tree for %ld entries\n",vals);
132     build_tree_from_lengths0(vals,hist,lengths);
133
134     /* save the book */
135     {
136       char *buffer=alloca(strlen(base)+5);
137       strcpy(buffer,base);
138       strcat(buffer,".vqh");
139       file=fopen(buffer,"w");
140       if(!file){
141         fprintf(stderr,"Could not open file %s\n",buffer);
142         exit(1);
143       }
144     }
145     
146     fprintf(file,
147  "/********************************************************************\n"
148  " *                                                                  *\n"
149  " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *\n"
150  " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
151  " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *\n"
152  " * PLEASE READ THESE TERMS DISTRIBUTING.                            *\n"
153  " *                                                                  *\n"
154  " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *\n"
155  " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *\n"
156  " * http://www.xiph.org/                                             *\n"
157  " *                                                                  *\n"
158  " ********************************************************************\n"
159  "\n"
160  " function: static codebook autogenerated by huff/huffbuld\n"
161  "\n"
162  " ********************************************************************/\n\n");
163
164     fprintf(file,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",base,base);
165     fprintf(file,"#include \"vorbis/codebook.h\"\n\n");
166     
167     /* first, the static vectors, then the book structure to tie it together. */
168     /* lengthlist */
169     fprintf(file,"static long _huff_lengthlist_%s[] = {\n",base);
170     for(j=0;j<vals;){
171       fprintf(file,"\t");
172       for(k=0;k<16 && j<vals;k++,j++)
173         fprintf(file,"%2ld,",lengths[j]);
174       fprintf(file,"\n");
175     }
176     fprintf(file,"};\n\n");
177     
178     /* the toplevel book */
179     fprintf(file,"static static_codebook _huff_book_%s = {\n",base);
180     fprintf(file,"\t%d, %ld,\n",subn,vals);
181     fprintf(file,"\t_huff_lengthlist_%s,\n",base);
182     fprintf(file,"\t0, 0, 0, 0, 0,\n");
183     fprintf(file,"\tNULL,\n");
184     fprintf(file,"\tNULL,\n");
185     fprintf(file,"\tNULL,\n");
186     fprintf(file,"};\n\n");
187     
188     fprintf(file,"\n#endif\n");
189     fclose(file);
190     fprintf(stderr,"Done.                                \n\n");
191   }
192   exit(0);
193 }
194
195