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 16959 2010-03-10 16:03:11Z 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 24 static int nsofar=0; 25 static 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 50 static 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 62 int 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 const 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 const static_codebook _huff_book_%s = {\n",base); 176 fprintf(file,"\t%d, %ld,\n",subn,vals); 177 fprintf(file,"\t(long *)_huff_lengthlist_%s,\n",base); 178 fprintf(file,"\t0, 0, 0, 0, 0,\n"); 179 fprintf(file,"\tNULL,\n"); 180 181 fprintf(file,"\t0\n};\n\n"); 182 183 fclose(file); 184 fprintf(stderr,"Done. \n\n"); 185 } 186 exit(0); 187 } 188 189 190 191 192 193 194 195 196 197 198 199