/*
 * GStreamer
 * Copyright (C) <2010-2012> Luis de Bethencourt <luis@debethencourt.com>
 *
 * Dilate - dilated eye video effect.
 * Based on Pete Warden's FreeFrame plugin with the same name.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * 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.
 */

/**
 * SECTION:element-dilate
 *
 * Dilate adjusts the colors of a video stream in realtime.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch -v videotestsrc ! dilate ! videoconvert ! autovideosink
 * ]| This pipeline shows the effect of dilate on a test stream
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <math.h>

#include "gstplugin.h"
#include "gstdilate.h"

GST_DEBUG_CATEGORY_STATIC (gst_dilate_debug);
#define GST_CAT_DEFAULT gst_dilate_debug

#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define CAPS_STR GST_VIDEO_CAPS_MAKE ("{  BGRx, RGBx }")
#else
#define CAPS_STR GST_VIDEO_CAPS_MAKE ("{  xBGR, xRGB }")
#endif

#define gst_dilate_parent_class parent_class
G_DEFINE_TYPE (GstDilate, gst_dilate, GST_TYPE_VIDEO_FILTER);

/* Filter signals and args. */
enum
{
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_ERODE,
  PROP_SILENT
};

/* Initializations */

#define DEFAULT_ERODE FALSE

static void transform (guint32 * src, guint32 * dest, gint video_area,
    gint width, gint height, gboolean erode);
static inline guint32 get_luminance (guint32 in);

/* The capabilities of the inputs and outputs. */

static GstStaticPadTemplate gst_dilate_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (CAPS_STR)
    );

static GstStaticPadTemplate gst_dilate_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (CAPS_STR)
    );

static void gst_dilate_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_dilate_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_dilate_finalize (GObject * object);

static GstFlowReturn gst_dilate_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame);

/* GObject vmethod implementations */

/* Initialize the dilate's class. */
static void
gst_dilate_class_init (GstDilateClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;

  gst_element_class_set_static_metadata (gstelement_class,
      "Dilate",
      "Filter/Effect/Video",
      "Dilate copies the brightest pixel around.",
      "Luis de Bethencourt <luis@debethencourt.com>");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_dilate_sink_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_dilate_src_template));

  gobject_class->set_property = gst_dilate_set_property;
  gobject_class->get_property = gst_dilate_get_property;
  gobject_class->finalize = gst_dilate_finalize;

  g_object_class_install_property (gobject_class, PROP_ERODE,
      g_param_spec_boolean ("erode", "Erode", "Erode parameter", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));

  g_object_class_install_property (gobject_class, PROP_SILENT,
      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  vfilter_class->transform_frame =
      GST_DEBUG_FUNCPTR (gst_dilate_transform_frame);
}

/* Initialize the element,
 * instantiate pads and add them to element,
 * set pad calback functions, and
 * initialize instance structure.
 */
static void
gst_dilate_init (GstDilate * filter)
{
  filter->erode = DEFAULT_ERODE;
  filter->silent = FALSE;
}

static void
gst_dilate_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDilate *filter = GST_DILATE (object);

  switch (prop_id) {
    case PROP_SILENT:
      filter->silent = g_value_get_boolean (value);
      break;
    case PROP_ERODE:
      filter->erode = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_dilate_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstDilate *filter = GST_DILATE (object);

  GST_OBJECT_LOCK (filter);
  switch (prop_id) {
    case PROP_SILENT:
      g_value_set_boolean (value, filter->silent);
      break;
    case PROP_ERODE:
      g_value_set_boolean (value, filter->erode);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (filter);
}

static void
gst_dilate_finalize (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

/* GstElement vmethod implementations */

/* Actual processing. */
static GstFlowReturn
gst_dilate_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  GstDilate *filter = GST_DILATE (vfilter);
  gint video_size, width, height;
  gboolean erode;
  guint32 *src, *dest;
  GstClockTime timestamp;
  gint64 stream_time;

  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  width = GST_VIDEO_FRAME_WIDTH (in_frame);
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);

  /* GstController: update the properties */
  timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
  stream_time =
      gst_segment_to_stream_time (&GST_BASE_TRANSFORM (filter)->segment,
      GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (filter), stream_time);

  GST_OBJECT_LOCK (filter);
  erode = filter->erode;
  GST_OBJECT_UNLOCK (filter);

  video_size = width * height;
  transform (src, dest, video_size, width, height, erode);

  return GST_FLOW_OK;
}

/* Entry point to initialize the plug-in.
 * Register the element factories and other features. */
gboolean
gst_dilate_plugin_init (GstPlugin * dilate)
{
  /* debug category for fltering log messages */
  GST_DEBUG_CATEGORY_INIT (gst_dilate_debug, "dilate", 0, "Template dilate");

  return gst_element_register (dilate, "dilate", GST_RANK_NONE,
      GST_TYPE_DILATE);
}

/*** Now the image processing work.... ***/

/* Return luminance of the color */
static inline guint32
get_luminance (guint32 in)
{
  guint32 red, green, blue, luminance;

  red = (in >> 16) & 0xff;
  green = (in >> 8) & 0xff;
  blue = (in) & 0xff;

  luminance = ((90 * red) + (115 * green) + (51 * blue));

  return luminance;
}

/* Transform processes each frame. */
static void
transform (guint32 * src, guint32 * dest, gint video_area, gint width,
    gint height, gboolean erode)
{
  guint32 out_luminance, down_luminance, right_luminance;
  guint32 up_luminance, left_luminance;

  guint32 *src_end = src + video_area;
  guint32 *up;
  guint32 *left;
  guint32 *down;
  guint32 *right;

  if (erode) {

    while (src != src_end) {
      guint32 *src_line_start = src;
      guint32 *src_line_end = src + width;
      while (src != src_line_end) {

        up = src - width;
        if (up < src) {
          up = src;
        }

        left = src - 1;
        if (left < src_line_start) {
          left = src;
        }

        down = src + width;
        if (down >= src_end) {
          down = src;
        }

        right = src + 1;
        if (right >= src_line_end) {
          right = src;
        }

        *dest = *src;
        out_luminance = get_luminance (*src);

        down_luminance = get_luminance (*down);
        if (down_luminance < out_luminance) {
          *dest = *down;
          out_luminance = down_luminance;
        }

        right_luminance = get_luminance (*right);
        if (right_luminance < out_luminance) {
          *dest = *right;
          out_luminance = right_luminance;
        }

        up_luminance = get_luminance (*up);
        if (up_luminance < out_luminance) {
          *dest = *up;
          out_luminance = up_luminance;
        }

        left_luminance = get_luminance (*left);
        if (left_luminance < out_luminance) {
          *dest = *left;
          out_luminance = left_luminance;
        }

        src += 1;
        dest += 1;
      }
    }

  } else {

    while (src != src_end) {
      guint32 *src_line_start = src;
      guint32 *src_line_end = src + width;
      while (src != src_line_end) {

        up = src - width;
        if (up < src) {
          up = src;
        }

        left = src - 1;
        if (left < src_line_start) {
          left = src;
        }

        down = src + width;
        if (down >= src_end) {
          down = src;
        }

        right = src + 1;
        if (right >= src_line_end) {
          right = src;
        }

        *dest = *src;
        out_luminance = get_luminance (*src);

        down_luminance = get_luminance (*down);
        if (down_luminance > out_luminance) {
          *dest = *down;
          out_luminance = down_luminance;
        }

        right_luminance = get_luminance (*right);
        if (right_luminance > out_luminance) {
          *dest = *right;
          out_luminance = right_luminance;
        }

        up_luminance = get_luminance (*up);
        if (up_luminance > out_luminance) {
          *dest = *up;
          out_luminance = up_luminance;
        }

        left_luminance = get_luminance (*left);
        if (left_luminance > out_luminance) {
          *dest = *left;
          out_luminance = left_luminance;
        }

        src += 1;
        dest += 1;
      }
    }
  }
}
