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-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
14 last mod: $Id: decinfo.c 14719 2008-04-12 11:36:40Z tterribe $
16 ********************************************************************/
25 /*Unpacks a series of octets from a given byte array into the pack buffer.
26 No checking is done to ensure the buffer contains enough data.
27 _opb: The pack buffer to read the octets from.
28 _buf: The byte array to store the unpacked bytes in.
29 _len: The number of octets to unpack.*/
30 static void oc_unpack_octets(oggpack_buffer
*_opb
,char *_buf
,size_t _len
){
33 theorapackB_read(_opb
,8,&val
);
38 /*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
39 static long oc_unpack_length(oggpack_buffer
*_opb
){
42 for(i
=0;i
<4;i
++)theorapackB_read(_opb
,8,ret
+i
);
43 return ret
[0]|ret
[1]<<8|ret
[2]<<16|ret
[3]<<24;
46 static int oc_info_unpack(oggpack_buffer
*_opb
,th_info
*_info
){
48 /*Check the codec bitstream version.*/
49 theorapackB_read(_opb
,8,&val
);
50 _info
->version_major
=(unsigned char)val
;
51 theorapackB_read(_opb
,8,&val
);
52 _info
->version_minor
=(unsigned char)val
;
53 theorapackB_read(_opb
,8,&val
);
54 _info
->version_subminor
=(unsigned char)val
;
55 /*verify we can parse this bitstream version.
56 We accept earlier minors and all subminors, by spec*/
57 if(_info
->version_major
>TH_VERSION_MAJOR
||
58 _info
->version_major
==TH_VERSION_MAJOR
&&
59 _info
->version_minor
>TH_VERSION_MINOR
){
62 /*Read the encoded frame description.*/
63 theorapackB_read(_opb
,16,&val
);
64 _info
->frame_width
=(ogg_uint32_t
)val
<<4;
65 theorapackB_read(_opb
,16,&val
);
66 _info
->frame_height
=(ogg_uint32_t
)val
<<4;
67 theorapackB_read(_opb
,24,&val
);
68 _info
->pic_width
=(ogg_uint32_t
)val
;
69 theorapackB_read(_opb
,24,&val
);
70 _info
->pic_height
=(ogg_uint32_t
)val
;
71 theorapackB_read(_opb
,8,&val
);
72 _info
->pic_x
=(ogg_uint32_t
)val
;
73 /*Note: The sense of pic_y is inverted in what we pass back to the
74 application compared to how it is stored in the bitstream.
75 This is because the bitstream uses a right-handed coordinate system, while
76 applications expect a left-handed one.*/
77 theorapackB_read(_opb
,8,&val
);
78 _info
->pic_y
=_info
->frame_height
-_info
->pic_height
-(ogg_uint32_t
)val
;
79 theorapackB_read(_opb
,32,&val
);
80 _info
->fps_numerator
=(ogg_uint32_t
)val
;
81 theorapackB_read(_opb
,32,&val
);
82 _info
->fps_denominator
=(ogg_uint32_t
)val
;
83 if(_info
->frame_width
==0||_info
->frame_height
==0||
84 _info
->pic_width
+_info
->pic_x
>_info
->frame_width
||
85 _info
->pic_height
+_info
->pic_y
>_info
->frame_height
||
86 _info
->fps_numerator
==0||_info
->fps_denominator
==0){
89 theorapackB_read(_opb
,24,&val
);
90 _info
->aspect_numerator
=(ogg_uint32_t
)val
;
91 theorapackB_read(_opb
,24,&val
);
92 _info
->aspect_denominator
=(ogg_uint32_t
)val
;
93 theorapackB_read(_opb
,8,&val
);
94 _info
->colorspace
=(th_colorspace
)val
;
95 theorapackB_read(_opb
,24,&val
);
96 _info
->target_bitrate
=(int)val
;
97 theorapackB_read(_opb
,6,&val
);
98 _info
->quality
=(int)val
;
99 theorapackB_read(_opb
,5,&val
);
100 _info
->keyframe_granule_shift
=(int)val
;
101 theorapackB_read(_opb
,2,&val
);
102 _info
->pixel_fmt
=(th_pixel_fmt
)val
;
103 if(_info
->pixel_fmt
==TH_PF_RSVD
)return TH_EBADHEADER
;
104 if(theorapackB_read(_opb
,3,&val
)<0||val
!=0)return TH_EBADHEADER
;
108 static int oc_comment_unpack(oggpack_buffer
*_opb
,th_comment
*_tc
){
111 /*Read the vendor string.*/
112 len
=oc_unpack_length(_opb
);
113 if(len
<0||theorapackB_bytes(_opb
)+len
>_opb
->storage
)return TH_EBADHEADER
;
114 _tc
->vendor
=_ogg_malloc((size_t)len
+1);
115 oc_unpack_octets(_opb
,_tc
->vendor
,len
);
116 _tc
->vendor
[len
]='\0';
117 /*Read the user comments.*/
118 _tc
->comments
=(int)oc_unpack_length(_opb
);
119 if(_tc
->comments
<0||_tc
->comments
>(LONG_MAX
>>2)||
120 theorapackB_bytes(_opb
)+((long)_tc
->comments
<<2)>_opb
->storage
){
121 return TH_EBADHEADER
;
123 _tc
->comment_lengths
=(int *)_ogg_malloc(
124 _tc
->comments
*sizeof(_tc
->comment_lengths
[0]));
125 _tc
->user_comments
=(char **)_ogg_malloc(
126 _tc
->comments
*sizeof(_tc
->user_comments
[0]));
127 for(i
=0;i
<_tc
->comments
;i
++){
128 len
=oc_unpack_length(_opb
);
129 if(len
<0||theorapackB_bytes(_opb
)+len
>_opb
->storage
){
131 return TH_EBADHEADER
;
133 _tc
->comment_lengths
[i
]=len
;
134 _tc
->user_comments
[i
]=_ogg_malloc((size_t)len
+1);
135 oc_unpack_octets(_opb
,_tc
->user_comments
[i
],len
);
136 _tc
->user_comments
[i
][len
]='\0';
138 return theorapackB_read(_opb
,0,&len
)<0?TH_EBADHEADER
:0;
141 static int oc_setup_unpack(oggpack_buffer
*_opb
,th_setup_info
*_setup
){
143 /*Read the quantizer tables.*/
144 ret
=oc_quant_params_unpack(_opb
,&_setup
->qinfo
);
146 /*Read the Huffman trees.*/
147 return oc_huff_trees_unpack(_opb
,_setup
->huff_tables
);
150 static void oc_setup_clear(th_setup_info
*_setup
){
151 oc_quant_params_clear(&_setup
->qinfo
);
152 oc_huff_trees_clear(_setup
->huff_tables
);
155 static int oc_dec_headerin(oggpack_buffer
*_opb
,th_info
*_info
,
156 th_comment
*_tc
,th_setup_info
**_setup
,ogg_packet
*_op
){
161 theorapackB_read(_opb
,8,&val
);
163 /*If we're at a data packet and we have received all three headers, we're
165 if(!(packtype
&0x80)&&_info
->frame_width
>0&&_tc
->vendor
!=NULL
&&*_setup
!=NULL
){
168 /*Check the codec string.*/
169 oc_unpack_octets(_opb
,buffer
,6);
170 if(memcmp(buffer
,"theora",6)!=0)return TH_ENOTFORMAT
;
172 /*Codec info header.*/
174 /*This should be the first packet, and we should not already be
176 if(!_op
->b_o_s
||_info
->frame_width
>0)return TH_EBADHEADER
;
177 ret
=oc_info_unpack(_opb
,_info
);
178 if(ret
<0)th_info_clear(_info
);
183 if(_tc
==NULL
)return TH_EFAULT
;
184 /*We shoud have already decoded the info header, and should not yet have
185 decoded the comment header.*/
186 if(_info
->frame_width
==0||_tc
->vendor
!=NULL
)return TH_EBADHEADER
;
187 ret
=oc_comment_unpack(_opb
,_tc
);
188 if(ret
<0)th_comment_clear(_tc
);
191 /*Codec setup header.*/
193 oc_setup_info
*setup
;
194 if(_tc
==NULL
||_setup
==NULL
)return TH_EFAULT
;
195 /*We should have already decoded the info header and the comment header,
196 and should not yet have decoded the setup header.*/
197 if(_info
->frame_width
==0||_tc
->vendor
==NULL
||*_setup
!=NULL
){
198 return TH_EBADHEADER
;
200 setup
=(oc_setup_info
*)_ogg_calloc(1,sizeof(*setup
));
201 ret
=oc_setup_unpack(_opb
,setup
);
203 oc_setup_clear(setup
);
212 /*We don't know what this header is.*/
213 return TH_EBADHEADER
;
220 /*Decodes one header packet.
221 This should be called repeatedly with the packets at the beginning of the
222 stream until it returns 0.*/
223 int th_decode_headerin(th_info
*_info
,th_comment
*_tc
,
224 th_setup_info
**_setup
,ogg_packet
*_op
){
227 if(_op
==NULL
)return TH_EBADHEADER
;
228 if(_info
==NULL
)return TH_EFAULT
;
229 theorapackB_readinit(&opb
,_op
->packet
,_op
->bytes
);
230 ret
=oc_dec_headerin(&opb
,_info
,_tc
,_setup
,_op
);
234 void th_setup_free(th_setup_info
*_setup
){
236 oc_setup_clear(_setup
);