/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent.
 */

#include "./aom_dsp_rtcd.h"
#include "./av1_rtcd.h"
#include "av1/common/filter.h"
#include "av1/common/scale.h"
#include "aom_dsp/aom_filter.h"

// Note: Expect val to be in q4 precision
static INLINE int scaled_x(int val, const struct scale_factors *sf) {
  const int off =
      (sf->x_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
  const int64_t tval = (int64_t)val * sf->x_scale_fp + off;
  return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
                                           REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
}

// Note: Expect val to be in q4 precision
static INLINE int scaled_y(int val, const struct scale_factors *sf) {
  const int off =
      (sf->y_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
  const int64_t tval = (int64_t)val * sf->y_scale_fp + off;
  return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
                                           REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
}

// Note: Expect val to be in q4 precision
static int unscaled_value(int val, const struct scale_factors *sf) {
  (void)sf;
  return val << SCALE_EXTRA_BITS;
}

static int get_fixed_point_scale_factor(int other_size, int this_size) {
  // Calculate scaling factor once for each reference frame
  // and use fixed point scaling factors in decoding and encoding routines.
  // Hardware implementations can calculate scale factor in device driver
  // and use multiplication and shifting on hardware instead of division.
  return ((other_size << REF_SCALE_SHIFT) + this_size / 2) / this_size;
}

// Given the fixed point scale, calculate coarse point scale.
static int fixed_point_scale_to_coarse_point_scale(int scale_fp) {
  return ROUND_POWER_OF_TWO(scale_fp, REF_SCALE_SHIFT - SCALE_SUBPEL_BITS);
}

// Note: x and y are integer precision, mvq4 is q4 precision.
MV32 av1_scale_mv(const MV32 *mvq4, int x, int y,
                  const struct scale_factors *sf) {
  const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf);
  const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf);
  const MV32 res = { scaled_y((y << SUBPEL_BITS) + mvq4->row, sf) - y_off_q4,
                     scaled_x((x << SUBPEL_BITS) + mvq4->col, sf) - x_off_q4 };
  return res;
}

void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
                                       int other_h, int this_w, int this_h) {
  if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) {
    sf->x_scale_fp = REF_INVALID_SCALE;
    sf->y_scale_fp = REF_INVALID_SCALE;
    return;
  }

  sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
  sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);

  sf->x_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->x_scale_fp);
  sf->y_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->y_scale_fp);

  if (av1_is_scaled(sf)) {
    sf->scale_value_x = scaled_x;
    sf->scale_value_y = scaled_y;
  } else {
    sf->scale_value_x = unscaled_value;
    sf->scale_value_y = unscaled_value;
  }

  // AV1 convolve functions
  // Special case convolve functions should produce the same result as
  // av1_convolve_2d.
  // subpel_x_q4 == 0 && subpel_y_q4 == 0
  sf->convolve[0][0][0] = av1_convolve_2d_copy_sr;
  // subpel_x_q4 == 0
  sf->convolve[0][1][0] = av1_convolve_y_sr;
  // subpel_y_q4 == 0
  sf->convolve[1][0][0] = av1_convolve_x_sr;
  // subpel_x_q4 != 0 && subpel_y_q4 != 0
  sf->convolve[1][1][0] = av1_convolve_2d_sr;
  // subpel_x_q4 == 0 && subpel_y_q4 == 0
  sf->convolve[0][0][1] = av1_jnt_convolve_2d_copy;
  // subpel_x_q4 == 0
  sf->convolve[0][1][1] = av1_jnt_convolve_y;
  // subpel_y_q4 == 0
  sf->convolve[1][0][1] = av1_jnt_convolve_x;
  // subpel_x_q4 != 0 && subpel_y_q4 != 0
  sf->convolve[1][1][1] = av1_jnt_convolve_2d;
  // AV1 High BD convolve functions
  // Special case convolve functions should produce the same result as
  // av1_highbd_convolve_2d.
  // subpel_x_q4 == 0 && subpel_y_q4 == 0
  sf->highbd_convolve[0][0][0] = av1_highbd_convolve_2d_copy_sr;
  // subpel_x_q4 == 0
  sf->highbd_convolve[0][1][0] = av1_highbd_convolve_y_sr;
  // subpel_y_q4 == 0
  sf->highbd_convolve[1][0][0] = av1_highbd_convolve_x_sr;
  // subpel_x_q4 != 0 && subpel_y_q4 != 0
  sf->highbd_convolve[1][1][0] = av1_highbd_convolve_2d_sr;
  // subpel_x_q4 == 0 && subpel_y_q4 == 0
  sf->highbd_convolve[0][0][1] = av1_highbd_jnt_convolve_2d_copy;
  // subpel_x_q4 == 0
  sf->highbd_convolve[0][1][1] = av1_highbd_jnt_convolve_y;
  // subpel_y_q4 == 0
  sf->highbd_convolve[1][0][1] = av1_highbd_jnt_convolve_x;
  // subpel_x_q4 != 0 && subpel_y_q4 != 0
  sf->highbd_convolve[1][1][1] = av1_highbd_jnt_convolve_2d;
}
