1 /********************************************************************
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
14 last mod: $Id: theora.c 17072 2010-03-26 05:07:26Z giles $
16 ********************************************************************/
26 #define theora_read(x,y,z) ( *z = oggpackB_read(x,y) )
28 static void _tp_readbuffer(oggpack_buffer *opb, char *buf, const long len)
33 for (i = 0; i < len; i++) {
34 theora_read(opb, 8, &ret);
39 static void _tp_readlsbint(oggpack_buffer *opb, long *value)
44 for (i = 0; i < 4; i++) {
45 theora_read(opb,8,&ret[i]);
47 *value = ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24;
50 void theora_info_clear(theora_info *c) {
51 memset(c,0,sizeof(*c));
54 static int _theora_unpack_info(theora_info *ci, oggpack_buffer *opb){
57 theora_read(opb,8,&ret);
58 ci->version_major=(unsigned char)ret;
59 theora_read(opb,8,&ret);
60 ci->version_minor=(unsigned char)ret;
61 theora_read(opb,8,&ret);
62 ci->version_subminor=(unsigned char)ret;
64 theora_read(opb,16,&ret);
66 theora_read(opb,16,&ret);
68 theora_read(opb,24,&ret);
70 theora_read(opb,24,&ret);
72 theora_read(opb,8,&ret);
74 theora_read(opb,8,&ret);
77 theora_read(opb,32,&ret);
78 ci->fps_numerator=ret;
79 theora_read(opb,32,&ret);
80 ci->fps_denominator=ret;
81 theora_read(opb,24,&ret);
82 ci->aspect_numerator=ret;
83 theora_read(opb,24,&ret);
84 ci->aspect_denominator=ret;
86 theora_read(opb,8,&ret);
88 theora_read(opb,24,&ret);
89 ci->target_bitrate=ret;
90 theora_read(opb,6,&ret);
93 theora_read(opb,5,&ret);
94 ci->granule_shift = ret;
96 theora_read(opb,2,&ret);
99 /* spare configuration bits */
100 if ( theora_read(opb,3,&ret) == -1 )
101 return (OC_BADHEADER);
106 void theora_comment_clear(theora_comment *tc){
109 for(i=0;i<tc->comments;i++)
110 if(tc->user_comments[i])_ogg_free(tc->user_comments[i]);
111 if(tc->user_comments)_ogg_free(tc->user_comments);
112 if(tc->comment_lengths)_ogg_free(tc->comment_lengths);
113 if(tc->vendor)_ogg_free(tc->vendor);
114 memset(tc,0,sizeof(*tc));
118 static int _theora_unpack_comment(theora_comment *tc, oggpack_buffer *opb){
122 _tp_readlsbint(opb,&len);
123 if(len<0)return(OC_BADHEADER);
124 tc->vendor=_ogg_calloc(1,len+1);
125 _tp_readbuffer(opb,tc->vendor, len);
126 tc->vendor[len]='\0';
128 _tp_readlsbint(opb,(long *) &tc->comments);
129 if(tc->comments<0)goto parse_err;
130 tc->user_comments=_ogg_calloc(tc->comments,sizeof(*tc->user_comments));
131 tc->comment_lengths=_ogg_calloc(tc->comments,sizeof(*tc->comment_lengths));
132 for(i=0;i<tc->comments;i++){
133 _tp_readlsbint(opb,&len);
134 if(len<0)goto parse_err;
135 tc->user_comments[i]=_ogg_calloc(1,len+1);
136 _tp_readbuffer(opb,tc->user_comments[i],len);
137 tc->user_comments[i][len]='\0';
138 tc->comment_lengths[i]=len;
143 theora_comment_clear(tc);
144 return(OC_BADHEADER);
147 static int _theora_unpack_tables(theora_info *c, oggpack_buffer *opb){
148 /* NOP: ogginfo doesn't use this information */
152 int theora_decode_header(theora_info *ci, theora_comment *cc, ogg_packet *op){
156 if(!op)return OC_BADHEADER;
158 opb = _ogg_malloc(sizeof(oggpack_buffer));
159 oggpackB_readinit(opb,op->packet,op->bytes);
164 theora_read(opb,8,&ret);
166 if(!(typeflag&0x80)) {
168 return(OC_NOTFORMAT);
171 _tp_readbuffer(opb,id,6);
172 if(memcmp(id,"theora",6)) {
174 return(OC_NOTFORMAT);
180 /* Not the initial packet */
182 return(OC_BADHEADER);
184 if(ci->version_major!=0){
185 /* previously initialized info header */
190 ret = _theora_unpack_info(ci,opb);
195 if(ci->version_major==0){
196 /* um... we didn't get the initial header */
198 return(OC_BADHEADER);
201 ret = _theora_unpack_comment(cc,opb);
206 if(ci->version_major==0 || cc->vendor==NULL){
207 /* um... we didn't get the initial header or comments yet */
209 return(OC_BADHEADER);
212 ret = _theora_unpack_tables(ci,opb);
218 /* ignore any trailing header packets for forward compatibility */
219 return(OC_NEWPACKET);
222 /* I don't think it's possible to get this far, but better safe.. */
224 return(OC_BADHEADER);