Blame vq/huffbuild.c

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