Restore alphabetic order for HAVE_ defines.
[mplayer/glamo.git] / libmpdemux / ebml.c
bloba007bd4ad4ec31ccd8412f7714a87664fe122728
1 /*
2 * native ebml reader for the Matroska demuxer
3 * copyright (c) 2004 Aurelien Jacobs <aurel@gnuage.org>
4 * based on the one written by Ronald Bultje for gstreamer
6 * This file is part of MPlayer.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "config.h"
25 #include <stdlib.h>
27 #include "stream/stream.h"
28 #include "ebml.h"
29 #include "libavutil/common.h"
30 #include "mpbswap.h"
31 #include "libavutil/intfloat_readwrite.h"
34 #ifndef SIZE_MAX
35 #define SIZE_MAX ((size_t)-1)
36 #endif
39 * Read: the element content data ID.
40 * Return: the ID.
42 uint32_t
43 ebml_read_id (stream_t *s, int *length)
45 int i, len_mask = 0x80;
46 uint32_t id;
48 for (i=0, id=stream_read_char (s); i<4 && !(id & len_mask); i++)
49 len_mask >>= 1;
50 if (i >= 4)
51 return EBML_ID_INVALID;
52 if (length)
53 *length = i + 1;
54 while (i--)
55 id = (id << 8) | stream_read_char (s);
56 return id;
60 * Read a variable length unsigned int.
62 uint64_t
63 ebml_read_vlen_uint (uint8_t *buffer, int *length)
65 int i, j, num_ffs = 0, len_mask = 0x80;
66 uint64_t num;
68 for (i=0, num=*buffer++; i<8 && !(num & len_mask); i++)
69 len_mask >>= 1;
70 if (i >= 8)
71 return EBML_UINT_INVALID;
72 j = i+1;
73 if (length)
74 *length = j;
75 if ((int)(num &= (len_mask - 1)) == len_mask - 1)
76 num_ffs++;
77 while (i--)
79 num = (num << 8) | *buffer++;
80 if ((num & 0xFF) == 0xFF)
81 num_ffs++;
83 if (j == num_ffs)
84 return EBML_UINT_INVALID;
85 return num;
89 * Read a variable length signed int.
91 int64_t
92 ebml_read_vlen_int (uint8_t *buffer, int *length)
94 uint64_t unum;
95 int l;
97 /* read as unsigned number first */
98 unum = ebml_read_vlen_uint (buffer, &l);
99 if (unum == EBML_UINT_INVALID)
100 return EBML_INT_INVALID;
101 if (length)
102 *length = l;
104 return unum - ((1 << ((7 * l) - 1)) - 1);
108 * Read: element content length.
110 uint64_t
111 ebml_read_length (stream_t *s, int *length)
113 int i, j, num_ffs = 0, len_mask = 0x80;
114 uint64_t len;
116 for (i=0, len=stream_read_char (s); i<8 && !(len & len_mask); i++)
117 len_mask >>= 1;
118 if (i >= 8)
119 return EBML_UINT_INVALID;
120 j = i+1;
121 if (length)
122 *length = j;
123 if ((int)(len &= (len_mask - 1)) == len_mask - 1)
124 num_ffs++;
125 while (i--)
127 len = (len << 8) | stream_read_char (s);
128 if ((len & 0xFF) == 0xFF)
129 num_ffs++;
131 if (j == num_ffs)
132 return EBML_UINT_INVALID;
133 return len;
137 * Read the next element as an unsigned int.
139 uint64_t
140 ebml_read_uint (stream_t *s, uint64_t *length)
142 uint64_t len, value = 0;
143 int l;
145 len = ebml_read_length (s, &l);
146 if (len == EBML_UINT_INVALID || len < 1 || len > 8)
147 return EBML_UINT_INVALID;
148 if (length)
149 *length = len + l;
151 while (len--)
152 value = (value << 8) | stream_read_char (s);
154 return value;
158 * Read the next element as a signed int.
160 int64_t
161 ebml_read_int (stream_t *s, uint64_t *length)
163 int64_t value = 0;
164 uint64_t len;
165 int l;
167 len = ebml_read_length (s, &l);
168 if (len == EBML_UINT_INVALID || len < 1 || len > 8)
169 return EBML_INT_INVALID;
170 if (length)
171 *length = len + l;
173 len--;
174 l = stream_read_char (s);
175 if (l & 0x80)
176 value = -1;
177 value = (value << 8) | l;
178 while (len--)
179 value = (value << 8) | stream_read_char (s);
181 return value;
185 * Read the next element as a float.
187 long double
188 ebml_read_float (stream_t *s, uint64_t *length)
190 long double value;
191 uint64_t len;
192 int l;
194 len = ebml_read_length (s, &l);
195 switch (len)
197 case 4:
198 value = av_int2flt(stream_read_dword(s));
199 break;
201 case 8:
202 value = av_int2dbl(stream_read_qword(s));
203 break;
205 default:
206 return EBML_FLOAT_INVALID;
209 if (length)
210 *length = len + l;
212 return value;
216 * Read the next element as an ASCII string.
218 char *
219 ebml_read_ascii (stream_t *s, uint64_t *length)
221 uint64_t len;
222 char *str;
223 int l;
225 len = ebml_read_length (s, &l);
226 if (len == EBML_UINT_INVALID)
227 return NULL;
228 if (len > SIZE_MAX - 1)
229 return NULL;
230 if (length)
231 *length = len + l;
233 str = (char *) malloc (len+1);
234 if (stream_read(s, str, len) != (int) len)
236 free (str);
237 return NULL;
239 str[len] = '\0';
241 return str;
245 * Read the next element as a UTF-8 string.
247 char *
248 ebml_read_utf8 (stream_t *s, uint64_t *length)
250 return ebml_read_ascii (s, length);
254 * Skip the next element.
257 ebml_read_skip (stream_t *s, uint64_t *length)
259 uint64_t len;
260 int l;
262 len = ebml_read_length (s, &l);
263 if (len == EBML_UINT_INVALID)
264 return 1;
265 if (length)
266 *length = len + l;
268 stream_skip(s, len);
270 return 0;
274 * Read the next element, but only the header. The contents
275 * are supposed to be sub-elements which can be read separately.
277 uint32_t
278 ebml_read_master (stream_t *s, uint64_t *length)
280 uint64_t len;
281 uint32_t id;
283 id = ebml_read_id (s, NULL);
284 if (id == EBML_ID_INVALID)
285 return id;
287 len = ebml_read_length (s, NULL);
288 if (len == EBML_UINT_INVALID)
289 return EBML_ID_INVALID;
290 if (length)
291 *length = len;
293 return id;
298 * Read an EBML header.
300 char *
301 ebml_read_header (stream_t *s, int *version)
303 uint64_t length, l, num;
304 uint32_t id;
305 char *str = NULL;
307 if (ebml_read_master (s, &length) != EBML_ID_HEADER)
308 return 0;
310 if (version)
311 *version = 1;
313 while (length > 0)
315 id = ebml_read_id (s, NULL);
316 if (id == EBML_ID_INVALID)
317 return NULL;
318 length -= 2;
320 switch (id)
322 /* is our read version uptodate? */
323 case EBML_ID_EBMLREADVERSION:
324 num = ebml_read_uint (s, &l);
325 if (num != EBML_VERSION)
326 return NULL;
327 break;
329 /* we only handle 8 byte lengths at max */
330 case EBML_ID_EBMLMAXSIZELENGTH:
331 num = ebml_read_uint (s, &l);
332 if (num != sizeof (uint64_t))
333 return NULL;
334 break;
336 /* we handle 4 byte IDs at max */
337 case EBML_ID_EBMLMAXIDLENGTH:
338 num = ebml_read_uint (s, &l);
339 if (num != sizeof (uint32_t))
340 return NULL;
341 break;
343 case EBML_ID_DOCTYPE:
344 str = ebml_read_ascii (s, &l);
345 if (str == NULL)
346 return NULL;
347 break;
349 case EBML_ID_DOCTYPEREADVERSION:
350 num = ebml_read_uint (s, &l);
351 if (num == EBML_UINT_INVALID)
352 return NULL;
353 if (version)
354 *version = num;
355 break;
357 /* we ignore these two, they don't tell us anything we care about */
358 case EBML_ID_VOID:
359 case EBML_ID_EBMLVERSION:
360 case EBML_ID_DOCTYPEVERSION:
361 default:
362 if (ebml_read_skip (s, &l))
363 return NULL;
364 break;
366 length -= l;
369 return str;