huffbuild.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
  6. * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
  9. * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
  10. * http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: hufftree builder
  14. last mod: $Id: huffbuild.c,v 1.5.2.5 2000/11/04 06:43:55 xiphmont Exp $
  15. ********************************************************************/
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include "bookutil.h"
  21. static int nsofar=0;
  22. static int getval(FILE *in,int begin,int n,int group,int max){
  23. float v;
  24. int i;
  25. long val=0;
  26. if(nsofar>=n || get_line_value(in,&v)){
  27. reset_next_value();
  28. nsofar=0;
  29. if(get_next_value(in,&v))
  30. return(-1);
  31. for(i=1;i<=begin;i++)
  32. get_line_value(in,&v);
  33. }
  34. val=(int)v;
  35. nsofar++;
  36. for(i=1;i<group;i++,nsofar++)
  37. if(nsofar>=n || get_line_value(in,&v))
  38. return(getval(in,begin,n,group,max));
  39. else
  40. val = val*max+(int)v;
  41. return(val);
  42. }
  43. static void usage(){
  44. fprintf(stderr,
  45. "usage:\n"
  46. "huffbuild <input>.vqd <begin,n,group> [noguard]\n"
  47. " where begin,n,group is first scalar, \n"
  48. " number of scalars of each in line,\n"
  49. " number of scalars in a group\n"
  50. "eg: huffbuild reslongaux.vqd 0,1024,4\n"
  51. "produces reslongaux.vqh\n\n");
  52. exit(1);
  53. }
  54. int main(int argc, char *argv[]){
  55. char *base;
  56. char *infile;
  57. int i,j,k,begin,n,subn,guard=1;
  58. FILE *file;
  59. int maxval=0;
  60. if(argc<3)usage();
  61. if(argc==4)guard=0;
  62. infile=strdup(argv[1]);
  63. base=strdup(infile);
  64. if(strrchr(base,'.'))
  65. strrchr(base,'.')[0]='\0';
  66. {
  67. char *pos=strchr(argv[2],',');
  68. begin=atoi(argv[2]);
  69. if(!pos)
  70. usage();
  71. else
  72. n=atoi(pos+1);
  73. pos=strchr(pos+1,',');
  74. if(!pos)
  75. usage();
  76. else
  77. subn=atoi(pos+1);
  78. if(n/subn*subn != n){
  79. fprintf(stderr,"n must be divisible by group\n");
  80. exit(1);
  81. }
  82. }
  83. /* scan the file for maximum value */
  84. file=fopen(infile,"r");
  85. if(!file){
  86. fprintf(stderr,"Could not open file %s\n",infile);
  87. exit(1);
  88. }
  89. i=0;
  90. while(1){
  91. long v;
  92. if(get_next_ivalue(file,&v))break;
  93. if(v>maxval)maxval=v;
  94. if(!(i++&0xff))spinnit("loading... ",i);
  95. }
  96. rewind(file);
  97. maxval++;
  98. {
  99. long vals=pow(maxval,subn);
  100. long *hist=_ogg_malloc(vals*sizeof(long));
  101. long *lengths=_ogg_malloc(vals*sizeof(long));
  102. for(j=0;j<vals;j++)hist[j]=guard;
  103. reset_next_value();
  104. i/=subn;
  105. while(!feof(file)){
  106. long val=getval(file,begin,n,subn,maxval);
  107. if(val==-1)break;
  108. hist[val]++;
  109. if(!(i--&0xff))spinnit("loading... ",i*subn);
  110. }
  111. fclose(file);
  112. /* we have the probabilities, build the tree */
  113. fprintf(stderr,"Building tree for %ld entries\n",vals);
  114. build_tree_from_lengths0(vals,hist,lengths);
  115. /* save the book */
  116. {
  117. char *buffer=alloca(strlen(base)+5);
  118. strcpy(buffer,base);
  119. strcat(buffer,".vqh");
  120. file=fopen(buffer,"w");
  121. if(!file){
  122. fprintf(stderr,"Could not open file %s\n",buffer);
  123. exit(1);
  124. }
  125. }
  126. fprintf(file,
  127. "/********************************************************************\n"
  128. " * *\n"
  129. " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *\n"
  130. " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
  131. " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *\n"
  132. " * PLEASE READ THESE TERMS DISTRIBUTING. *\n"
  133. " * *\n"
  134. " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *\n"
  135. " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *\n"
  136. " * http://www.xiph.org/ *\n"
  137. " * *\n"
  138. " ********************************************************************\n"
  139. "\n"
  140. " function: static codebook autogenerated by huff/huffbuld\n"
  141. "\n"
  142. " ********************************************************************/\n\n");
  143. fprintf(file,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",base,base);
  144. fprintf(file,"#include \"codebook.h\"\n\n");
  145. /* first, the static vectors, then the book structure to tie it together. */
  146. /* lengthlist */
  147. fprintf(file,"static long _huff_lengthlist_%s[] = {\n",base);
  148. for(j=0;j<vals;){
  149. fprintf(file,"\t");
  150. for(k=0;k<16 && j<vals;k++,j++)
  151. fprintf(file,"%2ld,",lengths[j]);
  152. fprintf(file,"\n");
  153. }
  154. fprintf(file,"};\n\n");
  155. /* the toplevel book */
  156. fprintf(file,"static static_codebook _huff_book_%s = {\n",base);
  157. fprintf(file,"\t%d, %ld,\n",subn,vals);
  158. fprintf(file,"\t_huff_lengthlist_%s,\n",base);
  159. fprintf(file,"\t0, 0, 0, 0, 0,\n");
  160. fprintf(file,"\tNULL,\n");
  161. fprintf(file,"\tNULL,\n");
  162. fprintf(file,"\tNULL,\n");
  163. fprintf(file,"\t0\n};\n\n");
  164. fprintf(file,"\n#endif\n");
  165. fclose(file);
  166. fprintf(stderr,"Done. \n\n");
  167. }
  168. exit(0);
  169. }