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.16 2000/01/20 04:42:55 xiphmont Exp $
17 ********************************************************************/
19 /* general handling of the header and the vorbis_info structure (and
24 #include "vorbis/codec.h"
26 #include "bookinternal.h"
32 static int ilog2(unsigned int v){
41 static void _v_writestring(oggpack_buffer *o,char *s){
43 _oggpack_write(o,*s++,8);
47 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
49 *buf++=_oggpack_read(o,8);
53 /* convenience functions for the interface */
54 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
55 vi->user_comments=realloc(vi->user_comments,
56 (vi->comments+2)*sizeof(char *));
57 vi->user_comments[vi->comments]=strdup(comment);
59 vi->user_comments[vi->comments]=NULL;
63 int vorbis_info_addvendor(vorbis_info *vi,char *vendor){
64 if(vi->vendor)free(vi->vendor);
65 vi->vendor=strdup(vendor);
69 /* libVorbis expects modes to be submitted in an already valid
70 vorbis_info structure, but also expects some of the elements to be
71 allocated storage. To make this easier, the Vorbis distribution
72 includes a number of modes in static storage as headers. To
73 allocate a copy, run it through vorbis_info_dup */
75 /* note that due to codebook size, codebooks are not fully duplicated.
76 The info structure (aside from the embedded codebook elements) will
79 int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){
81 memcpy(dest,source,sizeof(vorbis_info));
83 /* also dup individual pieces that need to be allocated */
84 /* dup user comments (unlikely to have any, but for completeness */
85 if(source->comments>0){
86 dest->user_comments=calloc(source->comments+1,sizeof(char *));
87 for(i=0;i<source->comments;i++)
88 dest->user_comments[i]=strdup(source->user_comments[i]);
92 dest->vendor=strdup(source->vendor);
94 /* dup mode maps, blockflags and map types */
96 dest->blockflags=malloc(source->modes*sizeof(int));
97 dest->windowtypes=malloc(source->modes*sizeof(int));
98 dest->transformtypes=malloc(source->modes*sizeof(int));
99 dest->mappingtypes=malloc(source->modes*sizeof(int));
100 dest->modelist=calloc(source->modes,sizeof(void *));
102 memcpy(dest->blockflags,source->blockflags,sizeof(int)*dest->modes);
103 memcpy(dest->windowtypes,source->windowtypes,sizeof(int)*dest->modes);
104 memcpy(dest->transformtypes,source->transformtypes,sizeof(int)*dest->modes);
105 memcpy(dest->mappingtypes,source->mappingtypes,sizeof(int)*dest->modes);
106 for(i=0;i<source->modes;i++){
107 if(dest->mappingtypes[i]<0|| dest->mappingtypes[i]>=VI_MAPB)goto err_out;
109 vorbis_map_dup_P[dest->mappingtypes[i]](source,source->modelist[i]);
115 dest->timetypes=malloc(source->times*sizeof(int));
116 dest->timelist=calloc(source->times,sizeof(void *));
117 memcpy(dest->timetypes,source->timetypes,sizeof(int)*dest->times);
118 for(i=0;i<source->times;i++){
119 if(dest->timetypes[i]<0|| dest->timetypes[i]>=VI_TIMEB)goto err_out;
121 vorbis_time_dup_P[dest->timetypes[i]](source->timelist[i]);
127 dest->floortypes=malloc(source->floors*sizeof(int));
128 dest->floorlist=calloc(source->floors,sizeof(void *));
129 memcpy(dest->floortypes,source->floortypes,sizeof(int)*dest->floors);
130 for(i=0;i<source->floors;i++){
131 if(dest->floortypes[i]<0|| dest->floortypes[i]>=VI_FLOORB)goto err_out;
133 vorbis_floor_dup_P[dest->floortypes[i]](source->floorlist[i]);
138 if(source->residues){
139 dest->residuetypes=malloc(source->residues*sizeof(int));
140 dest->residuelist=calloc(source->residues,sizeof(void *));
141 memcpy(dest->residuetypes,source->residuetypes,sizeof(int)*dest->residues);
142 for(i=0;i<source->residues;i++){
143 if(dest->residuetypes[i]<0|| dest->residuetypes[i]>=VI_RESB)
145 dest->residuelist[i]=
146 vorbis_res_dup_P[dest->residuetypes[i]](source->residuelist[i]);
150 /* dup (partially) books */
152 dest->booklist=malloc(source->books*sizeof(codebook *));
153 for(i=0;i<source->books;i++){
154 dest->booklist[i]=calloc(1,sizeof(codebook));
155 vorbis_book_dup(dest->booklist[i],source->booklist[i]);
159 /* dup psychoacoustics (if any) */
161 dest->psylist=calloc(source->psys,sizeof(void *));
162 for(i=0;i<source->psys;i++){
163 dest->psylist[i]=_vi_psy_dup(source->psylist[i]);
167 /* we do *not* dup local storage */
174 vorbis_info_clear(dest);
178 void vorbis_info_clear(vorbis_info *vi){
181 for(i=0;i<vi->comments;i++)
182 if(vi->user_comments[i])free(vi->user_comments[i]);
183 free(vi->user_comments);
185 if(vi->vendor)free(vi->vendor);
186 if(vi->windowtypes)free(vi->windowtypes);
187 if(vi->transformtypes)free(vi->transformtypes);
189 for(i=0;i<vi->modes;i++)
190 if(vi->mappingtypes[i]>=0 && vi->mappingtypes[i]<VI_MAPB)
191 vorbis_map_free_P[vi->mappingtypes[i]](vi->modelist[i]);
193 free(vi->mappingtypes);
194 free(vi->blockflags);
197 for(i=0;i<vi->times;i++)
198 if(vi->timetypes[i]>=0 && vi->timetypes[i]<VI_TIMEB)
199 vorbis_time_free_P[vi->timetypes[i]](vi->timelist[i]);
204 for(i=0;i<vi->floors;i++)
205 if(vi->floortypes[i]>=0 && vi->floortypes[i]<VI_FLOORB)
206 vorbis_floor_free_P[vi->floortypes[i]](vi->floorlist[i]);
208 free(vi->floortypes);
211 for(i=0;i<vi->residues;i++)
212 if(vi->residuetypes[i]>=0 && vi->residuetypes[i]<VI_RESB)
213 vorbis_res_free_P[vi->residuetypes[i]](vi->residuelist[i]);
214 free(vi->residuelist);
215 free(vi->residuetypes);
218 for(i=0;i<vi->books;i++){
220 vorbis_book_clear(vi->booklist[i]);
221 free(vi->booklist[i]);
227 for(i=0;i<vi->psys;i++)
228 _vi_psy_free(vi->psylist[i]);
232 if(vi->header)free(vi->header);
233 if(vi->header1)free(vi->header1);
234 if(vi->header2)free(vi->header2);
236 memset(vi,0,sizeof(vorbis_info));
239 /* Header packing/unpacking ********************************************/
241 static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
242 vi->version=_oggpack_read(opb,32);
243 if(vi->version!=0)return(-1);
245 vi->channels=_oggpack_read(opb,8);
246 vi->rate=_oggpack_read(opb,32);
248 vi->bitrate_upper=_oggpack_read(opb,32);
249 vi->bitrate_nominal=_oggpack_read(opb,32);
250 vi->bitrate_lower=_oggpack_read(opb,32);
252 vi->blocksizes[0]=1<<_oggpack_read(opb,4);
253 vi->blocksizes[1]=1<<_oggpack_read(opb,4);
255 if(vi->rate<1)goto err_out;
256 if(vi->channels<1)goto err_out;
257 if(vi->blocksizes[0]<8)goto err_out;
258 if(vi->blocksizes[1]<vi->blocksizes[0])goto err_out;
260 if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
264 vorbis_info_clear(vi);
268 static int _vorbis_unpack_comments(vorbis_info *vi,oggpack_buffer *opb){
270 int vendorlen=_oggpack_read(opb,32);
271 if(vendorlen<0)goto err_out;
272 vi->vendor=calloc(vendorlen+1,1);
273 _v_readstring(opb,vi->vendor,vendorlen);
274 vi->comments=_oggpack_read(opb,32);
275 if(vi->comments<0)goto err_out;
276 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
278 for(i=0;i<vi->comments;i++){
279 int len=_oggpack_read(opb,32);
280 if(len<0)goto err_out;
281 vi->user_comments[i]=calloc(len+1,1);
282 _v_readstring(opb,vi->user_comments[i],len);
284 if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
288 vorbis_info_clear(vi);
292 /* all of the real encoding details are here. The modes, books,
294 static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
297 /* time backend settings */
298 vi->times=_oggpack_read(opb,8);
299 vi->timetypes=malloc(vi->times*sizeof(int));
300 vi->timelist=calloc(vi->times,sizeof(void *));
301 for(i=0;i<vi->times;i++){
302 vi->timetypes[i]=_oggpack_read(opb,16);
303 if(vi->timetypes[i]<0 || vi->timetypes[i]>VI_TIMEB)goto err_out;
304 vi->timelist[i]=vorbis_time_unpack_P[vi->timetypes[i]](vi,opb);
305 if(!vi->timelist[i])goto err_out;
308 /* floor backend settings */
309 vi->floors=_oggpack_read(opb,8);
310 vi->floortypes=malloc(vi->floors*sizeof(int));
311 vi->floorlist=calloc(vi->floors,sizeof(void *));
312 for(i=0;i<vi->floors;i++){
313 vi->floortypes[i]=_oggpack_read(opb,16);
314 if(vi->floortypes[i]<0 || vi->floortypes[i]>VI_FLOORB)goto err_out;
315 vi->floorlist[i]=vorbis_floor_unpack_P[vi->floortypes[i]](vi,opb);
316 if(!vi->floorlist[i])goto err_out;
319 /* residue backend settings */
320 vi->residues=_oggpack_read(opb,8);
321 vi->residuetypes=malloc(vi->residues*sizeof(int));
322 vi->residuelist=calloc(vi->residues,sizeof(void *));
323 for(i=0;i<vi->residues;i++){
324 vi->residuetypes[i]=_oggpack_read(opb,16);
325 if(vi->residuetypes[i]<0 || vi->residuetypes[i]>VI_RESB)goto err_out;
326 vi->residuelist[i]=vorbis_res_unpack_P[vi->residuetypes[i]](vi,opb);
327 if(!vi->residuelist[i])goto err_out;
331 vi->books=_oggpack_read(opb,16);
332 vi->booklist=calloc(vi->books,sizeof(codebook *));
333 for(i=0;i<vi->books;i++){
334 vi->booklist[i]=calloc(1,sizeof(codebook));
335 if(vorbis_book_unpack(opb,vi->booklist[i]))goto err_out;
338 /* modes/mappings; these are loaded last in order that the mappings
339 can range-check their time/floor/res/book settings */
340 vi->modes=_oggpack_read(opb,8);
341 vi->blockflags=malloc(vi->modes*sizeof(int));
342 vi->windowtypes=malloc(vi->modes*sizeof(int));
343 vi->transformtypes=malloc(vi->modes*sizeof(int));
344 vi->mappingtypes=malloc(vi->modes*sizeof(int));
345 vi->modelist=calloc(vi->modes,sizeof(void *));
346 for(i=0;i<vi->modes;i++){
347 vi->blockflags[i]=_oggpack_read(opb,1);
348 vi->windowtypes[i]=_oggpack_read(opb,16);
349 vi->transformtypes[i]=_oggpack_read(opb,16);
350 vi->mappingtypes[i]=_oggpack_read(opb,16);
351 if(vi->windowtypes[i]!=0)goto err_out;
352 if(vi->transformtypes[i]!=0)goto err_out;
353 if(vi->mappingtypes[i]<0 || vi->mappingtypes[i]>VI_MAPB)goto err_out;
354 vi->modelist[i]=vorbis_map_unpack_P[vi->mappingtypes[i]](vi,opb);
355 if(!vi->modelist[i])goto err_out;
358 if(_oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
362 vorbis_info_clear(vi);
366 /* The Vorbis header is in three packets; the initial small packet in
367 the first page that identifies basic parameters, a second packet
368 with bitstream comments and a third packet that holds the
371 /* call before header in, or just to zero out uninitialized mem */
372 void vorbis_info_init(vorbis_info *vi){
373 memset(vi,0,sizeof(vorbis_info));
376 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
381 _oggpack_readinit(&opb,op->packet,op->bytes);
383 /* Which of the three types of header is this? */
384 /* Also verify header-ness, vorbis */
388 _v_readstring(&opb,buffer,6);
389 if(memcmp(buffer,"vorbis",6)){
390 /* not a vorbis header */
393 switch(_oggpack_read(&opb,8)){
396 /* Not the initial packet */
400 /* previously initialized info header */
404 return(_vorbis_unpack_info(vi,&opb));
408 /* um... we didn't get the initial header */
412 return(_vorbis_unpack_comments(vi,&opb));
415 if(vi->rate==0 || vi->vendor==NULL){
416 /* um... we didn;t get the initial header or comments yet */
420 return(_vorbis_unpack_books(vi,&opb));
423 /* Not a valid vorbis header type */
432 /* pack side **********************************************************/
434 static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
436 _v_writestring(opb,"vorbis");
437 _oggpack_write(opb,0x80,8);
439 /* basic information about the stream */
440 _oggpack_write(opb,0x00,32);
441 _oggpack_write(opb,vi->channels,8);
442 _oggpack_write(opb,vi->rate,32);
444 _oggpack_write(opb,vi->bitrate_upper,32);
445 _oggpack_write(opb,vi->bitrate_nominal,32);
446 _oggpack_write(opb,vi->bitrate_lower,32);
448 _oggpack_write(opb,ilog2(vi->blocksizes[0]),4);
449 _oggpack_write(opb,ilog2(vi->blocksizes[1]),4);
450 _oggpack_write(opb,1,1);
455 static int _vorbis_pack_comments(oggpack_buffer *opb,vorbis_info *vi){
456 char temp[]="Xiphophorus libVorbis I 20000114";
459 _v_writestring(opb,"vorbis");
460 _oggpack_write(opb,0x81,8);
463 _oggpack_write(opb,strlen(temp),32);
464 _v_writestring(opb,temp);
468 _oggpack_write(opb,vi->comments,32);
471 for(i=0;i<vi->comments;i++){
472 if(vi->user_comments[i]){
473 _oggpack_write(opb,strlen(vi->user_comments[i]),32);
474 _v_writestring(opb,vi->user_comments[i]);
476 _oggpack_write(opb,0,32);
480 _oggpack_write(opb,1,1);
485 static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
487 _v_writestring(opb,"vorbis");
488 _oggpack_write(opb,0x82,8);
491 _oggpack_write(opb,vi->times,8);
492 for(i=0;i<vi->times;i++){
493 _oggpack_write(opb,vi->timetypes[i],16);
494 vorbis_time_pack_P[vi->timetypes[i]](opb,vi->timelist[i]);
498 _oggpack_write(opb,vi->floors,8);
499 for(i=0;i<vi->floors;i++){
500 _oggpack_write(opb,vi->floortypes[i],16);
501 vorbis_floor_pack_P[vi->floortypes[i]](opb,vi->floorlist[i]);
505 _oggpack_write(opb,vi->residues,8);
506 for(i=0;i<vi->residues;i++){
507 _oggpack_write(opb,vi->residuetypes[i],16);
508 vorbis_res_pack_P[vi->residuetypes[i]](opb,vi->residuelist[i]);
512 _oggpack_write(opb,vi->books,16);
513 for(i=0;i<vi->books;i++)
514 if(vorbis_book_pack(vi->booklist[i],opb))goto err_out;
518 _oggpack_write(opb,vi->modes,8);
519 for(i=0;i<vi->modes;i++){
520 _oggpack_write(opb,vi->blockflags[i],1);
521 _oggpack_write(opb,vi->windowtypes[i],16);
522 _oggpack_write(opb,vi->transformtypes[i],16);
523 _oggpack_write(opb,vi->mappingtypes[i],16);
524 vorbis_map_pack_P[vi->mappingtypes[i]](vi,opb,vi->modelist[i]);
527 _oggpack_write(opb,1,1);
534 int vorbis_info_headerout(vorbis_info *vi,
537 ogg_packet *op_code){
541 /* first header packet **********************************************/
543 _oggpack_writeinit(&opb);
544 if(_vorbis_pack_info(&opb,vi))goto err_out;
546 /* build the packet */
547 if(vi->header)free(vi->header);
548 vi->header=malloc(_oggpack_bytes(&opb));
549 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
550 op->packet=vi->header;
551 op->bytes=_oggpack_bytes(&opb);
556 /* second header packet (comments) **********************************/
558 _oggpack_reset(&opb);
559 _v_writestring(&opb,"vorbis");
560 _oggpack_write(&opb,0x81,8);
561 if(_vorbis_pack_comments(&opb,vi))goto err_out;
563 if(vi->header1)free(vi->header1);
564 vi->header1=malloc(_oggpack_bytes(&opb));
565 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
566 op_comm->packet=vi->header1;
567 op_comm->bytes=_oggpack_bytes(&opb);
572 /* third header packet (modes/codebooks) ****************************/
574 _oggpack_reset(&opb);
575 _v_writestring(&opb,"vorbis");
576 _oggpack_write(&opb,0x82,8);
577 if(_vorbis_pack_books(&opb,vi))goto err_out;
579 if(vi->header2)free(vi->header2);
580 vi->header2=malloc(_oggpack_bytes(&opb));
581 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
582 op_code->packet=vi->header2;
583 op_code->bytes=_oggpack_bytes(&opb);
588 _oggpack_writeclear(&opb);
591 _oggpack_writeclear(&opb);
592 memset(op,0,sizeof(ogg_packet));
593 memset(op_comm,0,sizeof(ogg_packet));
594 memset(op_code,0,sizeof(ogg_packet));