/* GStreamer
 * Copyright (C) <2013> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
 * Copyright (C) <2013> Intel Corporation
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>

#include "gstwebpdec.h"

#define MIN_WIDTH 1
#define MAX_WIDTH 16383
#define MIN_HEIGHT 1
#define MAX_HEIGHT 16383

enum
{
  PROP_0,
  PROP_BYPASS_FILTERING,
  PROP_NO_FANCY_UPSAMPLING,
  PROP_USE_THREADS
};

static GstStaticPadTemplate gst_webp_dec_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("image/webp")
    );

/*Fixme: Add YUV support */
static GstStaticPadTemplate gst_webp_dec_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ RGB, RGBA, BGR, BGRA, ARGB, RGB16}"))
    );

GST_DEBUG_CATEGORY_STATIC (webp_dec_debug);
#define GST_CAT_DEFAULT webp_dec_debug

static void gst_webp_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_webp_dec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_webp_dec_start (GstVideoDecoder * bdec);
static gboolean gst_webp_dec_stop (GstVideoDecoder * bdec);
static gboolean gst_webp_dec_set_format (GstVideoDecoder * dec,
    GstVideoCodecState * state);
static GstFlowReturn gst_webp_dec_parse (GstVideoDecoder * bdec,
    GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos);
static GstFlowReturn gst_webp_dec_handle_frame (GstVideoDecoder * bdec,
    GstVideoCodecFrame * frame);
static gboolean gst_webp_dec_decide_allocation (GstVideoDecoder * bdec,
    GstQuery * query);
static gboolean gst_webp_dec_sink_event (GstVideoDecoder * bdec,
    GstEvent * event);

static gboolean gst_webp_dec_reset_frame (GstWebPDec * webpdec);

#define gst_webp_dec_parent_class parent_class
G_DEFINE_TYPE (GstWebPDec, gst_webp_dec, GST_TYPE_VIDEO_DECODER);

static void
gst_webp_dec_class_init (GstWebPDecClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstVideoDecoderClass *vdec_class;

  gobject_class = (GObjectClass *) klass;
  element_class = (GstElementClass *) klass;
  vdec_class = (GstVideoDecoderClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = gst_webp_dec_set_property;
  gobject_class->get_property = gst_webp_dec_get_property;

  gst_element_class_add_static_pad_template (element_class,
      &gst_webp_dec_src_pad_template);
  gst_element_class_add_static_pad_template (element_class,
      &gst_webp_dec_sink_pad_template);
  gst_element_class_set_static_metadata (element_class, "WebP image decoder",
      "Codec/Decoder/Image", "Decode images from WebP format",
      "Sreerenj Balachandran <sreerenj.balachandrn@intel.com>");

  g_object_class_install_property (gobject_class, PROP_BYPASS_FILTERING,
      g_param_spec_boolean ("bypass-filtering", "Bypass Filtering",
          "When enabled, skip the in-loop filtering", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_NO_FANCY_UPSAMPLING,
      g_param_spec_boolean ("no-fancy-upsampling", "No Fancy Upsampling",
          "When enabled, use faster pointwise upsampler", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_USE_THREADS,
      g_param_spec_boolean ("use-threads", "Use Threads",
          "When enabled, use multi-threaded decoding", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  vdec_class->start = gst_webp_dec_start;
  vdec_class->stop = gst_webp_dec_stop;
  vdec_class->parse = gst_webp_dec_parse;
  vdec_class->set_format = gst_webp_dec_set_format;
  vdec_class->handle_frame = gst_webp_dec_handle_frame;
  vdec_class->decide_allocation = gst_webp_dec_decide_allocation;
  vdec_class->sink_event = gst_webp_dec_sink_event;

  GST_DEBUG_CATEGORY_INIT (webp_dec_debug, "webpdec", 0, "WebP decoder");
}

static void
gst_webp_dec_init (GstWebPDec * dec)
{
  GST_DEBUG ("Initialize the webp decoder");

  memset (&dec->config, 0, sizeof (dec->config));
  dec->saw_header = FALSE;

  dec->bypass_filtering = FALSE;
  dec->no_fancy_upsampling = FALSE;
  dec->use_threads = FALSE;
  gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
      (dec), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (dec));
}

static gboolean
gst_webp_dec_reset_frame (GstWebPDec * webpdec)
{
  GST_DEBUG ("Reset the current frame properties");

  webpdec->saw_header = FALSE;

  if (!WebPInitDecoderConfig (&webpdec->config)) {
    GST_WARNING_OBJECT (webpdec,
        "Failed to configure the WebP image decoding libraray");
    return FALSE;
  }
  return TRUE;
}

static void
gst_webp_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWebPDec *dec;

  dec = GST_WEBP_DEC (object);

  switch (prop_id) {
    case PROP_BYPASS_FILTERING:
      dec->bypass_filtering = g_value_get_boolean (value);
      break;
    case PROP_NO_FANCY_UPSAMPLING:
      dec->no_fancy_upsampling = g_value_get_boolean (value);
      break;
    case PROP_USE_THREADS:
      dec->use_threads = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_webp_dec_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstWebPDec *dec;

  dec = GST_WEBP_DEC (object);

  switch (prop_id) {
    case PROP_BYPASS_FILTERING:
      g_value_set_boolean (value, dec->bypass_filtering);
      break;
    case PROP_NO_FANCY_UPSAMPLING:
      g_value_set_boolean (value, dec->no_fancy_upsampling);
      break;
    case PROP_USE_THREADS:
      g_value_set_boolean (value, dec->use_threads);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_webp_dec_start (GstVideoDecoder * decoder)
{
  GstWebPDec *webpdec = (GstWebPDec *) decoder;

  return gst_webp_dec_reset_frame (webpdec);
}

static gboolean
gst_webp_dec_stop (GstVideoDecoder * bdec)
{
  GstWebPDec *webpdec = (GstWebPDec *) bdec;

  if (webpdec->input_state) {
    gst_video_codec_state_unref (webpdec->input_state);
    webpdec->input_state = NULL;
  }
  if (webpdec->output_state) {
    gst_video_codec_state_unref (webpdec->output_state);
    webpdec->output_state = NULL;
  }
  return TRUE;
}

static gboolean
gst_webp_dec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
{
  GstWebPDec *webpdec = (GstWebPDec *) decoder;

  if (webpdec->input_state)
    gst_video_codec_state_unref (webpdec->input_state);
  webpdec->input_state = gst_video_codec_state_ref (state);

  return TRUE;
}

static gboolean
gst_webp_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
{
  GstBufferPool *pool = NULL;
  GstStructure *config;

  if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
    return FALSE;

  if (gst_query_get_n_allocation_pools (query) > 0)
    gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);

  if (pool == NULL)
    return FALSE;

  config = gst_buffer_pool_get_config (pool);
  if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_VIDEO_META);
  }
  gst_buffer_pool_set_config (pool, config);
  gst_object_unref (pool);

  return TRUE;
}

static gboolean
gst_webp_dec_sink_event (GstVideoDecoder * bdec, GstEvent * event)
{
  const GstSegment *segment;

  if (GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT)
    goto done;

  gst_event_parse_segment (event, &segment);

  if (segment->format == GST_FORMAT_TIME)
    gst_video_decoder_set_packetized (bdec, TRUE);
  else
    gst_video_decoder_set_packetized (bdec, FALSE);

done:
  return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (bdec, event);
}

static GstFlowReturn
gst_webp_dec_parse (GstVideoDecoder * decoder, GstVideoCodecFrame * frame,
    GstAdapter * adapter, gboolean at_eos)
{
  gsize toadd = 0;
  gsize size;
  gconstpointer data;
  GstByteReader reader;
  GstWebPDec *webpdec = (GstWebPDec *) decoder;

  size = gst_adapter_available (adapter);
  GST_DEBUG_OBJECT (decoder,
      "parsing webp image data (%" G_GSIZE_FORMAT " bytes)", size);

  if (at_eos) {
    GST_DEBUG ("Flushing all data out");
    toadd = size;

    /* If we have leftover data, throw it away */
    if (!webpdec->saw_header)
      goto drop_frame;
    goto have_full_frame;
  }

  if (!webpdec->saw_header) {
    guint32 code;

    if (size < 12)
      goto need_more_data;

    data = gst_adapter_map (adapter, size);
    gst_byte_reader_init (&reader, data, size);

    if (!gst_byte_reader_get_uint32_le (&reader, &code))
      goto error;

    if (code == GST_MAKE_FOURCC ('R', 'I', 'F', 'F')) {
      if (!gst_byte_reader_get_uint32_le (&reader, &webpdec->frame_size))
        goto error;

      if (!gst_byte_reader_get_uint32_le (&reader, &code))
        goto error;

      if (code == GST_MAKE_FOURCC ('W', 'E', 'B', 'P'))
        webpdec->saw_header = TRUE;

    }
  }

  if (!webpdec->saw_header)
    goto error;

  if (size >= (webpdec->frame_size + 8)) {
    toadd = webpdec->frame_size + 8;
    webpdec->saw_header = FALSE;
    goto have_full_frame;
  }

need_more_data:
  return GST_VIDEO_DECODER_FLOW_NEED_DATA;

have_full_frame:
  if (toadd)
    gst_video_decoder_add_to_frame (decoder, toadd);
  return gst_video_decoder_have_frame (decoder);

drop_frame:
  gst_adapter_flush (adapter, size);
  return GST_FLOW_OK;

error:
  return GST_FLOW_ERROR;
}

static GstFlowReturn
gst_webp_dec_update_src_caps (GstWebPDec * dec, GstMapInfo * map_info)
{
  WebPBitstreamFeatures features;
  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;

  if (WebPGetFeatures (map_info->data, map_info->size,
          &features) != VP8_STATUS_OK) {
    GST_ERROR_OBJECT (dec, "Failed to execute WebPGetFeatures");
    return GST_FLOW_ERROR;
  }

  if (features.width < MIN_WIDTH || features.width > MAX_WIDTH
      || features.height < MIN_HEIGHT || features.height > MAX_HEIGHT) {
    GST_ERROR_OBJECT (dec, "Dimensions of the frame is unspported by libwebp");
    return GST_FLOW_ERROR;
  }

  /* TODO: Add support for other formats */
  if (features.has_alpha) {
    format = GST_VIDEO_FORMAT_ARGB;
    dec->colorspace = MODE_ARGB;
  } else {
    format = GST_VIDEO_FORMAT_RGB;
    dec->colorspace = MODE_RGB;
  }

  /* Check if output state changed */
  if (dec->output_state) {
    GstVideoInfo *info = &dec->output_state->info;

    if (features.width == GST_VIDEO_INFO_WIDTH (info) &&
        features.height == GST_VIDEO_INFO_HEIGHT (info) &&
        GST_VIDEO_INFO_FORMAT (info) == format) {
      goto beach;
    }
    gst_video_codec_state_unref (dec->output_state);
  }

  dec->output_state =
      gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec), format,
      features.width, features.height, dec->input_state);

  if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec)))
    return GST_FLOW_NOT_NEGOTIATED;

beach:
  return GST_FLOW_OK;
}

static GstFlowReturn
gst_webp_dec_handle_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame)
{
  GstWebPDec *webpdec = (GstWebPDec *) decoder;
  GstMapInfo map_info;
  GstFlowReturn ret = GST_FLOW_OK;
  GstVideoFrame vframe;

  gst_buffer_map (frame->input_buffer, &map_info, GST_MAP_READ);

  ret = gst_webp_dec_update_src_caps (webpdec, &map_info);
  if (ret != GST_FLOW_OK) {
    gst_buffer_unmap (frame->input_buffer, &map_info);
    gst_video_codec_frame_unref (frame);
    goto done;
  }

  ret = gst_video_decoder_allocate_output_frame (decoder, frame);
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    GST_ERROR_OBJECT (decoder, "failed to allocate output frame");
    ret = GST_FLOW_ERROR;
    gst_buffer_unmap (frame->input_buffer, &map_info);
    gst_video_codec_frame_unref (frame);

    goto done;
  }

  if (!gst_video_frame_map (&vframe, &webpdec->output_state->info,
          frame->output_buffer, GST_MAP_READWRITE)) {
    GST_ERROR_OBJECT (decoder, "Failed to map output videoframe");
    ret = GST_FLOW_ERROR;
    gst_buffer_unmap (frame->input_buffer, &map_info);
    gst_video_codec_frame_unref (frame);

    goto done;
  }

  /* configure output buffer parameteres */
  webpdec->config.options.bypass_filtering = webpdec->bypass_filtering;
  webpdec->config.options.no_fancy_upsampling = webpdec->no_fancy_upsampling;
  webpdec->config.options.use_threads = webpdec->use_threads;
  webpdec->config.output.colorspace = webpdec->colorspace;
  webpdec->config.output.u.RGBA.rgba = (uint8_t *) vframe.map[0].data;
  webpdec->config.output.u.RGBA.stride =
      GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
  webpdec->config.output.u.RGBA.size = GST_VIDEO_FRAME_SIZE (&vframe);
  webpdec->config.output.is_external_memory = 1;

  if (WebPDecode (map_info.data, map_info.size,
          &webpdec->config) != VP8_STATUS_OK) {
    GST_ERROR_OBJECT (decoder, "Failed to decode the webp frame");
    ret = GST_FLOW_ERROR;
    gst_video_frame_unmap (&vframe);
    gst_buffer_unmap (frame->input_buffer, &map_info);
    gst_video_codec_frame_unref (frame);

    goto done;
  }

  gst_video_frame_unmap (&vframe);
  gst_buffer_unmap (frame->input_buffer, &map_info);

  ret = gst_video_decoder_finish_frame (decoder, frame);

  if (!gst_webp_dec_reset_frame (webpdec)) {
    ret = GST_FLOW_ERROR;
    goto done;
  }

done:
  return ret;
}

gboolean
gst_webp_dec_register (GstPlugin * plugin)
{
  return gst_element_register (plugin, "webpdec",
      GST_RANK_PRIMARY, GST_TYPE_WEBP_DEC);
}
