Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/libvorbis-1.2.0/vq/huffbuild.c @ 28

Last change on this file since 28 was 16, checked in by landauf, 17 years ago

added libvorbis

File size: 4.7 KB
RevLine 
[16]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 Xiph.Org Foundation http://www.xiph.org/                  *
10 *                                                                  *
11 ********************************************************************
12
13 function: hufftree builder
14 last mod: $Id: huffbuild.c 13293 2007-07-24 00:09:47Z xiphmont $
15
16 ********************************************************************/
17
18#include <stdlib.h>
19#include <string.h>
20#include <math.h>
21#include <stdio.h>
22#include "bookutil.h"
23
24static int nsofar=0;
25static int getval(FILE *in,int begin,int n,int group,int max){
26  float v;
27  int i;
28  long val=0;
29
30  if(nsofar>=n || get_line_value(in,&v)){
31    reset_next_value();
32    nsofar=0;
33    if(get_next_value(in,&v))
34      return(-1);
35    for(i=1;i<=begin;i++)
36      get_line_value(in,&v);
37  }
38
39  val=(int)v;
40  nsofar++;
41
42  for(i=1;i<group;i++,nsofar++)
43    if(nsofar>=n || get_line_value(in,&v))
44      return(getval(in,begin,n,group,max));
45    else
46      val = val*max+(int)v;
47  return(val);
48}
49
50static void usage(){
51  fprintf(stderr,
52          "usage:\n" 
53          "huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
54          "   where begin,n,group is first scalar, \n"
55          "                          number of scalars of each in line,\n"
56          "                          number of scalars in a group\n"
57          "eg: huffbuild reslongaux.vqd 0,1024,4\n"
58          "produces reslongaux.vqh\n\n");
59  exit(1);
60}
61
62int main(int argc, char *argv[]){
63  char *base;
64  char *infile;
65  int i,j,k,begin,n,subn,guard=1;
66  FILE *file;
67  int maxval=0;
68  int loval=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    char *dpos=strchr(argv[2],'-');
81    if(dpos){
82      loval=atoi(argv[2]);
83      maxval=atoi(dpos+1);
84      subn=1;
85      begin=0;
86    }else{
87      begin=atoi(argv[2]);
88      if(!pos)
89        usage();
90      else
91        n=atoi(pos+1);
92      pos=strchr(pos+1,',');
93      if(!pos)
94        usage();
95      else
96        subn=atoi(pos+1);
97      if(n/subn*subn != n){
98        fprintf(stderr,"n must be divisible by group\n");
99        exit(1);
100      }
101    }
102  }
103
104  /* scan the file for maximum value */
105  file=fopen(infile,"r");
106  if(!file){
107    fprintf(stderr,"Could not open file %s\n",infile);
108    if(!maxval)
109      exit(1);
110    else
111      fprintf(stderr,"  making untrained books.\n");
112
113  }
114
115  if(!maxval){
116    i=0;
117    while(1){
118      long v;
119      if(get_next_ivalue(file,&v))break;
120      if(v>maxval)maxval=v;
121     
122      if(!(i++&0xff))spinnit("loading... ",i);
123    }
124    rewind(file);
125    maxval++;
126  }
127
128  {
129    long vals=pow(maxval,subn);
130    long *hist=_ogg_calloc(vals,sizeof(long));
131    long *lengths=_ogg_calloc(vals,sizeof(long));
132   
133    for(j=loval;j<vals;j++)hist[j]=guard;
134   
135    if(file){
136      reset_next_value();
137      i/=subn;
138      while(!feof(file)){
139        long val=getval(file,begin,n,subn,maxval);
140        if(val==-1 || val>=vals)break;
141        hist[val]++;
142        if(!(i--&0xff))spinnit("loading... ",i*subn);
143      }
144      fclose(file);
145    }
146 
147    /* we have the probabilities, build the tree */
148    fprintf(stderr,"Building tree for %ld entries\n",vals);
149    build_tree_from_lengths0(vals,hist,lengths);
150
151    /* save the book */
152    {
153      char *buffer=alloca(strlen(base)+5);
154      strcpy(buffer,base);
155      strcat(buffer,".vqh");
156      file=fopen(buffer,"w");
157      if(!file){
158        fprintf(stderr,"Could not open file %s\n",buffer);
159        exit(1);
160      }
161    }
162   
163    /* first, the static vectors, then the book structure to tie it together. */
164    /* lengthlist */
165    fprintf(file,"static long _huff_lengthlist_%s[] = {\n",base);
166    for(j=0;j<vals;){
167      fprintf(file,"\t");
168      for(k=0;k<16 && j<vals;k++,j++)
169        fprintf(file,"%2ld,",lengths[j]);
170      fprintf(file,"\n");
171    }
172    fprintf(file,"};\n\n");
173   
174    /* the toplevel book */
175    fprintf(file,"static static_codebook _huff_book_%s = {\n",base);
176    fprintf(file,"\t%d, %ld,\n",subn,vals);
177    fprintf(file,"\t_huff_lengthlist_%s,\n",base);
178    fprintf(file,"\t0, 0, 0, 0, 0,\n");
179    fprintf(file,"\tNULL,\n");
180
181    fprintf(file,"\tNULL,\n");
182    fprintf(file,"\tNULL,\n");
183    fprintf(file,"\tNULL,\n");
184    fprintf(file,"\t0\n};\n\n");
185   
186    fclose(file);
187    fprintf(stderr,"Done.                                \n\n");
188  }
189  exit(0);
190}
191
192
193
194
195
196
197
198
199
200
201
Note: See TracBrowser for help on using the repository browser.