/* GStreamer
 * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) 2007 Wim Taymans <wim.taymans@collabora.co.uk>
 * Copyright (C) 2007 Edward Hervey <edward.hervey@collabora.co.uk>
 * Copyright (C) 2007 Jan Schmidt <thaytan@noraisin.net>
 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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-chromahold
 * 
 * The chromahold element will remove all color information for
 * all colors except a single one and converts them to grayscale.
 *
 * Sample pipeline:
 * |[
 * gst-launch videotestsrc pattern=smpte75 ! \
 *   chromahold target-r=0 target-g=0 target-b=255 ! \
 *   videoconvert ! autovideosink     \
 * ]| This pipeline only keeps the red color.
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
 * with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include "gstchromahold.h"

#include <stdlib.h>
#include <string.h>
#include <math.h>

GST_DEBUG_CATEGORY_STATIC (gst_chroma_hold_debug);
#define GST_CAT_DEFAULT gst_chroma_hold_debug

#define DEFAULT_TARGET_R 255
#define DEFAULT_TARGET_G 0
#define DEFAULT_TARGET_B 0
#define DEFAULT_TOLERANCE 30

enum
{
  PROP_0,
  PROP_TARGET_R,
  PROP_TARGET_G,
  PROP_TARGET_B,
  PROP_TOLERANCE,
  PROP_LAST
};

static GstStaticPadTemplate gst_chroma_hold_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ ARGB, BGRA, ABGR, RGBA, xRGB, BGRx, xBGR, RGBx}"))
    );

static GstStaticPadTemplate gst_chroma_hold_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ ARGB, BGRA, ABGR, RGBA, xRGB, BGRx, xBGR, RGBx}"))
    );

#define GST_CHROMA_HOLD_LOCK(self) G_STMT_START { \
  GST_LOG_OBJECT (self, "Locking chromahold from thread %p", g_thread_self ()); \
  g_mutex_lock (&self->lock); \
  GST_LOG_OBJECT (self, "Locked chromahold from thread %p", g_thread_self ()); \
} G_STMT_END

#define GST_CHROMA_HOLD_UNLOCK(self) G_STMT_START { \
  GST_LOG_OBJECT (self, "Unlocking chromahold from thread %p", \
      g_thread_self ()); \
  g_mutex_unlock (&self->lock); \
} G_STMT_END

static gboolean gst_chroma_hold_start (GstBaseTransform * trans);
static gboolean gst_chroma_hold_set_info (GstVideoFilter * vfilter,
    GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
    GstVideoInfo * out_info);
static GstFlowReturn gst_chroma_hold_transform_frame_ip (GstVideoFilter *
    vfilter, GstVideoFrame * frame);
static void gst_chroma_hold_before_transform (GstBaseTransform * btrans,
    GstBuffer * buf);

static void gst_chroma_hold_init_params (GstChromaHold * self);
static gboolean gst_chroma_hold_set_process_function (GstChromaHold * self);

static void gst_chroma_hold_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_chroma_hold_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_chroma_hold_finalize (GObject * object);

#define gst_chroma_hold_parent_class parent_class
G_DEFINE_TYPE (GstChromaHold, gst_chroma_hold, GST_TYPE_VIDEO_FILTER);

static void
gst_chroma_hold_class_init (GstChromaHoldClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;
  GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;

  gobject_class->set_property = gst_chroma_hold_set_property;
  gobject_class->get_property = gst_chroma_hold_get_property;
  gobject_class->finalize = gst_chroma_hold_finalize;

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_R,
      g_param_spec_uint ("target-r", "Target Red", "The Red target", 0, 255,
          DEFAULT_TARGET_R,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_G,
      g_param_spec_uint ("target-g", "Target Green", "The Green target", 0, 255,
          DEFAULT_TARGET_G,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_B,
      g_param_spec_uint ("target-b", "Target Blue", "The Blue target", 0, 255,
          DEFAULT_TARGET_B,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TOLERANCE,
      g_param_spec_uint ("tolerance", "Tolerance",
          "Tolerance for the target color", 0, 180, DEFAULT_TOLERANCE,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  btrans_class->start = GST_DEBUG_FUNCPTR (gst_chroma_hold_start);
  btrans_class->before_transform =
      GST_DEBUG_FUNCPTR (gst_chroma_hold_before_transform);

  vfilter_class->transform_frame_ip =
      GST_DEBUG_FUNCPTR (gst_chroma_hold_transform_frame_ip);
  vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_chroma_hold_set_info);

  gst_element_class_set_static_metadata (gstelement_class, "Chroma hold filter",
      "Filter/Effect/Video",
      "Removes all color information except for one color",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_chroma_hold_sink_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_chroma_hold_src_template));

  GST_DEBUG_CATEGORY_INIT (gst_chroma_hold_debug, "chromahold", 0,
      "chromahold - Removes all color information except for one color");
}

static void
gst_chroma_hold_init (GstChromaHold * self)
{
  self->target_r = DEFAULT_TARGET_R;
  self->target_g = DEFAULT_TARGET_G;
  self->target_b = DEFAULT_TARGET_B;
  self->tolerance = DEFAULT_TOLERANCE;

  g_mutex_init (&self->lock);
}

static void
gst_chroma_hold_finalize (GObject * object)
{
  GstChromaHold *self = GST_CHROMA_HOLD (object);

  g_mutex_clear (&self->lock);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_chroma_hold_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstChromaHold *self = GST_CHROMA_HOLD (object);

  GST_CHROMA_HOLD_LOCK (self);
  switch (prop_id) {
    case PROP_TARGET_R:
      self->target_r = g_value_get_uint (value);
      gst_chroma_hold_init_params (self);
      break;
    case PROP_TARGET_G:
      self->target_g = g_value_get_uint (value);
      gst_chroma_hold_init_params (self);
      break;
    case PROP_TARGET_B:
      self->target_b = g_value_get_uint (value);
      gst_chroma_hold_init_params (self);
      break;
    case PROP_TOLERANCE:
      self->tolerance = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_CHROMA_HOLD_UNLOCK (self);
}

static void
gst_chroma_hold_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstChromaHold *self = GST_CHROMA_HOLD (object);

  switch (prop_id) {
    case PROP_TARGET_R:
      g_value_set_uint (value, self->target_r);
      break;
    case PROP_TARGET_G:
      g_value_set_uint (value, self->target_g);
      break;
    case PROP_TARGET_B:
      g_value_set_uint (value, self->target_b);
      break;
    case PROP_TOLERANCE:
      g_value_set_uint (value, self->tolerance);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_chroma_hold_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
    GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
{
  GstChromaHold *self = GST_CHROMA_HOLD (vfilter);

  GST_CHROMA_HOLD_LOCK (self);

  GST_DEBUG_OBJECT (self,
      "Setting caps %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT, incaps, outcaps);

  self->format = GST_VIDEO_INFO_FORMAT (in_info);
  self->width = GST_VIDEO_INFO_WIDTH (in_info);
  self->height = GST_VIDEO_INFO_HEIGHT (in_info);

  if (!gst_chroma_hold_set_process_function (self)) {
    GST_WARNING_OBJECT (self, "No processing function for this caps");
    GST_CHROMA_HOLD_UNLOCK (self);
    return FALSE;
  }

  GST_CHROMA_HOLD_UNLOCK (self);

  return TRUE;
}

static inline gint
rgb_to_hue (gint r, gint g, gint b)
{
  gint m, M, C, C2, h;

  m = MIN (MIN (r, g), b);
  M = MAX (MAX (r, g), b);
  C = M - m;
  C2 = C >> 1;

  if (C == 0) {
    return G_MAXUINT;
  } else if (M == r) {
    h = ((256 * 60 * (g - b) + C2) / C);
  } else if (M == g) {
    h = ((256 * 60 * (b - r) + C2) / C) + 120 * 256;
  } else {
    /* if (M == b) */
    h = ((256 * 60 * (r - g) + C2) / C) + 240 * 256;
  }
  h >>= 8;

  if (h >= 360)
    h -= 360;
  else if (h < 0)
    h += 360;

  return h;
}

static inline gint
hue_dist (gint h1, gint h2)
{
  gint d1, d2;

  d1 = h1 - h2;
  d2 = h2 - h1;

  if (d1 < 0)
    d1 += 360;
  if (d2 < 0)
    d2 += 360;

  return MIN (d1, d2);
}

static void
gst_chroma_hold_process_xrgb (GstVideoFrame * frame, gint width,
    gint height, GstChromaHold * self)
{
  gint i, j;
  gint r, g, b;
  gint grey;
  gint h1, h2;
  gint tolerance = self->tolerance;
  gint p[4];
  gint diff;
  gint row_wrap;
  guint8 *dest;

  dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 3);
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 0);
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 1);
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 2);
  row_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) - 4 * width;

  h1 = self->hue;

  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      r = dest[p[1]];
      g = dest[p[2]];
      b = dest[p[3]];

      h2 = rgb_to_hue (r, g, b);
      diff = hue_dist (h1, h2);
      if (h1 == G_MAXUINT || diff > tolerance) {
        grey = (13938 * r + 46869 * g + 4730 * b) >> 16;
        grey = CLAMP (grey, 0, 255);
        dest[p[1]] = grey;
        dest[p[2]] = grey;
        dest[p[3]] = grey;
      }

      dest += 4;
    }
    dest += row_wrap;
  }
}

/* Protected with the chroma hold lock */
static void
gst_chroma_hold_init_params (GstChromaHold * self)
{
  self->hue = rgb_to_hue (self->target_r, self->target_g, self->target_b);
}

/* Protected with the chroma hold lock */
static gboolean
gst_chroma_hold_set_process_function (GstChromaHold * self)
{
  self->process = NULL;

  switch (self->format) {
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_ABGR:
    case GST_VIDEO_FORMAT_RGBA:
    case GST_VIDEO_FORMAT_BGRA:
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_xBGR:
    case GST_VIDEO_FORMAT_RGBx:
    case GST_VIDEO_FORMAT_BGRx:
      self->process = gst_chroma_hold_process_xrgb;
      break;
    default:
      break;
  }
  return self->process != NULL;
}

static gboolean
gst_chroma_hold_start (GstBaseTransform * btrans)
{
  GstChromaHold *self = GST_CHROMA_HOLD (btrans);

  GST_CHROMA_HOLD_LOCK (self);
  gst_chroma_hold_init_params (self);
  GST_CHROMA_HOLD_UNLOCK (self);

  return TRUE;
}

static void
gst_chroma_hold_before_transform (GstBaseTransform * btrans, GstBuffer * buf)
{
  GstChromaHold *self = GST_CHROMA_HOLD (btrans);
  GstClockTime timestamp;

  timestamp = gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME,
      GST_BUFFER_TIMESTAMP (buf));
  GST_LOG ("Got stream time of %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
  if (GST_CLOCK_TIME_IS_VALID (timestamp))
    gst_object_sync_values (GST_OBJECT (self), timestamp);
}

static GstFlowReturn
gst_chroma_hold_transform_frame_ip (GstVideoFilter * vfilter,
    GstVideoFrame * frame)
{
  GstChromaHold *self = GST_CHROMA_HOLD (vfilter);

  GST_CHROMA_HOLD_LOCK (self);

  if (G_UNLIKELY (!self->process)) {
    GST_ERROR_OBJECT (self, "Not negotiated yet");
    GST_CHROMA_HOLD_UNLOCK (self);
    return GST_FLOW_NOT_NEGOTIATED;
  }

  self->process (frame, self->width, self->height, self);

  GST_CHROMA_HOLD_UNLOCK (self);

  return GST_FLOW_OK;
}
