/* 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.
 */

#include <string.h>

#include "video-dither.h"
#include "video-orc.h"

/**
 * SECTION:gstvideodither
 * @short_description: Utility object for dithering and quantizing lines of video
 *
 * GstVideoDither provides implementations of several dithering algorithms
 * that can be applied to lines of video pixels to quantize and dither them.
 *
 */
struct _GstVideoDither
{
  GstVideoDitherMethod method;
  GstVideoDitherFlags flags;
  GstVideoFormat format;
  guint width;

  guint depth;
  guint n_comp;

  void (*func) (GstVideoDither * dither, gpointer pixels, guint x, guint y,
      guint width);
  guint8 shift[4];
  guint16 mask[4];
  guint64 orc_mask64;
  guint32 orc_mask32;

  gpointer errors;
};

static void
dither_none_u8_mask (GstVideoDither * dither, gpointer pixels, guint x, guint y,
    guint width)
{
  guint8 *p = pixels;

  video_orc_dither_none_4u8_mask (p + (x * 4), dither->orc_mask32, width);
}

static void
dither_none_u16_mask (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint16 *p = pixels;

  video_orc_dither_none_4u16_mask (p + (x * 4), dither->orc_mask64, width);
}

static void
dither_verterr_u8 (GstVideoDither * dither, gpointer pixels, guint x, guint y,
    guint width)
{
  guint8 *p = pixels;
  guint16 *e = dither->errors;

  if (y == 0)
    memset (e + (x * 4), 0, width * 8);

  video_orc_dither_verterr_4u8_mask (p + (x * 4), e + (x * 4),
      dither->orc_mask64, width);
}

static void
dither_verterr_u16 (GstVideoDither * dither, gpointer pixels, guint x, guint y,
    guint width)
{
  guint16 *p = pixels;
  guint16 *e = dither->errors;

  if (y == 0)
    memset (e + (x * 4), 0, width * 8);

  {
    gint i, end;
    guint16 *m = dither->mask;
    guint32 v, mp;

    end = (width + x) * 4;
    for (i = x * 4; i < end; i++) {
      mp = m[i & 3];
      v = p[i] + e[i];
      /* take new error and store */
      e[i] = v & mp;
      /* quantize and store */
      v &= ~mp;
      p[i] = MIN (v, 65535);
    }
  }
}

static void
dither_floyd_steinberg_u8 (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint8 *p = pixels;
  guint16 *e = dither->errors;

  if (y == 0)
    memset (e + (x * 4), 0, (width + 1) * 8);

  /* add and multiply errors from previous line */
  video_orc_dither_fs_muladd_u8 (e + x * 4, width * 4);
#if 1
  {
    gint i, end;
    guint16 *m = dither->mask, mp;
    guint16 v;

    end = (width + x) * 4;

    for (i = x * 4; i < end; i++) {
      mp = m[i & 3];
      v = p[i] + ((7 * e[i] + e[i + 4]) >> 4);
      /* take new error and store */
      e[i + 4] = v & mp;
      /* quantize and store */
      v &= ~mp;
      p[i] = MIN (v, 255);
    }
  }
#else
  video_orc_dither_fs_add_4u8 (p, e + x * 4, e + (x + 1) * 4,
      dither->orc_mask64, width);
#endif
}

static void
dither_floyd_steinberg_u16 (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint16 *p = pixels;
  guint16 *e = dither->errors;

  if (y == 0)
    memset (e + (x * 4), 0, (width + 1) * 8);

  {
    gint i, end;
    guint16 *m = dither->mask, mp;
    guint32 v;

    end = (width + x) * 4;
    for (i = x * 4; i < end; i++) {
      mp = m[i & 3];
      /* apply previous errors to pixel */
      v = p[i] + ((7 * e[i] + e[i + 4] + 5 * e[i + 8] + 3 * e[i + 12]) >> 4);
      /* take new error and store */
      e[i + 4] = v & mp;
      /* quantize and store */
      v &= ~mp;
      p[i] = MIN (v, 65535);
    }
  }
}

static void
dither_sierra_lite_u8 (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint8 *p = pixels;
  guint16 *e = dither->errors;
  gint i, end;
  guint16 *m = dither->mask, mp;
  guint16 v;

  if (y == 0)
    memset (e + (x * 4), 0, (width + 4) * 8);

  end = (width + x) * 4;
  for (i = x; i < end; i++) {
    mp = m[i & 3];
    /* apply previous errors to pixel */
    v = p[i] + ((2 * e[i] + e[i + 8] + e[i + 12]) >> 2);
    /* store new error */
    e[i + 4] = v & mp;
    /* quantize and store */
    v &= ~mp;
    p[i] = MIN (v, 255);
  }
}

static void
dither_sierra_lite_u16 (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint16 *p = pixels;
  guint16 *e = dither->errors;
  gint i, end;
  guint16 *m = dither->mask, mp;
  guint32 v;

  if (y == 0)
    memset (e + (x * 4), 0, (width + 4) * 8);

  end = (width + x) * 4;
  for (i = x; i < end; i++) {
    mp = m[i & 3];
    /* apply previous errors to pixel */
    v = p[i] + ((2 * e[i] + e[i + 8] + e[i + 12]) >> 2);
    /* store new error */
    e[i + 4] = v & mp;
    /* quantize and store */
    v &= ~mp;
    p[i] = MIN (v & ~mp, 65535);
  }
}

static const guint16 bayer_map[16][16] = {
  {0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170},
  {192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106},
  {48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154},
  {240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90},
  {12, 240, 44, 172, 4, 132, 36, 164, 14, 242, 46, 174, 6, 134, 38, 166},
  {204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102},
  {60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150},
  {252, 142, 220, 92, 244, 116, 212, 84, 254, 144, 222, 94, 246, 118, 214, 86},
  {3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169},
  {195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105},
  {51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153},
  {243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89},
  {15, 243, 47, 175, 7, 135, 39, 167, 13, 241, 45, 173, 5, 133, 37, 165},
  {207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101},
  {63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149},
  {255, 145, 223, 95, 247, 119, 215, 87, 253, 143, 221, 93, 245, 117, 213, 85}
};

static void
dither_ordered_u8 (GstVideoDither * dither, gpointer pixels, guint x, guint y,
    guint width)
{
  guint8 *p = pixels;
  guint8 *c = (guint8 *) dither->errors + ((y & 15) * width + (x & 15)) * 4;

  video_orc_dither_ordered_u8 (p, c, width * 4);
}

static void
dither_ordered_u8_mask (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint8 *p = pixels;
  guint16 *c = (guint16 *) dither->errors + ((y & 15) * width + (x & 15)) * 4;

  video_orc_dither_ordered_4u8_mask (p, c, dither->orc_mask64, width);
}

static void
dither_ordered_u16_mask (GstVideoDither * dither, gpointer pixels, guint x,
    guint y, guint width)
{
  guint16 *p = pixels;
  guint16 *c = (guint16 *) dither->errors + ((y & 15) * width + (x & 15)) * 4;

  video_orc_dither_ordered_4u16_mask (p, c, dither->orc_mask64, width);
}

static void
alloc_errors (GstVideoDither * dither, guint lines)
{
  guint width, n_comp;

  width = dither->width;
  n_comp = dither->n_comp;

  dither->errors = g_malloc0 (sizeof (guint16) * (width + 8) * n_comp * lines);
}

static void
setup_bayer (GstVideoDither * dither)
{
  guint i, j, k, width, n_comp, errdepth;
  guint8 *shift;

  width = dither->width;
  shift = dither->shift;
  n_comp = dither->n_comp;

  if (dither->depth == 8) {
    if (dither->flags & GST_VIDEO_DITHER_FLAG_QUANTIZE) {
      dither->func = dither_ordered_u8_mask;
      errdepth = 16;
    } else {
      dither->func = dither_ordered_u8;
      errdepth = 8;
    }
  } else {
    dither->func = dither_ordered_u16_mask;
    errdepth = 16;
  }

  alloc_errors (dither, 16);

  if (errdepth == 8) {
    for (i = 0; i < 16; i++) {
      guint8 *p = (guint8 *) dither->errors + (n_comp * width * i), v;
      for (j = 0; j < width; j++) {
        for (k = 0; k < n_comp; k++) {
          v = bayer_map[i & 15][j & 15];
          if (shift[k] < 8)
            v = v >> (8 - shift[k]);
          p[n_comp * j + k] = v;
        }
      }
    }
  } else {
    for (i = 0; i < 16; i++) {
      guint16 *p = (guint16 *) dither->errors + (n_comp * width * i), v;
      for (j = 0; j < width; j++) {
        for (k = 0; k < n_comp; k++) {
          v = bayer_map[i & 15][j & 15];
          if (shift[k] < 8)
            v = v >> (8 - shift[k]);
          p[n_comp * j + k] = v;
        }
      }
    }
  }
}

static gint
count_power (guint v)
{
  gint res = 0;
  while (v > 1) {
    res++;
    v >>= 1;
  }
  return res;
}

/**
 * gst_video_dither_new: (skip)
 * @method: a #GstVideoDitherMethod
 * @flags: a #GstVideoDitherFlags
 * @format: a #GstVideoFormat
 * @quantizer: quantizer
 * @width: the width of the lines
 *
 * Make a new dither object for dithering lines of @format using the
 * algorithm described by @method.
 *
 * Each component will be quantized to a multiple of @quantizer. Better
 * performance is achived when @quantizer is a power of 2.
 *
 * @width is the width of the lines that this ditherer will handle.
 *
 * Returns: a new #GstVideoDither
 */
GstVideoDither *
gst_video_dither_new (GstVideoDitherMethod method, GstVideoDitherFlags flags,
    GstVideoFormat format, guint quantizer[GST_VIDEO_MAX_COMPONENTS],
    guint width)
{
  GstVideoDither *dither;
  gint i;

  dither = g_slice_new0 (GstVideoDither);
  dither->method = method;
  dither->flags = flags;
  dither->format = format;
  dither->width = width;

  dither->n_comp = 4;

  switch (format) {
    case GST_VIDEO_FORMAT_AYUV:
    case GST_VIDEO_FORMAT_ARGB:
      dither->depth = 8;
      break;
    case GST_VIDEO_FORMAT_AYUV64:
    case GST_VIDEO_FORMAT_ARGB64:
      dither->depth = 16;
      break;
    default:
      g_slice_free (GstVideoDither, dither);
      g_return_val_if_reached (NULL);
      break;
  }

  for (i = 0; i < 4; i++) {
    /* FIXME, only power of 2 quantizers */
    guint q = quantizer[(i + 3) & 3];

    dither->shift[i] = count_power (q);
    dither->mask[i] = (1 << dither->shift[i]) - 1;
    GST_DEBUG ("%d: quant %d shift %d mask %08x", i, q, dither->shift[i],
        dither->mask[i]);
    dither->orc_mask64 =
        (dither->orc_mask64 << 16) | GUINT16_FROM_BE (dither->mask[i]);
    dither->orc_mask32 = (dither->orc_mask32 << 8) | (guint8) dither->mask[i];
  }
  dither->orc_mask64 = GUINT64_FROM_BE (dither->orc_mask64);
  dither->orc_mask32 = GUINT32_FROM_BE (dither->orc_mask32);
  GST_DEBUG ("mask64 %08" G_GINT64_MODIFIER "x", (guint64) dither->orc_mask64);
  GST_DEBUG ("mask32 %08x", dither->orc_mask32);

  switch (method) {
    case GST_VIDEO_DITHER_NONE:
      if (dither->flags & GST_VIDEO_DITHER_FLAG_QUANTIZE)
        if (dither->depth == 8)
          dither->func = dither_none_u8_mask;
        else
          dither->func = dither_none_u16_mask;
      else
        dither->func = NULL;
      break;
    case GST_VIDEO_DITHER_VERTERR:
      alloc_errors (dither, 1);
      if (dither->depth == 8) {
        dither->func = dither_verterr_u8;
      } else
        dither->func = dither_verterr_u16;
      break;
    case GST_VIDEO_DITHER_FLOYD_STEINBERG:
      alloc_errors (dither, 1);
      if (dither->depth == 8) {
        dither->func = dither_floyd_steinberg_u8;
      } else
        dither->func = dither_floyd_steinberg_u16;
      break;
    case GST_VIDEO_DITHER_SIERRA_LITE:
      alloc_errors (dither, 1);
      if (dither->depth == 8) {
        dither->func = dither_sierra_lite_u8;
      } else
        dither->func = dither_sierra_lite_u16;
      break;
    case GST_VIDEO_DITHER_BAYER:
      setup_bayer (dither);
      break;
  }
  return dither;
}

/**
 * gst_video_dither_free:
 * @dither: a #GstVideoDither
 *
 * Free @dither
 */
void
gst_video_dither_free (GstVideoDither * dither)
{
  g_return_if_fail (dither != NULL);

  g_free (dither->errors);
  g_slice_free (GstVideoDither, dither);
}

/**
 * gst_video_dither_line:
 * @dither: a #GstVideoDither
 * @line: pointer to the pixels of the line
 * @x: x coordinate
 * @y: y coordinate
 * @width: the width
 *
 * Dither @width pixels starting from offset @x in @line using @dither.
 *
 * @y is the line number of @line in the output image.
 */
void
gst_video_dither_line (GstVideoDither * dither, gpointer line, guint x, guint y,
    guint width)
{
  g_return_if_fail (dither != NULL);
  g_return_if_fail (x + width <= dither->width);

  if (dither->func)
    dither->func (dither, line, x, y, width);
}
