matroskademux: use bytereader based GstEbmlRead as a helper
[platform/upstream/gst-plugins-good.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;
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   const guint8 *data = NULL;
211
212   ret = gst_ebml_peek_id_length (id, length, prefix,
213       (GstPeekData) gst_ebml_read_peek, (gpointer) gst_ebml_read_br (ebml),
214       ebml->el, gst_ebml_read_get_pos (ebml));
215   if (ret != GST_FLOW_OK)
216     return ret;
217
218   GST_LOG_OBJECT (ebml->el, "id 0x%x at offset 0x%" G_GINT64_MODIFIER "x"
219       " of length %" G_GUINT64_FORMAT ", prefix %d", *id,
220       gst_ebml_read_get_pos (ebml), *length, *prefix);
221
222 #ifndef GST_DISABLE_GST_DEBUG
223   {
224     GstByteReader *br = gst_ebml_read_br (ebml);
225     guint size = gst_byte_reader_get_remaining (br);
226     gst_byte_reader_peek_data (br, size, &data);
227
228     GST_LOG_OBJECT (ebml->el, "current br %p; remaining %d", br, size);
229     if (data)
230       GST_MEMDUMP_OBJECT (ebml->el, "element", data, MIN (size, *length));
231   }
232 #endif
233
234   return ret;
235 }
236
237 GstFlowReturn
238 gst_ebml_peek_id (GstEbmlRead * ebml, guint32 * id)
239 {
240   guint64 length;
241   guint needed;
242
243   return gst_ebml_peek_id_full (ebml, id, &length, &needed);
244 }
245
246 /*
247  * Read the next element, the contents are supposed to be sub-elements which
248  * can be read separately.  A new bytereader is setup for doing so.
249  */
250 GstFlowReturn
251 gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
252 {
253   guint64 length;
254   guint prefix;
255   const guint8 *data;
256   GstFlowReturn ret;
257   GstEbmlMaster m;
258
259   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
260   if (ret != GST_FLOW_OK)
261     return ret;
262
263   /* we just at least peeked the id */
264   g_assert (gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix));
265
266   m.offset = gst_ebml_read_get_pos (ebml);
267   if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, &data))
268     return GST_FLOW_PARSE;
269
270   GST_LOG_OBJECT (ebml->el, "pushing level %d at offset %" G_GUINT64_FORMAT,
271       ebml->readers->len, m.offset);
272   gst_byte_reader_init (&m.br, data, length);
273   g_array_append_val (ebml->readers, m);
274
275   return GST_FLOW_OK;
276 }
277
278 /* explicitly pop a bytereader from stack.  Usually invoked automagically. */
279 GstFlowReturn
280 gst_ebml_read_pop_master (GstEbmlRead * ebml)
281 {
282   g_return_val_if_fail (ebml->readers, GST_FLOW_ERROR);
283
284   /* never remove initial bytereader */
285   if (ebml->readers->len > 1) {
286     GST_LOG_OBJECT (ebml->el, "popping level %d", ebml->readers->len - 1);
287     g_array_remove_index (ebml->readers, ebml->readers->len - 1);
288   }
289
290   return GST_FLOW_OK;
291 }
292
293 /*
294  * Skip the next element.
295  */
296
297 GstFlowReturn
298 gst_ebml_read_skip (GstEbmlRead * ebml)
299 {
300   guint64 length;
301   guint32 id;
302   guint prefix;
303   GstFlowReturn ret;
304
305   ret = gst_ebml_peek_id_full (ebml, &id, &length, &prefix);
306   if (ret != GST_FLOW_OK)
307     return ret;
308
309   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), length + prefix))
310     return GST_FLOW_PARSE;
311
312   return ret;
313 }
314
315 /*
316  * Read the next element as a GstBuffer (binary).
317  */
318
319 GstFlowReturn
320 gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
321 {
322   guint64 length;
323   guint prefix;
324   GstFlowReturn ret;
325
326   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
327   if (ret != GST_FLOW_OK)
328     return ret;
329
330   /* we just at least peeked the id */
331   g_assert (gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix));
332
333   if (G_LIKELY (length > 0)) {
334     guint offset;
335
336     offset = gst_ebml_read_get_pos (ebml) - ebml->offset;
337     if (G_LIKELY (gst_byte_reader_skip (gst_ebml_read_br (ebml), length))) {
338       *buf = gst_buffer_create_sub (ebml->buf, offset, length);
339     } else {
340       *buf = NULL;
341       return GST_FLOW_PARSE;
342     }
343   } else {
344     *buf = gst_buffer_new ();
345   }
346
347   return ret;
348 }
349
350 /*
351  * Read the next element, return a pointer to it and its size.
352  */
353
354 static GstFlowReturn
355 gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, const guint8 ** data,
356     guint * size)
357 {
358   guint64 length;
359   guint prefix;
360   GstFlowReturn ret;
361
362   *size = 0;
363
364   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
365   if (ret != GST_FLOW_OK)
366     return ret;
367
368   /* we just at least peeked the id */
369   g_assert (gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix));
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 < 1 || 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   *num = 0;
405   while (size > 0) {
406     *num = (*num << 8) | *data;
407     size--;
408     data++;
409   }
410
411   return ret;
412 }
413
414 /*
415  * Read the next element as a signed int.
416  */
417
418 GstFlowReturn
419 gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
420 {
421   const guint8 *data;
422   guint size;
423   gboolean negative = 0;
424   GstFlowReturn ret;
425
426   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
427   if (ret != GST_FLOW_OK)
428     return ret;
429
430   if (size < 1 || size > 8) {
431     GST_ERROR_OBJECT (ebml->el,
432         "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
433         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
434         gst_ebml_read_get_pos (ebml) - size);
435     return GST_FLOW_ERROR;
436   }
437
438   *num = 0;
439   if (*data & 0x80) {
440     negative = 1;
441     *num = *data & ~0x80;
442     size--;
443     data++;
444   }
445
446   while (size > 0) {
447     *num = (*num << 8) | *data;
448     size--;
449     data++;
450   }
451
452   /* make signed */
453   if (negative) {
454     *num = 0 - *num;
455   }
456
457   return ret;
458 }
459
460 /* Convert 80 bit extended precision float in big endian format to double.
461  * Code taken from libavutil/intfloat_readwrite.c from ffmpeg,
462  * licensed under LGPL */
463
464 struct _ext_float
465 {
466   guint8 exponent[2];
467   guint8 mantissa[8];
468 };
469
470 static gdouble
471 _ext2dbl (const guint8 * data)
472 {
473   struct _ext_float ext;
474   guint64 m = 0;
475   gint e, i;
476
477   memcpy (&ext.exponent, data, 2);
478   memcpy (&ext.mantissa, data + 2, 8);
479
480   for (i = 0; i < 8; i++)
481     m = (m << 8) + ext.mantissa[i];
482   e = (((gint) ext.exponent[0] & 0x7f) << 8) | ext.exponent[1];
483   if (e == 0x7fff && m)
484     return NAN;
485   e -= 16383 + 63;              /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
486                                  * mantissa bit is written as opposed to the
487                                  * single and double precision formats */
488   if (ext.exponent[0] & 0x80)
489     m = -m;
490   return ldexp (m, e);
491 }
492
493 /*
494  * Read the next element as a float.
495  */
496
497 GstFlowReturn
498 gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
499 {
500   const guint8 *data;
501   guint size;
502   GstFlowReturn ret;
503
504   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
505   if (ret != GST_FLOW_OK)
506     return ret;
507
508   if (size != 4 && size != 8 && size != 10) {
509     GST_ERROR_OBJECT (ebml->el,
510         "Invalid float element size %d at position %" G_GUINT64_FORMAT " (0x%"
511         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
512         gst_ebml_read_get_pos (ebml) - size);
513     return GST_FLOW_ERROR;
514   }
515
516   if (size == 4) {
517     gfloat f;
518
519     memcpy (&f, data, 4);
520     f = GFLOAT_FROM_BE (f);
521
522     *num = f;
523   } else if (size == 8) {
524     gdouble d;
525
526     memcpy (&d, data, 8);
527     d = GDOUBLE_FROM_BE (d);
528
529     *num = d;
530   } else {
531     *num = _ext2dbl (data);
532   }
533
534   return ret;
535 }
536
537 /*
538  * Read the next element as a C string.
539  */
540
541 static GstFlowReturn
542 gst_ebml_read_string (GstEbmlRead * ebml, guint32 * id, gchar ** str)
543 {
544   const guint8 *data;
545   guint size;
546   GstFlowReturn ret;
547
548   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
549   if (ret != GST_FLOW_OK)
550     return ret;
551
552   *str = g_malloc (size + 1);
553   memcpy (*str, data, size);
554   (*str)[size] = '\0';
555
556   return ret;
557 }
558
559 /*
560  * Read the next element as an ASCII string.
561  */
562
563 GstFlowReturn
564 gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str_out)
565 {
566   GstFlowReturn ret;
567   gchar *str;
568   gchar *iter;
569
570 #ifndef GST_DISABLE_GST_DEBUG
571   guint64 oldoff = ebml->offset;
572 #endif
573
574   ret = gst_ebml_read_string (ebml, id, &str);
575   if (ret != GST_FLOW_OK)
576     return ret;
577
578   for (iter = str; *iter != '\0'; iter++) {
579     if (G_UNLIKELY (*iter & 0x80)) {
580       GST_ERROR_OBJECT (ebml,
581           "Invalid ASCII string at offset %" G_GUINT64_FORMAT, oldoff);
582       g_free (str);
583       return GST_FLOW_ERROR;
584     }
585   }
586
587   *str_out = str;
588   return ret;
589 }
590
591 /*
592  * Read the next element as a UTF-8 string.
593  */
594
595 GstFlowReturn
596 gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
597 {
598   GstFlowReturn ret;
599
600 #ifndef GST_DISABLE_GST_DEBUG
601   guint64 oldoff = gst_ebml_read_get_pos (ebml);
602 #endif
603
604   ret = gst_ebml_read_string (ebml, id, str);
605   if (ret != GST_FLOW_OK)
606     return ret;
607
608   if (str != NULL && *str != NULL && **str != '\0' &&
609       !g_utf8_validate (*str, -1, NULL)) {
610     GST_WARNING_OBJECT (ebml->el,
611         "Invalid UTF-8 string at offset %" G_GUINT64_FORMAT, oldoff);
612   }
613
614   return ret;
615 }
616
617 /*
618  * Read the next element as a date.
619  * Returns the seconds since the unix epoch.
620  */
621
622 GstFlowReturn
623 gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
624 {
625   gint64 ebml_date;
626   GstFlowReturn ret;
627
628   ret = gst_ebml_read_sint (ebml, id, &ebml_date);
629   if (ret != GST_FLOW_OK)
630     return ret;
631
632   *date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;
633
634   return ret;
635 }
636
637 /*
638  * Read the next element as binary data.
639  */
640
641 GstFlowReturn
642 gst_ebml_read_binary (GstEbmlRead * ebml,
643     guint32 * id, guint8 ** binary, guint64 * length)
644 {
645   const guint8 *data;
646   guint size;
647   GstFlowReturn ret;
648
649   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
650   if (ret != GST_FLOW_OK)
651     return ret;
652
653   *length = size;
654   *binary = g_memdup (data, size);
655
656   return GST_FLOW_OK;
657 }