/* 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_pad_template (element_class,
      gst_static_pad_template_get (&gst_webp_dec_src_pad_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&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);
}
