annotate tremor/sharedbook.c @ 18001:a2683ee7cb5a

fix descrambling of asf file, where signed buffer could cause erroneous values to be filled in descrable variables, add misssing check for one of these variables and restore sign of these variables as insurance that these checks will work even in such case.
author iive
date Thu, 30 Mar 2006 23:06:18 +0000
parents c820ccd4f5eb
children cd6b211be811
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
1 /********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
2 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
4 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
5 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
6 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
7 * ALL REDISTRIBUTION RIGHTS RESERVED. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
8 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
9 ********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
10
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
11 function: basic shared codebook operations
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
12
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
13 ********************************************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
14
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
15 #include <stdlib.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
16 #include <math.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
17 #include <string.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
18 #include "ogg.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
19 #include "os.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
20 #include "misc.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
21 #include "ivorbiscodec.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
22 #include "codebook.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
23
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
24 /**** pack/unpack helpers ******************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
25 int _ilog(unsigned int v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
26 int ret=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
27 while(v){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
28 ret++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29 v>>=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31 return(ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 /* 32 bit float (not IEEE; nonnormalized mantissa +
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35 biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 Why not IEEE? It's just not that important here. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38 #define VQ_FEXP 10
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39 #define VQ_FMAN 21
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40 #define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42 static ogg_int32_t _float32_unpack(long val,int *point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43 long mant=val&0x1fffff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44 int sign=val&0x80000000;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45 long exp =(val&0x7fe00000L)>>VQ_FMAN;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47 exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 if(mant){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50 while(!(mant&0x40000000)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51 mant<<=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 exp-=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55 if(sign)mant= -mant;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
56 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
57 sign=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 exp=-9999;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61 *point=exp;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 return mant;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
63 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
64
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
65 /* given a list of word lengths, generate a list of codewords. Works
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 for length ordered or unordered, always assigns the lowest valued
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67 codewords first. Extended to handle unused entries (length 0) */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68 ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69 long i,j,count=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70 ogg_uint32_t marker[33];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71 ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 memset(marker,0,sizeof(marker));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74 for(i=0;i<n;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 long length=l[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 if(length>0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77 ogg_uint32_t entry=marker[length];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
78
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
79 /* when we claim a node for an entry, we also claim the nodes
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80 below it (pruning off the imagined tree that may have dangled
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 from it) as well as blocking the use of any nodes directly
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82 above for leaves */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 /* update ourself */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85 if(length<32 && (entry>>length)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 /* error condition; the lengths must specify an overpopulated tree */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87 _ogg_free(r);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88 return(NULL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90 r[count++]=entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92 /* Look to see if the next shorter marker points to the node
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93 above. if so, update it and repeat. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95 for(j=length;j>0;j--){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97 if(marker[j]&1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98 /* have to jump branches */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99 if(j==1)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 marker[1]++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102 marker[j]=marker[j-1]<<1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 break; /* invariant says next upper marker would already
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104 have been moved if it was on the same path */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 marker[j]++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
110 /* prune the tree; the implicit invariant says all the longer
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
111 markers were dangling from our just-taken node. Dangle them
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 from our *new* node. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113 for(j=length+1;j<33;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114 if((marker[j]>>1) == entry){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115 entry=marker[j];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116 marker[j]=marker[j-1]<<1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
118 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
119 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
120 if(sparsecount==0)count++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
121 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
122
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
123 /* bitreverse the words because our bitwise packer/unpacker is LSb
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124 endian */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125 for(i=0,count=0;i<n;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126 ogg_uint32_t temp=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127 for(j=0;j<l[i];j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128 temp<<=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 temp|=(r[count]>>j)&1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
130 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
131
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
132 if(sparsecount){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133 if(l[i])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134 r[count++]=temp;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136 r[count++]=temp;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139 return(r);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142 /* there might be a straightforward one-line way to do the below
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143 that's portable and totally safe against roundoff, but I haven't
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144 thought of it. Therefore, we opt on the side of caution */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
145 long _book_maptype1_quantvals(const static_codebook *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
146 /* get us a starting hint, we'll polish it below */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
147 int bits=_ilog(b->entries);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
148 int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
149
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
150 while(1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
151 long acc=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
152 long acc1=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
153 int i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
154 for(i=0;i<b->dim;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
155 acc*=vals;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
156 acc1*=vals+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
157 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
158 if(acc<=b->entries && acc1>b->entries){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
159 return(vals);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
160 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
161 if(acc>b->entries){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
162 vals--;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
163 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
164 vals++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
165 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
166 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
167 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
168 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
169
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
170 /* different than what _book_unquantize does for mainline:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
171 we repack the book in a fixed point format that shares the same
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
172 binary point. Upon first use, we can shift point if needed */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
173
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
174 /* we need to deal with two map types: in map type 1, the values are
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
175 generated algorithmically (each column of the vector counts through
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
176 the values in the quant vector). in map type 2, all the values came
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
177 in in an explicit list. Both value lists must be unpacked */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
178
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
179 ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
180 int *maxpoint){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
181 long j,k,count=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
182 if(b->maptype==1 || b->maptype==2){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
183 int quantvals;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
184 int minpoint,delpoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
185 ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
186 ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
187 ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
188 int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
189
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
190 *maxpoint=minpoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
191
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
192 /* maptype 1 and 2 both use a quantized value vector, but
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
193 different sizes */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
194 switch(b->maptype){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
195 case 1:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
196 /* most of the time, entries%dimensions == 0, but we need to be
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
197 well defined. We define that the possible vales at each
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
198 scalar is values == entries/dim. If entries%dim != 0, we'll
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
199 have 'too few' values (values*dim<entries), which means that
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
200 we'll have 'left over' entries; left over entries use zeroed
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
201 values (and are wasted). So don't generate codebooks like
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
202 that */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
203 quantvals=_book_maptype1_quantvals(b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
204 for(j=0;j<b->entries;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
205 if((sparsemap && b->lengthlist[j]) || !sparsemap){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
206 ogg_int32_t last=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
207 int lastpoint=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
208 int indexdiv=1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
209 for(k=0;k<b->dim;k++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
210 int index= (j/indexdiv)%quantvals;
16266
c820ccd4f5eb fix warnings and decoding on CYGWIN (produced only noise before this change)
faust3
parents: 14280
diff changeset
211 ogg_int32_t point;
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
212 int val=VFLOAT_MULTI(delta,delpoint,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
213 abs(b->quantlist[index]),&point);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
214
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
215 val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
216 val=VFLOAT_ADD(last,lastpoint,val,point,&point);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
217
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
218 if(b->q_sequencep){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
219 last=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
220 lastpoint=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
221 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
222
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
223 if(sparsemap){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
224 r[sparsemap[count]*b->dim+k]=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
225 rp[sparsemap[count]*b->dim+k]=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
226 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
227 r[count*b->dim+k]=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
228 rp[count*b->dim+k]=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
229 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
230 if(*maxpoint<point)*maxpoint=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
231 indexdiv*=quantvals;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
232 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
233 count++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
234 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
235
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
236 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
237 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
238 case 2:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
239 for(j=0;j<b->entries;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
240 if((sparsemap && b->lengthlist[j]) || !sparsemap){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
241 ogg_int32_t last=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
242 int lastpoint=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
243
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
244 for(k=0;k<b->dim;k++){
16266
c820ccd4f5eb fix warnings and decoding on CYGWIN (produced only noise before this change)
faust3
parents: 14280
diff changeset
245 ogg_int32_t point;
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
246 int val=VFLOAT_MULTI(delta,delpoint,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
247 abs(b->quantlist[j*b->dim+k]),&point);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
248
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
249 val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
250 val=VFLOAT_ADD(last,lastpoint,val,point,&point);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
251
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
252 if(b->q_sequencep){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
253 last=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
254 lastpoint=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
255 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
256
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
257 if(sparsemap){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
258 r[sparsemap[count]*b->dim+k]=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
259 rp[sparsemap[count]*b->dim+k]=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
260 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
261 r[count*b->dim+k]=val;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
262 rp[count*b->dim+k]=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
263 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
264 if(*maxpoint<point)*maxpoint=point;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
265 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
266 count++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
267 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
268 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
269 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
270 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
271
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
272 for(j=0;j<n*b->dim;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
273 if(rp[j]<*maxpoint)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
274 r[j]>>=*maxpoint-rp[j];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
275
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
276 _ogg_free(rp);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
277 return(r);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
278 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
279 return(NULL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
280 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
281
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
282 void vorbis_staticbook_clear(static_codebook *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
283 if(b->quantlist)_ogg_free(b->quantlist);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
284 if(b->lengthlist)_ogg_free(b->lengthlist);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
285 memset(b,0,sizeof(*b));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
286
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
287 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
288
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
289 void vorbis_staticbook_destroy(static_codebook *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
290 vorbis_staticbook_clear(b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
291 _ogg_free(b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
292 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
293
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
294 void vorbis_book_clear(codebook *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
295 /* static book is not cleared; we're likely called on the lookup and
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
296 the static codebook belongs to the info struct */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
297 if(b->valuelist)_ogg_free(b->valuelist);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
298 if(b->codelist)_ogg_free(b->codelist);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
299
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
300 if(b->dec_index)_ogg_free(b->dec_index);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
301 if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
302 if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
303
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
304 memset(b,0,sizeof(*b));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
305 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
306
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
307 static ogg_uint32_t bitreverse(ogg_uint32_t x){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
308 x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
309 x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
310 x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
311 x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
312 return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
313 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
314
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
315 static int sort32a(const void *a,const void *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
316 return ( (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)<<1)-1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
317 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
318
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
319 /* decode codebook arrangement is more heavily optimized than encode */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
320 int vorbis_book_init_decode(codebook *c,const static_codebook *s){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
321 int i,j,n=0,tabn;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
322 int *sortindex;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
323 memset(c,0,sizeof(*c));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
324
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
325 /* count actually used entries */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
326 for(i=0;i<s->entries;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
327 if(s->lengthlist[i]>0)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
328 n++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
329
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
330 c->entries=s->entries;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
331 c->used_entries=n;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
332 c->dim=s->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
333
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
334 c->q_min=s->q_min;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
335 c->q_delta=s->q_delta;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
336
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
337 /* two different remappings go on here.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
338
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
339 First, we collapse the likely sparse codebook down only to
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
340 actually represented values/words. This collapsing needs to be
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
341 indexed as map-valueless books are used to encode original entry
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
342 positions as integers.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
343
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
344 Second, we reorder all vectors, including the entry index above,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
345 by sorted bitreversed codeword to allow treeless decode. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
346
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
347 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
348 /* perform sort */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
349 ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
350 ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
351
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
352 if(codes==NULL)goto err_out;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
353
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
354 for(i=0;i<n;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
355 codes[i]=bitreverse(codes[i]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
356 codep[i]=codes+i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
357 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
358
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
359 qsort(codep,n,sizeof(*codep),sort32a);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
360
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
361 sortindex=(int *)alloca(n*sizeof(*sortindex));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
362 c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
363 /* the index is a reverse index */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
364 for(i=0;i<n;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
365 int position=codep[i]-codes;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
366 sortindex[position]=i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
367 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
368
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
369 for(i=0;i<n;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
370 c->codelist[sortindex[i]]=codes[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
371 _ogg_free(codes);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
372 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
373
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
374
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
375 c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
376 c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
377
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
378 for(n=0,i=0;i<s->entries;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
379 if(s->lengthlist[i]>0)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
380 c->dec_index[sortindex[n++]]=i;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
381
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
382 c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
383 for(n=0,i=0;i<s->entries;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
384 if(s->lengthlist[i]>0)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
385 c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
386
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
387 c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
388 if(c->dec_firsttablen<5)c->dec_firsttablen=5;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
389 if(c->dec_firsttablen>8)c->dec_firsttablen=8;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
390
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
391 tabn=1<<c->dec_firsttablen;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
392 c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
393 c->dec_maxlength=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
394
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
395 for(i=0;i<n;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
396 if(c->dec_maxlength<c->dec_codelengths[i])
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
397 c->dec_maxlength=c->dec_codelengths[i];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
398 if(c->dec_codelengths[i]<=c->dec_firsttablen){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
399 ogg_uint32_t orig=bitreverse(c->codelist[i]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
400 for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
401 c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
402 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
403 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
404
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
405 /* now fill in 'unused' entries in the firsttable with hi/lo search
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
406 hints for the non-direct-hits */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
407 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
408 ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
409 long lo=0,hi=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
410
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
411 for(i=0;i<tabn;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
412 ogg_uint32_t word=i<<(32-c->dec_firsttablen);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
413 if(c->dec_firsttable[bitreverse(word)]==0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
414 while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
415 while( hi<n && word>=(c->codelist[hi]&mask))hi++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
416
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
417 /* we only actually have 15 bits per hint to play with here.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
418 In order to overflow gracefully (nothing breaks, efficiency
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
419 just drops), encode as the difference from the extremes. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
420 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
421 unsigned long loval=lo;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
422 unsigned long hival=n-hi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
423
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
424 if(loval>0x7fff)loval=0x7fff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
425 if(hival>0x7fff)hival=0x7fff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
426 c->dec_firsttable[bitreverse(word)]=
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
427 0x80000000UL | (loval<<15) | hival;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
428 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
429 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
430 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
431 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
432
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
433
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
434 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
435 err_out:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
436 vorbis_book_clear(c);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
437 return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
438 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
439