1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: maintain the info structure, info <-> header packets
15 last mod: $Id: info.c,v 1.17 2000/01/22 13:28:21 xiphmont Exp $
17 ********************************************************************/
19 /* general handling of the header and the vorbis_info structure (and
24 #include "vorbis/codec.h"
26 #include "bookinternal.h"
33 static int ilog2(unsigned int v){
42 static void _v_writestring(oggpack_buffer *o,char *s){
44 _oggpack_write(o,*s++,8);
48 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
50 *buf++=_oggpack_read(o,8);
54 /* convenience functions for the interface */
55 int vorbis_dsp_addcomment(vorbis_dsp_state *v,char *comment){
56 vorbis_info *vi=v->vi;
57 vi->user_comments=realloc(vi->user_comments,
58 (vi->comments+2)*sizeof(char *));
59 vi->user_comments[vi->comments]=strdup(comment);
61 vi->user_comments[vi->comments]=NULL;
65 /* used by analysis, which has a minimally replicated vi */
66 void _vorbis_info_anrep(vorbis_info *dest, vorbis_info *source){
68 /* libVorbis expects modes to be submitted in an already valid
69 vorbis_info structure, but also expects some of the elements to be
70 allocated storage. To make this easier, the Vorbis distribution
71 includes a number of modes in static storage as headers. To
72 allocate a copy, run it through vorbis_info_dup */
74 /* note that due to codebook size, codebooks are not fully duplicated.
75 The info structure (aside from the embedded codebook elements) will
78 int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){
80 memcpy(dest,source,sizeof(vorbis_info));
82 /* also dup individual pieces that need to be allocated */
83 /* dup user comments (unlikely to have any, but for completeness */
84 if(source->comments>0){
85 dest->user_comments=calloc(source->comments+1,sizeof(char *));
86 for(i=0;i<source->comments;i++)
87 dest->user_comments[i]=strdup(source->user_comments[i]);
91 /* modes, maps, times, floors, residues, psychoacoustics are not
92 dupped; the pointer is just replicated by the above copy */
94 /* dup (partially) books */
96 dest->booklist=malloc(source->books*sizeof(codebook *));
97 for(i=0;i<source->books;i++){
98 dest->booklist[i]=calloc(1,sizeof(codebook));
99 vorbis_book_dup(dest->booklist[i],source->booklist[i]);
105 vorbis_info_clear(dest);
110 memset(vi,0,sizeof(vorbis_info));
113 void vorbis_info_anclear(vorbis_info *vi){
114 memset(vi,0,sizeof(vorbis_info));
119 /* used by synthesis, which has a full, alloced vi */
120 void vorbis_info_init(vorbis_info *vi){
121 memset(vi,0,sizeof(vorbis_info));
124 void vorbis_info_clear(vorbis_info *vi){
127 for(i=0;i<vi->comments;i++)
128 if(vi->user_comments[i])free(vi->user_comments[i]);
129 free(vi->user_comments);
131 if(vi->vendor)free(vi->vendor);
132 if(vi->windowtypes)free(vi->windowtypes);
133 if(vi->transformtypes)free(vi->transformtypes);
135 for(i=0;i<vi->modes;i++)
136 if(vi->mappingtypes[i]>=0 && vi->mappingtypes[i]<VI_MAPB)
137 vorbis_map_free_P[vi->mappingtypes[i]](vi->modelist[i]);
139 free(vi->mappingtypes);
140 free(vi->blockflags);
143 for(i=0;i<vi->times;i++)
144 if(vi->timetypes[i]>=0 && vi->timetypes[i]<VI_TIMEB)
145 vorbis_time_free_P[vi->timetypes[i]](vi->timelist[i]);
150 for(i=0;i<vi->floors;i++)
151 if(vi->floortypes[i]>=0 && vi->floortypes[i]<VI_FLOORB)
152 vorbis_floor_free_P[vi->floortypes[i]](vi->floorlist[i]);
154 free(vi->floortypes);
157 for(i=0;i<vi->residues;i++)
158 if(vi->residuetypes[i]>=0 && vi->residuetypes[i]<VI_RESB)
159 vorbis_res_free_P[vi->residuetypes[i]](vi->residuelist[i]);
160 free(vi->residuelist);
161 free(vi->residuetypes);
164 for(i=0;i<vi->books;i++){
166 vorbis_book_clear(vi->booklist[i]);
167 free(vi->booklist[i]);
173 for(i=0;i<vi->psys;i++)
174 _vi_psy_free(vi->psylist[i]);
178 if(vi->header)free(vi->header);
179 if(vi->header1)free(vi->header1);
180 if(vi->header2)free(vi->header2);
182 memset(vi,0,sizeof(vorbis_info));
185 /* Header packing/unpacking ********************************************/
187 static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
188 vi->version=_oggpack_read(opb,32);
189 if(vi->version!=0)return(-1);
191 vi->channels=_oggpack_read(opb,8);
192 vi->rate=_oggpack_read(opb,32);
194 vi->bitrate_upper=_oggpack_read(opb,32);
195 vi->bitrate_nominal=_oggpack_read(opb,32);
196 vi->bitrate_lower=_oggpack_read(opb,32);
198 vi->blocksizes[0]=1<<_oggpack_read(opb,4);
199 vi->blocksizes[1]=1<<_oggpack_read(opb,4);
201 if(vi->rate<1)goto err_out;
202 if(vi->channels<1)goto err_out;
203 if(vi->blocksizes[0]<8)goto err_out;
204 if(vi->blocksizes[1]<vi->blocksizes[0])goto err_out;
206 if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
210 vorbis_info_clear(vi);
214 static int _vorbis_unpack_comments(vorbis_info *vi,oggpack_buffer *opb){
216 int vendorlen=_oggpack_read(opb,32);
217 if(vendorlen<0)goto err_out;
218 vi->vendor=calloc(vendorlen+1,1);
219 _v_readstring(opb,vi->vendor,vendorlen);
220 vi->comments=_oggpack_read(opb,32);
221 if(vi->comments<0)goto err_out;
222 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
224 for(i=0;i<vi->comments;i++){
225 int len=_oggpack_read(opb,32);
226 if(len<0)goto err_out;
227 vi->user_comments[i]=calloc(len+1,1);
228 _v_readstring(opb,vi->user_comments[i],len);
230 if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
234 vorbis_info_clear(vi);
238 /* all of the real encoding details are here. The modes, books,
240 static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
243 /* time backend settings */
244 vi->times=_oggpack_read(opb,8);
245 vi->timetypes=malloc(vi->times*sizeof(int));
246 vi->timelist=calloc(vi->times,sizeof(void *));
247 for(i=0;i<vi->times;i++){
248 vi->timetypes[i]=_oggpack_read(opb,16);
249 if(vi->timetypes[i]<0 || vi->timetypes[i]>VI_TIMEB)goto err_out;
250 vi->timelist[i]=vorbis_time_unpack_P[vi->timetypes[i]](vi,opb);
251 if(!vi->timelist[i])goto err_out;
254 /* floor backend settings */
255 vi->floors=_oggpack_read(opb,8);
256 vi->floortypes=malloc(vi->floors*sizeof(int));
257 vi->floorlist=calloc(vi->floors,sizeof(void *));
258 for(i=0;i<vi->floors;i++){
259 vi->floortypes[i]=_oggpack_read(opb,16);
260 if(vi->floortypes[i]<0 || vi->floortypes[i]>VI_FLOORB)goto err_out;
261 vi->floorlist[i]=vorbis_floor_unpack_P[vi->floortypes[i]](vi,opb);
262 if(!vi->floorlist[i])goto err_out;
265 /* residue backend settings */
266 vi->residues=_oggpack_read(opb,8);
267 vi->residuetypes=malloc(vi->residues*sizeof(int));
268 vi->residuelist=calloc(vi->residues,sizeof(void *));
269 for(i=0;i<vi->residues;i++){
270 vi->residuetypes[i]=_oggpack_read(opb,16);
271 if(vi->residuetypes[i]<0 || vi->residuetypes[i]>VI_RESB)goto err_out;
272 vi->residuelist[i]=vorbis_res_unpack_P[vi->residuetypes[i]](vi,opb);
273 if(!vi->residuelist[i])goto err_out;
277 vi->books=_oggpack_read(opb,16);
278 vi->booklist=calloc(vi->books,sizeof(codebook *));
279 for(i=0;i<vi->books;i++){
280 vi->booklist[i]=calloc(1,sizeof(codebook));
281 if(vorbis_book_unpack(opb,vi->booklist[i]))goto err_out;
284 /* modes/mappings; these are loaded last in order that the mappings
285 can range-check their time/floor/res/book settings */
286 vi->modes=_oggpack_read(opb,8);
287 vi->blockflags=malloc(vi->modes*sizeof(int));
288 vi->windowtypes=malloc(vi->modes*sizeof(int));
289 vi->transformtypes=malloc(vi->modes*sizeof(int));
290 vi->mappingtypes=malloc(vi->modes*sizeof(int));
291 vi->modelist=calloc(vi->modes,sizeof(void *));
292 for(i=0;i<vi->modes;i++){
293 vi->blockflags[i]=_oggpack_read(opb,1);
294 vi->windowtypes[i]=_oggpack_read(opb,16);
295 vi->transformtypes[i]=_oggpack_read(opb,16);
296 vi->mappingtypes[i]=_oggpack_read(opb,16);
297 if(vi->windowtypes[i]<0 || vi->windowtypes[i]>VI_WINDOWB)goto err_out;
298 if(vi->transformtypes[i]<0 || vi->transformtypes[i]>VI_TRANSFORMB)goto err_out;
299 if(vi->mappingtypes[i]<0 || vi->mappingtypes[i]>VI_MAPB)goto err_out;
300 vi->modelist[i]=vorbis_map_unpack_P[vi->mappingtypes[i]](vi,opb);
301 if(!vi->modelist[i])goto err_out;
304 if(_oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
308 vorbis_info_clear(vi);
312 /* The Vorbis header is in three packets; the initial small packet in
313 the first page that identifies basic parameters, a second packet
314 with bitstream comments and a third packet that holds the
317 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
322 _oggpack_readinit(&opb,op->packet,op->bytes);
324 /* Which of the three types of header is this? */
325 /* Also verify header-ness, vorbis */
329 _v_readstring(&opb,buffer,6);
330 if(memcmp(buffer,"vorbis",6)){
331 /* not a vorbis header */
334 switch(_oggpack_read(&opb,8)){
337 /* Not the initial packet */
341 /* previously initialized info header */
345 return(_vorbis_unpack_info(vi,&opb));
349 /* um... we didn't get the initial header */
353 return(_vorbis_unpack_comments(vi,&opb));
356 if(vi->rate==0 || vi->vendor==NULL){
357 /* um... we didn;t get the initial header or comments yet */
361 return(_vorbis_unpack_books(vi,&opb));
364 /* Not a valid vorbis header type */
373 /* pack side **********************************************************/
375 static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
377 _v_writestring(opb,"vorbis");
378 _oggpack_write(opb,0x80,8);
380 /* basic information about the stream */
381 _oggpack_write(opb,0x00,32);
382 _oggpack_write(opb,vi->channels,8);
383 _oggpack_write(opb,vi->rate,32);
385 _oggpack_write(opb,vi->bitrate_upper,32);
386 _oggpack_write(opb,vi->bitrate_nominal,32);
387 _oggpack_write(opb,vi->bitrate_lower,32);
389 _oggpack_write(opb,ilog2(vi->blocksizes[0]),4);
390 _oggpack_write(opb,ilog2(vi->blocksizes[1]),4);
391 _oggpack_write(opb,1,1);
396 static int _vorbis_pack_comments(oggpack_buffer *opb,vorbis_info *vi){
397 char temp[]="Xiphophorus libVorbis I 20000114";
400 _v_writestring(opb,"vorbis");
401 _oggpack_write(opb,0x81,8);
404 _oggpack_write(opb,strlen(temp),32);
405 _v_writestring(opb,temp);
409 _oggpack_write(opb,vi->comments,32);
412 for(i=0;i<vi->comments;i++){
413 if(vi->user_comments[i]){
414 _oggpack_write(opb,strlen(vi->user_comments[i]),32);
415 _v_writestring(opb,vi->user_comments[i]);
417 _oggpack_write(opb,0,32);
421 _oggpack_write(opb,1,1);
426 static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
428 _v_writestring(opb,"vorbis");
429 _oggpack_write(opb,0x82,8);
432 _oggpack_write(opb,vi->times,8);
433 for(i=0;i<vi->times;i++){
434 _oggpack_write(opb,vi->timetypes[i],16);
435 vorbis_time_pack_P[vi->timetypes[i]](opb,vi->timelist[i]);
439 _oggpack_write(opb,vi->floors,8);
440 for(i=0;i<vi->floors;i++){
441 _oggpack_write(opb,vi->floortypes[i],16);
442 vorbis_floor_pack_P[vi->floortypes[i]](opb,vi->floorlist[i]);
446 _oggpack_write(opb,vi->residues,8);
447 for(i=0;i<vi->residues;i++){
448 _oggpack_write(opb,vi->residuetypes[i],16);
449 vorbis_res_pack_P[vi->residuetypes[i]](opb,vi->residuelist[i]);
453 _oggpack_write(opb,vi->books,16);
454 for(i=0;i<vi->books;i++)
455 if(vorbis_book_pack(vi->booklist[i],opb))goto err_out;
459 _oggpack_write(opb,vi->modes,8);
460 for(i=0;i<vi->modes;i++){
461 _oggpack_write(opb,vi->blockflags[i],1);
462 _oggpack_write(opb,vi->windowtypes[i],16);
463 _oggpack_write(opb,vi->transformtypes[i],16);
464 _oggpack_write(opb,vi->mappingtypes[i],16);
465 vorbis_map_pack_P[vi->mappingtypes[i]](vi,opb,vi->modelist[i]);
468 _oggpack_write(opb,1,1);
475 int vorbis_analysis_headerout(vorbis_dsp_state *v,
478 ogg_packet *op_code){
479 vorbis_info *vi=v->vi;
482 /* first header packet **********************************************/
484 _oggpack_writeinit(&opb);
485 if(_vorbis_pack_info(&opb,vi))goto err_out;
487 /* build the packet */
488 if(v->header)free(v->header);
489 v->header=malloc(_oggpack_bytes(&opb));
490 memcpy(v->header,opb.buffer,_oggpack_bytes(&opb));
491 op->packet=v->header;
492 op->bytes=_oggpack_bytes(&opb);
497 /* second header packet (comments) **********************************/
499 _oggpack_reset(&opb);
500 _v_writestring(&opb,"vorbis");
501 _oggpack_write(&opb,0x81,8);
502 if(_vorbis_pack_comments(&opb,vi))goto err_out;
504 if(v->header1)free(v->header1);
505 v->header1=malloc(_oggpack_bytes(&opb));
506 memcpy(v->header1,opb.buffer,_oggpack_bytes(&opb));
507 op_comm->packet=v->header1;
508 op_comm->bytes=_oggpack_bytes(&opb);
513 /* third header packet (modes/codebooks) ****************************/
515 _oggpack_reset(&opb);
516 _v_writestring(&opb,"vorbis");
517 _oggpack_write(&opb,0x82,8);
518 if(_vorbis_pack_books(&opb,vi))goto err_out;
520 if(v->header2)free(v->header2);
521 v->header2=malloc(_oggpack_bytes(&opb));
522 memcpy(v->header2,opb.buffer,_oggpack_bytes(&opb));
523 op_code->packet=v->header2;
524 op_code->bytes=_oggpack_bytes(&opb);
529 _oggpack_writeclear(&opb);
532 _oggpack_writeclear(&opb);
533 memset(op,0,sizeof(ogg_packet));
534 memset(op_comm,0,sizeof(ogg_packet));
535 memset(op_code,0,sizeof(ogg_packet));