bookutil.c 19 KB

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