diff options
Diffstat (limited to 'lib/rbcodec/codecs/libtremor/info.c')
-rw-r--r-- | lib/rbcodec/codecs/libtremor/info.c | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libtremor/info.c b/lib/rbcodec/codecs/libtremor/info.c new file mode 100644 index 0000000000..d922711e34 --- /dev/null +++ b/lib/rbcodec/codecs/libtremor/info.c | |||
@@ -0,0 +1,330 @@ | |||
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-2003 * | ||
10 | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * | ||
11 | * * | ||
12 | ******************************************************************** | ||
13 | |||
14 | function: maintain the info structure, info <-> header packets | ||
15 | |||
16 | ********************************************************************/ | ||
17 | |||
18 | /* general handling of the header and the vorbis_info structure (and | ||
19 | substructures) */ | ||
20 | |||
21 | #include "config-tremor.h" | ||
22 | #include <string.h> | ||
23 | #include <ctype.h> | ||
24 | #include "ogg.h" | ||
25 | #include "ivorbiscodec.h" | ||
26 | #include "codec_internal.h" | ||
27 | #include "codebook.h" | ||
28 | #include "registry.h" | ||
29 | #include "window.h" | ||
30 | #include "misc.h" | ||
31 | #include "os.h" | ||
32 | |||
33 | /* helpers */ | ||
34 | static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ | ||
35 | while(bytes--){ | ||
36 | *buf++=oggpack_read(o,8); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | void vorbis_comment_init(vorbis_comment *vc){ | ||
42 | memset(vc,0,sizeof(*vc)); | ||
43 | } | ||
44 | |||
45 | void vorbis_comment_clear(vorbis_comment *vc){ | ||
46 | if(vc){ | ||
47 | long i; | ||
48 | if(vc->user_comments){ | ||
49 | for(i=0;i<vc->comments;i++) | ||
50 | if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); | ||
51 | _ogg_free(vc->user_comments); | ||
52 | } | ||
53 | if(vc->comment_lengths)_ogg_free(vc->comment_lengths); | ||
54 | if(vc->vendor)_ogg_free(vc->vendor); | ||
55 | memset(vc,0,sizeof(*vc)); | ||
56 | } | ||
57 | } | ||
58 | */ | ||
59 | |||
60 | /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. | ||
61 | They may be equal, but short will never ge greater than long */ | ||
62 | int vorbis_info_blocksize(vorbis_info *vi,int zo){ | ||
63 | codec_setup_info *ci = (codec_setup_info *)vi->codec_setup; | ||
64 | return ci ? ci->blocksizes[zo] : -1; | ||
65 | } | ||
66 | |||
67 | /* used by synthesis, which has a full, alloced vi */ | ||
68 | void vorbis_info_init(vorbis_info *vi){ | ||
69 | memset(vi,0,sizeof(*vi)); | ||
70 | vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info)); | ||
71 | } | ||
72 | |||
73 | void vorbis_info_clear(vorbis_info *vi){ | ||
74 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | ||
75 | int i; | ||
76 | |||
77 | if(ci){ | ||
78 | |||
79 | for(i=0;i<ci->modes;i++) | ||
80 | if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); | ||
81 | |||
82 | for(i=0;i<ci->maps;i++) /* unpack does the range checking */ | ||
83 | if(ci->map_param[i]) | ||
84 | _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); | ||
85 | |||
86 | for(i=0;i<ci->floors;i++) /* unpack does the range checking */ | ||
87 | if(ci->floor_param[i]) | ||
88 | _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); | ||
89 | |||
90 | for(i=0;i<ci->residues;i++) /* unpack does the range checking */ | ||
91 | if(ci->residue_param[i]) | ||
92 | _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); | ||
93 | |||
94 | for(i=0;i<ci->books;i++){ | ||
95 | if(ci->book_param[i]){ | ||
96 | /* knows if the book was not alloced */ | ||
97 | vorbis_staticbook_destroy(ci->book_param[i]); | ||
98 | } | ||
99 | if(ci->fullbooks) | ||
100 | vorbis_book_clear(ci->fullbooks+i); | ||
101 | } | ||
102 | if(ci->fullbooks) | ||
103 | _ogg_free(ci->fullbooks); | ||
104 | |||
105 | _ogg_free(ci); | ||
106 | } | ||
107 | |||
108 | memset(vi,0,sizeof(*vi)); | ||
109 | } | ||
110 | |||
111 | /* Header packing/unpacking ********************************************/ | ||
112 | |||
113 | static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ | ||
114 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | ||
115 | if(!ci)return(OV_EFAULT); | ||
116 | |||
117 | vi->version=oggpack_read(opb,32); | ||
118 | if(vi->version!=0)return(OV_EVERSION); | ||
119 | |||
120 | vi->channels=oggpack_read(opb,8); | ||
121 | vi->rate=oggpack_read(opb,32); | ||
122 | |||
123 | vi->bitrate_upper=oggpack_read(opb,32); | ||
124 | vi->bitrate_nominal=oggpack_read(opb,32); | ||
125 | vi->bitrate_lower=oggpack_read(opb,32); | ||
126 | |||
127 | ci->blocksizes_nbits[0]=oggpack_read(opb,4); | ||
128 | ci->blocksizes_nbits[1]=oggpack_read(opb,4); | ||
129 | ci->blocksizes[0]=1<<(ci->blocksizes_nbits[0]); | ||
130 | ci->blocksizes[1]=1<<(ci->blocksizes_nbits[1]); | ||
131 | |||
132 | if(vi->rate<1)goto err_out; | ||
133 | if(vi->channels<1)goto err_out; | ||
134 | if(ci->blocksizes[0]<64)goto err_out; | ||
135 | if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out; | ||
136 | if(ci->blocksizes[1]>8192)goto err_out; | ||
137 | |||
138 | if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ | ||
139 | |||
140 | return(0); | ||
141 | err_out: | ||
142 | vorbis_info_clear(vi); | ||
143 | return(OV_EBADHEADER); | ||
144 | } | ||
145 | |||
146 | #if 0 | ||
147 | static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ | ||
148 | int vendorlen; | ||
149 | vendorlen=oggpack_read(opb,32); | ||
150 | if(vendorlen<0)goto err_out; | ||
151 | if(vendorlen>opb->storage-oggpack_bytes(opb))goto err_out; | ||
152 | vc->vendor=(char *)_ogg_calloc(vendorlen+1,1); | ||
153 | if(vc->vendor==NULL)goto err_out; | ||
154 | _v_readstring(opb,vc->vendor,vendorlen); | ||
155 | vc->comments=0; | ||
156 | /* ROCKBOX: the meat of this function was deleted as we don't need it */ | ||
157 | return(0); | ||
158 | err_out: | ||
159 | vorbis_comment_clear(vc); | ||
160 | return(OV_EBADHEADER); | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | /* all of the real encoding details are here. The modes, books, | ||
165 | everything */ | ||
166 | static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ | ||
167 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | ||
168 | int i; | ||
169 | if(!ci)return(OV_EFAULT); | ||
170 | |||
171 | /* codebooks */ | ||
172 | ci->books=oggpack_read(opb,8)+1; | ||
173 | if(ci->books<=0)goto err_out; | ||
174 | for(i=0;i<ci->books;i++){ | ||
175 | ci->book_param[i]=vorbis_staticbook_unpack(opb); | ||
176 | if(!ci->book_param[i])goto err_out; | ||
177 | } | ||
178 | |||
179 | /* time backend settings */ | ||
180 | ci->times=oggpack_read(opb,6)+1; | ||
181 | if(ci->times<=0)goto err_out; | ||
182 | for(i=0;i<ci->times;i++){ | ||
183 | ci->time_type[i]=oggpack_read(opb,16); | ||
184 | if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out; | ||
185 | /* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb); | ||
186 | Vorbis I has no time backend */ | ||
187 | /*if(!ci->time_param[i])goto err_out;*/ | ||
188 | } | ||
189 | |||
190 | /* floor backend settings */ | ||
191 | ci->floors=oggpack_read(opb,6)+1; | ||
192 | if(ci->floors<=0)goto err_out; | ||
193 | for(i=0;i<ci->floors;i++){ | ||
194 | ci->floor_type[i]=oggpack_read(opb,16); | ||
195 | if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; | ||
196 | ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); | ||
197 | if(!ci->floor_param[i])goto err_out; | ||
198 | } | ||
199 | |||
200 | /* residue backend settings */ | ||
201 | ci->residues=oggpack_read(opb,6)+1; | ||
202 | if(ci->residues<=0)goto err_out; | ||
203 | for(i=0;i<ci->residues;i++){ | ||
204 | ci->residue_type[i]=oggpack_read(opb,16); | ||
205 | if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; | ||
206 | ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); | ||
207 | if(!ci->residue_param[i])goto err_out; | ||
208 | } | ||
209 | |||
210 | /* map backend settings */ | ||
211 | ci->maps=oggpack_read(opb,6)+1; | ||
212 | if(ci->maps<=0)goto err_out; | ||
213 | for(i=0;i<ci->maps;i++){ | ||
214 | ci->map_type[i]=oggpack_read(opb,16); | ||
215 | if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; | ||
216 | ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); | ||
217 | if(!ci->map_param[i])goto err_out; | ||
218 | } | ||
219 | |||
220 | /* mode settings */ | ||
221 | ci->modes=oggpack_read(opb,6)+1; | ||
222 | if(ci->modes<=0)goto err_out; | ||
223 | for(i=0;i<ci->modes;i++){ | ||
224 | ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i])); | ||
225 | ci->mode_param[i]->blockflag=oggpack_read(opb,1); | ||
226 | ci->mode_param[i]->windowtype=oggpack_read(opb,16); | ||
227 | ci->mode_param[i]->transformtype=oggpack_read(opb,16); | ||
228 | ci->mode_param[i]->mapping=oggpack_read(opb,8); | ||
229 | |||
230 | if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; | ||
231 | if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; | ||
232 | if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; | ||
233 | if(ci->mode_param[i]->mapping<0)goto err_out; | ||
234 | } | ||
235 | |||
236 | if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ | ||
237 | |||
238 | return(0); | ||
239 | err_out: | ||
240 | vorbis_info_clear(vi); | ||
241 | return(OV_EBADHEADER); | ||
242 | } | ||
243 | |||
244 | /* Is this packet a vorbis ID header? */ | ||
245 | int vorbis_synthesis_idheader(ogg_packet *op){ | ||
246 | oggpack_buffer opb; | ||
247 | char buffer[6]; | ||
248 | |||
249 | if(op){ | ||
250 | oggpack_readinit(&opb,op->packet,op->bytes); | ||
251 | |||
252 | if(!op->b_o_s) | ||
253 | return(0); /* Not the initial packet */ | ||
254 | |||
255 | if(oggpack_read(&opb,8) != 1) | ||
256 | return 0; /* not an ID header */ | ||
257 | |||
258 | memset(buffer,0,6); | ||
259 | _v_readstring(&opb,buffer,6); | ||
260 | if(memcmp(buffer,"vorbis",6)) | ||
261 | return 0; /* not vorbis */ | ||
262 | |||
263 | return 1; | ||
264 | } | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | /* The Vorbis header is in three packets; the initial small packet in | ||
270 | the first page that identifies basic parameters, a second packet | ||
271 | with bitstream comments and a third packet that holds the | ||
272 | codebook. */ | ||
273 | |||
274 | int vorbis_synthesis_headerin(vorbis_info *vi,ogg_packet *op){ | ||
275 | oggpack_buffer opb; | ||
276 | |||
277 | if(op){ | ||
278 | oggpack_readinit(&opb,op->packet,op->bytes); | ||
279 | |||
280 | /* Which of the three types of header is this? */ | ||
281 | /* Also verify header-ness, vorbis */ | ||
282 | { | ||
283 | char buffer[6]; | ||
284 | int packtype=oggpack_read(&opb,8); | ||
285 | memset(buffer,0,6); | ||
286 | _v_readstring(&opb,buffer,6); | ||
287 | if(memcmp(buffer,"vorbis",6)){ | ||
288 | /* not a vorbis header */ | ||
289 | return(OV_ENOTVORBIS); | ||
290 | } | ||
291 | switch(packtype){ | ||
292 | case 0x01: /* least significant *bit* is read first */ | ||
293 | if(!op->b_o_s){ | ||
294 | /* Not the initial packet */ | ||
295 | return(OV_EBADHEADER); | ||
296 | } | ||
297 | if(vi->rate!=0){ | ||
298 | /* previously initialized info header */ | ||
299 | return(OV_EBADHEADER); | ||
300 | } | ||
301 | |||
302 | return(_vorbis_unpack_info(vi,&opb)); | ||
303 | |||
304 | case 0x03: /* least significant *bit* is read first */ | ||
305 | if(vi->rate==0){ | ||
306 | /* um... we didn't get the initial header */ | ||
307 | return(OV_EBADHEADER); | ||
308 | } | ||
309 | |||
310 | /*return(_vorbis_unpack_comment(vc,&opb));*/ | ||
311 | return 0; | ||
312 | |||
313 | case 0x05: /* least significant *bit* is read first */ | ||
314 | if(vi->rate==0 /*|| vc->vendor==NULL*/){ | ||
315 | /* um... we didn;t get the initial header or comments yet */ | ||
316 | return(OV_EBADHEADER); | ||
317 | } | ||
318 | |||
319 | return(_vorbis_unpack_books(vi,&opb)); | ||
320 | |||
321 | default: | ||
322 | /* Not a valid vorbis header type */ | ||
323 | return(OV_EBADHEADER); | ||
324 | break; | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | return(OV_EBADHEADER); | ||
329 | } | ||
330 | |||