/*
 * GStreamer
 * Copyright (C) 2013 Miguel Casas-Sanchez <miguelecasassanchez@gmail.com>
 *
 * 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-retinex
 *
 * Basic and multiscale retinex for colour image enhancement, see article:
 *
 * Rahman, Zia-ur, Daniel J. Jobson, and Glenn A. Woodell. "Multi-scale retinex for
 * color image enhancement." Image Processing, 1996. Proceedings., International
 * Conference on. Vol. 3. IEEE, 1996.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 videotestsrc ! decodebin ! videoconvert ! retinex ! videoconvert ! xvimagesink
 * ]|
 * </refsect2>
 */

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

#include "gstretinex.h"
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/imgproc/imgproc.hpp>

GST_DEBUG_CATEGORY_STATIC (gst_retinex_debug);
#define GST_CAT_DEFAULT gst_retinex_debug

using namespace cv;
/* Filter signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_METHOD,
  PROP_SCALES
};
typedef enum
{
  METHOD_BASIC,
  METHOD_MULTISCALE
} GstRetinexMethod;

#define DEFAULT_METHOD METHOD_BASIC
#define DEFAULT_SCALES 3

#define GST_TYPE_RETINEX_METHOD (gst_retinex_method_get_type ())
static GType
gst_retinex_method_get_type (void)
{
  static GType etype = 0;
  if (etype == 0) {
    static const GEnumValue values[] = {
      {METHOD_BASIC, "Basic retinex restoration", "basic"},
      {METHOD_MULTISCALE, "Mutiscale retinex restoration", "multiscale"},
      {0, NULL, NULL},
    };
    etype = g_enum_register_static ("GstRetinexMethod", values);
  }
  return etype;
}

G_DEFINE_TYPE (GstRetinex, gst_retinex, GST_TYPE_VIDEO_FILTER);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")));

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")));


static void gst_retinex_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_retinex_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstFlowReturn gst_retinex_transform_ip (GstBaseTransform * btrans,
    GstBuffer * buf);
static gboolean gst_retinex_set_caps (GstBaseTransform * btrans,
    GstCaps * incaps, GstCaps * outcaps);

static void gst_retinex_release_all_images (GstRetinex * filter);

static gboolean gst_retinex_stop (GstBaseTransform * basesrc);

/* initialize the retinex's class */
static void
gst_retinex_class_init (GstRetinexClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;

  gobject_class->set_property = gst_retinex_set_property;
  gobject_class->get_property = gst_retinex_get_property;

  btrans_class->transform_ip = gst_retinex_transform_ip;
  btrans_class->set_caps = gst_retinex_set_caps;
  btrans_class->stop = gst_retinex_stop;

  g_object_class_install_property (gobject_class, PROP_METHOD,
      g_param_spec_enum ("method",
          "Retinex method to use",
          "Retinex method to use",
          GST_TYPE_RETINEX_METHOD, DEFAULT_METHOD,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, PROP_SCALES,
      g_param_spec_int ("scales", "scales",
          "Amount of gaussian filters (scales) used in multiscale retinex", 1,
          4, DEFAULT_SCALES,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  gst_element_class_set_static_metadata (element_class,
      "Retinex image colour enhacement", "Filter/Effect/Video",
      "Multiscale retinex for colour image enhancement",
      "Miguel Casas-Sanchez <miguelecasassanchez@gmail.com>");

  gst_element_class_add_static_pad_template (element_class, &src_factory);
  gst_element_class_add_static_pad_template (element_class, &sink_factory);
}

/* initialize the new element
 * instantiate pads and add them to element
 * set pad calback functions
 * initialize instance structure
 */
static void
gst_retinex_init (GstRetinex * filter)
{
  filter->method = DEFAULT_METHOD;
  filter->scales = DEFAULT_SCALES;
  filter->current_scales = 0;
  gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER_CAST (filter),
      TRUE);
}


static void
gst_retinex_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRetinex *retinex = GST_RETINEX (object);

  switch (prop_id) {
    case PROP_METHOD:
      retinex->method = g_value_get_enum (value);
      break;
    case PROP_SCALES:
      retinex->scales = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_retinex_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRetinex *filter = GST_RETINEX (object);

  switch (prop_id) {
    case PROP_METHOD:
      g_value_set_enum (value, filter->method);
      break;
    case PROP_SCALES:
      g_value_set_int (value, filter->scales);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* GstElement vmethod implementations */
/* this function handles the link with other elements */
static gboolean
gst_retinex_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstRetinex *retinex = GST_RETINEX (btrans);
  CvSize size;
  GstVideoInfo info;
  gst_video_info_from_caps (&info, incaps);

  size = cvSize (info.width, info.height);

  /* If cvRGB is already allocated, it means there's a cap modification,
     so release first all the images.                                      */
  if (NULL != retinex->cvRGBin)
    gst_retinex_release_all_images (retinex);

  retinex->cvRGBin = cvCreateImageHeader (size, IPL_DEPTH_8U, 3);
  retinex->cvRGBout = cvCreateImageHeader (size, IPL_DEPTH_8U, 3);

  retinex->cvA = cvCreateImage (size, IPL_DEPTH_32F, 3);
  retinex->cvB = cvCreateImage (size, IPL_DEPTH_32F, 3);
  retinex->cvC = cvCreateImage (size, IPL_DEPTH_32F, 3);
  retinex->cvD = cvCreateImage (size, IPL_DEPTH_32F, 3);

  return TRUE;
}

/* Clean up */
static gboolean
gst_retinex_stop (GstBaseTransform * basesrc)
{
  GstRetinex *filter = GST_RETINEX (basesrc);

  if (filter->cvRGBin != NULL)
    gst_retinex_release_all_images (filter);

  g_free (filter->weights);
  filter->weights = NULL;
  g_free (filter->sigmas);
  filter->sigmas = NULL;

  return TRUE;
}

static void
gst_retinex_release_all_images (GstRetinex * filter)
{
  cvReleaseImage (&filter->cvRGBin);
  cvReleaseImage (&filter->cvRGBout);

  cvReleaseImage (&filter->cvA);
  cvReleaseImage (&filter->cvB);
  cvReleaseImage (&filter->cvC);
  cvReleaseImage (&filter->cvD);
}

static GstFlowReturn
gst_retinex_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
{
  GstRetinex *retinex = GST_RETINEX (btrans);
  GstMapInfo info;
  double sigma = 14.0;
  int gain = 128;
  int offset = 128;
  int filter_size;
  Mat icvD = cvarrToMat(retinex->cvD, false);

  if (!gst_buffer_map (buf, &info, (GstMapFlags) GST_MAP_READWRITE)) {
    return GST_FLOW_ERROR;
  }
  retinex->cvRGBin->imageData = (char *) info.data;

  /* Basic retinex restoration.  The image and a filtered image are converted
     to the log domain and subtracted.
     O = Log(I) - Log(H(I))
     where O is the output, H is a gaussian 2d filter and I is the input image. */
  if (METHOD_BASIC == retinex->method) {
    /*  Compute log image */
    cvConvert (retinex->cvRGBin, retinex->cvA);
    cvLog (retinex->cvA, retinex->cvB);

    /*  Compute log of blured image */
    filter_size = (int) floor (sigma * 6) / 2;
    filter_size = filter_size * 2 + 1;

    cvConvert (retinex->cvRGBin, retinex->cvD);
    GaussianBlur (icvD, icvD, Size (filter_size, filter_size), 0.0, 0.0);
    cvLog (retinex->cvD, retinex->cvC);

    /*  Compute difference */
    cvSub (retinex->cvB, retinex->cvC, retinex->cvA, NULL);

    /*  Restore */
    cvConvertScale (retinex->cvA, retinex->cvRGBin, (float) gain,
        (float) offset);
  }
  /* Multiscale retinex restoration.  The image and a set of filtered images are
     converted to the log domain and subtracted from the original with some set
     of weights. Typicaly called with three equally weighted scales of fine,
     medium and wide standard deviations.
     O = Log(I) - sum_i [ wi * Log(H(I)) ]
     where O is the output, H is a gaussian 2d filter and I is the input image
     sum_i means summatory on var i with i in [0..scales) and wi are the weights */
  else if (METHOD_MULTISCALE == retinex->method) {
    int i;

    /* allocate or reallocate the weights and sigmas according to scales */
    if (retinex->current_scales != retinex->scales || !retinex->sigmas) {
      retinex->weights =
          (double *) g_realloc (retinex->weights,
          sizeof (double) * retinex->scales);
      retinex->sigmas =
          (double *) g_realloc (retinex->sigmas,
          sizeof (double) * retinex->scales);
      for (i = 0; i < retinex->scales; i++) {
        retinex->weights[i] = 1.0 / (double) retinex->scales;
        retinex->sigmas[i] = 10.0 + 4.0 * (double) retinex->scales;
      }
      retinex->current_scales = retinex->scales;
    }

    /*  Compute log image */
    cvConvert (retinex->cvRGBin, retinex->cvA);
    cvLog (retinex->cvA, retinex->cvB);

    /*  Filter at each scale */
    for (i = 0; i < retinex->scales; i++) {
      filter_size = (int) floor (retinex->sigmas[i] * 6) / 2;
      filter_size = filter_size * 2 + 1;

      cvConvert (retinex->cvRGBin, retinex->cvD);
      GaussianBlur (icvD, icvD, Size (filter_size, filter_size), 0.0, 0.0);
      cvLog (retinex->cvD, retinex->cvC);

      /*  Compute weighted difference */
      cvScale (retinex->cvC, retinex->cvC, retinex->weights[i], 0.0);
      cvSub (retinex->cvB, retinex->cvC, retinex->cvB, NULL);
    }

    /*  Restore */
    cvConvertScale (retinex->cvB, retinex->cvRGBin, (float) gain,
        (float) offset);
  }

  return GST_FLOW_OK;
}

/* entry point to initialize the plug-in
 * initialize the plug-in itself
 * register the element factories and other features
 */
gboolean
gst_retinex_plugin_init (GstPlugin * plugin)
{
  /* debug category for fltering log messages
   *
   */
  GST_DEBUG_CATEGORY_INIT (gst_retinex_debug, "retinex",
      0, "Multiscale retinex for colour image enhancement");

  return gst_element_register (plugin, "retinex", GST_RANK_NONE,
      GST_TYPE_RETINEX);
}
