/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * aomedia.org/license/patent-license/.
 */

#ifndef AOM_AV1_COMMON_CONVOLVE_H_
#define AOM_AV1_COMMON_CONVOLVE_H_
#include "av1/common/filter.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef uint16_t CONV_BUF_TYPE;
typedef struct ConvolveParams {
  int do_average;
  CONV_BUF_TYPE *dst;
  int dst_stride;
  int round_0;
  int round_1;
  int plane;
  int is_compound;
  int fwd_offset;
  int bck_offset;
} ConvolveParams;

#if CONFIG_PC_WIENER || CONFIG_WIENER_NONSEP
#define NONSEP_PIXELS_MAX 32
#define NONSEP_COEFFS_MAX 32
#define NONSEP_ROW_ID 0
#define NONSEP_COL_ID 1
#define NONSEP_BUF_POS 2

static INLINE int16_t clip_base(int16_t x, int bit_depth) {
  (void)bit_depth;
  return x;
}

typedef struct NonsepFilterConfig {
  int prec_bits;
  int num_pixels;
  int num_pixels2;
  const int (*config)[3];
  const int (*config2)[3];
  int strict_bounds;
  int subtract_center;
} NonsepFilterConfig;

// Nonseparable convolution.
void av1_convolve_nonsep_highbd(const uint16_t *dgd, int width, int height,
                                int stride, const NonsepFilterConfig *config,
                                const int16_t *filter, uint16_t *dst,
                                int dst_stride, int bit_depth);
#endif  // CONFIG_PC_WIENER || CONFIG_WIENER_NONSEP

#if CONFIG_WIENER_NONSEP_CROSS_FILT
// Nonseparable convolution with dual input planes - used for cross component
// filtering.
void av1_convolve_nonsep_dual_highbd(const uint16_t *dgd, int width, int height,
                                     int stride, const uint16_t *dgd2,
                                     int stride2,
                                     const NonsepFilterConfig *config,
                                     const int16_t *filter, uint16_t *dst,
                                     int dst_stride, int bit_depth);

#endif  // CONFIG_WIENER_NONSEP_CROSS_FILT

#define ROUND0_BITS 3
#define COMPOUND_ROUND1_BITS 7
#define WIENER_ROUND0_BITS 3

#define WIENER_CLAMP_LIMIT(r0, bd) (1 << ((bd) + 1 + FILTER_BITS - r0))

typedef void (*aom_convolve_fn_t)(const uint8_t *src, int src_stride,
                                  uint8_t *dst, int dst_stride, int w, int h,
                                  const InterpFilterParams *filter_params_x,
                                  const InterpFilterParams *filter_params_y,
                                  const int subpel_x_qn, const int subpel_y_qn,
                                  ConvolveParams *conv_params);

typedef void (*aom_highbd_convolve_fn_t)(
    const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, int w,
    int h, const InterpFilterParams *filter_params_x,
    const InterpFilterParams *filter_params_y, const int subpel_x_qn,
    const int subpel_y_qn, ConvolveParams *conv_params, int bd);

struct AV1Common;
struct scale_factors;

static INLINE int is_uneven_wtd_comp_avg(const ConvolveParams *params) {
  return params->do_average &&
         (params->fwd_offset != (1 << (DIST_PRECISION_BITS - 1)) ||
          params->bck_offset != (1 << (DIST_PRECISION_BITS - 1)));
}

static INLINE void init_conv_params(ConvolveParams *params) {
  memset(params, 0, sizeof(*params));
  params->fwd_offset = 1 << (DIST_PRECISION_BITS - 1);
  params->bck_offset = 1 << (DIST_PRECISION_BITS - 1);
}

static INLINE ConvolveParams get_conv_params_no_round(int cmp_index, int plane,
                                                      CONV_BUF_TYPE *dst,
                                                      int dst_stride,
                                                      int is_compound, int bd) {
  ConvolveParams conv_params;
  assert(IMPLIES(cmp_index, is_compound));

  init_conv_params(&conv_params);
  conv_params.is_compound = is_compound;
  conv_params.round_0 = ROUND0_BITS;
  conv_params.round_1 = is_compound ? COMPOUND_ROUND1_BITS
                                    : 2 * FILTER_BITS - conv_params.round_0;
  const int intbufrange = bd + FILTER_BITS - conv_params.round_0 + 2;
  assert(IMPLIES(bd < 12, intbufrange <= 16));
  if (intbufrange > 16) {
    conv_params.round_0 += intbufrange - 16;
    if (!is_compound) conv_params.round_1 -= intbufrange - 16;
  }
  // TODO(yunqing): The following dst should only be valid while
  // is_compound = 1;
  conv_params.dst = dst;
  conv_params.dst_stride = dst_stride;
  conv_params.plane = plane;

  // By default, set do average to 1 if this is the second single prediction
  // in a compound mode.
  conv_params.do_average = cmp_index;
  return conv_params;
}

static INLINE ConvolveParams get_conv_params(int do_average, int plane,
                                             int bd) {
  return get_conv_params_no_round(do_average, plane, NULL, 0, 0, bd);
}

static INLINE ConvolveParams get_conv_params_wiener(int bd) {
  ConvolveParams conv_params;
  (void)bd;

  init_conv_params(&conv_params);
  conv_params.do_average = 0;
  conv_params.is_compound = 0;
  conv_params.round_0 = WIENER_ROUND0_BITS;
  conv_params.round_1 = 2 * FILTER_BITS - conv_params.round_0;
  const int intbufrange = bd + FILTER_BITS - conv_params.round_0 + 2;
  assert(IMPLIES(bd < 12, intbufrange <= 16));
  if (intbufrange > 16) {
    conv_params.round_0 += intbufrange - 16;
    conv_params.round_1 -= intbufrange - 16;
  }
  conv_params.dst = NULL;
  conv_params.dst_stride = 0;
  conv_params.plane = 0;
  return conv_params;
}

void av1_highbd_convolve_2d_facade(const uint16_t *src8, int src_stride,
                                   uint16_t *dst, int dst_stride, int w, int h,
                                   const InterpFilterParams *interp_filters[2],
                                   const int subpel_x_qn, int x_step_q4,
                                   const int subpel_y_qn, int y_step_q4,
                                   int scaled, ConvolveParams *conv_params,
                                   int bd);

// TODO(sarahparker) This will need to be integerized and optimized
void av1_convolve_2d_sobel_y_c(const uint8_t *src, int src_stride, double *dst,
                               int dst_stride, int w, int h, int dir,
                               double norm);

#ifdef __cplusplus
}  // extern "C"
#endif

#if CONFIG_PC_WIENER

// Updates the line buffers holding sums of features that in turn enable
// box-filtering of features. Accomplishes the first step of the update by
// subtracting the contribution of the out-of-scope line.
void prepare_feature_sum_bufs_c(int *feature_sum_buffers[],
                                int16_t *feature_line_buffers[],
                                int feature_length, int buffer_row,
                                int col_begin, int col_end, int buffer_col);

// Updates the line buffers holding sums of features that in turn enable
// box-filtering of features. Accomplishes the second step of the update by
// adding the contribution of the newly in-scope line.
void update_feature_sum_bufs_c(int *feature_sum_buffers[],
                               int16_t *feature_line_buffers[],
                               int feature_length, int buffer_row,
                               int col_begin, int col_end, int buffer_col);

// Calculates horizontal/vertical/diagonal/anti-diagonal gradients over a line
// and stores the results in associated line buffers. See CWG-C016 contribution
// for details.
void calc_gradient_in_various_directions_c(int16_t *feature_line_buffers[],
                                           int row, int buffer_row,
                                           const uint16_t *dgd, int dgd_stride,
                                           int width, int col_begin,
                                           int col_end, int feature_length,
                                           int buffer_col);
#endif  // CONFIG_PC_WIENER

#endif  // AOM_AV1_COMMON_CONVOLVE_H_
