tizen 2.0 init
[framework/multimedia/gst-plugins-good0.10.git] / gst / matroska / ebml-read.c
1 /* GStreamer EBML I/O
2  * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  *
4  * ebml-read.c: read EBML data from file/stream
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include "ebml-read.h"
29 #include "ebml-ids.h"
30
31 #include <math.h>
32
33 /* NAN is supposed to be in math.h, Microsoft defines it in xmath.h */
34 #ifdef _MSC_VER
35 #include <xmath.h>
36 #endif
37
38 /* If everything goes wrong try 0.0/0.0 which should be NAN */
39 #ifndef NAN
40 #define NAN (0.0 / 0.0)
41 #endif
42
43 GST_DEBUG_CATEGORY (ebmlread_debug);
44 #define GST_CAT_DEFAULT ebmlread_debug
45
46 /* Peeks following element id and element length in datastream provided
47  * by @peek with @ctx as user data.
48  * Returns GST_FLOW_UNEXPECTED if not enough data to read id and length.
49  * Otherwise, @needed provides the prefix length (id + length), and
50  * @length provides element length.
51  *
52  * @object and @offset are provided for informative messaging/debug purposes.
53  */
54 GstFlowReturn
55 gst_ebml_peek_id_length (guint32 * _id, guint64 * _length, guint * _needed,
56     GstPeekData peek, gpointer * ctx, GstElement * el, guint64 offset)
57 {
58   guint needed;
59   const guint8 *buf;
60   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
61   guint64 total;
62   guint8 b;
63   GstFlowReturn ret;
64
65   g_return_val_if_fail (_id != NULL, GST_FLOW_ERROR);
66   g_return_val_if_fail (_length != NULL, GST_FLOW_ERROR);
67   g_return_val_if_fail (_needed != NULL, GST_FLOW_ERROR);
68
69   /* well ... */
70   *_id = (guint32) GST_EBML_SIZE_UNKNOWN;
71   *_length = GST_EBML_SIZE_UNKNOWN;
72
73   /* read element id */
74   needed = 2;
75   ret = peek (ctx, needed, &buf);
76   if (ret != GST_FLOW_OK)
77     goto peek_error;
78   b = GST_READ_UINT8 (buf);
79   total = (guint64) b;
80   while (read <= 4 && !(total & len_mask)) {
81     read++;
82     len_mask >>= 1;
83   }
84   if (G_UNLIKELY (read > 4))
85     goto invalid_id;
86
87   /* need id and at least something for subsequent length */
88   needed = read + 1;
89   ret = peek (ctx, needed, &buf);
90   if (ret != GST_FLOW_OK)
91     goto peek_error;
92   while (n < read) {
93     b = GST_READ_UINT8 (buf + n);
94     total = (total << 8) | b;
95     ++n;
96   }
97   *_id = (guint32) total;
98
99   /* read element length */
100   b = GST_READ_UINT8 (buf + n);
101   total = (guint64) b;
102   len_mask = 0x80;
103   read = 1;
104   while (read <= 8 && !(total & len_mask)) {
105     read++;
106     len_mask >>= 1;
107   }
108   if (G_UNLIKELY (read > 8))
109     goto invalid_length;
110   if ((total &= (len_mask - 1)) == len_mask - 1)
111     num_ffs++;
112
113   needed += read - 1;
114   ret = peek (ctx, needed, &buf);
115   if (ret != GST_FLOW_OK)
116     goto peek_error;
117   buf += (needed - read);
118   n = 1;
119   while (n < read) {
120     guint8 b = GST_READ_UINT8 (buf + n);
121
122     if (G_UNLIKELY (b == 0xff))
123       num_ffs++;
124     total = (total << 8) | b;
125     ++n;
126   }
127
128   if (G_UNLIKELY (read == num_ffs))
129     *_length = G_MAXUINT64;
130   else
131     *_length = total;
132
133   *_needed = needed;
134
135   return GST_FLOW_OK;
136
137   /* ERRORS */
138 peek_error:
139   {
140     GST_WARNING_OBJECT (el, "peek failed, ret = %d", ret);
141     *_needed = needed;
142     return ret;
143   }
144 invalid_id:
145   {
146     GST_ERROR_OBJECT (el,
147         "Invalid EBML ID size tag (0x%x) at position %" G_GUINT64_FORMAT " (0x%"
148         G_GINT64_MODIFIER "x)", (guint) b, offset, offset);
149     return GST_FLOW_ERROR;
150   }
151 invalid_length:
152   {
153     GST_ERROR_OBJECT (el,
154         "Invalid EBML length size tag (0x%x) at position %" G_GUINT64_FORMAT
155         " (0x%" G_GINT64_MODIFIER "x)", (guint) b, offset, offset);
156     return GST_FLOW_ERROR;
157   }
158 }
159
160 /* setup for parsing @buf at position @offset on behalf of @el.
161  * Takes ownership of @buf. */
162 void
163 gst_ebml_read_init (GstEbmlRead * ebml, GstElement * el, GstBuffer * buf,
164     guint64 offset)
165 {
166   GstEbmlMaster m;
167
168   g_return_if_fail (el);
169   g_return_if_fail (buf);
170
171   ebml->el = el;
172   ebml->offset = offset;
173   ebml->buf = buf;
174   ebml->readers = g_array_sized_new (FALSE, FALSE, sizeof (GstEbmlMaster), 10);
175   m.offset = ebml->offset;
176   gst_byte_reader_init (&m.br, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
177   g_array_append_val (ebml->readers, m);
178 }
179
180 void
181 gst_ebml_read_clear (GstEbmlRead * ebml)
182 {
183   if (ebml->readers)
184     g_array_free (ebml->readers, TRUE);
185   ebml->readers = NULL;
186   if (ebml->buf)
187     gst_buffer_unref (ebml->buf);
188   ebml->buf = NULL;
189   ebml->el = NULL;
190 }
191
192 static GstFlowReturn
193 gst_ebml_read_peek (GstByteReader * br, guint peek, const guint8 ** data)
194 {
195   if (G_LIKELY (gst_byte_reader_peek_data (br, peek, data)))
196     return GST_FLOW_OK;
197   else
198     return GST_FLOW_UNEXPECTED;
199 }
200
201 static GstFlowReturn
202 gst_ebml_peek_id_full (GstEbmlRead * ebml, guint32 * id, guint64 * length,
203     guint * prefix)
204 {
205   GstFlowReturn ret;
206
207   ret = gst_ebml_peek_id_length (id, length, prefix,
208       (GstPeekData) gst_ebml_read_peek, (gpointer) gst_ebml_read_br (ebml),
209       ebml->el, gst_ebml_read_get_pos (ebml));
210   if (ret != GST_FLOW_OK)
211     return ret;
212
213   GST_LOG_OBJECT (ebml->el, "id 0x%x at offset 0x%" G_GINT64_MODIFIER "x"
214       " of length %" G_GUINT64_FORMAT ", prefix %d", *id,
215       gst_ebml_read_get_pos (ebml), *length, *prefix);
216
217 #ifndef GST_DISABLE_GST_DEBUG
218   {
219     const guint8 *data = NULL;
220     GstByteReader *br = gst_ebml_read_br (ebml);
221     guint size = gst_byte_reader_get_remaining (br);
222
223     gst_byte_reader_peek_data (br, size, &data);
224
225     GST_LOG_OBJECT (ebml->el, "current br %p; remaining %d", br, size);
226     if (data)
227       GST_MEMDUMP_OBJECT (ebml->el, "element", data, MIN (size, *length));
228   }
229 #endif
230
231   return ret;
232 }
233
234 GstFlowReturn
235 gst_ebml_peek_id (GstEbmlRead * ebml, guint32 * id)
236 {
237   guint64 length;
238   guint needed;
239
240   return gst_ebml_peek_id_full (ebml, id, &length, &needed);
241 }
242
243 /*
244  * Read the next element, the contents are supposed to be sub-elements which
245  * can be read separately.  A new bytereader is setup for doing so.
246  */
247 GstFlowReturn
248 gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
249 {
250   guint64 length;
251   guint prefix;
252   const guint8 *data = NULL;
253   GstFlowReturn ret;
254   GstEbmlMaster m;
255
256   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
257   if (ret != GST_FLOW_OK)
258     return ret;
259
260   /* we just at least peeked the id */
261   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
262     return GST_FLOW_ERROR;      /* FIXME: do proper error handling */
263
264   m.offset = gst_ebml_read_get_pos (ebml);
265   if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, &data))
266     return GST_FLOW_PARSE;
267
268   GST_LOG_OBJECT (ebml->el, "pushing level %d at offset %" G_GUINT64_FORMAT,
269       ebml->readers->len, m.offset);
270   gst_byte_reader_init (&m.br, data, length);
271   g_array_append_val (ebml->readers, m);
272
273   return GST_FLOW_OK;
274 }
275
276 /* explicitly pop a bytereader from stack.  Usually invoked automagically. */
277 GstFlowReturn
278 gst_ebml_read_pop_master (GstEbmlRead * ebml)
279 {
280   g_return_val_if_fail (ebml->readers, GST_FLOW_ERROR);
281
282   /* never remove initial bytereader */
283   if (ebml->readers->len > 1) {
284     GST_LOG_OBJECT (ebml->el, "popping level %d", ebml->readers->len - 1);
285     g_array_remove_index (ebml->readers, ebml->readers->len - 1);
286   }
287
288   return GST_FLOW_OK;
289 }
290
291 /*
292  * Skip the next element.
293  */
294
295 GstFlowReturn
296 gst_ebml_read_skip (GstEbmlRead * ebml)
297 {
298   guint64 length;
299   guint32 id;
300   guint prefix;
301   GstFlowReturn ret;
302
303   ret = gst_ebml_peek_id_full (ebml, &id, &length, &prefix);
304   if (ret != GST_FLOW_OK)
305     return ret;
306
307   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), length + prefix))
308     return GST_FLOW_PARSE;
309
310   return ret;
311 }
312
313 /*
314  * Read the next element as a GstBuffer (binary).
315  */
316
317 GstFlowReturn
318 gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
319 {
320   guint64 length;
321   guint prefix;
322   GstFlowReturn ret;
323
324   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
325   if (ret != GST_FLOW_OK)
326     return ret;
327
328   /* we just at least peeked the id */
329   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
330     return GST_FLOW_ERROR;      /* FIXME: do proper error handling */
331
332   if (G_LIKELY (length > 0)) {
333     guint offset;
334
335     offset = gst_ebml_read_get_pos (ebml) - ebml->offset;
336     if (G_LIKELY (gst_byte_reader_skip (gst_ebml_read_br (ebml), length))) {
337       *buf = gst_buffer_create_sub (ebml->buf, offset, length);
338     } else {
339       *buf = NULL;
340       return GST_FLOW_PARSE;
341     }
342   } else {
343     *buf = gst_buffer_new ();
344   }
345
346   return ret;
347 }
348
349 /*
350  * Read the next element, return a pointer to it and its size.
351  */
352
353 static GstFlowReturn
354 gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, const guint8 ** data,
355     guint * size)
356 {
357   guint64 length;
358   guint prefix;
359   GstFlowReturn ret;
360
361   *size = 0;
362
363   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
364   if (ret != GST_FLOW_OK)
365     return ret;
366
367   /* we just at least peeked the id */
368   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
369     return GST_FLOW_ERROR;      /* FIXME: do proper error handling */
370
371   *data = NULL;
372   if (G_LIKELY (length >= 0)) {
373     if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, data))
374       return GST_FLOW_PARSE;
375   }
376
377   *size = length;
378
379   return ret;
380 }
381
382 /*
383  * Read the next element as an unsigned int.
384  */
385
386 GstFlowReturn
387 gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
388 {
389   const guint8 *data;
390   guint size;
391   GstFlowReturn ret;
392
393   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
394   if (ret != GST_FLOW_OK)
395     return ret;
396
397   if (size > 8) {
398     GST_ERROR_OBJECT (ebml->el,
399         "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
400         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
401         gst_ebml_read_get_pos (ebml) - size);
402     return GST_FLOW_ERROR;
403   }
404
405   if (size == 0) {
406     *num = 0;
407     return ret;
408   }
409
410   *num = 0;
411   while (size > 0) {
412     *num = (*num << 8) | *data;
413     size--;
414     data++;
415   }
416
417   return ret;
418 }
419
420 /*
421  * Read the next element as a signed int.
422  */
423
424 GstFlowReturn
425 gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
426 {
427   const guint8 *data;
428   guint size;
429   gboolean negative = 0;
430   GstFlowReturn ret;
431
432   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
433   if (ret != GST_FLOW_OK)
434     return ret;
435
436   if (size > 8) {
437     GST_ERROR_OBJECT (ebml->el,
438         "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
439         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
440         gst_ebml_read_get_pos (ebml) - size);
441     return GST_FLOW_ERROR;
442   }
443
444   if (size == 0) {
445     *num = 0;
446     return ret;
447   }
448
449   *num = 0;
450   if (*data & 0x80) {
451     negative = 1;
452     *num = *data & ~0x80;
453     size--;
454     data++;
455   }
456
457   while (size > 0) {
458     *num = (*num << 8) | *data;
459     size--;
460     data++;
461   }
462
463   /* make signed */
464   if (negative) {
465     *num = 0 - *num;
466   }
467
468   return ret;
469 }
470
471 /* Convert 80 bit extended precision float in big endian format to double.
472  * Code taken from libavutil/intfloat_readwrite.c from ffmpeg,
473  * licensed under LGPL */
474
475 struct _ext_float
476 {
477   guint8 exponent[2];
478   guint8 mantissa[8];
479 };
480
481 static gdouble
482 _ext2dbl (const guint8 * data)
483 {
484   struct _ext_float ext;
485   guint64 m = 0;
486   gint e, i;
487
488   memcpy (&ext.exponent, data, 2);
489   memcpy (&ext.mantissa, data + 2, 8);
490
491   for (i = 0; i < 8; i++)
492     m = (m << 8) + ext.mantissa[i];
493   e = (((gint) ext.exponent[0] & 0x7f) << 8) | ext.exponent[1];
494   if (e == 0x7fff && m)
495     return NAN;
496   e -= 16383 + 63;              /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
497                                  * mantissa bit is written as opposed to the
498                                  * single and double precision formats */
499   if (ext.exponent[0] & 0x80)
500     m = -m;
501   return ldexp (m, e);
502 }
503
504 /*
505  * Read the next element as a float.
506  */
507
508 GstFlowReturn
509 gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
510 {
511   const guint8 *data;
512   guint size;
513   GstFlowReturn ret;
514
515   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
516   if (ret != GST_FLOW_OK)
517     return ret;
518
519   if (size != 0 && size != 4 && size != 8 && size != 10) {
520     GST_ERROR_OBJECT (ebml->el,
521         "Invalid float element size %d at position %" G_GUINT64_FORMAT " (0x%"
522         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
523         gst_ebml_read_get_pos (ebml) - size);
524     return GST_FLOW_ERROR;
525   }
526
527   if (size == 4) {
528     gfloat f;
529
530     memcpy (&f, data, 4);
531     f = GFLOAT_FROM_BE (f);
532
533     *num = f;
534   } else if (size == 8) {
535     gdouble d;
536
537     memcpy (&d, data, 8);
538     d = GDOUBLE_FROM_BE (d);
539
540     *num = d;
541   } else if (size == 10) {
542     *num = _ext2dbl (data);
543   } else {
544     /* size == 0 means a value of 0.0 */
545     *num = 0.0;
546   }
547
548   return ret;
549 }
550
551 /*
552  * Read the next element as a C string.
553  */
554
555 static GstFlowReturn
556 gst_ebml_read_string (GstEbmlRead * ebml, guint32 * id, gchar ** str)
557 {
558   const guint8 *data;
559   guint size;
560   GstFlowReturn ret;
561
562   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
563   if (ret != GST_FLOW_OK)
564     return ret;
565
566   *str = g_malloc (size + 1);
567   memcpy (*str, data, size);
568   (*str)[size] = '\0';
569
570   return ret;
571 }
572
573 /*
574  * Read the next element as an ASCII string.
575  */
576
577 GstFlowReturn
578 gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str_out)
579 {
580   GstFlowReturn ret;
581   gchar *str;
582   gchar *iter;
583
584 #ifndef GST_DISABLE_GST_DEBUG
585   guint64 oldoff = ebml->offset;
586 #endif
587
588   ret = gst_ebml_read_string (ebml, id, &str);
589   if (ret != GST_FLOW_OK)
590     return ret;
591
592   for (iter = str; *iter != '\0'; iter++) {
593     if (G_UNLIKELY (*iter & 0x80)) {
594       GST_ERROR_OBJECT (ebml,
595           "Invalid ASCII string at offset %" G_GUINT64_FORMAT, oldoff);
596       g_free (str);
597       return GST_FLOW_ERROR;
598     }
599   }
600
601   *str_out = str;
602   return ret;
603 }
604
605 /*
606  * Read the next element as a UTF-8 string.
607  */
608
609 GstFlowReturn
610 gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
611 {
612   GstFlowReturn ret;
613
614 #ifndef GST_DISABLE_GST_DEBUG
615   guint64 oldoff = gst_ebml_read_get_pos (ebml);
616 #endif
617
618   ret = gst_ebml_read_string (ebml, id, str);
619   if (ret != GST_FLOW_OK)
620     return ret;
621
622   if (str != NULL && *str != NULL && **str != '\0' &&
623       !g_utf8_validate (*str, -1, NULL)) {
624     GST_WARNING_OBJECT (ebml->el,
625         "Invalid UTF-8 string at offset %" G_GUINT64_FORMAT, oldoff);
626   }
627
628   return ret;
629 }
630
631 /*
632  * Read the next element as a date.
633  * Returns the seconds since the unix epoch.
634  */
635
636 GstFlowReturn
637 gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
638 {
639   gint64 ebml_date;
640   GstFlowReturn ret;
641
642   ret = gst_ebml_read_sint (ebml, id, &ebml_date);
643   if (ret != GST_FLOW_OK)
644     return ret;
645
646   *date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;
647
648   return ret;
649 }
650
651 /*
652  * Read the next element as binary data.
653  */
654
655 GstFlowReturn
656 gst_ebml_read_binary (GstEbmlRead * ebml,
657     guint32 * id, guint8 ** binary, guint64 * length)
658 {
659   const guint8 *data;
660   guint size;
661   GstFlowReturn ret;
662
663   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
664   if (ret != GST_FLOW_OK)
665     return ret;
666
667   *length = size;
668   *binary = g_memdup (data, size);
669
670   return GST_FLOW_OK;
671 }