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