1 /********************************************************************
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. *
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/ *
12 ********************************************************************
14 function: utility functions for loading .vqh and .vqd files
15 last mod: $Id: bookutil.c,v 1.11 2000/02/21 01:12:53 xiphmont Exp $
17 ********************************************************************/
24 #include "vorbis/codebook.h"
27 void codebook_unquantize(codebook *b){
29 const static_codebook *c=b->c;
30 double mindel=float24_unpack(c->q_min);
31 double delta=float24_unpack(c->q_delta);
32 if(!b->valuelist)b->valuelist=malloc(sizeof(double)*c->entries*c->dim);
34 for(j=0;j<c->entries;j++){
36 for(k=0;k<c->dim;k++){
37 double val=c->quantlist[j*c->dim+k]*delta+last+mindel;
38 b->valuelist[j*c->dim+k]=val;
39 if(c->q_sequencep)last=val;
45 /* A few little utils for reading files */
46 /* read a line. Use global, persistent buffering */
47 static char *linebuffer=NULL;
48 static int lbufsize=0;
49 char *get_line(FILE *in){
51 if(feof(in))return NULL;
57 if(sofar+1>=lbufsize){
60 linebuffer=malloc(lbufsize);
63 linebuffer=realloc(linebuffer,lbufsize);
70 if(sofar==0)return(NULL);
71 /* fallthrough correct */
73 linebuffer[sofar]='\0';
77 linebuffer[sofar++]=c;
78 linebuffer[sofar]='\0';
84 if(linebuffer[0]=='#'){
92 /* read the next numerical value from the given file */
93 static char *value_line_buff=NULL;
95 int get_line_value(FILE *in,double *value){
98 if(!value_line_buff)return(-1);
100 *value=strtod(value_line_buff, &next);
101 if(next==value_line_buff){
102 value_line_buff=NULL;
105 value_line_buff=next;
106 while(*value_line_buff>44)value_line_buff++;
107 if(*value_line_buff==44)value_line_buff++;
112 int get_next_value(FILE *in,double *value){
114 if(get_line_value(in,value)){
115 value_line_buff=get_line(in);
116 if(!value_line_buff)return(-1);
123 int get_next_ivalue(FILE *in,long *ivalue){
125 int ret=get_next_value(in,&value);
130 static double sequence_base=0.;
131 static int v_sofar=0;
132 void reset_next_value(void){
133 value_line_buff=NULL;
138 int get_vector(codebook *b,FILE *in,int start, int n,double *a){
140 const static_codebook *c=b->c;
144 if(v_sofar==n || get_line_value(in,a)){
146 if(get_next_value(in,a))
148 for(i=0;i<start;i++){
150 get_line_value(in,a);
154 for(i=1;i<c->dim;i++)
155 if(get_line_value(in,a+i))
159 double temp=a[c->dim-1];
160 for(i=0;i<c->dim;i++)a[i]-=sequence_base;
161 if(c->q_sequencep)sequence_base=temp;
171 /* read lines fromt he beginning until we find one containing the
173 char *find_seek_to(FILE *in,char *s){
176 char *line=get_line(in);
186 /* this reads the format as written by vqbuild; innocent (legal)
187 tweaking of the file that would not affect its valid header-ness
188 will break this routine */
190 codebook *codebook_load(char *filename){
191 codebook *b=calloc(1,sizeof(codebook));
192 static_codebook *c=(static_codebook *)(b->c=calloc(1,sizeof(static_codebook)));
193 encode_aux *a=calloc(1,sizeof(encode_aux));
194 FILE *in=fopen(filename,"r");
201 fprintf(stderr,"Couldn't open codebook %s\n",filename);
205 /* find the codebook struct */
206 find_seek_to(in,"static static_codebook _vq_book_");
208 /* get the major important values */
210 if(sscanf(line,"%ld, %ld, %ld, %ld, %d, %d",
211 &(c->dim),&(c->entries),&(c->q_min),&(c->q_delta),&(c->q_quant),
212 &(c->q_sequencep))!=6){
213 fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
217 /* find the auxiliary encode struct (if any) */
218 find_seek_to(in,"static encode_aux _vq_aux_");
225 if(sscanf(line,"%ld, %ld",&(a->aux),&(a->alloc))!=2){
226 fprintf(stderr,"2: syntax in %s in line:\t %s",filename,line);
230 /* load the quantized entries */
231 find_seek_to(in,"static long _vq_quantlist_");
233 c->quantlist=malloc(sizeof(long)*c->entries*c->dim);
234 for(i=0;i<c->entries*c->dim;i++)
235 if(get_next_ivalue(in,c->quantlist+i)){
236 fprintf(stderr,"out of data while reading codebook %s\n",filename);
240 /* load the lengthlist */
241 find_seek_to(in,"static long _vq_lengthlist");
243 c->lengthlist=malloc(sizeof(long)*c->entries);
244 for(i=0;i<c->entries;i++)
245 if(get_next_ivalue(in,c->lengthlist+i)){
246 fprintf(stderr,"out of data while reading codebook %s\n",filename);
251 find_seek_to(in,"static long _vq_ptr0");
253 a->ptr0=malloc(sizeof(long)*a->aux);
254 for(i=0;i<a->aux;i++)
255 if(get_next_ivalue(in,a->ptr0+i)){
256 fprintf(stderr,"out of data while reading codebook %s\n",filename);
261 find_seek_to(in,"static long _vq_ptr1");
263 a->ptr1=malloc(sizeof(long)*a->aux);
264 for(i=0;i<a->aux;i++)
265 if(get_next_ivalue(in,a->ptr1+i)){
266 fprintf(stderr,"out of data while reading codebook %s\n",filename);
272 find_seek_to(in,"static long _vq_p_");
274 a->p=malloc(sizeof(long)*a->aux);
275 for(i=0;i<a->aux;i++)
276 if(get_next_ivalue(in,a->p+i)){
277 fprintf(stderr,"out of data while reading codebook %s\n",filename);
282 find_seek_to(in,"static long _vq_q_");
284 a->q=malloc(sizeof(long)*a->aux);
285 for(i=0;i<a->aux;i++)
286 if(get_next_ivalue(in,a->q+i)){
287 fprintf(stderr,"out of data while reading codebook %s\n",filename);
294 /* might as well unquantize the entries while we're at it */
295 codebook_unquantize(b);
297 /* don't need n and c */
302 /* the new version! we have ptr0[0] distinct trees in the auxiliary
303 encoding structure. Find the best match in each one, choosing the
306 int codebook_entry(codebook *b,double *val){
307 const static_codebook *c=b->c;
308 encode_aux *t=c->encode_tree;
309 int trees=t->ptr0[0];
313 double this,best=_dist(c->dim,val,b->valuelist);
315 for(i=1;i<c->entries;i++){
316 this=_dist(c->dim,val,b->valuelist+i*c->dim);
324 double *n=alloca(c->dim*sizeof(double));
328 int ptr=t->ptr0[--trees],k;
332 double *p=b->valuelist+t->p[ptr];
333 double *q=b->valuelist+t->q[ptr];
335 for(k=0;k<c->dim;k++){
341 for(k=0;k<c->dim;k++)
353 for(k=0;k<c->dim;k++){
354 double one=val[k]-(b->valuelist-ptr*c->dim)[k];
357 if(best==-1 || dist<bestmetric){
367 /* 24 bit float (not IEEE; nonnormalized mantissa +
368 biased exponent ): neeeeemm mmmmmmmm mmmmmmmm */
370 long float24_pack(double val){
378 exp= floor(log(val)/log(2));
379 mant=rint(ldexp(val,17-exp));
380 exp=(exp+VQ_FEXP_BIAS)<<18;
382 return(sign|exp|mant);
385 double float24_unpack(long val){
386 double mant=val&0x3ffff;
387 double sign=val&0x800000;
388 double exp =(val&0x7c0000)>>18;
390 return(ldexp(mant,exp-17-VQ_FEXP_BIAS));
393 void spinnit(char *s,int n){
395 static long lasttime=0;
397 struct timeval thistime;
399 gettimeofday(&thistime,NULL);
400 test=thistime.tv_sec*10+thistime.tv_usec/100000;
404 fprintf(stderr,"%s%d ",s,n);
409 fprintf(stderr,"| \r");
412 fprintf(stderr,"/ \r");
415 fprintf(stderr,"- \r");
418 fprintf(stderr,"\\ \r");
425 void build_tree_from_lengths(int vals, long *hist, long *lengths){
427 long *membership=malloc(vals*sizeof(long));
429 for(i=0;i<vals;i++)membership[i]=i;
431 /* find codeword lengths */
432 /* much more elegant means exist. Brute force n^2, minimum thought */
434 int first=-1,second=-1;
437 spinnit("building... ",i);
439 /* find the two nodes to join */
441 if(least==-1 || hist[j]<least){
447 if((least==-1 || hist[j]<least) && membership[j]!=first){
449 second=membership[j];
451 if(first==-1 || second==-1){
452 fprintf(stderr,"huffman fault; no free branch\n");
457 least=hist[first]+hist[second];
459 if(membership[j]==first || membership[j]==second){
465 for(i=0;i<vals-1;i++)
466 if(membership[i]!=membership[i+1]){
467 fprintf(stderr,"huffman fault; failed to build single tree\n");