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

#include "config/aom_config.h"

#include "aom_scale/yv12config.h"
#include "aom_mem/aom_mem.h"
#include "aom_scale/aom_scale.h"

#if HAVE_DSPR2
static void extend_plane(uint8_t *const src, int src_stride, int width,
                         int height, int extend_top, int extend_left,
                         int extend_bottom, int extend_right) {
  int i, j;
  uint8_t *left_src, *right_src;
  uint8_t *left_dst_start, *right_dst_start;
  uint8_t *left_dst, *right_dst;
  uint8_t *top_src, *bot_src;
  uint8_t *top_dst, *bot_dst;
  uint32_t left_pix;
  uint32_t right_pix;
  uint32_t linesize;

  /* copy the left and right most columns out */
  left_src = src;
  right_src = src + width - 1;
  left_dst_start = src - extend_left;
  right_dst_start = src + width;

  for (i = height; i--;) {
    left_dst = left_dst_start;
    right_dst = right_dst_start;

    __asm__ __volatile__(
        "lb        %[left_pix],     0(%[left_src])      \n\t"
        "lb        %[right_pix],    0(%[right_src])     \n\t"
        "replv.qb  %[left_pix],     %[left_pix]         \n\t"
        "replv.qb  %[right_pix],    %[right_pix]        \n\t"

        : [left_pix] "=&r"(left_pix), [right_pix] "=&r"(right_pix)
        : [left_src] "r"(left_src), [right_src] "r"(right_src));

    for (j = extend_left / 4; j--;) {
      __asm__ __volatile__(
          "sw     %[left_pix],    0(%[left_dst])     \n\t"
          "sw     %[right_pix],   0(%[right_dst])    \n\t"

          :
          : [left_dst] "r"(left_dst), [left_pix] "r"(left_pix),
            [right_dst] "r"(right_dst), [right_pix] "r"(right_pix));

      left_dst += 4;
      right_dst += 4;
    }

    for (j = extend_left % 4; j--;) {
      __asm__ __volatile__(
          "sb     %[left_pix],    0(%[left_dst])     \n\t"
          "sb     %[right_pix],   0(%[right_dst])     \n\t"

          :
          : [left_dst] "r"(left_dst), [left_pix] "r"(left_pix),
            [right_dst] "r"(right_dst), [right_pix] "r"(right_pix));

      left_dst += 1;
      right_dst += 1;
    }

    left_src += src_stride;
    right_src += src_stride;
    left_dst_start += src_stride;
    right_dst_start += src_stride;
  }

  /* Now copy the top and bottom lines into each line of the respective
   * borders
   */
  top_src = src - extend_left;
  bot_src = src + src_stride * (height - 1) - extend_left;
  top_dst = src + src_stride * (-extend_top) - extend_left;
  bot_dst = src + src_stride * (height)-extend_left;
  linesize = extend_left + extend_right + width;
  assert(linesize <= src_stride);

  for (i = 0; i < extend_top; i++) {
    memcpy(top_dst, top_src, linesize);
    top_dst += src_stride;
  }

  for (i = 0; i < extend_bottom; i++) {
    memcpy(bot_dst, bot_src, linesize);
    bot_dst += src_stride;
  }
}

static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) {
  const int c_w = ybf->uv_crop_width;
  const int c_h = ybf->uv_crop_height;
  const int ss_x = ybf->subsampling_x;
  const int ss_y = ybf->subsampling_y;
  const int c_et = ext_size >> ss_y;
  const int c_el = ext_size >> ss_x;
  const int c_eb = c_et + ybf->uv_height - ybf->uv_crop_height;
  const int c_er = c_el + ybf->uv_width - ybf->uv_crop_width;

  assert(ybf->y_height - ybf->y_crop_height < 16);
  assert(ybf->y_width - ybf->y_crop_width < 16);
  assert(ybf->y_height - ybf->y_crop_height >= 0);
  assert(ybf->y_width - ybf->y_crop_width >= 0);

  extend_plane(ybf->y_buffer, ybf->y_stride, ybf->y_crop_width,
               ybf->y_crop_height, ext_size, ext_size,
               ext_size + ybf->y_height - ybf->y_crop_height,
               ext_size + ybf->y_width - ybf->y_crop_width);

  extend_plane(ybf->u_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er);

  extend_plane(ybf->v_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er);
}

void aom_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf,
                                    const int num_planes) {
  extend_frame(ybf, ybf->border, num_planes);
}

void aom_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf,
                                          const int num_planes) {
  const int inner_bw = (ybf->border > AOMINNERBORDERINPIXELS)
                           ? AOMINNERBORDERINPIXELS
                           : ybf->border;
  extend_frame(ybf, inner_bw, num_planes);
}
#endif
