Home | History | Annotate | Download | only in common
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 #include "extend.h"
     13 #include "vpx_mem/vpx_mem.h"
     14 
     15 
     16 static void copy_and_extend_plane
     17 (
     18     unsigned char *s, /* source */
     19     int sp,           /* source pitch */
     20     unsigned char *d, /* destination */
     21     int dp,           /* destination pitch */
     22     int h,            /* height */
     23     int w,            /* width */
     24     int et,           /* extend top border */
     25     int el,           /* extend left border */
     26     int eb,           /* extend bottom border */
     27     int er            /* extend right border */
     28 )
     29 {
     30     int i;
     31     unsigned char *src_ptr1, *src_ptr2;
     32     unsigned char *dest_ptr1, *dest_ptr2;
     33     int linesize;
     34 
     35     /* copy the left and right most columns out */
     36     src_ptr1 = s;
     37     src_ptr2 = s + w - 1;
     38     dest_ptr1 = d - el;
     39     dest_ptr2 = d + w;
     40 
     41     for (i = 0; i < h; i++)
     42     {
     43         vpx_memset(dest_ptr1, src_ptr1[0], el);
     44         vpx_memcpy(dest_ptr1 + el, src_ptr1, w);
     45         vpx_memset(dest_ptr2, src_ptr2[0], er);
     46         src_ptr1  += sp;
     47         src_ptr2  += sp;
     48         dest_ptr1 += dp;
     49         dest_ptr2 += dp;
     50     }
     51 
     52     /* Now copy the top and bottom lines into each line of the respective
     53      * borders
     54      */
     55     src_ptr1 = d - el;
     56     src_ptr2 = d + dp * (h - 1) - el;
     57     dest_ptr1 = d + dp * (-et) - el;
     58     dest_ptr2 = d + dp * (h) - el;
     59     linesize = el + er + w;
     60 
     61     for (i = 0; i < et; i++)
     62     {
     63         vpx_memcpy(dest_ptr1, src_ptr1, linesize);
     64         dest_ptr1 += dp;
     65     }
     66 
     67     for (i = 0; i < eb; i++)
     68     {
     69         vpx_memcpy(dest_ptr2, src_ptr2, linesize);
     70         dest_ptr2 += dp;
     71     }
     72 }
     73 
     74 
     75 void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src,
     76                                YV12_BUFFER_CONFIG *dst)
     77 {
     78     int et = dst->border;
     79     int el = dst->border;
     80     int eb = dst->border + dst->y_height - src->y_height;
     81     int er = dst->border + dst->y_width - src->y_width;
     82 
     83     copy_and_extend_plane(src->y_buffer, src->y_stride,
     84                           dst->y_buffer, dst->y_stride,
     85                           src->y_height, src->y_width,
     86                           et, el, eb, er);
     87 
     88     et = dst->border >> 1;
     89     el = dst->border >> 1;
     90     eb = (dst->border >> 1) + dst->uv_height - src->uv_height;
     91     er = (dst->border >> 1) + dst->uv_width - src->uv_width;
     92 
     93     copy_and_extend_plane(src->u_buffer, src->uv_stride,
     94                           dst->u_buffer, dst->uv_stride,
     95                           src->uv_height, src->uv_width,
     96                           et, el, eb, er);
     97 
     98     copy_and_extend_plane(src->v_buffer, src->uv_stride,
     99                           dst->v_buffer, dst->uv_stride,
    100                           src->uv_height, src->uv_width,
    101                           et, el, eb, er);
    102 }
    103 
    104 
    105 void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src,
    106                                          YV12_BUFFER_CONFIG *dst,
    107                                          int srcy, int srcx,
    108                                          int srch, int srcw)
    109 {
    110     int et = dst->border;
    111     int el = dst->border;
    112     int eb = dst->border + dst->y_height - src->y_height;
    113     int er = dst->border + dst->y_width - src->y_width;
    114     int src_y_offset = srcy * src->y_stride + srcx;
    115     int dst_y_offset = srcy * dst->y_stride + srcx;
    116     int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1);
    117     int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1);
    118 
    119     /* If the side is not touching the bounder then don't extend. */
    120     if (srcy)
    121       et = 0;
    122     if (srcx)
    123       el = 0;
    124     if (srcy + srch != src->y_height)
    125       eb = 0;
    126     if (srcx + srcw != src->y_width)
    127       er = 0;
    128 
    129     copy_and_extend_plane(src->y_buffer + src_y_offset,
    130                           src->y_stride,
    131                           dst->y_buffer + dst_y_offset,
    132                           dst->y_stride,
    133                           srch, srcw,
    134                           et, el, eb, er);
    135 
    136     et = (et + 1) >> 1;
    137     el = (el + 1) >> 1;
    138     eb = (eb + 1) >> 1;
    139     er = (er + 1) >> 1;
    140     srch = (srch + 1) >> 1;
    141     srcw = (srcw + 1) >> 1;
    142 
    143     copy_and_extend_plane(src->u_buffer + src_uv_offset,
    144                           src->uv_stride,
    145                           dst->u_buffer + dst_uv_offset,
    146                           dst->uv_stride,
    147                           srch, srcw,
    148                           et, el, eb, er);
    149 
    150     copy_and_extend_plane(src->v_buffer + src_uv_offset,
    151                           src->uv_stride,
    152                           dst->v_buffer + dst_uv_offset,
    153                           dst->uv_stride,
    154                           srch, srcw,
    155                           et, el, eb, er);
    156 }
    157 
    158 
    159 /* note the extension is only for the last row, for intra prediction purpose */
    160 void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf,
    161                        unsigned char *YPtr,
    162                        unsigned char *UPtr,
    163                        unsigned char *VPtr)
    164 {
    165     int i;
    166 
    167     YPtr += ybf->y_stride * 14;
    168     UPtr += ybf->uv_stride * 6;
    169     VPtr += ybf->uv_stride * 6;
    170 
    171     for (i = 0; i < 4; i++)
    172     {
    173         YPtr[i] = YPtr[-1];
    174         UPtr[i] = UPtr[-1];
    175         VPtr[i] = VPtr[-1];
    176     }
    177 
    178     YPtr += ybf->y_stride;
    179     UPtr += ybf->uv_stride;
    180     VPtr += ybf->uv_stride;
    181 
    182     for (i = 0; i < 4; i++)
    183     {
    184         YPtr[i] = YPtr[-1];
    185         UPtr[i] = UPtr[-1];
    186         VPtr[i] = VPtr[-1];
    187     }
    188 }
    189