huffbuild.c 4.7 KB

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