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

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