|
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 } |