/* GStreamer
 * Copyright (C) <2014> Wim Taymans <wim.taymans@gmail.com>
 *
 * 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 <stdio.h>
#include <math.h>

#include "video-resampler.h"

#ifndef GST_DISABLE_GST_DEBUG
#define GST_CAT_DEFAULT ensure_debug_category()
static GstDebugCategory *
ensure_debug_category (void)
{
  static gsize cat_gonce = 0;

  if (g_once_init_enter (&cat_gonce)) {
    gsize cat_done;

    cat_done = (gsize) _gst_debug_category_new ("video-resampler", 0,
        "video-resampler object");

    g_once_init_leave (&cat_gonce, cat_done);
  }

  return (GstDebugCategory *) cat_gonce;
}
#else
#define ensure_debug_category() /* NOOP */
#endif /* GST_DISABLE_GST_DEBUG */

/**
 * SECTION:gstvideoresampler
 * @short_description: Utility structure for resampler information
 *
 * #GstVideoResampler is a structure which holds the information
 * required to perform various kinds of resampling filtering.
 *
 */


#define DEFAULT_OPT_CUBIC_B (1.0 / 3.0)
#define DEFAULT_OPT_CUBIC_C (1.0 / 3.0)

#define DEFAULT_OPT_ENVELOPE 2.0
#define DEFAULT_OPT_SHARPNESS 1.0
#define DEFAULT_OPT_SHARPEN 0.0

#define DEFAULT_OPT_MAX_TAPS 128

typedef struct _ResamplerParams ResamplerParams;

struct _ResamplerParams
{
  GstVideoResamplerMethod method;
  GstVideoResamplerFlags flags;

  gdouble shift;

    gdouble (*get_tap) (ResamplerParams * params, gint l, gint xi, gdouble x);

  /* for cubic */
  gdouble b, c;
  /* used by lanczos */
  gdouble ex, fx, dx;
  /* extra params */
  gdouble envelope;
  gdouble sharpness;
  gdouble sharpen;

  GstVideoResampler *resampler;
};

static gdouble
get_opt_double (GstStructure * options, const gchar * name, gdouble def)
{
  gdouble res;
  if (!options || !gst_structure_get_double (options, name, &res))
    res = def;
  return res;
}

static gint
get_opt_int (GstStructure * options, const gchar * name, gint def)
{
  gint res;
  if (!options || !gst_structure_get_int (options, name, &res))
    res = def;
  return res;
}

#define GET_OPT_CUBIC_B(options) get_opt_double(options, \
    GST_VIDEO_RESAMPLER_OPT_CUBIC_B, DEFAULT_OPT_CUBIC_B)
#define GET_OPT_CUBIC_C(options) get_opt_double(options, \
    GST_VIDEO_RESAMPLER_OPT_CUBIC_C, DEFAULT_OPT_CUBIC_C)
#define GET_OPT_ENVELOPE(options) get_opt_double(options, \
    GST_VIDEO_RESAMPLER_OPT_ENVELOPE, DEFAULT_OPT_ENVELOPE)
#define GET_OPT_SHARPNESS(options) get_opt_double(options, \
    GST_VIDEO_RESAMPLER_OPT_SHARPNESS, DEFAULT_OPT_SHARPNESS)
#define GET_OPT_SHARPEN(options) get_opt_double(options, \
    GST_VIDEO_RESAMPLER_OPT_SHARPEN, DEFAULT_OPT_SHARPEN)
#define GET_OPT_MAX_TAPS(options) get_opt_int(options, \
    GST_VIDEO_RESAMPLER_OPT_MAX_TAPS, DEFAULT_OPT_MAX_TAPS)

static double
sinc (double x)
{
  if (x == 0)
    return 1;

  return sin (G_PI * x) / (G_PI * x);
}

static double
envelope (double x)
{
  if (x <= -1 || x >= 1)
    return 0;
  return sinc (x);
}

static gdouble
get_nearest_tap (ResamplerParams * params, gint l, gint xi, gdouble x)
{
  return 1.0;
}

static gdouble
get_linear_tap (ResamplerParams * params, gint l, gint xi, gdouble x)
{
  gdouble res, a;
  gint xl = xi + l;

  a = fabs (x - xl) * params->fx;

  if (a < 1.0)
    res = 1.0 - a;
  else
    res = 0.0;

  return res;
}

static gdouble
get_cubic_tap (ResamplerParams * params, gint l, gint xi, gdouble x)
{
  gdouble a, a2, a3, b, c;
  gint xl = xi + l;

  a = fabs (x - xl) * params->fx;
  a2 = a * a;
  a3 = a2 * a;

  b = params->b;
  c = params->c;

  if (a <= 1.0)
    return ((12.0 - 9.0 * b - 6.0 * c) * a3 +
        (-18.0 + 12.0 * b + 6.0 * c) * a2 + (6.0 - 2.0 * b)) / 6.0;
  else if (a <= 2.0)
    return ((-b - 6.0 * c) * a3 +
        (6.0 * b + 30.0 * c) * a2 +
        (-12.0 * b - 48.0 * c) * a + (8.0 * b + 24.0 * c)) / 6.0;
  else
    return 0.0;
}

static gdouble
get_sinc_tap (ResamplerParams * params, gint l, gint xi, gdouble x)
{
  gint xl = xi + l;
  return sinc ((x - xl) * params->fx);
}

static gdouble
get_lanczos_tap (ResamplerParams * params, gint l, gint xi, gdouble x)
{
  gint xl = xi + l;
  gdouble env = envelope ((x - xl) * params->ex);
  return (sinc ((x - xl) * params->fx) - params->sharpen) * env;
}

static void
resampler_calculate_taps (ResamplerParams * params)
{
  GstVideoResampler *resampler = params->resampler;
  gint j;
  guint32 *offset, *n_taps, *phase;
  gint tap_offs;
  gint max_taps;
  gint in_size, out_size;
  gdouble shift;
  gdouble corr;

  in_size = resampler->in_size;
  out_size = resampler->out_size;

  max_taps = resampler->max_taps;
  tap_offs = (max_taps - 1) / 2;
  corr = (max_taps == 1 ? 0.0 : 0.5);

  shift = params->shift;

  resampler->taps = g_malloc (sizeof (gdouble) * max_taps * out_size);
  n_taps = resampler->n_taps = g_malloc (sizeof (guint32) * out_size);
  offset = resampler->offset = g_malloc (sizeof (guint32) * out_size);
  phase = resampler->phase = g_malloc (sizeof (guint32) * out_size);

  for (j = 0; j < out_size; j++) {
    gdouble ox, x;
    gint xi;
    gint l;
    gdouble weight;
    gdouble *taps;

    /* center of the output pixel */
    ox = (0.5 + (gdouble) j - shift) / out_size;
    /* x is the source pixel to use, can be fractional */
    x = ox * (gdouble) in_size - corr;
    x = CLAMP (x, 0, in_size - 1);
    /* this is the first source pixel to use */
    xi = floor (x - tap_offs);

    offset[j] = xi;
    phase[j] = j;
    n_taps[j] = max_taps;
    weight = 0;
    taps = resampler->taps + j * max_taps;

    for (l = 0; l < max_taps; l++) {
      taps[l] = params->get_tap (params, l, xi, x);
      weight += taps[l];
    }

    for (l = 0; l < max_taps; l++)
      taps[l] /= weight;

    if (xi < 0) {
      gint sh = -xi;

      for (l = 0; l < sh; l++) {
        taps[sh] += taps[l];
      }
      for (l = 0; l < max_taps - sh; l++) {
        taps[l] = taps[sh + l];
      }
      for (; l < max_taps; l++) {
        taps[l] = 0;
      }
      offset[j] += sh;
    }
    if (xi > in_size - max_taps) {
      gint sh = xi - (in_size - max_taps);

      for (l = 0; l < sh; l++) {
        taps[max_taps - sh - 1] += taps[max_taps - sh + l];
      }
      for (l = 0; l < max_taps - sh; l++) {
        taps[max_taps - 1 - l] = taps[max_taps - 1 - sh - l];
      }
      for (l = 0; l < sh; l++) {
        taps[l] = 0;
      }
      offset[j] -= sh;
    }
  }
}

static void
resampler_dump (GstVideoResampler * resampler)
{
#if 0
  gint i, max_taps, out_size;

  out_size = resampler->out_size;
  max_taps = resampler->max_taps;

  for (i = 0; i < out_size; i++) {
    gint j, o, phase, n_taps;
    gdouble sum;

    o = resampler->offset[i];
    n_taps = resampler->n_taps[i];
    phase = resampler->phase[i];

    printf ("%u: \t%d  ", i, o);
    sum = 0;
    for (j = 0; j < n_taps; j++) {
      gdouble tap;
      tap = resampler->taps[phase * max_taps + j];
      printf ("\t%f ", tap);
      sum += tap;
    }
    printf ("\t: sum %f\n", sum);
  }
#endif
}


/**
 * gst_video_resampler_new:
 * @resampler: a #GstVideoResampler
 * @method: a #GstVideoResamplerMethod
 * @flags: #GstVideoResamplerFlags
 * @n_phases: number of phases to use
 * @n_taps: number of taps to use
 * @in_size: number of source elements
 * @out_size: number of destination elements
 * @options: extra options
 *
 * Make a new resampler. @in_size source elements will
 * be resampled to @out_size destination elements.
 *
 * @n_taps specifies the amount of elements to use from the source for one output
 * element. If n_taps is 0, this function chooses a good value automatically based
 * on the @method and @in_size/@out_size.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.6
 */
gboolean
gst_video_resampler_init (GstVideoResampler * resampler,
    GstVideoResamplerMethod method, GstVideoResamplerFlags flags,
    guint n_phases, guint n_taps, gdouble shift, guint in_size, guint out_size,
    GstStructure * options)
{
  ResamplerParams params;
  gint max_taps;
  gdouble scale_factor;

  g_return_val_if_fail (in_size != 0, FALSE);
  g_return_val_if_fail (out_size != 0, FALSE);
  g_return_val_if_fail (n_phases == out_size, FALSE);

  resampler->in_size = in_size;
  resampler->out_size = out_size;
  resampler->n_phases = n_phases;

  params.method = method;
  params.flags = flags;
  params.shift = shift;
  params.resampler = resampler;

  GST_DEBUG ("%d %u  %u->%u", method, n_taps, in_size, out_size);

  params.sharpness = GET_OPT_SHARPNESS (options);
  params.sharpen = GET_OPT_SHARPEN (options);

  scale_factor = in_size / (gdouble) out_size;
  if (scale_factor > 1.0) {
    params.fx = (1.0 / scale_factor) * params.sharpness;
  } else {
    params.fx = (1.0) * params.sharpness;
  }

  max_taps = GET_OPT_MAX_TAPS (options);
  n_taps = MIN (n_taps, max_taps);

  switch (method) {
    case GST_VIDEO_RESAMPLER_METHOD_NEAREST:
      params.envelope = GET_OPT_ENVELOPE (options);
      params.get_tap = get_nearest_tap;
      if (n_taps == 0)
        n_taps = 1;
      break;
    case GST_VIDEO_RESAMPLER_METHOD_LINEAR:
      params.get_tap = get_linear_tap;
      params.envelope = 1.0;
      break;
    case GST_VIDEO_RESAMPLER_METHOD_CUBIC:
      params.b = GET_OPT_CUBIC_B (options);
      params.c = GET_OPT_CUBIC_C (options);
      params.envelope = 2.0;
      params.get_tap = get_cubic_tap;
      break;
    case GST_VIDEO_RESAMPLER_METHOD_SINC:
      params.envelope = GET_OPT_ENVELOPE (options);
      params.get_tap = get_sinc_tap;
      break;
    case GST_VIDEO_RESAMPLER_METHOD_LANCZOS:
      params.envelope = GET_OPT_ENVELOPE (options);
      params.get_tap = get_lanczos_tap;
      break;
    default:
      break;
  }

  if (n_taps == 0) {
    params.dx = ceil (2.0 * params.envelope / params.fx);
    n_taps = CLAMP (params.dx, 0, max_taps);
  }
  if (flags & GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS && n_taps > 3)
    n_taps /= 2;
  params.fx = 2.0 * params.envelope / n_taps;
  params.ex = 2.0 / n_taps;

  if (n_taps > in_size)
    n_taps = in_size;

  resampler->max_taps = n_taps;

  resampler_calculate_taps (&params);

  resampler_dump (resampler);

  return TRUE;
}

/**
 * gst_video_resampler_clear:
 * @resampler: a #GstVideoResampler
 *
 * Clear a previously initialized #GstVideoResampler @resampler.
 *
 * Since: 1.6
 */
void
gst_video_resampler_clear (GstVideoResampler * resampler)
{
  g_return_if_fail (resampler != NULL);

  g_free (resampler->phase);
  g_free (resampler->offset);
  g_free (resampler->n_taps);
  g_free (resampler->taps);
}
