Initial WebM release
[libvpx.git] / vp8 / common / arm / reconintra4x4_arm.c
blob334d352360921b4de5a77f235a982d2ced656f34
1 /*
2 * Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license and patent
5 * grant that can be found in the LICENSE file in the root of the source
6 * tree. All contributing project authors may be found in the AUTHORS
7 * file in the root of the source tree.
8 */
11 #include "vpx_ports/config.h"
12 #include "recon.h"
13 #include "vpx_mem/vpx_mem.h"
14 #include "reconintra.h"
16 void vp8_predict_intra4x4(BLOCKD *x,
17 int b_mode,
18 unsigned char *predictor)
20 int i, r, c;
22 unsigned char *Above = *(x->base_dst) + x->dst - x->dst_stride;
23 unsigned char Left[4];
24 unsigned char top_left = Above[-1];
26 Left[0] = (*(x->base_dst))[x->dst - 1];
27 Left[1] = (*(x->base_dst))[x->dst - 1 + x->dst_stride];
28 Left[2] = (*(x->base_dst))[x->dst - 1 + 2 * x->dst_stride];
29 Left[3] = (*(x->base_dst))[x->dst - 1 + 3 * x->dst_stride];
31 switch (b_mode)
33 case B_DC_PRED:
35 int expected_dc = 0;
37 for (i = 0; i < 4; i++)
39 expected_dc += Above[i];
40 expected_dc += Left[i];
43 expected_dc = (expected_dc + 4) >> 3;
45 for (r = 0; r < 4; r++)
47 for (c = 0; c < 4; c++)
49 predictor[c] = expected_dc;
52 predictor += 16;
55 break;
56 case B_TM_PRED:
58 // prediction similar to true_motion prediction
59 for (r = 0; r < 4; r++)
61 for (c = 0; c < 4; c++)
63 int pred = Above[c] - top_left + Left[r];
65 if (pred < 0)
66 pred = 0;
68 if (pred > 255)
69 pred = 255;
71 predictor[c] = pred;
74 predictor += 16;
77 break;
79 case B_VE_PRED:
82 unsigned int ap[4];
83 ap[0] = (top_left + 2 * Above[0] + Above[1] + 2) >> 2;
84 ap[1] = (Above[0] + 2 * Above[1] + Above[2] + 2) >> 2;
85 ap[2] = (Above[1] + 2 * Above[2] + Above[3] + 2) >> 2;
86 ap[3] = (Above[2] + 2 * Above[3] + Above[4] + 2) >> 2;
88 for (r = 0; r < 4; r++)
90 for (c = 0; c < 4; c++)
93 predictor[c] = ap[c];
96 predictor += 16;
100 break;
103 case B_HE_PRED:
106 unsigned int lp[4];
107 lp[0] = (top_left + 2 * Left[0] + Left[1] + 2) >> 2;
108 lp[1] = (Left[0] + 2 * Left[1] + Left[2] + 2) >> 2;
109 lp[2] = (Left[1] + 2 * Left[2] + Left[3] + 2) >> 2;
110 lp[3] = (Left[2] + 2 * Left[3] + Left[3] + 2) >> 2;
112 for (r = 0; r < 4; r++)
114 for (c = 0; c < 4; c++)
116 predictor[c] = lp[r];
119 predictor += 16;
122 break;
123 case B_LD_PRED:
125 unsigned char *ptr = Above;
126 predictor[0 * 16 + 0] = (ptr[0] + ptr[1] * 2 + ptr[2] + 2) >> 2;
127 predictor[0 * 16 + 1] =
128 predictor[1 * 16 + 0] = (ptr[1] + ptr[2] * 2 + ptr[3] + 2) >> 2;
129 predictor[0 * 16 + 2] =
130 predictor[1 * 16 + 1] =
131 predictor[2 * 16 + 0] = (ptr[2] + ptr[3] * 2 + ptr[4] + 2) >> 2;
132 predictor[0 * 16 + 3] =
133 predictor[1 * 16 + 2] =
134 predictor[2 * 16 + 1] =
135 predictor[3 * 16 + 0] = (ptr[3] + ptr[4] * 2 + ptr[5] + 2) >> 2;
136 predictor[1 * 16 + 3] =
137 predictor[2 * 16 + 2] =
138 predictor[3 * 16 + 1] = (ptr[4] + ptr[5] * 2 + ptr[6] + 2) >> 2;
139 predictor[2 * 16 + 3] =
140 predictor[3 * 16 + 2] = (ptr[5] + ptr[6] * 2 + ptr[7] + 2) >> 2;
141 predictor[3 * 16 + 3] = (ptr[6] + ptr[7] * 2 + ptr[7] + 2) >> 2;
144 break;
145 case B_RD_PRED:
148 unsigned char pp[9];
150 pp[0] = Left[3];
151 pp[1] = Left[2];
152 pp[2] = Left[1];
153 pp[3] = Left[0];
154 pp[4] = top_left;
155 pp[5] = Above[0];
156 pp[6] = Above[1];
157 pp[7] = Above[2];
158 pp[8] = Above[3];
160 predictor[3 * 16 + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
161 predictor[3 * 16 + 1] =
162 predictor[2 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
163 predictor[3 * 16 + 2] =
164 predictor[2 * 16 + 1] =
165 predictor[1 * 16 + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
166 predictor[3 * 16 + 3] =
167 predictor[2 * 16 + 2] =
168 predictor[1 * 16 + 1] =
169 predictor[0 * 16 + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
170 predictor[2 * 16 + 3] =
171 predictor[1 * 16 + 2] =
172 predictor[0 * 16 + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
173 predictor[1 * 16 + 3] =
174 predictor[0 * 16 + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
175 predictor[0 * 16 + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
178 break;
179 case B_VR_PRED:
182 unsigned char pp[9];
184 pp[0] = Left[3];
185 pp[1] = Left[2];
186 pp[2] = Left[1];
187 pp[3] = Left[0];
188 pp[4] = top_left;
189 pp[5] = Above[0];
190 pp[6] = Above[1];
191 pp[7] = Above[2];
192 pp[8] = Above[3];
195 predictor[3 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
196 predictor[2 * 16 + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
197 predictor[3 * 16 + 1] =
198 predictor[1 * 16 + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
199 predictor[2 * 16 + 1] =
200 predictor[0 * 16 + 0] = (pp[4] + pp[5] + 1) >> 1;
201 predictor[3 * 16 + 2] =
202 predictor[1 * 16 + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
203 predictor[2 * 16 + 2] =
204 predictor[0 * 16 + 1] = (pp[5] + pp[6] + 1) >> 1;
205 predictor[3 * 16 + 3] =
206 predictor[1 * 16 + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
207 predictor[2 * 16 + 3] =
208 predictor[0 * 16 + 2] = (pp[6] + pp[7] + 1) >> 1;
209 predictor[1 * 16 + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
210 predictor[0 * 16 + 3] = (pp[7] + pp[8] + 1) >> 1;
213 break;
214 case B_VL_PRED:
217 unsigned char *pp = Above;
219 predictor[0 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
220 predictor[1 * 16 + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
221 predictor[2 * 16 + 0] =
222 predictor[0 * 16 + 1] = (pp[1] + pp[2] + 1) >> 1;
223 predictor[1 * 16 + 1] =
224 predictor[3 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
225 predictor[2 * 16 + 1] =
226 predictor[0 * 16 + 2] = (pp[2] + pp[3] + 1) >> 1;
227 predictor[3 * 16 + 1] =
228 predictor[1 * 16 + 2] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
229 predictor[0 * 16 + 3] =
230 predictor[2 * 16 + 2] = (pp[3] + pp[4] + 1) >> 1;
231 predictor[1 * 16 + 3] =
232 predictor[3 * 16 + 2] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
233 predictor[2 * 16 + 3] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
234 predictor[3 * 16 + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
236 break;
238 case B_HD_PRED:
240 unsigned char pp[9];
241 pp[0] = Left[3];
242 pp[1] = Left[2];
243 pp[2] = Left[1];
244 pp[3] = Left[0];
245 pp[4] = top_left;
246 pp[5] = Above[0];
247 pp[6] = Above[1];
248 pp[7] = Above[2];
249 pp[8] = Above[3];
252 predictor[3 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
253 predictor[3 * 16 + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
254 predictor[2 * 16 + 0] =
255 predictor[3 * 16 + 2] = (pp[1] + pp[2] + 1) >> 1;
256 predictor[2 * 16 + 1] =
257 predictor[3 * 16 + 3] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
258 predictor[2 * 16 + 2] =
259 predictor[1 * 16 + 0] = (pp[2] + pp[3] + 1) >> 1;
260 predictor[2 * 16 + 3] =
261 predictor[1 * 16 + 1] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
262 predictor[1 * 16 + 2] =
263 predictor[0 * 16 + 0] = (pp[3] + pp[4] + 1) >> 1;
264 predictor[1 * 16 + 3] =
265 predictor[0 * 16 + 1] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
266 predictor[0 * 16 + 2] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
267 predictor[0 * 16 + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
269 break;
272 case B_HU_PRED:
274 unsigned char *pp = Left;
275 predictor[0 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
276 predictor[0 * 16 + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
277 predictor[0 * 16 + 2] =
278 predictor[1 * 16 + 0] = (pp[1] + pp[2] + 1) >> 1;
279 predictor[0 * 16 + 3] =
280 predictor[1 * 16 + 1] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
281 predictor[1 * 16 + 2] =
282 predictor[2 * 16 + 0] = (pp[2] + pp[3] + 1) >> 1;
283 predictor[1 * 16 + 3] =
284 predictor[2 * 16 + 1] = (pp[2] + pp[3] * 2 + pp[3] + 2) >> 2;
285 predictor[2 * 16 + 2] =
286 predictor[2 * 16 + 3] =
287 predictor[3 * 16 + 0] =
288 predictor[3 * 16 + 1] =
289 predictor[3 * 16 + 2] =
290 predictor[3 * 16 + 3] = pp[3];
292 break;
297 // copy 4 bytes from the above right down so that the 4x4 prediction modes using pixels above and
298 // to the right prediction have filled in pixels to use.
299 void vp8_intra_prediction_down_copy(MACROBLOCKD *x)
301 unsigned char *above_right = *(x->block[0].base_dst) + x->block[0].dst - x->block[0].dst_stride + 16;
303 unsigned int *src_ptr = (unsigned int *)above_right;
304 unsigned int *dst_ptr0 = (unsigned int *)(above_right + 4 * x->block[0].dst_stride);
305 unsigned int *dst_ptr1 = (unsigned int *)(above_right + 8 * x->block[0].dst_stride);
306 unsigned int *dst_ptr2 = (unsigned int *)(above_right + 12 * x->block[0].dst_stride);
308 *dst_ptr0 = *src_ptr;
309 *dst_ptr1 = *src_ptr;
310 *dst_ptr2 = *src_ptr;
316 void vp8_recon_intra4x4mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
318 int i;
320 vp8_intra_prediction_down_copy(x);
322 for(i=0;i<16;i++)
324 BLOCKD *b = &x->block[i];
326 vp8_predict_intra4x4(b, x->block[i].bmi.mode,x->block[i].predictor);
327 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
330 vp8_recon_intra_mbuv(x);
334 void vp8_recon_intra4x4mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
336 int i;
337 BLOCKD *b = &x->block[0];
339 vp8_intra_prediction_down_copy(x);
342 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
343 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
344 b += 1;
346 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
347 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
348 b += 1;
350 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
351 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
352 b += 1;
354 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
355 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
356 b += 1;
358 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
359 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
360 b += 1;
362 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
363 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
364 b += 1;
366 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
367 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
368 b += 1;
370 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
371 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
372 b += 1;
374 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
375 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
376 b += 1;
378 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
379 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
380 b += 1;
382 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
383 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
384 b += 1;
386 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
387 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
388 b += 1;
390 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
391 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
392 b += 1;
394 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
395 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
396 b += 1;
398 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
399 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
400 b += 1;
402 vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
403 RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
406 vp8_recon_intra_mbuv(rtcd, x);