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-2009 *
9 * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
11 ********************************************************************
16 ********************************************************************/
23 /*Only used for fuzzing.*/
24 #if defined(HAVE_MEMORY_CONSTRAINT)
25 static const int MAX_FUZZING_WIDTH
= 16384;
26 static const int MAX_FUZZING_HEIGHT
= 16384;
30 /*Unpacks a series of octets from a given byte array into the pack buffer.
31 No checking is done to ensure the buffer contains enough data.
32 _opb: The pack buffer to read the octets from.
33 _buf: The byte array to store the unpacked bytes in.
34 _len: The number of octets to unpack.*/
35 static void oc_unpack_octets(oc_pack_buf
*_opb
,char *_buf
,size_t _len
){
38 val
=oc_pack_read(_opb
,8);
43 /*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
44 static long oc_unpack_length(oc_pack_buf
*_opb
){
47 for(i
=0;i
<4;i
++)ret
[i
]=oc_pack_read(_opb
,8);
48 return ret
[0]|ret
[1]<<8|ret
[2]<<16|ret
[3]<<24;
51 static int oc_info_unpack(oc_pack_buf
*_opb
,th_info
*_info
){
53 /*Check the codec bitstream version.*/
54 val
=oc_pack_read(_opb
,8);
55 _info
->version_major
=(unsigned char)val
;
56 val
=oc_pack_read(_opb
,8);
57 _info
->version_minor
=(unsigned char)val
;
58 val
=oc_pack_read(_opb
,8);
59 _info
->version_subminor
=(unsigned char)val
;
60 /*verify we can parse this bitstream version.
61 We accept earlier minors and all subminors, by spec*/
62 if(_info
->version_major
>TH_VERSION_MAJOR
||
63 (_info
->version_major
==TH_VERSION_MAJOR
&&
64 _info
->version_minor
>TH_VERSION_MINOR
)){
67 /*Read the encoded frame description.*/
68 val
=oc_pack_read(_opb
,16);
69 _info
->frame_width
=(ogg_uint32_t
)val
<<4;
70 val
=oc_pack_read(_opb
,16);
71 _info
->frame_height
=(ogg_uint32_t
)val
<<4;
72 val
=oc_pack_read(_opb
,24);
73 _info
->pic_width
=(ogg_uint32_t
)val
;
74 val
=oc_pack_read(_opb
,24);
75 _info
->pic_height
=(ogg_uint32_t
)val
;
76 val
=oc_pack_read(_opb
,8);
77 _info
->pic_x
=(ogg_uint32_t
)val
;
78 val
=oc_pack_read(_opb
,8);
79 _info
->pic_y
=(ogg_uint32_t
)val
;
80 val
=oc_pack_read(_opb
,32);
81 _info
->fps_numerator
=(ogg_uint32_t
)val
;
82 val
=oc_pack_read(_opb
,32);
83 _info
->fps_denominator
=(ogg_uint32_t
)val
;
84 if(_info
->frame_width
==0||_info
->frame_height
==0||
85 _info
->pic_width
+_info
->pic_x
>_info
->frame_width
||
86 _info
->pic_height
+_info
->pic_y
>_info
->frame_height
||
87 _info
->fps_numerator
==0||_info
->fps_denominator
==0){
90 #if defined(HAVE_MEMORY_CONSTRAINT)
91 if(_info
->frame_width
>=MAX_FUZZING_WIDTH
&&_info
->frame_height
>=MAX_FUZZING_HEIGHT
){
95 /*Note: The sense of pic_y is inverted in what we pass back to the
96 application compared to how it is stored in the bitstream.
97 This is because the bitstream uses a right-handed coordinate system, while
98 applications expect a left-handed one.*/
99 _info
->pic_y
=_info
->frame_height
-_info
->pic_height
-_info
->pic_y
;
100 val
=oc_pack_read(_opb
,24);
101 _info
->aspect_numerator
=(ogg_uint32_t
)val
;
102 val
=oc_pack_read(_opb
,24);
103 _info
->aspect_denominator
=(ogg_uint32_t
)val
;
104 val
=oc_pack_read(_opb
,8);
105 _info
->colorspace
=(th_colorspace
)val
;
106 val
=oc_pack_read(_opb
,24);
107 _info
->target_bitrate
=(int)val
;
108 val
=oc_pack_read(_opb
,6);
109 _info
->quality
=(int)val
;
110 val
=oc_pack_read(_opb
,5);
111 _info
->keyframe_granule_shift
=(int)val
;
112 val
=oc_pack_read(_opb
,2);
113 _info
->pixel_fmt
=(th_pixel_fmt
)val
;
114 if(_info
->pixel_fmt
==TH_PF_RSVD
)return TH_EBADHEADER
;
115 val
=oc_pack_read(_opb
,3);
116 if(val
!=0||oc_pack_bytes_left(_opb
)<0)return TH_EBADHEADER
;
120 static int oc_comment_unpack(oc_pack_buf
*_opb
,th_comment
*_tc
){
123 /*Read the vendor string.*/
124 len
=oc_unpack_length(_opb
);
125 if(len
<0||len
>oc_pack_bytes_left(_opb
))return TH_EBADHEADER
;
126 _tc
->vendor
=_ogg_malloc((size_t)len
+1);
127 if(_tc
->vendor
==NULL
)return TH_EFAULT
;
128 oc_unpack_octets(_opb
,_tc
->vendor
,len
);
129 _tc
->vendor
[len
]='\0';
130 /*Read the user comments.*/
131 _tc
->comments
=(int)oc_unpack_length(_opb
);
133 if(len
<0||len
>(LONG_MAX
>>2)||len
<<2>oc_pack_bytes_left(_opb
)){
135 return TH_EBADHEADER
;
137 _tc
->comment_lengths
=(int *)_ogg_malloc(
138 _tc
->comments
*sizeof(_tc
->comment_lengths
[0]));
139 _tc
->user_comments
=(char **)_ogg_malloc(
140 _tc
->comments
*sizeof(_tc
->user_comments
[0]));
141 if(_tc
->comment_lengths
==NULL
||_tc
->user_comments
==NULL
){
145 for(i
=0;i
<_tc
->comments
;i
++){
146 len
=oc_unpack_length(_opb
);
147 if(len
<0||len
>oc_pack_bytes_left(_opb
)){
149 return TH_EBADHEADER
;
151 _tc
->comment_lengths
[i
]=len
;
152 _tc
->user_comments
[i
]=_ogg_malloc((size_t)len
+1);
153 if(_tc
->user_comments
[i
]==NULL
){
157 oc_unpack_octets(_opb
,_tc
->user_comments
[i
],len
);
158 _tc
->user_comments
[i
][len
]='\0';
160 return oc_pack_bytes_left(_opb
)<0?TH_EBADHEADER
:0;
163 static int oc_setup_unpack(oc_pack_buf
*_opb
,th_setup_info
*_setup
){
165 /*Read the quantizer tables.*/
166 ret
=oc_quant_params_unpack(_opb
,&_setup
->qinfo
);
168 /*Read the Huffman trees.*/
169 return oc_huff_trees_unpack(_opb
,_setup
->huff_tables
);
172 static void oc_setup_clear(th_setup_info
*_setup
){
173 oc_quant_params_clear(&_setup
->qinfo
);
174 oc_huff_trees_clear(_setup
->huff_tables
);
177 static int oc_dec_headerin(oc_pack_buf
*_opb
,th_info
*_info
,
178 th_comment
*_tc
,th_setup_info
**_setup
,ogg_packet
*_op
){
183 val
=oc_pack_read(_opb
,8);
185 /*If we're at a data packet...*/
186 if(!(packtype
&0x80)){
187 /*Check to make sure we received all three headers...
188 If we haven't seen any valid headers, assume this is not actually
190 if(_info
->frame_width
<=0)return TH_ENOTFORMAT
;
191 /*Follow our documentation, which says we'll return TH_EFAULT if this
192 are NULL (_info was checked by our caller).*/
193 if(_tc
==NULL
)return TH_EFAULT
;
194 /*And if any other headers were missing, declare this packet "out of
196 if(_tc
->vendor
==NULL
)return TH_EBADHEADER
;
197 /*Don't check this until it's needed, since we allow passing NULL for the
198 arguments that we're not expecting the next header to fill in yet.*/
199 if(_setup
==NULL
)return TH_EFAULT
;
200 if(*_setup
==NULL
)return TH_EBADHEADER
;
201 /*If we got everything, we're done.*/
204 /*Check the codec string.*/
205 oc_unpack_octets(_opb
,buffer
,6);
206 if(memcmp(buffer
,"theora",6)!=0)return TH_ENOTFORMAT
;
208 /*Codec info header.*/
210 /*This should be the first packet, and we should not already be
212 if(!_op
->b_o_s
||_info
->frame_width
>0)return TH_EBADHEADER
;
213 ret
=oc_info_unpack(_opb
,_info
);
214 if(ret
<0)th_info_clear(_info
);
219 if(_tc
==NULL
)return TH_EFAULT
;
220 /*We shoud have already decoded the info header, and should not yet have
221 decoded the comment header.*/
222 if(_info
->frame_width
==0||_tc
->vendor
!=NULL
)return TH_EBADHEADER
;
223 ret
=oc_comment_unpack(_opb
,_tc
);
224 if(ret
<0)th_comment_clear(_tc
);
227 /*Codec setup header.*/
229 oc_setup_info
*setup
;
230 if(_tc
==NULL
||_setup
==NULL
)return TH_EFAULT
;
231 /*We should have already decoded the info header and the comment header,
232 and should not yet have decoded the setup header.*/
233 if(_info
->frame_width
==0||_tc
->vendor
==NULL
||*_setup
!=NULL
){
234 return TH_EBADHEADER
;
236 setup
=(oc_setup_info
*)_ogg_calloc(1,sizeof(*setup
));
237 if(setup
==NULL
)return TH_EFAULT
;
238 ret
=oc_setup_unpack(_opb
,setup
);
240 oc_setup_clear(setup
);
249 /*We don't know what this header is.*/
250 return TH_EBADHEADER
;
257 /*Decodes one header packet.
258 This should be called repeatedly with the packets at the beginning of the
259 stream until it returns 0.*/
260 int th_decode_headerin(th_info
*_info
,th_comment
*_tc
,
261 th_setup_info
**_setup
,ogg_packet
*_op
){
263 if(_op
==NULL
)return TH_EBADHEADER
;
264 if(_info
==NULL
)return TH_EFAULT
;
265 oc_pack_readinit(&opb
,_op
->packet
,_op
->bytes
);
266 return oc_dec_headerin(&opb
,_info
,_tc
,_setup
,_op
);
269 void th_setup_free(th_setup_info
*_setup
){
271 oc_setup_clear(_setup
);