/*
 *  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 "vp9/common/vp9_extend.h"
#include "vpx_mem/vpx_mem.h"

static void copy_and_extend_plane(uint8_t *s,       /* source */
                                  int sp,           /* source pitch */
                                  uint8_t *d,       /* destination */
                                  int dp,           /* destination pitch */
                                  int h,            /* height */
                                  int w,            /* width */
                                  int et,           /* extend top border */
                                  int el,           /* extend left border */
                                  int eb,           /* extend bottom border */
                                  int er) {         /* extend right border */
  int i;
  uint8_t *src_ptr1, *src_ptr2;
  uint8_t *dest_ptr1, *dest_ptr2;
  int linesize;

  /* copy the left and right most columns out */
  src_ptr1 = s;
  src_ptr2 = s + w - 1;
  dest_ptr1 = d - el;
  dest_ptr2 = d + w;

  for (i = 0; i < h; i++) {
    vpx_memset(dest_ptr1, src_ptr1[0], el);
    vpx_memcpy(dest_ptr1 + el, src_ptr1, w);
    vpx_memset(dest_ptr2, src_ptr2[0], er);
    src_ptr1  += sp;
    src_ptr2  += sp;
    dest_ptr1 += dp;
    dest_ptr2 += dp;
  }

  /* Now copy the top and bottom lines into each line of the respective
   * borders
   */
  src_ptr1 = d - el;
  src_ptr2 = d + dp * (h - 1) - el;
  dest_ptr1 = d + dp * (-et) - el;
  dest_ptr2 = d + dp * (h) - el;
  linesize = el + er + w;

  for (i = 0; i < et; i++) {
    vpx_memcpy(dest_ptr1, src_ptr1, linesize);
    dest_ptr1 += dp;
  }

  for (i = 0; i < eb; i++) {
    vpx_memcpy(dest_ptr2, src_ptr2, linesize);
    dest_ptr2 += dp;
  }
}

void vp9_copy_and_extend_frame(YV12_BUFFER_CONFIG *src,
                               YV12_BUFFER_CONFIG *dst) {
  int et = dst->border;
  int el = dst->border;
  int eb = dst->border + dst->y_height - src->y_height;
  int er = dst->border + dst->y_width - src->y_width;

  copy_and_extend_plane(src->y_buffer, src->y_stride,
                        dst->y_buffer, dst->y_stride,
                        src->y_height, src->y_width,
                        et, el, eb, er);

  et = dst->border >> 1;
  el = dst->border >> 1;
  eb = (dst->border >> 1) + dst->uv_height - src->uv_height;
  er = (dst->border >> 1) + dst->uv_width - src->uv_width;

  copy_and_extend_plane(src->u_buffer, src->uv_stride,
                        dst->u_buffer, dst->uv_stride,
                        src->uv_height, src->uv_width,
                        et, el, eb, er);

  copy_and_extend_plane(src->v_buffer, src->uv_stride,
                        dst->v_buffer, dst->uv_stride,
                        src->uv_height, src->uv_width,
                        et, el, eb, er);
}

void vp9_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
                                         YV12_BUFFER_CONFIG *dst,
                                         int srcy, int srcx,
                                         int srch, int srcw) {
  int et = dst->border;
  int el = dst->border;
  int eb = dst->border + dst->y_height - src->y_height;
  int er = dst->border + dst->y_width - src->y_width;
  int src_y_offset = srcy * src->y_stride + srcx;
  int dst_y_offset = srcy * dst->y_stride + srcx;
  int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1);
  int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1);

  // If the side is not touching the bounder then don't extend.
  if (srcy)
    et = 0;
  if (srcx)
    el = 0;
  if (srcy + srch != src->y_height)
    eb = 0;
  if (srcx + srcw != src->y_width)
    er = 0;

  copy_and_extend_plane(src->y_buffer + src_y_offset,
                        src->y_stride,
                        dst->y_buffer + dst_y_offset,
                        dst->y_stride,
                        srch, srcw,
                        et, el, eb, er);

  et = (et + 1) >> 1;
  el = (el + 1) >> 1;
  eb = (eb + 1) >> 1;
  er = (er + 1) >> 1;
  srch = (srch + 1) >> 1;
  srcw = (srcw + 1) >> 1;

  copy_and_extend_plane(src->u_buffer + src_uv_offset,
                        src->uv_stride,
                        dst->u_buffer + dst_uv_offset,
                        dst->uv_stride,
                        srch, srcw,
                        et, el, eb, er);

  copy_and_extend_plane(src->v_buffer + src_uv_offset,
                        src->uv_stride,
                        dst->v_buffer + dst_uv_offset,
                        dst->uv_stride,
                        srch, srcw,
                        et, el, eb, er);
}

/* note the extension is only for the last row, for intra prediction purpose */
void vp9_extend_mb_row(YV12_BUFFER_CONFIG *ybf, uint8_t *YPtr,
                       uint8_t *UPtr, uint8_t *VPtr) {
  int i;

  YPtr += ybf->y_stride * 14;
  UPtr += ybf->uv_stride * 6;
  VPtr += ybf->uv_stride * 6;

  for (i = 0; i < 4; i++) {
    YPtr[i] = YPtr[-1];
    UPtr[i] = UPtr[-1];
    VPtr[i] = VPtr[-1];
  }

  YPtr += ybf->y_stride;
  UPtr += ybf->uv_stride;
  VPtr += ybf->uv_stride;

  for (i = 0; i < 4; i++) {
    YPtr[i] = YPtr[-1];
    UPtr[i] = UPtr[-1];
    VPtr[i] = VPtr[-1];
  }
}
