Incremental update.
[platform/upstream/libvorbis.git] / lib / info.c
1 /********************************************************************
2  *                                                                  *
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.                            *
7  *                                                                  *
8  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *
9  * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: maintain the info structure, info <-> header packets
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Oct 03 1999
18
19  ********************************************************************/
20
21 /* This fills in a vorbis_info structure with settings from a few
22    pre-defined encoding modes.  Also handles choosing/blowing in the
23    codebook */
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include "modes.h"
28 #include "bitwise.h"
29
30 /* one test mode for now; temporary of course */
31 int vorbis_info_modeset(vorbis_info *vi, int mode){
32   if(mode<0 || mode>predef_mode_max)return(-1);
33
34   /* handle the flat settings first */
35   memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
36   vi->user_comments=calloc(1,sizeof(char *));
37   vi->vendor=strdup("Xiphophorus libVorbis I 19991003");
38
39   return(0);
40 }
41
42 /* convenience function */
43 int vorbis_info_add_comment(vorbis_info *vi,char *comment){
44   vi->user_comments=realloc(vi->user_comments,
45                             (vi->max_comment+2)*sizeof(char *));
46   vi->user_comments[vi->max_comment]=strdup(comment);
47   vi->max_comment++;
48   vi->user_comments[vi->max_comment]=NULL;
49   return(0);
50 }
51
52 static int _v_writestring(oggpack_buffer *o,char *s){
53   while(*s){
54     _oggpack_write(o,*s++,8);
55   }
56 }
57
58 static char *_v_readstring(oggpack_buffer *o,int bytes){
59   char *ret=calloc(bytes+1,1);
60   char *ptr=ret;
61   while(bytes--){
62     *ptr++=_oggpack_read(o,8);
63   }
64   return(ret);
65 }
66
67 /* The Vorbis header is in three packets; the initial small packet in
68    the first page that identifies basic parameters, a second packet
69    with bitstream comments and a third packet that holds the
70    codebook. */
71
72 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
73
74 }
75
76 int vorbis_info_headerout(vorbis_info *vi,
77                           ogg_packet *op,
78                           ogg_packet *op_comm,
79                           ogg_packet *op_code){
80
81   oggpack_buffer opb;
82   /* initial header:
83
84      codec id     "vorbis"
85      codec ver    (4 octets, lsb first: currently 0x00)
86      pcm channels (4 octets, lsb first)
87      pcm rate     (4 octets, lsb first)
88      
89      small block  (4 octets, lsb first)
90      large block  (4 octets, lsb first)
91      envelopesa   (4 octets, lsb first)
92      envelopech   (4 octets, lsb first)
93      floororder   octet
94      flooroctaves octet
95      floorch      (4 octets, lsb first)
96    */
97
98   _oggpack_writeinit(&opb);
99   _v_writestring(&obp,"vorbis");
100   _oggpack_write(&opb,0x00,32);
101
102   _oggpack_write(&opb,vi->channels,32);
103   _oggpack_write(&opb,vi->rate,32);
104   _oggpack_write(&opb,vi->smallblock,32);
105   _oggpack_write(&opb,vi->largeblock,32);
106   _oggpack_write(&opb,vi->envelopesa,32);
107   _oggpack_write(&opb,vi->envelopech,32);
108   _oggpack_write(&opb,vi->floororder,8);
109   _oggpack_write(&opb,vi->flooroctaves,8);
110   _oggpack_write(&opb,vi->floorch,32);
111
112   /* build the packet */
113   if(vi->header)free(vi->header);
114   vi->header=memcpy(opb.buffer,_oggpack_bytes(&opb));
115   op->packet=vi->header;
116   op->bytes=_oggpack_bytes(&opb);
117   op->b_o_s=1;
118   op->e_o_s=0;
119   op->frameno=0;
120
121   /* comment header:
122      vendor len     (4 octets, lsb first)
123      vendor and id  (n octects as above)
124      comments       (4 octets, lsb first)
125      comment 0 len  (4 octets, lsb first)
126      comment 0 len  (n octets as above)
127      ...
128      comment n-1 len  (4 octets, lsb first)
129      comment 0-1 len  (n octets as above)
130   */
131
132   _oggpack_reset(&opb);
133   if(vi->vendor){
134     _oggpack_write(&opb,strlen(vi->vendor),32);
135     _oggpack_write(&opb,vi->vendor,strlen(vi->vendor));
136   }else{
137     _oggpack_write(&opb,0,32);
138   }
139   
140   _oggpack_write(&opb,vi->max_comment,32);
141   if(vi->max_comment){
142     int i;
143     for(i=0;i<=vi->max_comment;i++){
144       if(vi->user_comments[i]){
145         _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
146         _oggpack_write(&opb,vi->user_comments[i],strlen(vi->user_comments[i]));
147       }else{
148         _oggpack_write(&opb,0,32);
149       }
150     }
151   }
152   
153   if(vi->header1)free(vi->header1);
154   vi->header1=memcpy(opb.buffer,_oggpack_bytes(&opb));
155   op_comm->packet=vi->header1;
156   op_comm->bytes=_oggpack_bytes(&opb);
157   op_comm->b_o_s=0;
158   op_comm->e_o_s=0;
159   op_comm->frameno=0;
160
161   /* codebook header:
162      nul so far; not encoded yet */
163
164   if(vi->header2)free(vi->header2);
165   vi->header2=NULL;
166   op_code->packet=vi->header2;
167   op_code->bytes=0;
168   op_code->b_o_s=0;
169   op_code->e_o_s=0;
170   op_code->frameno=0;
171
172   return(0);
173 }
174
175 int vorbis_info_clear(vorbis_info *vi){
176   /* clear the non-flat storage before zeroing */
177
178   /* comments */
179   if(vi->user_comments){
180     char **ptr=vi->user_comments;
181     while(*ptr){
182       free(*(ptr++));
183     }
184     free(vi->user_comments);
185   }
186
187   /* vendor string */
188   if(vi->vendor)free(vi->vendor);
189
190   /* local encoding storage */
191   if(vi->header)free(vi->header);
192   if(vi->header1)free(vi->header1);
193   if(vi->header2)free(vi->header2);
194
195   memset(vi,0,sizeof(vorbis_info));
196 }
197   
198