huffbuild.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
  6. * PLEASE READ THESE TERMS DISTRIBUTING. *
  7. * *
  8. * THE OggSQUISH 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.2.4.2 2000/04/21 16:35:38 xiphmont Exp $
  15. ********************************************************************/
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include "../vq/bookutil.h"
  21. static int nsofar=0;
  22. static int getval(FILE *in,int begin,int n,int group,int max){
  23. double 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>\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;
  58. FILE *file;
  59. int maxval=0;
  60. if(argc<3)usage();
  61. infile=strdup(argv[1]);
  62. base=strdup(infile);
  63. if(strrchr(base,'.'))
  64. strrchr(base,'.')[0]='\0';
  65. {
  66. char *pos=strchr(argv[2],',');
  67. begin=atoi(argv[2]);
  68. if(!pos)
  69. usage();
  70. else
  71. n=atoi(pos+1);
  72. pos=strchr(pos+1,',');
  73. if(!pos)
  74. usage();
  75. else
  76. subn=atoi(pos+1);
  77. if(n/subn*subn != n){
  78. fprintf(stderr,"n must be divisible by group\n");
  79. exit(1);
  80. }
  81. }
  82. /* scan the file for maximum value */
  83. file=fopen(infile,"r");
  84. if(!file){
  85. fprintf(stderr,"Could not open file %s\n",infile);
  86. exit(1);
  87. }
  88. i=0;
  89. while(1){
  90. long v;
  91. if(get_next_ivalue(file,&v))break;
  92. if(v>maxval)maxval=v;
  93. if(!(i++&0xff))spinnit("loading... ",i);
  94. }
  95. rewind(file);
  96. maxval++;
  97. {
  98. long vals=pow(maxval,subn);
  99. long *hist=malloc(vals*sizeof(long));
  100. long *lengths=malloc(vals*sizeof(long));
  101. for(j=0;j<vals;j++)hist[j]=1;
  102. reset_next_value();
  103. i/=subn;
  104. while(!feof(file)){
  105. long val=getval(file,begin,n,subn,maxval);
  106. if(val==-1)break;
  107. hist[val]++;
  108. if(!(i--&0xff))spinnit("loading... ",i*subn);
  109. }
  110. fclose(file);
  111. /* we have the probabilities, build the tree */
  112. fprintf(stderr,"Building tree for %ld entries\n",vals);
  113. build_tree_from_lengths(vals,hist,lengths);
  114. /* save the book */
  115. {
  116. char *buffer=alloca(strlen(base)+5);
  117. strcpy(buffer,base);
  118. strcat(buffer,".vqh");
  119. file=fopen(buffer,"w");
  120. if(!file){
  121. fprintf(stderr,"Could not open file %s\n",buffer);
  122. exit(1);
  123. }
  124. }
  125. fprintf(file,
  126. "/********************************************************************\n"
  127. " * *\n"
  128. " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *\n"
  129. " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
  130. " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *\n"
  131. " * PLEASE READ THESE TERMS DISTRIBUTING. *\n"
  132. " * *\n"
  133. " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *\n"
  134. " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *\n"
  135. " * http://www.xiph.org/ *\n"
  136. " * *\n"
  137. " ********************************************************************\n"
  138. "\n"
  139. " function: static codebook autogenerated by huff/huffbuld\n"
  140. "\n"
  141. " ********************************************************************/\n\n");
  142. fprintf(file,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",base,base);
  143. fprintf(file,"#include \"vorbis/codebook.h\"\n\n");
  144. /* first, the static vectors, then the book structure to tie it together. */
  145. /* lengthlist */
  146. fprintf(file,"static long _huff_lengthlist_%s[] = {\n",base);
  147. for(j=0;j<vals;){
  148. fprintf(file,"\t");
  149. for(k=0;k<16 && j<vals;k++,j++)
  150. fprintf(file,"%2ld,",lengths[j]);
  151. fprintf(file,"\n");
  152. }
  153. fprintf(file,"};\n\n");
  154. /* the toplevel book */
  155. fprintf(file,"static static_codebook _huff_book_%s = {\n",base);
  156. fprintf(file,"\t%d, %ld,\n",subn,vals);
  157. fprintf(file,"\t_huff_lengthlist_%s,\n",base);
  158. fprintf(file,"\t0, 0, 0, 0, 0,\n");
  159. fprintf(file,"\tNULL,\n");
  160. fprintf(file,"\tNULL,\n");
  161. fprintf(file,"\tNULL,\n");
  162. fprintf(file,"};\n\n");
  163. fprintf(file,"\n#endif\n");
  164. fclose(file);
  165. fprintf(stderr,"Done. \n\n");
  166. }
  167. exit(0);
  168. }