1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
4 * *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
11 * *
12 ********************************************************************
13
14 function: basic codebook pack/unpack/code/decode operations
15
16 ********************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include "ogg.h"
22 #include "ivorbiscodec.h"
23 #include "codebook.h"
24 #include "misc.h"
25
26 /* unpacks a codebook from the packet buffer into the codebook struct,
27 readies the codebook auxiliary structures for decode *************/
vorbis_staticbook_unpack(oggpack_buffer * opb)28 static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
29 long i,j;
30 static_codebook *s=_ogg_calloc(1,sizeof(*s));
31
32 /* make sure alignment is correct */
33 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
34
35 /* first the basic parameters */
36 s->dim=oggpack_read(opb,16);
37 s->entries=oggpack_read(opb,24);
38 if(s->entries==-1)goto _eofout;
39
40 if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
41
42 /* codeword ordering.... length ordered or unordered? */
43 switch((int)oggpack_read(opb,1)){
44 case 0:{
45 long unused;
46 /* allocated but unused entries? */
47 unused=oggpack_read(opb,1);
48 if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
49 goto _eofout;
50 /* unordered */
51 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
52
53 /* allocated but unused entries? */
54 if(unused){
55 /* yes, unused entries */
56
57 for(i=0;i<s->entries;i++){
58 if(oggpack_read(opb,1)){
59 long num=oggpack_read(opb,5);
60 if(num==-1)goto _eofout;
61 s->lengthlist[i]=num+1;
62 }else
63 s->lengthlist[i]=0;
64 }
65 }else{
66 /* all entries used; no tagging */
67 for(i=0;i<s->entries;i++){
68 long num=oggpack_read(opb,5);
69 if(num==-1)goto _eofout;
70 s->lengthlist[i]=num+1;
71 }
72 }
73
74 break;
75 }
76 case 1:
77 /* ordered */
78 {
79 long length=oggpack_read(opb,5)+1;
80 if(length==0)goto _eofout;
81 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
82
83 for(i=0;i<s->entries;){
84 long num=oggpack_read(opb,_ilog(s->entries-i));
85 if(num==-1)goto _eofout;
86 if(length>32 || num>s->entries-i ||
87 (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
88 goto _errout;
89 }
90 for(j=0;j<num;j++,i++)
91 s->lengthlist[i]=length;
92 length++;
93 }
94 }
95 break;
96 default:
97 /* EOF */
98 goto _eofout;
99 }
100
101 /* Do we have a mapping to unpack? */
102 switch((s->maptype=oggpack_read(opb,4))){
103 case 0:
104 /* no mapping */
105 break;
106 case 1: case 2:
107 /* implicitly populated value mapping */
108 /* explicitly populated value mapping */
109
110 s->q_min=oggpack_read(opb,32);
111 s->q_delta=oggpack_read(opb,32);
112 s->q_quant=oggpack_read(opb,4)+1;
113 s->q_sequencep=oggpack_read(opb,1);
114 if(s->q_sequencep==-1)goto _eofout;
115
116 {
117 int quantvals=0;
118 switch(s->maptype){
119 case 1:
120 quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
121 break;
122 case 2:
123 quantvals=s->entries*s->dim;
124 break;
125 }
126
127 /* quantized values */
128 if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
129 goto _eofout;
130 s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
131 for(i=0;i<quantvals;i++)
132 s->quantlist[i]=oggpack_read(opb,s->q_quant);
133
134 if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
135 }
136 break;
137 default:
138 goto _errout;
139 }
140
141 /* all set */
142 return(s);
143
144 _errout:
145 _eofout:
146 vorbis_staticbook_destroy(s);
147 return(NULL);
148 }
149
150 /* the 'eliminate the decode tree' optimization actually requires the
151 codewords to be MSb first, not LSb. This is an annoying inelegancy
152 (and one of the first places where carefully thought out design
153 turned out to be wrong; Vorbis II and future Ogg codecs should go
154 to an MSb bitpacker), but not actually the huge hit it appears to
155 be. The first-stage decode table catches most words so that
156 bitreverse is not in the main execution path. */
157
bitreverse(ogg_uint32_t x)158 static ogg_uint32_t bitreverse(ogg_uint32_t x){
159 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
160 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
161 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
162 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
163 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
164 }
165
decode_packed_entry_number(codebook * book,oggpack_buffer * b)166 STIN long decode_packed_entry_number(codebook *book,
167 oggpack_buffer *b){
168 int read=book->dec_maxlength;
169 long lo,hi;
170 long lok = oggpack_look(b,book->dec_firsttablen);
171
172 if (lok >= 0) {
173 long entry = book->dec_firsttable[lok];
174 if(entry&0x80000000UL){
175 lo=(entry>>15)&0x7fff;
176 hi=book->used_entries-(entry&0x7fff);
177 }else{
178 oggpack_adv(b, book->dec_codelengths[entry-1]);
179 return(entry-1);
180 }
181 }else{
182 lo=0;
183 hi=book->used_entries;
184 }
185
186 lok = oggpack_look(b, read);
187
188 while(lok<0 && read>1)
189 lok = oggpack_look(b, --read);
190
191 if(lok<0){
192 oggpack_adv(b,1); /* force eop */
193 return -1;
194 }
195
196 /* bisect search for the codeword in the ordered list */
197 {
198 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
199
200 while(hi-lo>1){
201 long p=(hi-lo)>>1;
202 long test=book->codelist[lo+p]>testword;
203 lo+=p&(test-1);
204 hi-=p&(-test);
205 }
206
207 if(book->dec_codelengths[lo]<=read){
208 oggpack_adv(b, book->dec_codelengths[lo]);
209 return(lo);
210 }
211 }
212
213 oggpack_adv(b, read+1);
214 return(-1);
215 }
216
217 /* Decode side is specced and easier, because we don't need to find
218 matches using different criteria; we simply read and map. There are
219 two things we need to do 'depending':
220
221 We may need to support interleave. We don't really, but it's
222 convenient to do it here rather than rebuild the vector later.
223
224 Cascades may be additive or multiplicitive; this is not inherent in
225 the codebook, but set in the code using the codebook. Like
226 interleaving, it's easiest to do it here.
227 addmul==0 -> declarative (set the value)
228 addmul==1 -> additive
229 addmul==2 -> multiplicitive */
230
231 /* returns the [original, not compacted] entry number or -1 on eof *********/
vorbis_book_decode(codebook * book,oggpack_buffer * b)232 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
233 if(book->used_entries>0){
234 long packed_entry=decode_packed_entry_number(book,b);
235 if(packed_entry>=0)
236 return(book->dec_index[packed_entry]);
237 }
238
239 /* if there's no dec_index, the codebook unpacking isn't collapsed */
240 return(-1);
241 }
242
243 /* returns 0 on OK or -1 on eof *************************************/
244 /* decode vector / dim granularity gaurding is done in the upper layer */
vorbis_book_decodevs_add(codebook * book,ogg_int32_t * a,oggpack_buffer * b,int n,int point)245 long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
246 oggpack_buffer *b,int n,int point){
247 if(book->used_entries>0){
248 int step=n/book->dim;
249 long *entry = (long *)alloca(sizeof(*entry)*step);
250 ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
251 int i,j,o;
252 int shift=point-book->binarypoint;
253
254 if(shift>=0){
255 for (i = 0; i < step; i++) {
256 entry[i]=decode_packed_entry_number(book,b);
257 if(entry[i]==-1)return(-1);
258 t[i] = book->valuelist+entry[i]*book->dim;
259 }
260 for(i=0,o=0;i<book->dim;i++,o+=step)
261 for (j=0;o+j<n && j<step;j++)
262 a[o+j]+=t[j][i]>>shift;
263 }else{
264 for (i = 0; i < step; i++) {
265 entry[i]=decode_packed_entry_number(book,b);
266 if(entry[i]==-1)return(-1);
267 t[i] = book->valuelist+entry[i]*book->dim;
268 }
269 for(i=0,o=0;i<book->dim;i++,o+=step)
270 for (j=0;o+j<n && j<step;j++)
271 a[o+j]+=t[j][i]<<-shift;
272 }
273 }
274 return(0);
275 }
276
277 /* decode vector / dim granularity gaurding is done in the upper layer */
vorbis_book_decodev_add(codebook * book,ogg_int32_t * a,oggpack_buffer * b,int n,int point)278 long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
279 oggpack_buffer *b,int n,int point){
280 if(book->used_entries>0){
281 int i,j,entry;
282 ogg_int32_t *t;
283 int shift=point-book->binarypoint;
284
285 if(shift>=0){
286 for(i=0;i<n;){
287 entry = decode_packed_entry_number(book,b);
288 if(entry==-1)return(-1);
289 t = book->valuelist+entry*book->dim;
290 for (j=0;i<n && j<book->dim;)
291 a[i++]+=t[j++]>>shift;
292 }
293 }else{
294 for(i=0;i<n;){
295 entry = decode_packed_entry_number(book,b);
296 if(entry==-1)return(-1);
297 t = book->valuelist+entry*book->dim;
298 for (j=0;i<n && j<book->dim;)
299 a[i++]+=t[j++]<<-shift;
300 }
301 }
302 }
303 return(0);
304 }
305
306 /* unlike the others, we guard against n not being an integer number
307 of <dim> internally rather than in the upper layer (called only by
308 floor0) */
vorbis_book_decodev_set(codebook * book,ogg_int32_t * a,oggpack_buffer * b,int n,int point)309 long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
310 oggpack_buffer *b,int n,int point){
311 if(book->used_entries>0){
312 int i,j,entry;
313 ogg_int32_t *t;
314 int shift=point-book->binarypoint;
315
316 if(shift>=0){
317
318 for(i=0;i<n;){
319 entry = decode_packed_entry_number(book,b);
320 if(entry==-1)return(-1);
321 t = book->valuelist+entry*book->dim;
322 for (j=0;i<n && j<book->dim;){
323 a[i++]=t[j++]>>shift;
324 }
325 }
326 }else{
327
328 for(i=0;i<n;){
329 entry = decode_packed_entry_number(book,b);
330 if(entry==-1)return(-1);
331 t = book->valuelist+entry*book->dim;
332 for (j=0;i<n && j<book->dim;){
333 a[i++]=t[j++]<<-shift;
334 }
335 }
336 }
337 }else{
338
339 int i,j;
340 for(i=0;i<n;){
341 a[i++]=0;
342 }
343 }
344 return(0);
345 }
346
347 /* decode vector / dim granularity gaurding is done in the upper layer */
vorbis_book_decodevv_add(codebook * book,ogg_int32_t ** a,long offset,int ch,oggpack_buffer * b,int n,int point)348 long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\
349 long offset,int ch,
350 oggpack_buffer *b,int n,int point){
351 if(book->used_entries>0){
352 long i,j,entry;
353 int chptr=0;
354 int shift=point-book->binarypoint;
355 int m=offset+n;
356 if(shift>=0){
357
358 for(i=offset;i<m;){
359 entry = decode_packed_entry_number(book,b);
360 if(entry==-1)return(-1);
361 {
362 const ogg_int32_t *t = book->valuelist+entry*book->dim;
363 for (j=0;i<m && j<book->dim;j++){
364 a[chptr++][i]+=t[j]>>shift;
365 if(chptr==ch){
366 chptr=0;
367 i++;
368 }
369 }
370 }
371 }
372 }else{
373
374 for(i=offset;i<m;){
375 entry = decode_packed_entry_number(book,b);
376 if(entry==-1)return(-1);
377 {
378 const ogg_int32_t *t = book->valuelist+entry*book->dim;
379 for (j=0;i<m && j<book->dim;j++){
380 a[chptr++][i]+=t[j]<<-shift;
381 if(chptr==ch){
382 chptr=0;
383 i++;
384 }
385 }
386 }
387 }
388 }
389 }
390 return(0);
391 }
392