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


static void copy_and_extend_plane
(
    unsigned char *s, /* source */
    int sp,           /* source pitch */
    unsigned char *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;
    unsigned char *src_ptr1, *src_ptr2;
    unsigned char *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 vp8_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 vp8_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 vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf,
                       unsigned char *YPtr,
                       unsigned char *UPtr,
                       unsigned char *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];
    }
}
