/* 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_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;

  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;

  gst_video_decoder_set_packetized (GST_VIDEO_DECODER (webpdec), FALSE);

  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);

  if (decoder->input_segment.format == GST_FORMAT_TIME)
    gst_video_decoder_set_packetized (decoder, TRUE);
  else
    gst_video_decoder_set_packetized (decoder, FALSE);

  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 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);
}
