1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
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. *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12 ********************************************************************
14 function: basic codebook pack/unpack/code/decode operations
16 ********************************************************************/
18 #include "config-tremor.h"
22 #include "ivorbiscodec.h"
27 /* unpacks a codebook from the packet buffer into the codebook struct,
28 readies the codebook auxiliary structures for decode *************/
29 static_codebook
*vorbis_staticbook_unpack(oggpack_buffer
*opb
){
31 static_codebook
*s
=_ogg_calloc(1,sizeof(*s
));
33 /* make sure alignment is correct */
34 if(oggpack_read(opb
,24)!=0x564342)goto _eofout
;
36 /* first the basic parameters */
37 s
->dim
=oggpack_read(opb
,16);
38 s
->entries
=oggpack_read(opb
,24);
39 if(s
->entries
==-1)goto _eofout
;
41 if(_ilog(s
->dim
)+_ilog(s
->entries
)>24)goto _eofout
;
43 /* codeword ordering.... length ordered or unordered? */
44 switch((int)oggpack_read(opb
,1)){
47 /* allocated but unused entries? */
48 unused
=oggpack_read(opb
,1);
49 if((s
->entries
*(unused
?1:5)+7)>>3>opb
->storage
-oggpack_bytes(opb
))
52 s
->lengthlist
=(long *)_ogg_malloc(sizeof(*s
->lengthlist
)*s
->entries
);
54 /* allocated but unused entries? */
56 /* yes, unused entries */
58 for(i
=0;i
<s
->entries
;i
++){
59 if(oggpack_read(opb
,1)){
60 long num
=oggpack_read(opb
,5);
61 if(num
==-1)goto _eofout
;
62 s
->lengthlist
[i
]=num
+1;
67 /* all entries used; no tagging */
68 for(i
=0;i
<s
->entries
;i
++){
69 long num
=oggpack_read(opb
,5);
70 if(num
==-1)goto _eofout
;
71 s
->lengthlist
[i
]=num
+1;
80 long length
=oggpack_read(opb
,5)+1;
81 if(length
==0)goto _eofout
;
82 s
->lengthlist
=(long *)_ogg_malloc(sizeof(*s
->lengthlist
)*s
->entries
);
84 for(i
=0;i
<s
->entries
;){
85 long num
=oggpack_read(opb
,_ilog(s
->entries
-i
));
86 if(num
==-1)goto _eofout
;
87 if(length
>32 || num
>s
->entries
-i
||
88 (num
>0 && (num
-1)>>(length
>>1)>>((length
+1)>>1))>0){
91 for(j
=0;j
<num
;j
++,i
++)
92 s
->lengthlist
[i
]=length
;
102 /* Do we have a mapping to unpack? */
103 switch((s
->maptype
=oggpack_read(opb
,4))){
108 /* implicitly populated value mapping */
109 /* explicitly populated value mapping */
111 s
->q_min
=oggpack_read(opb
,32);
112 s
->q_delta
=oggpack_read(opb
,32);
113 s
->q_quant
=oggpack_read(opb
,4)+1;
114 s
->q_sequencep
=oggpack_read(opb
,1);
115 if(s
->q_sequencep
==-1)goto _eofout
;
121 quantvals
=(s
->dim
==0?0:_book_maptype1_quantvals(s
));
124 quantvals
=s
->entries
*s
->dim
;
128 /* quantized values */
129 if((quantvals
*s
->q_quant
+7)>>3>opb
->storage
-oggpack_bytes(opb
))
131 s
->quantlist
=(long *)_ogg_malloc(sizeof(*s
->quantlist
)*quantvals
);
132 for(i
=0;i
<quantvals
;i
++)
133 s
->quantlist
[i
]=oggpack_read(opb
,s
->q_quant
);
135 if(quantvals
&&s
->quantlist
[quantvals
-1]==-1)goto _eofout
;
147 vorbis_staticbook_destroy(s
);
151 /* the 'eliminate the decode tree' optimization actually requires the
152 codewords to be MSb first, not LSb. This is an annoying inelegancy
153 (and one of the first places where carefully thought out design
154 turned out to be wrong; Vorbis II and future Ogg codecs should go
155 to an MSb bitpacker), but not actually the huge hit it appears to
156 be. The first-stage decode table catches most words so that
157 bitreverse is not in the main execution path. */
159 static inline ogg_uint32_t
bitreverse(register ogg_uint32_t x
)
164 unsigned mask
= 0x0f0f0f0f;
166 unsigned mask
= 0x00ff00ff;
170 "rev %[r], %[x] \n" /* swap halfwords and bytes */
171 "and %[t], %[m], %[r] \n" /* Sequence is one instruction */
172 "eor %[r], %[t], %[r] \n" /* longer than on <= ARMv5, but */
173 "mov %[t], %[t], lsl #4 \n" /* interlock free */
174 "orr %[r], %[t], %[r], lsr #4\n" /* nibbles swapped */
175 "eor %[m], %[m], %[m], lsl #2\n" /* mask = 0x33333333 */
176 "and %[t], %[m], %[r] \n"
177 "eor %[r], %[t], %[r] \n"
178 "mov %[t], %[t], lsl #2 \n"
179 "orr %[r], %[t], %[r], lsr #2\n" /* dibits swapped */
180 "eor %[m], %[m], %[m], lsl #1\n" /* mask = 0x55555555 */
181 "and %[t], %[m], %[r] \n"
182 "eor %[r], %[t], %[r] \n"
183 "mov %[t], %[t], lsl #1 \n"
184 "orr %[r], %[t], %[r], lsr #1\n" /* bits swapped */
185 #else /* ARM_ARCH <= 5 */
186 "mov %[r], %[x], ror #16 \n" /* swap halfwords */
187 "and %[t], %[m], %[r], lsr #8\n"
188 "eor %[r], %[r], %[t], lsl #8\n"
189 "orr %[r], %[t], %[r], lsl #8\n" /* bytes swapped */
190 "eor %[m], %[m], %[m], lsl #4\n" /* mask = 0x0f0f0f0f */
191 "and %[t], %[m], %[r], lsr #4\n"
192 "eor %[r], %[r], %[t], lsl #4\n"
193 "orr %[r], %[t], %[r], lsl #4\n" /* nibbles swapped */
194 "eor %[m], %[m], %[m], lsl #2\n" /* mask = 0x33333333 */
195 "and %[t], %[m], %[r], lsr #2\n"
196 "eor %[r], %[r], %[t], lsl #2\n"
197 "orr %[r], %[t], %[r], lsl #2\n" /* dibits swapped */
198 "eor %[m], %[m], %[m], lsl #1\n" /* mask = 0x55555555 */
199 "and %[t], %[m], %[r], lsr #1\n"
200 "eor %[r], %[r], %[t], lsl #1\n"
201 "orr %[r], %[t], %[r], lsl #1\n" /* bits swapped */
202 #endif /* ARM_ARCH */
210 #else /* !_ARM_ASSEM_ */
214 asm ("swap %[r]" : [r
] "+d" (ret
)); /* swap halfwords */
216 ret
= (x
>>16) | (x
<<16);
218 tmp
= ret
& 0x00ff00ff;
220 ret
= (ret
>> 8) | (tmp
<< 8); /* bytes swapped */
221 tmp
= ret
& 0x0f0f0f0f;
223 ret
= (ret
>> 4) | (tmp
<< 4); /* 4-bit units swapped */
224 tmp
= ret
& 0x33333333;
226 ret
= (ret
>> 2) | (tmp
<< 2); /* 2-bit units swapped */
227 tmp
= ret
& 0x55555555;
229 ret
= (ret
>> 1) | (tmp
<< 1); /* done */
230 #endif /* !_ARM_ASSEM_ */
234 static inline long bisect_codelist(long lo
, long hi
, ogg_uint32_t cache
,
235 const ogg_uint32_t
*codelist
)
237 ogg_uint32_t testword
=bitreverse(cache
);
239 while(LIKELY(p
= (hi
-lo
) >> 1) > 0){
240 if(codelist
[lo
+p
] > testword
)
248 STIN
long decode_packed_entry_number(codebook
*book
,
250 int read
=book
->dec_maxlength
;
252 long lok
= oggpack_look(b
,book
->dec_firsttablen
);
254 if (LIKELY(lok
>= 0)) {
255 ogg_int32_t entry
= book
->dec_firsttable
[lok
];
256 if(UNLIKELY(entry
< 0)){
257 lo
=(entry
>>15)&0x7fff;
258 hi
=book
->used_entries
-(entry
&0x7fff);
260 oggpack_adv(b
, book
->dec_codelengths
[entry
-1]);
265 hi
=book
->used_entries
;
268 lok
= oggpack_look(b
, read
);
270 while(lok
<0 && read
>1)
271 lok
= oggpack_look(b
, --read
);
274 oggpack_adv(b
,1); /* force eop */
278 /* bisect search for the codeword in the ordered list */
280 lo
= bisect_codelist(lo
, hi
, lok
, book
->codelist
);
282 if(book
->dec_codelengths
[lo
]<=read
){
283 oggpack_adv(b
, book
->dec_codelengths
[lo
]);
288 oggpack_adv(b
, read
+1);
292 static long decode_packed_block(codebook
*book
, oggpack_buffer
*b
,
295 long *bufend
= buf
+ n
;
297 while (bufptr
<bufend
) {
298 if(b
->endbyte
< b
->storage
- 8) {
300 unsigned long bit
, bitend
;
302 ogg_uint32_t cache
= 0;
304 const unsigned int cachemask
= (1<<book
->dec_firsttablen
)-1;
305 const int book_dec_maxlength
= book
->dec_maxlength
;
306 const ogg_uint32_t
*book_dec_firsttable
= book
->dec_firsttable
;
307 const long book_used_entries
= book
->used_entries
;
308 const ogg_uint32_t
*book_codelist
= book
->codelist
;
309 const char *book_dec_codelengths
= book
->dec_codelengths
;
311 adr
= (unsigned long)b
->ptr
;
312 bit
= (adr
&3)*8+b
->endbit
;
313 ptr
= (ogg_uint32_t
*)(adr
&~3);
314 bitend
= ((adr
&3)+(b
->storage
-b
->endbyte
))*8;
315 while (bufptr
<bufend
){
316 if (UNLIKELY(cachesize
<book_dec_maxlength
)) {
317 if (bit
-cachesize
+32>=bitend
)
320 cache
= letoh32(ptr
[bit
>>5]);
323 cache
|= letoh32(ptr
[(bit
>>5)+1]) << (32-(bit
&31));
329 ogg_int32_t entry
= book_dec_firsttable
[cache
&cachemask
];
330 if(UNLIKELY(entry
< 0)){
331 const long lo
= (entry
>>15)&0x7fff, hi
= book_used_entries
-(entry
&0x7fff);
332 entry
= bisect_codelist(lo
, hi
, cache
, book_codelist
);
337 int l
= book_dec_codelengths
[entry
];
342 adr
=(unsigned long)b
->ptr
;
343 bit
-=(adr
&3)*8+cachesize
;
348 long r
= decode_packed_entry_number(book
, b
);
349 if (r
== -1) return bufptr
-buf
;
356 /* Decode side is specced and easier, because we don't need to find
357 matches using different criteria; we simply read and map. There are
358 two things we need to do 'depending':
360 We may need to support interleave. We don't really, but it's
361 convenient to do it here rather than rebuild the vector later.
363 Cascades may be additive or multiplicitive; this is not inherent in
364 the codebook, but set in the code using the codebook. Like
365 interleaving, it's easiest to do it here.
366 addmul==0 -> declarative (set the value)
367 addmul==1 -> additive
368 addmul==2 -> multiplicitive */
370 /* returns the [original, not compacted] entry number or -1 on eof *********/
371 long vorbis_book_decode(codebook
*book
, oggpack_buffer
*b
){
372 if(book
->used_entries
>0){
373 long packed_entry
=decode_packed_entry_number(book
,b
);
375 return(book
->dec_index
[packed_entry
]);
378 /* if there's no dec_index, the codebook unpacking isn't collapsed */
382 /* returns 0 on OK or -1 on eof *************************************/
383 long vorbis_book_decodevs_add(codebook
*book
,ogg_int32_t
*a
,
384 oggpack_buffer
*b
,int n
,int point
){
385 if(book
->used_entries
>0){
386 int step
=n
/book
->dim
;
387 long *entry
= (long *)alloca(sizeof(*entry
)*step
);
388 ogg_int32_t
**t
= (ogg_int32_t
**)alloca(sizeof(*t
)*step
);
390 int shift
=point
-book
->binarypoint
;
393 for (i
= 0; i
< step
; i
++) {
394 entry
[i
]=decode_packed_entry_number(book
,b
);
395 if(entry
[i
]==-1)return(-1);
396 t
[i
] = book
->valuelist
+entry
[i
]*book
->dim
;
398 for(i
=0,o
=0;i
<book
->dim
;i
++,o
+=step
)
400 a
[o
+j
]+=t
[j
][i
]>>shift
;
402 for (i
= 0; i
< step
; i
++) {
403 entry
[i
]=decode_packed_entry_number(book
,b
);
404 if(entry
[i
]==-1)return(-1);
405 t
[i
] = book
->valuelist
+entry
[i
]*book
->dim
;
407 for(i
=0,o
=0;i
<book
->dim
;i
++,o
+=step
)
409 a
[o
+j
]+=t
[j
][i
]<<-shift
;
415 long vorbis_book_decodev_add(codebook
*book
,ogg_int32_t
*a
,
416 oggpack_buffer
*b
,int n
,int point
){
417 if(book
->used_entries
>0){
420 int shift
=point
-book
->binarypoint
;
424 entry
= decode_packed_entry_number(book
,b
);
425 if(entry
==-1)return(-1);
426 t
= book
->valuelist
+entry
*book
->dim
;
427 for (j
=0;j
<book
->dim
;)
428 a
[i
++]+=t
[j
++]>>shift
;
433 entry
= decode_packed_entry_number(book
,b
);
434 if(entry
==-1)return(-1);
435 t
= book
->valuelist
+entry
*book
->dim
;
436 for (j
=0;j
<book
->dim
;)
437 a
[i
++]+=t
[j
++]<<shift
;
444 long vorbis_book_decodev_set(codebook
*book
,ogg_int32_t
*a
,
445 oggpack_buffer
*b
,int n
,int point
){
446 if(book
->used_entries
>0){
449 int shift
=point
-book
->binarypoint
;
454 entry
= decode_packed_entry_number(book
,b
);
455 if(entry
==-1)return(-1);
456 t
= book
->valuelist
+entry
*book
->dim
;
457 for (j
=0;j
<book
->dim
;){
458 a
[i
++]=t
[j
++]>>shift
;
464 entry
= decode_packed_entry_number(book
,b
);
465 if(entry
==-1)return(-1);
466 t
= book
->valuelist
+entry
*book
->dim
;
467 for (j
=0;j
<book
->dim
;){
468 a
[i
++]=t
[j
++]<<shift
;
476 for (j
=0;j
<book
->dim
;){
484 static long vorbis_book_decodevv_add_2ch_even(codebook
*book
,ogg_int32_t
**a
,
485 long offset
,oggpack_buffer
*b
,
486 unsigned int n
,int point
){
488 int shift
=point
-book
->binarypoint
;
490 ogg_int32_t
*p0
= &(a
[0][offset
]);
491 ogg_int32_t
*p1
= &(a
[1][offset
]);
492 const unsigned long dim
= book
->dim
;
493 const ogg_int32_t
* const vlist
= book
->valuelist
;
499 chunk
=(n
*2-1)/dim
+ 1;
500 read
= decode_packed_block(book
,b
,entries
,chunk
);
502 const ogg_int32_t
*t
= vlist
+entries
[k
]*dim
;
503 const ogg_int32_t
*u
= t
+dim
;
505 *p0
++ += *t
++>>shift
;
506 *p1
++ += *t
++>>shift
;
509 if (read
<chunk
)return-1;
517 chunk
=(n
*2-1)/dim
+ 1;
518 read
= decode_packed_block(book
,b
,entries
,chunk
);
520 const ogg_int32_t
*t
= vlist
+entries
[k
]*dim
;
521 const ogg_int32_t
*u
= t
+dim
;
523 *p0
++ += *t
++<<shift
;
524 *p1
++ += *t
++<<shift
;
527 if (read
<chunk
)return-1;
534 long vorbis_book_decodevv_add(codebook
*book
,ogg_int32_t
**a
,
536 oggpack_buffer
*b
,int n
,int point
){
537 if(LIKELY(book
->used_entries
>0)){
538 long i
,j
,k
,chunk
,read
;
540 int shift
=point
-book
->binarypoint
;
543 if (!(book
->dim
&1) && ch
==2)
544 return vorbis_book_decodevv_add_2ch_even(book
,a
,offset
,b
,n
,point
);
548 for(i
=offset
;i
<offset
+n
;){
550 if (chunk
*book
->dim
>(offset
+n
-i
)*ch
)
551 chunk
=((offset
+n
-i
)*ch
+book
->dim
-1)/book
->dim
;
552 read
= decode_packed_block(book
,b
,entries
,chunk
);
554 const ogg_int32_t
*t
= book
->valuelist
+entries
[k
]*book
->dim
;
555 for (j
=0;j
<book
->dim
;j
++){
556 a
[chptr
++][i
]+=t
[j
]>>shift
;
563 if (read
<chunk
)return-1;
567 for(i
=offset
;i
<offset
+n
;){
569 if (chunk
*book
->dim
>(offset
+n
-i
)*ch
)
570 chunk
=((offset
+n
-i
)*ch
+book
->dim
-1)/book
->dim
;
571 read
= decode_packed_block(book
,b
,entries
,chunk
);
573 const ogg_int32_t
*t
= book
->valuelist
+entries
[k
]*book
->dim
;
574 for (j
=0;j
<book
->dim
;j
++){
575 a
[chptr
++][i
]+=t
[j
]<<shift
;
582 if (read
<chunk
)return-1;