bookutil.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  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: utility functions for loading .vqh and .vqd files
  14. last mod: $Id: bookutil.c,v 1.16.2.1 2000/08/31 09:00:02 xiphmont Exp $
  15. ********************************************************************/
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <math.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include "vorbis/codebook.h"
  22. #include "../lib/sharedbook.h"
  23. #include "bookutil.h"
  24. /* A few little utils for reading files */
  25. /* read a line. Use global, persistent buffering */
  26. static char *linebuffer=NULL;
  27. static int lbufsize=0;
  28. char *get_line(FILE *in){
  29. long sofar=0;
  30. if(feof(in))return NULL;
  31. while(1){
  32. int gotline=0;
  33. while(!gotline){
  34. if(sofar+1>=lbufsize){
  35. if(!lbufsize){
  36. lbufsize=1024;
  37. linebuffer=malloc(lbufsize);
  38. }else{
  39. lbufsize*=2;
  40. linebuffer=realloc(linebuffer,lbufsize);
  41. }
  42. }
  43. {
  44. long c=fgetc(in);
  45. switch(c){
  46. case EOF:
  47. if(sofar==0)return(NULL);
  48. /* fallthrough correct */
  49. case '\n':
  50. linebuffer[sofar]='\0';
  51. gotline=1;
  52. break;
  53. default:
  54. linebuffer[sofar++]=c;
  55. linebuffer[sofar]='\0';
  56. break;
  57. }
  58. }
  59. }
  60. if(linebuffer[0]=='#'){
  61. sofar=0;
  62. }else{
  63. return(linebuffer);
  64. }
  65. }
  66. }
  67. /* read the next numerical value from the given file */
  68. static char *value_line_buff=NULL;
  69. int get_line_value(FILE *in,float *value){
  70. char *next;
  71. if(!value_line_buff)return(-1);
  72. *value=strtod(value_line_buff, &next);
  73. if(next==value_line_buff){
  74. value_line_buff=NULL;
  75. return(-1);
  76. }else{
  77. value_line_buff=next;
  78. while(*value_line_buff>44)value_line_buff++;
  79. if(*value_line_buff==44)value_line_buff++;
  80. return(0);
  81. }
  82. }
  83. int get_next_value(FILE *in,float *value){
  84. while(1){
  85. if(get_line_value(in,value)){
  86. value_line_buff=get_line(in);
  87. if(!value_line_buff)return(-1);
  88. }else{
  89. return(0);
  90. }
  91. }
  92. }
  93. int get_next_ivalue(FILE *in,long *ivalue){
  94. float value;
  95. int ret=get_next_value(in,&value);
  96. *ivalue=value;
  97. return(ret);
  98. }
  99. static float sequence_base=0.;
  100. static int v_sofar=0;
  101. void reset_next_value(void){
  102. value_line_buff=NULL;
  103. sequence_base=0.;
  104. v_sofar=0;
  105. }
  106. char *setup_line(FILE *in){
  107. reset_next_value();
  108. value_line_buff=get_line(in);
  109. return(value_line_buff);
  110. }
  111. int get_vector(codebook *b,FILE *in,int start, int n,float *a){
  112. int i;
  113. const static_codebook *c=b->c;
  114. while(1){
  115. if(v_sofar==n || get_line_value(in,a)){
  116. reset_next_value();
  117. if(get_next_value(in,a))
  118. break;
  119. for(i=0;i<start;i++){
  120. sequence_base=*a;
  121. get_line_value(in,a);
  122. }
  123. }
  124. for(i=1;i<c->dim;i++)
  125. if(get_line_value(in,a+i))
  126. break;
  127. if(i==c->dim){
  128. float temp=a[c->dim-1];
  129. for(i=0;i<c->dim;i++)a[i]-=sequence_base;
  130. if(c->q_sequencep)sequence_base=temp;
  131. v_sofar++;
  132. return(0);
  133. }
  134. sequence_base=0.;
  135. }
  136. return(-1);
  137. }
  138. /* read lines fromt he beginning until we find one containing the
  139. specified string */
  140. char *find_seek_to(FILE *in,char *s){
  141. rewind(in);
  142. while(1){
  143. char *line=get_line(in);
  144. if(line){
  145. if(strstr(line,s))
  146. return(line);
  147. }else
  148. return(NULL);
  149. }
  150. }
  151. /* this reads the format as written by vqbuild/latticebuild; innocent
  152. (legal) tweaking of the file that would not affect its valid
  153. header-ness will break this routine */
  154. codebook *codebook_load(char *filename){
  155. codebook *b=calloc(1,sizeof(codebook));
  156. static_codebook *c=(static_codebook *)(b->c=calloc(1,sizeof(static_codebook)));
  157. encode_aux_nearestmatch *a=NULL;
  158. encode_aux_threshmatch *t=NULL;
  159. encode_aux_pigeonhole *p=NULL;
  160. int quant_to_read=0;
  161. FILE *in=fopen(filename,"r");
  162. char *line;
  163. long i;
  164. if(in==NULL){
  165. fprintf(stderr,"Couldn't open codebook %s\n",filename);
  166. exit(1);
  167. }
  168. /* find the codebook struct */
  169. find_seek_to(in,"static static_codebook _vq_book_");
  170. /* get the major important values */
  171. line=get_line(in);
  172. if(sscanf(line,"%ld, %ld,",
  173. &(c->dim),&(c->entries))!=2){
  174. fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
  175. exit(1);
  176. }
  177. line=get_line(in);
  178. line=get_line(in);
  179. if(sscanf(line,"%d, %ld, %ld, %d, %d,",
  180. &(c->maptype),&(c->q_min),&(c->q_delta),&(c->q_quant),
  181. &(c->q_sequencep))!=5){
  182. fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
  183. exit(1);
  184. }
  185. /* find the auxiliary encode struct[s] (if any) */
  186. if(find_seek_to(in,"static encode_aux_nearestmatch _vq_aux")){
  187. /* how big? */
  188. c->nearest_tree=a=calloc(1,sizeof(encode_aux_nearestmatch));
  189. line=get_line(in);
  190. line=get_line(in);
  191. line=get_line(in);
  192. line=get_line(in);
  193. line=get_line(in);
  194. if(sscanf(line,"%ld, %ld",&(a->aux),&(a->alloc))!=2){
  195. fprintf(stderr,"2: syntax in %s in line:\t %s",filename,line);
  196. exit(1);
  197. }
  198. /* load ptr0 */
  199. find_seek_to(in,"static long _vq_ptr0");
  200. reset_next_value();
  201. a->ptr0=malloc(sizeof(long)*a->aux);
  202. for(i=0;i<a->aux;i++)
  203. if(get_next_ivalue(in,a->ptr0+i)){
  204. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  205. exit(1);
  206. }
  207. /* load ptr1 */
  208. find_seek_to(in,"static long _vq_ptr1");
  209. reset_next_value();
  210. a->ptr1=malloc(sizeof(long)*a->aux);
  211. for(i=0;i<a->aux;i++)
  212. if(get_next_ivalue(in,a->ptr1+i)){
  213. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  214. exit(1);
  215. }
  216. /* load p */
  217. find_seek_to(in,"static long _vq_p_");
  218. reset_next_value();
  219. a->p=malloc(sizeof(long)*a->aux);
  220. for(i=0;i<a->aux;i++)
  221. if(get_next_ivalue(in,a->p+i)){
  222. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  223. exit(1);
  224. }
  225. /* load q */
  226. find_seek_to(in,"static long _vq_q_");
  227. reset_next_value();
  228. a->q=malloc(sizeof(long)*a->aux);
  229. for(i=0;i<a->aux;i++)
  230. if(get_next_ivalue(in,a->q+i)){
  231. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  232. exit(1);
  233. }
  234. }
  235. if(find_seek_to(in,"static encode_aux_threshmatch _vq_aux")){
  236. /* how big? */
  237. c->thresh_tree=t=calloc(1,sizeof(encode_aux_threshmatch));
  238. line=get_line(in);
  239. line=get_line(in);
  240. line=get_line(in);
  241. if(sscanf(line,"%d",&(t->quantvals))!=1){
  242. fprintf(stderr,"3: syntax in %s in line:\t %s",filename,line);
  243. exit(1);
  244. }
  245. line=get_line(in);
  246. if(sscanf(line,"%d",&(t->threshvals))!=1){
  247. fprintf(stderr,"4: syntax in %s in line:\t %s",filename,line);
  248. exit(1);
  249. }
  250. /* load quantthresh */
  251. find_seek_to(in,"static float _vq_quantthresh_");
  252. reset_next_value();
  253. t->quantthresh=malloc(sizeof(float)*t->threshvals);
  254. for(i=0;i<t->threshvals-1;i++)
  255. if(get_next_value(in,t->quantthresh+i)){
  256. fprintf(stderr,"out of data 1 while reading codebook %s\n",filename);
  257. exit(1);
  258. }
  259. /* load quantmap */
  260. find_seek_to(in,"static long _vq_quantmap_");
  261. reset_next_value();
  262. t->quantmap=malloc(sizeof(long)*t->threshvals);
  263. for(i=0;i<t->threshvals;i++)
  264. if(get_next_ivalue(in,t->quantmap+i)){
  265. fprintf(stderr,"out of data 2 while reading codebook %s\n",filename);
  266. exit(1);
  267. }
  268. }
  269. if(find_seek_to(in,"static encode_aux_pigeonhole _vq_aux")){
  270. int pigeons=1,i;
  271. /* how big? */
  272. c->pigeon_tree=p=calloc(1,sizeof(encode_aux_pigeonhole));
  273. line=get_line(in);
  274. if(sscanf(line,"%lf, %lf, %d, %d",&(p->min),&(p->del),
  275. &(p->mapentries),&(p->quantvals))!=4){
  276. fprintf(stderr,"5: syntax in %s in line:\t %s",filename,line);
  277. exit(1);
  278. }
  279. line=get_line(in);
  280. line=get_line(in);
  281. if(sscanf(line,"%ld",&(p->fittotal))!=1){
  282. fprintf(stderr,"6: syntax in %s in line:\t %s",filename,line);
  283. exit(1);
  284. }
  285. /* load pigeonmap */
  286. find_seek_to(in,"static long _vq_pigeonmap_");
  287. reset_next_value();
  288. p->pigeonmap=malloc(sizeof(long)*p->mapentries);
  289. for(i=0;i<p->mapentries;i++)
  290. if(get_next_ivalue(in,p->pigeonmap+i)){
  291. fprintf(stderr,"out of data (pigeonmap) while reading codebook %s\n",filename);
  292. exit(1);
  293. }
  294. /* load fitlist */
  295. find_seek_to(in,"static long _vq_fitlist_");
  296. reset_next_value();
  297. p->fitlist=malloc(sizeof(long)*p->fittotal);
  298. for(i=0;i<p->fittotal;i++)
  299. if(get_next_ivalue(in,p->fitlist+i)){
  300. fprintf(stderr,"out of data (fitlist) while reading codebook %s\n",filename);
  301. exit(1);
  302. }
  303. /* load fitmap */
  304. find_seek_to(in,"static long _vq_fitmap_");
  305. reset_next_value();
  306. for(i=0;i<c->dim;i++)pigeons*=p->quantvals;
  307. p->fitmap=malloc(sizeof(long)*pigeons);
  308. for(i=0;i<pigeons;i++)
  309. if(get_next_ivalue(in,p->fitmap+i)){
  310. fprintf(stderr,"out of data (fitmap) while reading codebook %s\n",filename);
  311. exit(1);
  312. }
  313. /* load fitlength */
  314. find_seek_to(in,"static long _vq_fitlength_");
  315. reset_next_value();
  316. p->fitlength=malloc(sizeof(long)*pigeons);
  317. for(i=0;i<pigeons;i++)
  318. if(get_next_ivalue(in,p->fitlength+i)){
  319. fprintf(stderr,"out of data (fitlength) while reading codebook %s\n",filename);
  320. exit(1);
  321. }
  322. }
  323. switch(c->maptype){
  324. case 0:
  325. quant_to_read=0;
  326. break;
  327. case 1:
  328. quant_to_read=_book_maptype1_quantvals(c);
  329. break;
  330. case 2:
  331. quant_to_read=c->entries*c->dim;
  332. break;
  333. }
  334. /* load the quantized entries */
  335. find_seek_to(in,"static long _vq_quantlist_");
  336. reset_next_value();
  337. c->quantlist=malloc(sizeof(long)*quant_to_read);
  338. for(i=0;i<quant_to_read;i++)
  339. if(get_next_ivalue(in,c->quantlist+i)){
  340. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  341. exit(1);
  342. }
  343. /* load the lengthlist */
  344. find_seek_to(in,"static long _vq_lengthlist");
  345. reset_next_value();
  346. c->lengthlist=malloc(sizeof(long)*c->entries);
  347. for(i=0;i<c->entries;i++)
  348. if(get_next_ivalue(in,c->lengthlist+i)){
  349. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  350. exit(1);
  351. }
  352. /* got it all */
  353. fclose(in);
  354. vorbis_book_init_encode(b,c);
  355. return(b);
  356. }
  357. void spinnit(char *s,int n){
  358. static int p=0;
  359. static long lasttime=0;
  360. long test;
  361. struct timeval thistime;
  362. gettimeofday(&thistime,NULL);
  363. test=thistime.tv_sec*10+thistime.tv_usec/100000;
  364. if(lasttime!=test){
  365. lasttime=test;
  366. fprintf(stderr,"%s%d ",s,n);
  367. p++;if(p>3)p=0;
  368. switch(p){
  369. case 0:
  370. fprintf(stderr,"| \r");
  371. break;
  372. case 1:
  373. fprintf(stderr,"/ \r");
  374. break;
  375. case 2:
  376. fprintf(stderr,"- \r");
  377. break;
  378. case 3:
  379. fprintf(stderr,"\\ \r");
  380. break;
  381. }
  382. fflush(stderr);
  383. }
  384. }
  385. void build_tree_from_lengths(int vals, long *hist, long *lengths){
  386. int i,j;
  387. long *membership=malloc(vals*sizeof(long));
  388. long *histsave=alloca(vals*sizeof(long));
  389. memcpy(histsave,hist,vals*sizeof(long));
  390. for(i=0;i<vals;i++)membership[i]=i;
  391. /* find codeword lengths */
  392. /* much more elegant means exist. Brute force n^2, minimum thought */
  393. for(i=vals;i>1;i--){
  394. int first=-1,second=-1;
  395. long least=-1;
  396. spinnit("building... ",i);
  397. /* find the two nodes to join */
  398. for(j=0;j<vals;j++)
  399. if(least==-1 || hist[j]<least){
  400. least=hist[j];
  401. first=membership[j];
  402. }
  403. least=-1;
  404. for(j=0;j<vals;j++)
  405. if((least==-1 || hist[j]<least) && membership[j]!=first){
  406. least=hist[j];
  407. second=membership[j];
  408. }
  409. if(first==-1 || second==-1){
  410. fprintf(stderr,"huffman fault; no free branch\n");
  411. exit(1);
  412. }
  413. /* join them */
  414. least=hist[first]+hist[second];
  415. for(j=0;j<vals;j++)
  416. if(membership[j]==first || membership[j]==second){
  417. membership[j]=first;
  418. hist[j]=least;
  419. lengths[j]++;
  420. }
  421. }
  422. for(i=0;i<vals-1;i++)
  423. if(membership[i]!=membership[i+1]){
  424. fprintf(stderr,"huffman fault; failed to build single tree\n");
  425. exit(1);
  426. }
  427. /* for sanity check purposes: how many bits would it have taken to
  428. encode the training set? */
  429. {
  430. long bitsum=0;
  431. long samples=0;
  432. for(i=0;i<vals;i++){
  433. bitsum+=(histsave[i]-1)*lengths[i];
  434. samples+=histsave[i]-1;
  435. }
  436. if(samples){
  437. fprintf(stderr,"\rTotal samples in training set: %ld \n",samples);
  438. fprintf(stderr,"\rTotal bits used to represent training set: %ld\n",
  439. bitsum);
  440. }
  441. }
  442. free(membership);
  443. }
  444. /* wrap build_tree_from_lengths to allow zero entries in the histogram */
  445. void build_tree_from_lengths0(int vals, long *hist, long *lengths){
  446. /* pack the 'sparse' hit list into a dense list, then unpack
  447. the lengths after the build */
  448. int upper=0,i;
  449. long *lengthlist=calloc(vals,sizeof(long));
  450. long *newhist=alloca(vals*sizeof(long));
  451. for(i=0;i<vals;i++)
  452. if(hist[i]>0)
  453. newhist[upper++]=hist[i];
  454. if(upper != vals){
  455. fprintf(stderr,"\rEliminating %d unused entries; %d entries remain\n",
  456. vals-upper,upper);
  457. }
  458. build_tree_from_lengths(upper,newhist,lengthlist);
  459. upper=0;
  460. for(i=0;i<vals;i++)
  461. if(hist[i]>0)
  462. lengths[i]=lengthlist[upper++];
  463. else
  464. lengths[i]=0;
  465. free(lengthlist);
  466. }
  467. void write_codebook(FILE *out,char *name,const static_codebook *c){
  468. encode_aux_pigeonhole *p=c->pigeon_tree;
  469. encode_aux_threshmatch *t=c->thresh_tree;
  470. encode_aux_nearestmatch *n=c->nearest_tree;
  471. int i,j,k;
  472. /* save the book in C header form */
  473. fprintf(out,
  474. "/********************************************************************\n"
  475. " * *\n"
  476. " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *\n"
  477. " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
  478. " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *\n"
  479. " * PLEASE READ THESE TERMS DISTRIBUTING. *\n"
  480. " * *\n"
  481. " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *\n"
  482. " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *\n"
  483. " * http://www.xiph.org/ *\n"
  484. " * *\n"
  485. " ********************************************************************\n"
  486. "\n"
  487. " function: static codebook autogenerated by vq/somethingorother\n"
  488. "\n"
  489. " ********************************************************************/\n\n");
  490. fprintf(out,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",name,name);
  491. fprintf(out,"#include \"vorbis/codebook.h\"\n\n");
  492. /* first, the static vectors, then the book structure to tie it together. */
  493. /* quantlist */
  494. if(c->quantlist){
  495. long vals=(c->maptype==1?_book_maptype1_quantvals(c):c->entries*c->dim);
  496. fprintf(out,"static long _vq_quantlist_%s[] = {\n",name);
  497. for(j=0;j<vals;j++){
  498. fprintf(out,"\t%ld,\n",c->quantlist[j]);
  499. }
  500. fprintf(out,"};\n\n");
  501. }
  502. /* lengthlist */
  503. fprintf(out,"static long _vq_lengthlist_%s[] = {\n",name);
  504. for(j=0;j<c->entries;){
  505. fprintf(out,"\t");
  506. for(k=0;k<16 && j<c->entries;k++,j++)
  507. fprintf(out,"%2ld,",c->lengthlist[j]);
  508. fprintf(out,"\n");
  509. }
  510. fprintf(out,"};\n\n");
  511. if(t){
  512. /* quantthresh */
  513. fprintf(out,"static float _vq_quantthresh_%s[] = {\n",name);
  514. for(j=0;j<t->threshvals-1;){
  515. fprintf(out,"\t");
  516. for(k=0;k<8 && j<t->threshvals-1;k++,j++)
  517. fprintf(out,"%.5g, ",t->quantthresh[j]);
  518. fprintf(out,"\n");
  519. }
  520. fprintf(out,"};\n\n");
  521. /* quantmap */
  522. fprintf(out,"static long _vq_quantmap_%s[] = {\n",name);
  523. for(j=0;j<t->threshvals;){
  524. fprintf(out,"\t");
  525. for(k=0;k<8 && j<t->threshvals;k++,j++)
  526. fprintf(out,"%5ld,",t->quantmap[j]);
  527. fprintf(out,"\n");
  528. }
  529. fprintf(out,"};\n\n");
  530. fprintf(out,"static encode_aux_threshmatch _vq_auxt_%s = {\n",name);
  531. fprintf(out,"\t_vq_quantthresh_%s,\n",name);
  532. fprintf(out,"\t_vq_quantmap_%s,\n",name);
  533. fprintf(out,"\t%d,\n",t->quantvals);
  534. fprintf(out,"\t%d\n};\n\n",t->threshvals);
  535. }
  536. if(p){
  537. int pigeons=1;
  538. for(i=0;i<c->dim;i++)pigeons*=p->quantvals;
  539. /* pigeonmap */
  540. fprintf(out,"static long _vq_pigeonmap_%s[] = {\n",name);
  541. for(j=0;j<p->mapentries;){
  542. fprintf(out,"\t");
  543. for(k=0;k<8 && j<p->mapentries;k++,j++)
  544. fprintf(out,"%5ld, ",p->pigeonmap[j]);
  545. fprintf(out,"\n");
  546. }
  547. fprintf(out,"};\n\n");
  548. /* fitlist */
  549. fprintf(out,"static long _vq_fitlist_%s[] = {\n",name);
  550. for(j=0;j<p->fittotal;){
  551. fprintf(out,"\t");
  552. for(k=0;k<8 && j<p->fittotal;k++,j++)
  553. fprintf(out,"%5ld, ",p->fitlist[j]);
  554. fprintf(out,"\n");
  555. }
  556. fprintf(out,"};\n\n");
  557. /* fitmap */
  558. fprintf(out,"static long _vq_fitmap_%s[] = {\n",name);
  559. for(j=0;j<pigeons;){
  560. fprintf(out,"\t");
  561. for(k=0;k<8 && j<pigeons;k++,j++)
  562. fprintf(out,"%5ld, ",p->fitmap[j]);
  563. fprintf(out,"\n");
  564. }
  565. fprintf(out,"};\n\n");
  566. /* fitlength */
  567. fprintf(out,"static long _vq_fitlength_%s[] = {\n",name);
  568. for(j=0;j<pigeons;){
  569. fprintf(out,"\t");
  570. for(k=0;k<8 && j<pigeons;k++,j++)
  571. fprintf(out,"%5ld, ",p->fitlength[j]);
  572. fprintf(out,"\n");
  573. }
  574. fprintf(out,"};\n\n");
  575. fprintf(out,"static encode_aux_pigeonhole _vq_auxp_%s = {\n",name);
  576. fprintf(out,"\t%g, %g, %d, %d,\n",
  577. p->min,p->del,p->mapentries,p->quantvals);
  578. fprintf(out,"\t_vq_pigeonmap_%s,\n",name);
  579. fprintf(out,"\t%ld,\n",p->fittotal);
  580. fprintf(out,"\t_vq_fitlist_%s,\n",name);
  581. fprintf(out,"\t_vq_fitmap_%s,\n",name);
  582. fprintf(out,"\t_vq_fitlength_%s\n};\n\n",name);
  583. }
  584. if(n){
  585. /* ptr0 */
  586. fprintf(out,"static long _vq_ptr0_%s[] = {\n",name);
  587. for(j=0;j<n->aux;){
  588. fprintf(out,"\t");
  589. for(k=0;k<8 && j<n->aux;k++,j++)
  590. fprintf(out,"%6ld,",n->ptr0[j]);
  591. fprintf(out,"\n");
  592. }
  593. fprintf(out,"};\n\n");
  594. /* ptr1 */
  595. fprintf(out,"static long _vq_ptr1_%s[] = {\n",name);
  596. for(j=0;j<n->aux;){
  597. fprintf(out,"\t");
  598. for(k=0;k<8 && j<n->aux;k++,j++)
  599. fprintf(out,"%6ld,",n->ptr1[j]);
  600. fprintf(out,"\n");
  601. }
  602. fprintf(out,"};\n\n");
  603. /* p */
  604. fprintf(out,"static long _vq_p_%s[] = {\n",name);
  605. for(j=0;j<n->aux;){
  606. fprintf(out,"\t");
  607. for(k=0;k<8 && j<n->aux;k++,j++)
  608. fprintf(out,"%6ld,",n->p[j]*c->dim);
  609. fprintf(out,"\n");
  610. }
  611. fprintf(out,"};\n\n");
  612. /* q */
  613. fprintf(out,"static long _vq_q_%s[] = {\n",name);
  614. for(j=0;j<n->aux;){
  615. fprintf(out,"\t");
  616. for(k=0;k<8 && j<n->aux;k++,j++)
  617. fprintf(out,"%6ld,",n->q[j]*c->dim);
  618. fprintf(out,"\n");
  619. }
  620. fprintf(out,"};\n\n");
  621. fprintf(out,"static encode_aux_nearestmatch _vq_auxn_%s = {\n",name);
  622. fprintf(out,"\t_vq_ptr0_%s,\n",name);
  623. fprintf(out,"\t_vq_ptr1_%s,\n",name);
  624. fprintf(out,"\t_vq_p_%s,\n",name);
  625. fprintf(out,"\t_vq_q_%s,\n",name);
  626. fprintf(out,"\t%ld, %ld\n};\n\n",n->aux,n->aux);
  627. }
  628. /* tie it all together */
  629. fprintf(out,"static static_codebook _vq_book_%s = {\n",name);
  630. fprintf(out,"\t%ld, %ld,\n",c->dim,c->entries);
  631. fprintf(out,"\t_vq_lengthlist_%s,\n",name);
  632. fprintf(out,"\t%d, %ld, %ld, %d, %d,\n",
  633. c->maptype,c->q_min,c->q_delta,c->q_quant,c->q_sequencep);
  634. if(c->quantlist)
  635. fprintf(out,"\t_vq_quantlist_%s,\n",name);
  636. else
  637. fprintf(out,"\tNULL,\n");
  638. if(n)
  639. fprintf(out,"\t&_vq_auxn_%s,\n",name);
  640. else
  641. fprintf(out,"\tNULL,\n");
  642. if(t)
  643. fprintf(out,"\t&_vq_auxt_%s,\n",name);
  644. else
  645. fprintf(out,"\tNULL,\n");
  646. if(p)
  647. fprintf(out,"\t&_vq_auxp_%s,\n",name);
  648. else
  649. fprintf(out,"\tNULL,\n");
  650. fprintf(out,"};\n\n");
  651. fprintf(out,"\n#endif\n");
  652. }