[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 | |
---|
| 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 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 | |
---|