cannam@86: /******************************************************************** cannam@86: * * cannam@86: * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * cannam@86: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * cannam@86: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * cannam@86: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * cannam@86: * * cannam@86: * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * cannam@86: * by the Xiph.Org Foundation http://www.xiph.org/ * cannam@86: * * cannam@86: ******************************************************************** cannam@86: cannam@86: function: hufftree builder cannam@86: last mod: $Id: huffbuild.c 16959 2010-03-10 16:03:11Z xiphmont $ cannam@86: cannam@86: ********************************************************************/ cannam@86: cannam@86: #include cannam@86: #include cannam@86: #include cannam@86: #include cannam@86: #include "bookutil.h" cannam@86: cannam@86: static int nsofar=0; cannam@86: static int getval(FILE *in,int begin,int n,int group,int max){ cannam@86: float v; cannam@86: int i; cannam@86: long val=0; cannam@86: cannam@86: if(nsofar>=n || get_line_value(in,&v)){ cannam@86: reset_next_value(); cannam@86: nsofar=0; cannam@86: if(get_next_value(in,&v)) cannam@86: return(-1); cannam@86: for(i=1;i<=begin;i++) cannam@86: get_line_value(in,&v); cannam@86: } cannam@86: cannam@86: val=(int)v; cannam@86: nsofar++; cannam@86: cannam@86: for(i=1;i=n || get_line_value(in,&v)) cannam@86: return(getval(in,begin,n,group,max)); cannam@86: else cannam@86: val = val*max+(int)v; cannam@86: return(val); cannam@86: } cannam@86: cannam@86: static void usage(){ cannam@86: fprintf(stderr, cannam@86: "usage:\n" cannam@86: "huffbuild .vqd | [noguard]\n" cannam@86: " where begin,n,group is first scalar, \n" cannam@86: " number of scalars of each in line,\n" cannam@86: " number of scalars in a group\n" cannam@86: "eg: huffbuild reslongaux.vqd 0,1024,4\n" cannam@86: "produces reslongaux.vqh\n\n"); cannam@86: exit(1); cannam@86: } cannam@86: cannam@86: int main(int argc, char *argv[]){ cannam@86: char *base; cannam@86: char *infile; cannam@86: int i,j,k,begin,n,subn,guard=1; cannam@86: FILE *file; cannam@86: int maxval=0; cannam@86: int loval=0; cannam@86: cannam@86: if(argc<3)usage(); cannam@86: if(argc==4)guard=0; cannam@86: cannam@86: infile=strdup(argv[1]); cannam@86: base=strdup(infile); cannam@86: if(strrchr(base,'.')) cannam@86: strrchr(base,'.')[0]='\0'; cannam@86: cannam@86: { cannam@86: char *pos=strchr(argv[2],','); cannam@86: char *dpos=strchr(argv[2],'-'); cannam@86: if(dpos){ cannam@86: loval=atoi(argv[2]); cannam@86: maxval=atoi(dpos+1); cannam@86: subn=1; cannam@86: begin=0; cannam@86: }else{ cannam@86: begin=atoi(argv[2]); cannam@86: if(!pos) cannam@86: usage(); cannam@86: else cannam@86: n=atoi(pos+1); cannam@86: pos=strchr(pos+1,','); cannam@86: if(!pos) cannam@86: usage(); cannam@86: else cannam@86: subn=atoi(pos+1); cannam@86: if(n/subn*subn != n){ cannam@86: fprintf(stderr,"n must be divisible by group\n"); cannam@86: exit(1); cannam@86: } cannam@86: } cannam@86: } cannam@86: cannam@86: /* scan the file for maximum value */ cannam@86: file=fopen(infile,"r"); cannam@86: if(!file){ cannam@86: fprintf(stderr,"Could not open file %s\n",infile); cannam@86: if(!maxval) cannam@86: exit(1); cannam@86: else cannam@86: fprintf(stderr," making untrained books.\n"); cannam@86: cannam@86: } cannam@86: cannam@86: if(!maxval){ cannam@86: i=0; cannam@86: while(1){ cannam@86: long v; cannam@86: if(get_next_ivalue(file,&v))break; cannam@86: if(v>maxval)maxval=v; cannam@86: cannam@86: if(!(i++&0xff))spinnit("loading... ",i); cannam@86: } cannam@86: rewind(file); cannam@86: maxval++; cannam@86: } cannam@86: cannam@86: { cannam@86: long vals=pow(maxval,subn); cannam@86: long *hist=_ogg_calloc(vals,sizeof(long)); cannam@86: long *lengths=_ogg_calloc(vals,sizeof(long)); cannam@86: cannam@86: for(j=loval;j=vals)break; cannam@86: hist[val]++; cannam@86: if(!(i--&0xff))spinnit("loading... ",i*subn); cannam@86: } cannam@86: fclose(file); cannam@86: } cannam@86: cannam@86: /* we have the probabilities, build the tree */ cannam@86: fprintf(stderr,"Building tree for %ld entries\n",vals); cannam@86: build_tree_from_lengths0(vals,hist,lengths); cannam@86: cannam@86: /* save the book */ cannam@86: { cannam@86: char *buffer=alloca(strlen(base)+5); cannam@86: strcpy(buffer,base); cannam@86: strcat(buffer,".vqh"); cannam@86: file=fopen(buffer,"w"); cannam@86: if(!file){ cannam@86: fprintf(stderr,"Could not open file %s\n",buffer); cannam@86: exit(1); cannam@86: } cannam@86: } cannam@86: cannam@86: /* first, the static vectors, then the book structure to tie it together. */ cannam@86: /* lengthlist */ cannam@86: fprintf(file,"static const long _huff_lengthlist_%s[] = {\n",base); cannam@86: for(j=0;j