/* GStreamer AVI GAB2 subtitle parser
 * Copyright (C) <2007> Thijs Vermeir <thijsvermeir@gmail.com>
 * Copyright (C) <2007> Tim-Philipp Müller <tim centricular net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:element-avisubtitle
 *
 * <refsect2>
 * <para>
 * Parses the subtitle stream from an avi file.
 * </para>
 * <title>Example launch line</title>
 * <para>
 * <programlisting>
 * gst-launch-1.0 filesrc location=subtitle.avi ! avidemux name=demux ! queue ! avisubtitle ! subparse ! textoverlay name=overlay ! videoconvert ! autovideosink demux. ! queue ! decodebin ! overlay.
 * </programlisting>
 * This plays an avi file with a video and subtitle stream.
 * </para>
 * </refsect2>
 *
 * Last reviewed on 2008-02-01
 */

/* example of a subtitle chunk in an avi file
 * 00000000: 47 41 42 32 00 02 00 10 00 00 00 45 00 6e 00 67  GAB2.......E.n.g
 * 00000010: 00 6c 00 69 00 73 00 68 00 00 00 04 00 8e 00 00  .l.i.s.h........
 * 00000020: 00 ef bb bf 31 0d 0a 30 30 3a 30 30 3a 30 30 2c  ....1..00:00:00,
 * 00000030: 31 30 30 20 2d 2d 3e 20 30 30 3a 30 30 3a 30 32  100 --> 00:00:02
 * 00000040: 2c 30 30 30 0d 0a 3c 62 3e 41 6e 20 55 54 46 38  ,000..<b>An UTF8
 * 00000050: 20 53 75 62 74 69 74 6c 65 20 77 69 74 68 20 42   Subtitle with B
 * 00000060: 4f 4d 3c 2f 62 3e 0d 0a 0d 0a 32 0d 0a 30 30 3a  OM</b>....2..00:
 * 00000070: 30 30 3a 30 32 2c 31 30 30 20 2d 2d 3e 20 30 30  00:02,100 --> 00
 * 00000080: 3a 30 30 3a 30 34 2c 30 30 30 0d 0a 53 6f 6d 65  :00:04,000..Some
 * 00000090: 74 68 69 6e 67 20 6e 6f 6e 41 53 43 49 49 20 2d  thing nonASCII -
 * 000000a0: 20 c2 b5 c3 b6 c3 a4 c3 bc c3 9f 0d 0a 0d 0a      ..............
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>

#include "gstavisubtitle.h"

GST_DEBUG_CATEGORY_STATIC (avisubtitle_debug);
#define GST_CAT_DEFAULT avisubtitle_debug

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-subtitle-avi")
    );

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-subtitle")
    );

static void gst_avi_subtitle_title_tag (GstAviSubtitle * sub, gchar * title);
static GstFlowReturn gst_avi_subtitle_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstStateChangeReturn gst_avi_subtitle_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_avi_subtitle_send_event (GstElement * element,
    GstEvent * event);

#define gst_avi_subtitle_parent_class parent_class
G_DEFINE_TYPE (GstAviSubtitle, gst_avi_subtitle, GST_TYPE_ELEMENT);

#define IS_BOM_UTF8(data)     ((GST_READ_UINT32_BE(data) >> 8) == 0xEFBBBF)
#define IS_BOM_UTF16_BE(data) (GST_READ_UINT16_BE(data) == 0xFEFF)
#define IS_BOM_UTF16_LE(data) (GST_READ_UINT16_LE(data) == 0xFEFF)
#define IS_BOM_UTF32_BE(data) (GST_READ_UINT32_BE(data) == 0xFEFF)
#define IS_BOM_UTF32_LE(data) (GST_READ_UINT32_LE(data) == 0xFEFF)

static GstBuffer *
gst_avi_subtitle_extract_file (GstAviSubtitle * sub, GstBuffer * buffer,
    guint offset, guint len)
{
  const gchar *input_enc = NULL;
  GstBuffer *ret = NULL;
  gchar *data;
  GstMapInfo map;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  data = (gchar *) (map.data + offset);

  if (len >= (3 + 1) && IS_BOM_UTF8 (data) &&
      g_utf8_validate (data + 3, len - 3, NULL)) {
    ret =
        gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset + 3,
        len - 3);
  } else if (len >= 2 && IS_BOM_UTF16_BE (data)) {
    input_enc = "UTF-16BE";
    data += 2;
    len -= 2;
  } else if (len >= 2 && IS_BOM_UTF16_LE (data)) {
    input_enc = "UTF-16LE";
    data += 2;
    len -= 2;
  } else if (len >= 4 && IS_BOM_UTF32_BE (data)) {
    input_enc = "UTF-32BE";
    data += 4;
    len -= 4;
  } else if (len >= 4 && IS_BOM_UTF32_LE (data)) {
    input_enc = "UTF-32LE";
    data += 4;
    len -= 4;
  } else if (g_utf8_validate (data, len, NULL)) {
    /* not specified, check if it's UTF-8 */
    ret = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, len);
  } else {
    /* we could fall back to gst_tag_freeform_to_utf8() here */
    GST_WARNING_OBJECT (sub, "unspecified encoding, and not UTF-8");
    ret = NULL;
    goto done;
  }

  g_return_val_if_fail (ret != NULL || input_enc != NULL, NULL);

  if (input_enc) {
    GError *err = NULL;
    gchar *utf8;
    gsize slen;

    GST_DEBUG_OBJECT (sub, "converting subtitles from %s to UTF-8", input_enc);
    utf8 = g_convert (data, len, "UTF-8", input_enc, NULL, NULL, &err);

    if (err != NULL) {
      GST_WARNING_OBJECT (sub, "conversion to UTF-8 failed : %s", err->message);
      g_error_free (err);
      ret = NULL;
      goto done;
    }

    ret = gst_buffer_new ();
    slen = strlen (utf8);
    gst_buffer_append_memory (ret,
        gst_memory_new_wrapped (0, utf8, slen, 0, slen, utf8, g_free));

    GST_BUFFER_OFFSET (ret) = 0;
  }

done:
  gst_buffer_unmap (buffer, &map);

  return ret;
}

/**
 * gst_avi_subtitle_title_tag:
 * @sub: subtitle element
 * @title: the title of this subtitle stream
 *
 * Send an event to the srcpad of the @sub element with the title
 * of the subtitle stream as a GST_TAG_TITLE
 */
static void
gst_avi_subtitle_title_tag (GstAviSubtitle * sub, gchar * title)
{
  gst_pad_push_event (sub->src,
      gst_event_new_tag (gst_tag_list_new (GST_TAG_TITLE, title, NULL)));
}

static GstFlowReturn
gst_avi_subtitle_parse_gab2_chunk (GstAviSubtitle * sub, GstBuffer * buf)
{
  gchar *name_utf8;
  guint name_length;
  guint file_length;
  GstMapInfo map;

  gst_buffer_map (buf, &map, GST_MAP_READ);

  /* check the magic word "GAB2\0", and the next word must be 2 */
  if (map.size < 12 || memcmp (map.data, "GAB2\0\2\0", 5 + 2) != 0)
    goto wrong_magic_word;

  /* read 'name' of subtitle */
  name_length = GST_READ_UINT32_LE (map.data + 5 + 2);
  GST_LOG_OBJECT (sub, "length of name: %u", name_length);
  if (map.size <= 17 + name_length)
    goto wrong_name_length;

  name_utf8 =
      g_convert ((gchar *) map.data + 11, name_length, "UTF-8", "UTF-16LE",
      NULL, NULL, NULL);

  if (name_utf8) {
    GST_LOG_OBJECT (sub, "subtitle name: %s", name_utf8);
    gst_avi_subtitle_title_tag (sub, name_utf8);
    g_free (name_utf8);
  }

  /* next word must be 4 */
  if (GST_READ_UINT16_LE (map.data + 11 + name_length) != 0x4)
    goto wrong_fixed_word_2;

  file_length = GST_READ_UINT32_LE (map.data + 13 + name_length);
  GST_LOG_OBJECT (sub, "length srt/ssa file: %u", file_length);

  if (map.size < (17 + name_length + file_length))
    goto wrong_total_length;

  /* store this, so we can send it again after a seek; note that we shouldn't
   * assume all the remaining data in the chunk is subtitle data, there may
   * be padding at the end for some reason, so only parse file_length bytes */
  sub->subfile =
      gst_avi_subtitle_extract_file (sub, buf, 17 + name_length, file_length);

  if (sub->subfile == NULL)
    goto extract_failed;

  gst_buffer_unmap (buf, &map);

  return GST_FLOW_OK;

  /* ERRORS */
wrong_magic_word:
  {
    GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL), ("Wrong magic word"));
    gst_buffer_unmap (buf, &map);
    return GST_FLOW_ERROR;
  }
wrong_name_length:
  {
    GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
        ("name doesn't fit in buffer (%" G_GSIZE_FORMAT " < %d)", map.size,
            17 + name_length));
    gst_buffer_unmap (buf, &map);
    return GST_FLOW_ERROR;
  }
wrong_fixed_word_2:
  {
    GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
        ("wrong fixed word: expected %u, got %u", 4,
            GST_READ_UINT16_LE (map.data + 11 + name_length)));
    gst_buffer_unmap (buf, &map);
    return GST_FLOW_ERROR;
  }
wrong_total_length:
  {
    GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
        ("buffer size is wrong: need %d bytes, have %" G_GSIZE_FORMAT " bytes",
            17 + name_length + file_length, map.size));
    gst_buffer_unmap (buf, &map);
    return GST_FLOW_ERROR;
  }
extract_failed:
  {
    GST_ELEMENT_ERROR (sub, STREAM, DECODE, (NULL),
        ("could not extract subtitles"));
    gst_buffer_unmap (buf, &map);
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
gst_avi_subtitle_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstAviSubtitle *sub = GST_AVI_SUBTITLE (parent);
  GstFlowReturn ret;

  if (sub->subfile != NULL) {
    GST_WARNING_OBJECT (sub, "Got more buffers than expected, dropping");
    ret = GST_FLOW_EOS;
    goto done;
  }

  /* we expect exactly one buffer with the whole srt/ssa file in it */
  ret = gst_avi_subtitle_parse_gab2_chunk (sub, buffer);
  if (ret != GST_FLOW_OK)
    goto done;

  /* now push the subtitle data downstream */
  ret = gst_pad_push (sub->src, gst_buffer_ref (sub->subfile));

done:

  gst_buffer_unref (buffer);
  return ret;
}

static gboolean
gst_avi_subtitle_send_event (GstElement * element, GstEvent * event)
{
  GstAviSubtitle *avisubtitle = GST_AVI_SUBTITLE (element);
  gboolean ret = FALSE;

  if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
    if (avisubtitle->subfile) {
      if (gst_pad_push (avisubtitle->src,
              gst_buffer_ref (avisubtitle->subfile)) == GST_FLOW_OK)
        ret = TRUE;
    }
  }
  gst_event_unref (event);
  return ret;
}

static void
gst_avi_subtitle_class_init (GstAviSubtitleClass * klass)
{
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  GST_DEBUG_CATEGORY_INIT (avisubtitle_debug, "avisubtitle", 0,
      "parse avi subtitle stream");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_avi_subtitle_change_state);
  gstelement_class->send_event =
      GST_DEBUG_FUNCPTR (gst_avi_subtitle_send_event);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_template));

  gst_element_class_set_static_metadata (gstelement_class,
      "Avi subtitle parser", "Codec/Parser/Subtitle",
      "Parse avi subtitle stream", "Thijs Vermeir <thijsvermeir@gmail.com>");
}

static void
gst_avi_subtitle_init (GstAviSubtitle * self)
{
  GstCaps *caps;

  self->src = gst_pad_new_from_static_template (&src_template, "src");
  gst_element_add_pad (GST_ELEMENT (self), self->src);

  self->sink = gst_pad_new_from_static_template (&sink_template, "sink");
  gst_pad_set_chain_function (self->sink,
      GST_DEBUG_FUNCPTR (gst_avi_subtitle_chain));

  caps = gst_static_pad_template_get_caps (&src_template);
  gst_pad_set_caps (self->src, caps);
  gst_caps_unref (caps);

  gst_pad_use_fixed_caps (self->src);
  gst_element_add_pad (GST_ELEMENT (self), self->sink);

  self->subfile = NULL;
}

static GstStateChangeReturn
gst_avi_subtitle_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstAviSubtitle *sub = GST_AVI_SUBTITLE (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (sub->subfile) {
        gst_buffer_unref (sub->subfile);
        sub->subfile = NULL;
      }
      break;
    default:
      break;
  }

  return ret;
}
