/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

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

#include "./vpx_dsp_rtcd.h"
#include "./vpx_config.h"
#include "./vpx_scale_rtcd.h"
#include "./vp9_rtcd.h"

#include "vpx_dsp/vpx_dsp_common.h"
#include "vpx_dsp/postproc.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/system_state.h"
#include "vpx_scale/vpx_scale.h"
#include "vpx_scale/yv12config.h"

#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_postproc.h"
#include "vp9/common/vp9_textblit.h"

#if CONFIG_VP9_POSTPROC
static const int16_t kernel5[] = {
  1, 1, 4, 1, 1
};

static const uint8_t q_diff_thresh = 20;
static const uint8_t last_q_thresh = 170;
extern const int16_t vpx_rv[];

#if CONFIG_VP9_HIGHBITDEPTH
void vp9_highbd_post_proc_down_and_across_c(const uint16_t *src_ptr,
                                            uint16_t *dst_ptr,
                                            int src_pixels_per_line,
                                            int dst_pixels_per_line,
                                            int rows,
                                            int cols,
                                            int flimit) {
  uint16_t const *p_src;
  uint16_t *p_dst;
  int row, col, i, v, kernel;
  int pitch = src_pixels_per_line;
  uint16_t d[8];

  for (row = 0; row < rows; row++) {
    // post_proc_down for one row.
    p_src = src_ptr;
    p_dst = dst_ptr;

    for (col = 0; col < cols; col++) {
      kernel = 4;
      v = p_src[col];

      for (i = -2; i <= 2; i++) {
        if (abs(v - p_src[col + i * pitch]) > flimit)
          goto down_skip_convolve;

        kernel += kernel5[2 + i] * p_src[col + i * pitch];
      }

      v = (kernel >> 3);

    down_skip_convolve:
      p_dst[col] = v;
    }

    /* now post_proc_across */
    p_src = dst_ptr;
    p_dst = dst_ptr;

    for (i = 0; i < 8; i++)
      d[i] = p_src[i];

    for (col = 0; col < cols; col++) {
      kernel = 4;
      v = p_src[col];

      d[col & 7] = v;

      for (i = -2; i <= 2; i++) {
        if (abs(v - p_src[col + i]) > flimit)
          goto across_skip_convolve;

        kernel += kernel5[2 + i] * p_src[col + i];
      }

      d[col & 7] = (kernel >> 3);

    across_skip_convolve:
      if (col >= 2)
        p_dst[col - 2] = d[(col - 2) & 7];
    }

    /* handle the last two pixels */
    p_dst[col - 2] = d[(col - 2) & 7];
    p_dst[col - 1] = d[(col - 1) & 7];


    /* next row */
    src_ptr += pitch;
    dst_ptr += dst_pixels_per_line;
  }
}
#endif  // CONFIG_VP9_HIGHBITDEPTH

static int q2mbl(int x) {
  if (x < 20) x = 20;

  x = 50 + (x - 50) * 10 / 8;
  return x * x / 3;
}

#if CONFIG_VP9_HIGHBITDEPTH
void vp9_highbd_mbpost_proc_across_ip_c(uint16_t *src, int pitch,
                                        int rows, int cols, int flimit) {
  int r, c, i;

  uint16_t *s = src;
  uint16_t d[16];


  for (r = 0; r < rows; r++) {
    int sumsq = 0;
    int sum   = 0;

    for (i = -8; i <= 6; i++) {
      sumsq += s[i] * s[i];
      sum   += s[i];
      d[i + 8] = 0;
    }

    for (c = 0; c < cols + 8; c++) {
      int x = s[c + 7] - s[c - 8];
      int y = s[c + 7] + s[c - 8];

      sum  += x;
      sumsq += x * y;

      d[c & 15] = s[c];

      if (sumsq * 15 - sum * sum < flimit) {
        d[c & 15] = (8 + sum + s[c]) >> 4;
      }

      s[c - 8] = d[(c - 8) & 15];
    }

    s += pitch;
  }
}
#endif  // CONFIG_VP9_HIGHBITDEPTH


#if CONFIG_VP9_HIGHBITDEPTH
void vp9_highbd_mbpost_proc_down_c(uint16_t *dst, int pitch,
                                   int rows, int cols, int flimit) {
  int r, c, i;
  const int16_t *rv3 = &vpx_rv[63 & rand()];  // NOLINT

  for (c = 0; c < cols; c++) {
    uint16_t *s = &dst[c];
    int sumsq = 0;
    int sum = 0;
    uint16_t d[16];
    const int16_t *rv2 = rv3 + ((c * 17) & 127);

    for (i = -8; i <= 6; i++) {
      sumsq += s[i * pitch] * s[i * pitch];
      sum += s[i * pitch];
    }

    for (r = 0; r < rows + 8; r++) {
      sumsq += s[7 * pitch] * s[ 7 * pitch] - s[-8 * pitch] * s[-8 * pitch];
      sum += s[7 * pitch] - s[-8 * pitch];
      d[r & 15] = s[0];

      if (sumsq * 15 - sum * sum < flimit) {
        d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4;
      }

      s[-8 * pitch] = d[(r - 8) & 15];
      s += pitch;
    }
  }
}
#endif  // CONFIG_VP9_HIGHBITDEPTH

static void deblock_and_de_macro_block(YV12_BUFFER_CONFIG   *source,
                                       YV12_BUFFER_CONFIG   *post,
                                       int                   q,
                                       int                   low_var_thresh,
                                       int                   flag,
                                       uint8_t              *limits) {
  (void) low_var_thresh;
  (void) flag;
#if CONFIG_VP9_HIGHBITDEPTH
  if (source->flags & YV12_FLAG_HIGHBITDEPTH) {
    double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
    int ppl = (int)(level + .5);
    vp9_highbd_post_proc_down_and_across(CONVERT_TO_SHORTPTR(source->y_buffer),
                                         CONVERT_TO_SHORTPTR(post->y_buffer),
                                         source->y_stride, post->y_stride,
                                         source->y_height, source->y_width,
                                         ppl);

    vp9_highbd_mbpost_proc_across_ip(CONVERT_TO_SHORTPTR(post->y_buffer),
                                     post->y_stride, post->y_height,
                                     post->y_width, q2mbl(q));

    vp9_highbd_mbpost_proc_down(CONVERT_TO_SHORTPTR(post->y_buffer),
                                post->y_stride, post->y_height,
                                post->y_width, q2mbl(q));

    vp9_highbd_post_proc_down_and_across(CONVERT_TO_SHORTPTR(source->u_buffer),
                                         CONVERT_TO_SHORTPTR(post->u_buffer),
                                         source->uv_stride, post->uv_stride,
                                         source->uv_height, source->uv_width,
                                         ppl);
    vp9_highbd_post_proc_down_and_across(CONVERT_TO_SHORTPTR(source->v_buffer),
                                         CONVERT_TO_SHORTPTR(post->v_buffer),
                                         source->uv_stride, post->uv_stride,
                                         source->uv_height, source->uv_width,
                                         ppl);
  } else {
#endif  // CONFIG_VP9_HIGHBITDEPTH
    vp9_deblock(source, post, q, limits);
    vpx_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height,
                              post->y_width, q2mbl(q));
    vpx_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height,
                         post->y_width, q2mbl(q));
#if CONFIG_VP9_HIGHBITDEPTH
  }
#endif  // CONFIG_VP9_HIGHBITDEPTH
}

void vp9_deblock(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
                 int q, uint8_t *limits) {
  const int ppl = (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q
                        + 0.0065 + 0.5);
#if CONFIG_VP9_HIGHBITDEPTH
  if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
    int i;
    const uint8_t * const srcs[3] =
        {src->y_buffer, src->u_buffer, src->v_buffer};
    const int src_strides[3] = {src->y_stride, src->uv_stride, src->uv_stride};
    const int src_widths[3] = {src->y_width, src->uv_width, src->uv_width};
    const int src_heights[3] = {src->y_height, src->uv_height, src->uv_height};

    uint8_t * const dsts[3] = {dst->y_buffer, dst->u_buffer, dst->v_buffer};
    const int dst_strides[3] = {dst->y_stride, dst->uv_stride, dst->uv_stride};
    for (i = 0; i < MAX_MB_PLANE; ++i) {
      vp9_highbd_post_proc_down_and_across(CONVERT_TO_SHORTPTR(srcs[i]),
                                           CONVERT_TO_SHORTPTR(dsts[i]),
                                           src_strides[i], dst_strides[i],
                                           src_heights[i], src_widths[i], ppl);
    }
  } else {
#endif  // CONFIG_VP9_HIGHBITDEPTH
    int mbr;
    const int mb_rows = src->y_height / 16;
    const int mb_cols = src->y_width / 16;

    memset(limits, (unsigned char) ppl, 16 * mb_cols);

    for (mbr = 0; mbr < mb_rows; mbr++) {
      vpx_post_proc_down_and_across_mb_row(
          src->y_buffer + 16 * mbr * src->y_stride,
          dst->y_buffer + 16 * mbr * dst->y_stride, src->y_stride,
          dst->y_stride, src->y_width, limits, 16);
      vpx_post_proc_down_and_across_mb_row(
          src->u_buffer + 8 * mbr * src->uv_stride,
          dst->u_buffer + 8 * mbr * dst->uv_stride, src->uv_stride,
          dst->uv_stride, src->uv_width, limits, 8);
      vpx_post_proc_down_and_across_mb_row(
          src->v_buffer + 8 * mbr * src->uv_stride,
          dst->v_buffer + 8 * mbr * dst->uv_stride, src->uv_stride,
          dst->uv_stride, src->uv_width, limits, 8);
    }
#if CONFIG_VP9_HIGHBITDEPTH
  }
#endif  // CONFIG_VP9_HIGHBITDEPTH
}

void vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
                 int q, uint8_t *limits) {
  vp9_deblock(src, dst, q, limits);
}

static void swap_mi_and_prev_mi(VP9_COMMON *cm) {
  // Current mip will be the prev_mip for the next frame.
  MODE_INFO *temp = cm->postproc_state.prev_mip;
  cm->postproc_state.prev_mip = cm->mip;
  cm->mip = temp;

  // Update the upper left visible macroblock ptrs.
  cm->mi = cm->mip + cm->mi_stride + 1;
  cm->postproc_state.prev_mi = cm->postproc_state.prev_mip + cm->mi_stride + 1;
}

int vp9_post_proc_frame(struct VP9Common *cm,
                        YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) {
  const int q = VPXMIN(105, cm->lf.filter_level * 2);
  const int flags = ppflags->post_proc_flag;
  YV12_BUFFER_CONFIG *const ppbuf = &cm->post_proc_buffer;
  struct postproc_state *const ppstate = &cm->postproc_state;

  if (!cm->frame_to_show)
    return -1;

  if (!flags) {
    *dest = *cm->frame_to_show;
    return 0;
  }

  vpx_clear_system_state();

  // Alloc memory for prev_mip in the first frame.
  if (cm->current_video_frame == 1) {
    cm->postproc_state.last_base_qindex = cm->base_qindex;
    cm->postproc_state.last_frame_valid = 1;
    ppstate->prev_mip = vpx_calloc(cm->mi_alloc_size, sizeof(*cm->mip));
    if (!ppstate->prev_mip) {
      return 1;
    }
    ppstate->prev_mi = ppstate->prev_mip + cm->mi_stride + 1;
    memset(ppstate->prev_mip, 0,
           cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
  }

  // Allocate post_proc_buffer_int if needed.
  if ((flags & VP9D_MFQE) && !cm->post_proc_buffer_int.buffer_alloc) {
    if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) {
      const int width = ALIGN_POWER_OF_TWO(cm->width, 4);
      const int height = ALIGN_POWER_OF_TWO(cm->height, 4);

      if (vpx_alloc_frame_buffer(&cm->post_proc_buffer_int, width, height,
                                 cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
                                 cm->use_highbitdepth,
#endif  // CONFIG_VP9_HIGHBITDEPTH
                                 VP9_ENC_BORDER_IN_PIXELS,
                                 cm->byte_alignment) < 0) {
        vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                           "Failed to allocate MFQE framebuffer");
      }

      // Ensure that postproc is set to all 0s so that post proc
      // doesn't pull random data in from edge.
      memset(cm->post_proc_buffer_int.buffer_alloc, 128,
             cm->post_proc_buffer.frame_size);
    }
  }

  if (vpx_realloc_frame_buffer(&cm->post_proc_buffer, cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
                               cm->use_highbitdepth,
#endif
                               VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
                               NULL, NULL, NULL) < 0)
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                       "Failed to allocate post-processing buffer");

  if (flags & (VP9D_DEMACROBLOCK | VP9D_DEBLOCK)) {
    if (!cm->postproc_state.limits) {
      cm->postproc_state.limits = vpx_calloc(
          cm->width, sizeof(*cm->postproc_state.limits));
    }
  }


  if ((flags & VP9D_MFQE) && cm->current_video_frame >= 2 &&
      cm->postproc_state.last_frame_valid && cm->bit_depth == 8 &&
      cm->postproc_state.last_base_qindex <= last_q_thresh &&
      cm->base_qindex - cm->postproc_state.last_base_qindex >= q_diff_thresh) {
    vp9_mfqe(cm);
    // TODO(jackychen): Consider whether enable deblocking by default
    // if mfqe is enabled. Need to take both the quality and the speed
    // into consideration.
    if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) {
      vp8_yv12_copy_frame(ppbuf, &cm->post_proc_buffer_int);
    }
    if ((flags & VP9D_DEMACROBLOCK) && cm->post_proc_buffer_int.buffer_alloc) {
      deblock_and_de_macro_block(&cm->post_proc_buffer_int, ppbuf,
                                 q + (ppflags->deblocking_level - 5) * 10,
                                 1, 0, cm->postproc_state.limits);
    } else if (flags & VP9D_DEBLOCK) {
      vp9_deblock(&cm->post_proc_buffer_int, ppbuf, q,
                  cm->postproc_state.limits);
    } else {
      vp8_yv12_copy_frame(&cm->post_proc_buffer_int, ppbuf);
    }
  } else if (flags & VP9D_DEMACROBLOCK) {
    deblock_and_de_macro_block(cm->frame_to_show, ppbuf,
                               q + (ppflags->deblocking_level - 5) * 10, 1, 0,
                               cm->postproc_state.limits);
  } else if (flags & VP9D_DEBLOCK) {
    vp9_deblock(cm->frame_to_show, ppbuf, q, cm->postproc_state.limits);
  } else {
    vp8_yv12_copy_frame(cm->frame_to_show, ppbuf);
  }

  cm->postproc_state.last_base_qindex = cm->base_qindex;
  cm->postproc_state.last_frame_valid = 1;

  if (flags & VP9D_ADDNOISE) {
    const int noise_level = ppflags->noise_level;
    if (ppstate->last_q != q ||
        ppstate->last_noise != noise_level) {
      double sigma;
      int clamp, i;
      vpx_clear_system_state();
      sigma = noise_level + .5 + .6 * q / 63.0;
      clamp = vpx_setup_noise(sigma, sizeof(ppstate->noise),
                              ppstate->noise);

      for (i = 0; i < 16; i++) {
        ppstate->blackclamp[i] = clamp;
        ppstate->whiteclamp[i] = clamp;
        ppstate->bothclamp[i] = 2 * clamp;
      }
      ppstate->last_q = q;
      ppstate->last_noise = noise_level;
    }
    vpx_plane_add_noise(ppbuf->y_buffer, ppstate->noise, ppstate->blackclamp,
                        ppstate->whiteclamp, ppstate->bothclamp,
                        ppbuf->y_width, ppbuf->y_height, ppbuf->y_stride);
  }

  *dest = *ppbuf;

  /* handle problem with extending borders */
  dest->y_width = cm->width;
  dest->y_height = cm->height;
  dest->uv_width = dest->y_width >> cm->subsampling_x;
  dest->uv_height = dest->y_height >> cm->subsampling_y;

  swap_mi_and_prev_mi(cm);
  return 0;
}
#endif  // CONFIG_VP9_POSTPROC
