annotate tremor/codebook.c @ 18715:30d7ddf08889

Fix window position when changing videos while in fullscreen and for window managers that modify position on Map. Oked by Alexander Strasser.
author reimar
date Thu, 15 Jun 2006 08:00:37 +0000
parents 8631a3803289
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 codebook pack/unpack/code/decode 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 <string.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
17 #include <math.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 "ivorbiscodec.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
20 #include "codebook.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
21 #include "misc.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
22 #include "os.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 /* unpacks a codebook from the packet buffer into the codebook struct,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
25 readies the codebook auxiliary structures for decode *************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
26 int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
27 long i,j;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
28 memset(s,0,sizeof(*s));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30 /* make sure alignment is correct */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33 /* first the basic parameters */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 s->dim=oggpack_read(opb,16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35 s->entries=oggpack_read(opb,24);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 if(s->entries==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38 /* codeword ordering.... length ordered or unordered? */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39 switch((int)oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40 case 0:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41 /* unordered */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44 /* allocated but unused entries? */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45 if(oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46 /* yes, unused entries */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48 for(i=0;i<s->entries;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 if(oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50 long num=oggpack_read(opb,5);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51 if(num==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 s->lengthlist[i]=num+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54 s->lengthlist[i]=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55 }
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 /* all entries used; no tagging */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 for(i=0;i<s->entries;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 long num=oggpack_read(opb,5);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60 if(num==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61 s->lengthlist[i]=num+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 }
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 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 case 1:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67 /* ordered */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69 long length=oggpack_read(opb,5)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 for(i=0;i<s->entries;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73 long num=oggpack_read(opb,_ilog(s->entries-i));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74 if(num==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 for(j=0;j<num && i<s->entries;j++,i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 s->lengthlist[i]=length;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77 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 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 default:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82 /* EOF */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83 return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 /* Do we have a mapping to unpack? */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87 switch((s->maptype=oggpack_read(opb,4))){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88 case 0:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 /* no mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91 case 1: case 2:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92 /* implicitly populated value mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93 /* explicitly populated value mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95 s->q_min=oggpack_read(opb,32);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96 s->q_delta=oggpack_read(opb,32);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97 s->q_quant=oggpack_read(opb,4)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98 s->q_sequencep=oggpack_read(opb,1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 int quantvals=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102 switch(s->maptype){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 case 1:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104 quantvals=_book_maptype1_quantvals(s);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 case 2:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 quantvals=s->entries*s->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
110
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
111 /* quantized values */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113 for(i=0;i<quantvals;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114 s->quantlist[i]=oggpack_read(opb,s->q_quant);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116 if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 }
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 default:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
120 goto _errout;
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 /* all set */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126 _errout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127 _eofout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128 vorbis_staticbook_clear(s);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 return(-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 /* the 'eliminate the decode tree' optimization actually requires the
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133 codewords to be MSb first, not LSb. This is an annoying inelegancy
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134 (and one of the first places where carefully thought out design
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 turned out to be wrong; Vorbis II and future Ogg codecs should go
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136 to an MSb bitpacker), but not actually the huge hit it appears to
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137 be. The first-stage decode table catches most words so that
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138 bitreverse is not in the main execution path. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 static ogg_uint32_t bitreverse(ogg_uint32_t x){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
145 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
146 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
147
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
148 static inline long decode_packed_entry_number(codebook *book,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
149 oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
150 int read=book->dec_maxlength;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
151 long lo,hi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
152 long lok = oggpack_look(b,book->dec_firsttablen);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
153
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
154 if (lok >= 0) {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
155 long entry = book->dec_firsttable[lok];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
156 if(entry&0x80000000UL){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
157 lo=(entry>>15)&0x7fff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
158 hi=book->used_entries-(entry&0x7fff);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
159 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
160 oggpack_adv(b, book->dec_codelengths[entry-1]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
161 return(entry-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
162 }
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 lo=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
165 hi=book->used_entries;
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 lok = oggpack_look(b, read);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
169
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
170 while(lok<0 && read>1)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
171 lok = oggpack_look(b, --read);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
172 if(lok<0)return -1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
173
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
174 /* bisect search for the codeword in the ordered list */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
175 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
176 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
177
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
178 while(hi-lo>1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
179 long p=(hi-lo)>>1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
180 long test=book->codelist[lo+p]>testword;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
181 lo+=p&(test-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
182 hi-=p&(-test);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
183 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
184
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
185 if(book->dec_codelengths[lo]<=read){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
186 oggpack_adv(b, book->dec_codelengths[lo]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
187 return(lo);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
188 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
189 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
190
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
191 oggpack_adv(b, read);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
192 return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
193 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
194
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
195 /* Decode side is specced and easier, because we don't need to find
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
196 matches using different criteria; we simply read and map. There are
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
197 two things we need to do 'depending':
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
198
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
199 We may need to support interleave. We don't really, but it's
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
200 convenient to do it here rather than rebuild the vector later.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
201
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
202 Cascades may be additive or multiplicitive; this is not inherent in
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
203 the codebook, but set in the code using the codebook. Like
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
204 interleaving, it's easiest to do it here.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
205 addmul==0 -> declarative (set the value)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
206 addmul==1 -> additive
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
207 addmul==2 -> multiplicitive */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
208
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
209 /* returns the [original, not compacted] entry number or -1 on eof *********/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
210 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
211 long packed_entry=decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
212 if(packed_entry>=0)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
213 return(book->dec_index[packed_entry]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
214
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
215 /* if there's no dec_index, the codebook unpacking isn't collapsed */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
216 return(packed_entry);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
217 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
218
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
219 /* returns 0 on OK or -1 on eof *************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
220 long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
221 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
222 int step=n/book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
223 long *entry = (long *)alloca(sizeof(*entry)*step);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
224 ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
225 int i,j,o;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
226 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
227
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
228 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
229 for (i = 0; i < step; i++) {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
230 entry[i]=decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
231 if(entry[i]==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
232 t[i] = book->valuelist+entry[i]*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
233 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
234 for(i=0,o=0;i<book->dim;i++,o+=step)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
235 for (j=0;j<step;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
236 a[o+j]+=t[j][i]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
237 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
238 for (i = 0; i < step; i++) {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
239 entry[i]=decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
240 if(entry[i]==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
241 t[i] = book->valuelist+entry[i]*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
242 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
243 for(i=0,o=0;i<book->dim;i++,o+=step)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
244 for (j=0;j<step;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
245 a[o+j]+=t[j][i]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
246 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
247 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
248 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
249
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
250 long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
251 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
252 int i,j,entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
253 ogg_int32_t *t;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
254 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
255
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
256 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
257 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
258 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
259 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
260 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
261 for (j=0;j<book->dim;)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
262 a[i++]+=t[j++]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
263 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
264 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
265 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
266 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
267 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
268 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
269 for (j=0;j<book->dim;)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
270 a[i++]+=t[j++]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
271 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
272 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
273 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
274 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
275
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
276 long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
277 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
278 int i,j,entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
279 ogg_int32_t *t;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
280 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
281
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
282 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
283
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
284 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
285 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
286 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
287 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
288 for (j=0;j<book->dim;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
289 a[i++]=t[j++]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
290 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
291 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
292 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
293
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
294 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
295 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
296 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
297 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
298 for (j=0;j<book->dim;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
299 a[i++]=t[j++]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
300 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
301 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
302 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
303 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
304 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
305
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
306 long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
307 long offset,int ch,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
308 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
309 long i,j,entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
310 int chptr=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
311 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
312
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
313 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
314
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
315 for(i=offset;i<offset+n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
316 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
317 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
318 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
319 const ogg_int32_t *t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
320 for (j=0;j<book->dim;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
321 a[chptr++][i]+=t[j]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
322 if(chptr==ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
323 chptr=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
324 i++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
325 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
326 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
327 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
328 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
329 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
330
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
331 for(i=offset;i<offset+n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
332 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
333 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
334 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
335 const ogg_int32_t *t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
336 for (j=0;j<book->dim;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
337 a[chptr++][i]+=t[j]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
338 if(chptr==ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
339 chptr=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
340 i++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
341 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
342 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
343 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
344 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
345 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
346 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
347 }