/* GStreamer
 * Copyright (C) <2014> Sreerenj Balachandran <sreerenjb@gnome.org>
 *
 * 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 <stdlib.h>             /* free */

#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>

#include "gstwebpenc.h"

#define GST_CAT_DEFAULT webpenc_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0,
  PROP_LOSSLESS,
  PROP_QUALITY,
  PROP_SPEED,
  PROP_PRESET
};

#define DEFAULT_LOSSLESS FALSE
#define DEFAULT_QUALITY 90
#define DEFAULT_SPEED 4
#define DEFAULT_PRESET WEBP_PRESET_PHOTO

static void gst_webp_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_webp_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static gboolean gst_webp_enc_start (GstVideoEncoder * benc);
static gboolean gst_webp_enc_stop (GstVideoEncoder * benc);
static gboolean gst_webp_enc_set_format (GstVideoEncoder * encoder,
    GstVideoCodecState * state);
static GstFlowReturn gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
    GstVideoCodecFrame * frame);
static gboolean gst_webp_enc_propose_allocation (GstVideoEncoder * encoder,
    GstQuery * query);

static GstStaticPadTemplate webp_enc_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12, RGB, RGBA}"))
    );
static GstStaticPadTemplate webp_enc_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("image/webp, "
        "framerate = (fraction) [0/1, MAX], "
        "width = (int) [ 16, 16383 ], " "height = (int) [ 16, 16383 ]")
    );

enum
{
  GST_WEBP_PRESET_DEFAULT,
  GST_WEBP_PRESET_PICTURE,
  GST_WEBP_PRESET_PHOTO,
  GST_WEBP_PRESET_DRAWING,
  GST_WEBP_PRESET_ICON,
  GST_WEBP_PREET_TEXT
};

static const GEnumValue preset_values[] = {
  {GST_WEBP_PRESET_DEFAULT, "Default", "none"},
  {GST_WEBP_PRESET_PICTURE, "Digital picture,inner shot", "picture"},
  {GST_WEBP_PRESET_PHOTO, "Outdoor photo, natural lighting", "photo"},
  {GST_WEBP_PRESET_DRAWING, "Hand or Line drawing", "drawing"},
  {GST_WEBP_PRESET_ICON, "Small-sized colorful images", "icon"},
  {GST_WEBP_PREET_TEXT, "text-like", "text"},
  {0, NULL, NULL},
};

#define GST_WEBP_ENC_PRESET_TYPE (gst_webp_enc_preset_get_type())
static GType
gst_webp_enc_preset_get_type (void)
{
  static GType preset_type = 0;

  if (!preset_type) {
    preset_type = g_enum_register_static ("GstWebpEncPreset", preset_values);
  }
  return preset_type;
}

#define gst_webp_enc_parent_class parent_class
G_DEFINE_TYPE (GstWebpEnc, gst_webp_enc, GST_TYPE_VIDEO_ENCODER);

static void
gst_webp_enc_class_init (GstWebpEncClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstVideoEncoderClass *venc_class;

  gobject_class = (GObjectClass *) klass;
  element_class = (GstElementClass *) klass;
  venc_class = (GstVideoEncoderClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = gst_webp_enc_set_property;
  gobject_class->get_property = gst_webp_enc_get_property;
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&webp_enc_sink_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&webp_enc_src_factory));
  gst_element_class_set_static_metadata (element_class, "WEBP image encoder",
      "Codec/Encoder/Image",
      "Encode images in WEBP format",
      "Sreerenj Balachandran <sreerenjb@gnome.org>");

  venc_class->start = gst_webp_enc_start;
  venc_class->stop = gst_webp_enc_stop;
  venc_class->set_format = gst_webp_enc_set_format;
  venc_class->handle_frame = gst_webp_enc_handle_frame;
  venc_class->propose_allocation = gst_webp_enc_propose_allocation;

  g_object_class_install_property (gobject_class, PROP_LOSSLESS,
      g_param_spec_boolean ("lossless", "Lossless",
          "Enable lossless encoding",
          DEFAULT_LOSSLESS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_QUALITY,
      g_param_spec_float ("quality", "quality-level",
          "quality level, between 0 (smallest file) and 100 (biggest)",
          0, 100, DEFAULT_QUALITY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_SPEED,
      g_param_spec_uint ("speed", "Compression Method",
          "quality/speed trade-off (0=fast, 6=slower-better)",
          0, 6, DEFAULT_SPEED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PRESET,
      g_param_spec_enum ("preset", "preset tuning",
          "Preset name for visual tuning",
          GST_WEBP_ENC_PRESET_TYPE, DEFAULT_PRESET,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  GST_DEBUG_CATEGORY_INIT (webpenc_debug, "webpenc", 0,
      "WEBP encoding element");
}

static void
gst_webp_enc_init (GstWebpEnc * webpenc)
{
  webpenc->lossless = DEFAULT_LOSSLESS;
  webpenc->quality = DEFAULT_QUALITY;
  webpenc->speed = DEFAULT_SPEED;
  webpenc->preset = DEFAULT_PRESET;

  webpenc->use_argb = FALSE;
  webpenc->rgb_format = GST_VIDEO_FORMAT_UNKNOWN;
}

static gboolean
gst_webp_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
{
  GstWebpEnc *enc = GST_WEBP_ENC (encoder);
  GstVideoCodecState *output_state;
  GstVideoInfo *info;
  GstVideoFormat format;

  info = &state->info;
  format = GST_VIDEO_INFO_FORMAT (info);

  if (GST_VIDEO_INFO_IS_YUV (info)) {
    switch (format) {
      case GST_VIDEO_FORMAT_I420:
      case GST_VIDEO_FORMAT_YV12:
        enc->webp_color_space = WEBP_YUV420;
        break;
      default:
        break;
    }
  } else {
    if (GST_VIDEO_INFO_IS_RGB (info)) {
      enc->rgb_format = format;
      enc->use_argb = 1;
    }
  }

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

  output_state =
      gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (enc),
      gst_caps_new_empty_simple ("image/webp"), enc->input_state);
  gst_video_codec_state_unref (output_state);

  return TRUE;
}

static gboolean
gst_webp_set_picture_params (GstWebpEnc * enc)
{
  GstVideoInfo *info;
  gboolean ret = TRUE;

  info = &enc->input_state->info;

  if (!WebPPictureInit (&enc->webp_picture)) {
    ret = FALSE;
    goto failed_pic_init;
  }

  enc->webp_picture.use_argb = enc->use_argb;
  if (!enc->use_argb)
    enc->webp_picture.colorspace = enc->webp_color_space;

  enc->webp_picture.width = GST_VIDEO_INFO_WIDTH (info);
  enc->webp_picture.height = GST_VIDEO_INFO_HEIGHT (info);

  WebPMemoryWriterInit (&enc->webp_writer);
  enc->webp_picture.writer = WebPMemoryWrite;
  enc->webp_picture.custom_ptr = &enc->webp_writer;

  return ret;

failed_pic_init:
  {
    GST_ERROR_OBJECT (enc, "Failed to Initialize WebPPicture !");
    return ret;
  }
}

static GstFlowReturn
gst_webp_enc_handle_frame (GstVideoEncoder * encoder,
    GstVideoCodecFrame * frame)
{
  GstWebpEnc *enc = GST_WEBP_ENC (encoder);
  GstBuffer *out_buffer = NULL;
  GstVideoFrame vframe;

  GST_LOG_OBJECT (enc, "got new frame");

  gst_webp_set_picture_params (enc);

  if (!gst_video_frame_map (&vframe, &enc->input_state->info,
          frame->input_buffer, GST_MAP_READ))
    return GST_FLOW_ERROR;

  if (!enc->use_argb) {
    enc->webp_picture.y = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
    enc->webp_picture.u = GST_VIDEO_FRAME_COMP_DATA (&vframe, 1);
    enc->webp_picture.v = GST_VIDEO_FRAME_COMP_DATA (&vframe, 2);

    enc->webp_picture.y_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
    enc->webp_picture.uv_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 1);

  } else {
    switch (enc->rgb_format) {
      case GST_VIDEO_FORMAT_RGB:
        WebPPictureImportRGB (&enc->webp_picture,
            GST_VIDEO_FRAME_COMP_DATA (&vframe, 0),
            GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0));
        break;
      case GST_VIDEO_FORMAT_RGBA:
        WebPPictureImportRGBA (&enc->webp_picture,
            GST_VIDEO_FRAME_COMP_DATA (&vframe, 0),
            GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0));
        break;
      default:
        break;
    }
  }

  if (WebPEncode (&enc->webp_config, &enc->webp_picture)) {
    WebPPictureFree (&enc->webp_picture);

    out_buffer = gst_buffer_new_allocate (NULL, enc->webp_writer.size, NULL);
    if (!out_buffer) {
      GST_ERROR_OBJECT (enc, "Failed to create output buffer");
      return GST_FLOW_ERROR;
    }
    gst_buffer_fill (out_buffer, 0, enc->webp_writer.mem,
        enc->webp_writer.size);
    free (enc->webp_writer.mem);
  } else {
    GST_ERROR_OBJECT (enc, "Failed to encode WebPPicture");
    return GST_FLOW_ERROR;
  }

  gst_video_frame_unmap (&vframe);
  frame->output_buffer = out_buffer;
  return gst_video_encoder_finish_frame (encoder, frame);
}

static gboolean
gst_webp_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
{
  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
  return
      GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
      query);
}

static void
gst_webp_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWebpEnc *webpenc = GST_WEBP_ENC (object);

  switch (prop_id) {
    case PROP_LOSSLESS:
      webpenc->lossless = g_value_get_boolean (value);
      break;
    case PROP_QUALITY:
      webpenc->quality = g_value_get_float (value);
      break;
    case PROP_SPEED:
      webpenc->speed = g_value_get_uint (value);
      break;
    case PROP_PRESET:
      webpenc->preset = g_value_get_enum (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

}

static void
gst_webp_enc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstWebpEnc *webpenc = GST_WEBP_ENC (object);

  switch (prop_id) {
    case PROP_LOSSLESS:
      g_value_set_boolean (value, webpenc->lossless);
      break;
    case PROP_QUALITY:
      g_value_set_float (value, webpenc->quality);
      break;
    case PROP_SPEED:
      g_value_set_uint (value, webpenc->speed);
      break;
    case PROP_PRESET:
      g_value_set_enum (value, webpenc->preset);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_webp_enc_start (GstVideoEncoder * benc)
{
  GstWebpEnc *enc = (GstWebpEnc *) benc;

  if (!WebPConfigPreset (&enc->webp_config, enc->preset, enc->quality)) {
    GST_ERROR_OBJECT (enc, "Failed to Initialize WebPConfig ");
    return FALSE;
  }

  enc->webp_config.lossless = enc->lossless;
  enc->webp_config.method = enc->speed;
  if (!WebPValidateConfig (&enc->webp_config)) {
    GST_ERROR_OBJECT (enc, "Failed to Validate the WebPConfig");
    return FALSE;
  }
  return TRUE;
}

static gboolean
gst_webp_enc_stop (GstVideoEncoder * benc)
{
  GstWebpEnc *enc = GST_WEBP_ENC (benc);
  if (enc->input_state)
    gst_video_codec_state_unref (enc->input_state);
  return TRUE;
}

gboolean
gst_webp_enc_register (GstPlugin * plugin)
{
  return gst_element_register (plugin, "webpenc",
      GST_RANK_PRIMARY, GST_TYPE_WEBP_ENC);
}
