view src/libvorbis-1.3.3/vq/huffbuild.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 05aa0afa9217
children
line wrap: on
line source
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

 function: hufftree builder
 last mod: $Id: huffbuild.c 16959 2010-03-10 16:03:11Z xiphmont $

 ********************************************************************/

#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include "bookutil.h"

static int nsofar=0;
static int getval(FILE *in,int begin,int n,int group,int max){
  float v;
  int i;
  long val=0;

  if(nsofar>=n || get_line_value(in,&v)){
    reset_next_value();
    nsofar=0;
    if(get_next_value(in,&v))
      return(-1);
    for(i=1;i<=begin;i++)
      get_line_value(in,&v);
  }

  val=(int)v;
  nsofar++;

  for(i=1;i<group;i++,nsofar++)
    if(nsofar>=n || get_line_value(in,&v))
      return(getval(in,begin,n,group,max));
    else
      val = val*max+(int)v;
  return(val);
}

static void usage(){
  fprintf(stderr,
          "usage:\n" 
          "huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
          "   where begin,n,group is first scalar, \n"
          "                          number of scalars of each in line,\n"
          "                          number of scalars in a group\n"
          "eg: huffbuild reslongaux.vqd 0,1024,4\n"
          "produces reslongaux.vqh\n\n");
  exit(1);
}

int main(int argc, char *argv[]){
  char *base;
  char *infile;
  int i,j,k,begin,n,subn,guard=1;
  FILE *file;
  int maxval=0;
  int loval=0;

  if(argc<3)usage();
  if(argc==4)guard=0;

  infile=strdup(argv[1]);
  base=strdup(infile);
  if(strrchr(base,'.'))
    strrchr(base,'.')[0]='\0';

  {
    char *pos=strchr(argv[2],',');
    char *dpos=strchr(argv[2],'-');
    if(dpos){
      loval=atoi(argv[2]);
      maxval=atoi(dpos+1);
      subn=1;
      begin=0;
    }else{
      begin=atoi(argv[2]);
      if(!pos)
        usage();
      else
        n=atoi(pos+1);
      pos=strchr(pos+1,',');
      if(!pos)
        usage();
      else
        subn=atoi(pos+1);
      if(n/subn*subn != n){
        fprintf(stderr,"n must be divisible by group\n");
        exit(1);
      }
    }
  }

  /* scan the file for maximum value */
  file=fopen(infile,"r");
  if(!file){
    fprintf(stderr,"Could not open file %s\n",infile);
    if(!maxval)
      exit(1);
    else
      fprintf(stderr,"  making untrained books.\n");

  }

  if(!maxval){
    i=0;
    while(1){
      long v;
      if(get_next_ivalue(file,&v))break;
      if(v>maxval)maxval=v;
      
      if(!(i++&0xff))spinnit("loading... ",i);
    }
    rewind(file);
    maxval++;
  }

  {
    long vals=pow(maxval,subn);
    long *hist=_ogg_calloc(vals,sizeof(long));
    long *lengths=_ogg_calloc(vals,sizeof(long));
    
    for(j=loval;j<vals;j++)hist[j]=guard;
    
    if(file){
      reset_next_value();
      i/=subn;
      while(!feof(file)){
        long val=getval(file,begin,n,subn,maxval);
        if(val==-1 || val>=vals)break;
        hist[val]++;
        if(!(i--&0xff))spinnit("loading... ",i*subn);
      }
      fclose(file);
    }
 
    /* we have the probabilities, build the tree */
    fprintf(stderr,"Building tree for %ld entries\n",vals);
    build_tree_from_lengths0(vals,hist,lengths);

    /* save the book */
    {
      char *buffer=alloca(strlen(base)+5);
      strcpy(buffer,base);
      strcat(buffer,".vqh");
      file=fopen(buffer,"w");
      if(!file){
        fprintf(stderr,"Could not open file %s\n",buffer);
        exit(1);
      }
    }
    
    /* first, the static vectors, then the book structure to tie it together. */
    /* lengthlist */
    fprintf(file,"static const long _huff_lengthlist_%s[] = {\n",base);
    for(j=0;j<vals;){
      fprintf(file,"\t");
      for(k=0;k<16 && j<vals;k++,j++)
        fprintf(file,"%2ld,",lengths[j]);
      fprintf(file,"\n");
    }
    fprintf(file,"};\n\n");
    
    /* the toplevel book */
    fprintf(file,"static const static_codebook _huff_book_%s = {\n",base);
    fprintf(file,"\t%d, %ld,\n",subn,vals);
    fprintf(file,"\t(long *)_huff_lengthlist_%s,\n",base);
    fprintf(file,"\t0, 0, 0, 0, 0,\n");
    fprintf(file,"\tNULL,\n");

    fprintf(file,"\t0\n};\n\n");
    
    fclose(file);
    fprintf(stderr,"Done.                                \n\n");
  }
  exit(0);
}