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 "vpx_config.h"
13#include "vp8_rtcd.h"
14#include "blockd.h"
15
16void vp8_intra4x4_predict_c(unsigned char *Above,
17                            unsigned char *yleft, int left_stride,
18                            int           _b_mode,
19                            unsigned char *dst, int dst_stride,
20                            unsigned char top_left)
21{
22    int i, r, c;
23    B_PREDICTION_MODE b_mode = (B_PREDICTION_MODE)_b_mode;
24    unsigned char Left[4];
25    Left[0] = yleft[0];
26    Left[1] = yleft[left_stride];
27    Left[2] = yleft[2 * left_stride];
28    Left[3] = yleft[3 * left_stride];
29
30    switch (b_mode)
31    {
32    case B_DC_PRED:
33    {
34        int expected_dc = 0;
35
36        for (i = 0; i < 4; i++)
37        {
38            expected_dc += Above[i];
39            expected_dc += Left[i];
40        }
41
42        expected_dc = (expected_dc + 4) >> 3;
43
44        for (r = 0; r < 4; r++)
45        {
46            for (c = 0; c < 4; c++)
47            {
48                dst[c] = expected_dc;
49            }
50
51            dst += dst_stride;
52        }
53    }
54    break;
55    case B_TM_PRED:
56    {
57        /* prediction similar to true_motion prediction */
58        for (r = 0; r < 4; r++)
59        {
60            for (c = 0; c < 4; c++)
61            {
62                int pred = Above[c] - top_left + Left[r];
63
64                if (pred < 0)
65                    pred = 0;
66
67                if (pred > 255)
68                    pred = 255;
69
70                dst[c] = pred;
71            }
72
73            dst += dst_stride;
74        }
75    }
76    break;
77
78    case B_VE_PRED:
79    {
80
81        unsigned int ap[4];
82        ap[0] = (top_left  + 2 * Above[0] + Above[1] + 2) >> 2;
83        ap[1] = (Above[0] + 2 * Above[1] + Above[2] + 2) >> 2;
84        ap[2] = (Above[1] + 2 * Above[2] + Above[3] + 2) >> 2;
85        ap[3] = (Above[2] + 2 * Above[3] + Above[4] + 2) >> 2;
86
87        for (r = 0; r < 4; r++)
88        {
89            for (c = 0; c < 4; c++)
90            {
91
92                dst[c] = ap[c];
93            }
94
95            dst += dst_stride;
96        }
97
98    }
99    break;
100
101
102    case B_HE_PRED:
103    {
104
105        unsigned int lp[4];
106        lp[0] = (top_left + 2 * Left[0] + Left[1] + 2) >> 2;
107        lp[1] = (Left[0] + 2 * Left[1] + Left[2] + 2) >> 2;
108        lp[2] = (Left[1] + 2 * Left[2] + Left[3] + 2) >> 2;
109        lp[3] = (Left[2] + 2 * Left[3] + Left[3] + 2) >> 2;
110
111        for (r = 0; r < 4; r++)
112        {
113            for (c = 0; c < 4; c++)
114            {
115                dst[c] = lp[r];
116            }
117
118            dst += dst_stride;
119        }
120    }
121    break;
122    case B_LD_PRED:
123    {
124        unsigned char *ptr = Above;
125        dst[0 * dst_stride + 0] = (ptr[0] + ptr[1] * 2 + ptr[2] + 2) >> 2;
126        dst[0 * dst_stride + 1] =
127            dst[1 * dst_stride + 0] = (ptr[1] + ptr[2] * 2 + ptr[3] + 2) >> 2;
128        dst[0 * dst_stride + 2] =
129            dst[1 * dst_stride + 1] =
130                dst[2 * dst_stride + 0] = (ptr[2] + ptr[3] * 2 + ptr[4] + 2) >> 2;
131        dst[0 * dst_stride + 3] =
132            dst[1 * dst_stride + 2] =
133                dst[2 * dst_stride + 1] =
134                    dst[3 * dst_stride + 0] = (ptr[3] + ptr[4] * 2 + ptr[5] + 2) >> 2;
135        dst[1 * dst_stride + 3] =
136            dst[2 * dst_stride + 2] =
137                dst[3 * dst_stride + 1] = (ptr[4] + ptr[5] * 2 + ptr[6] + 2) >> 2;
138        dst[2 * dst_stride + 3] =
139            dst[3 * dst_stride + 2] = (ptr[5] + ptr[6] * 2 + ptr[7] + 2) >> 2;
140        dst[3 * dst_stride + 3] = (ptr[6] + ptr[7] * 2 + ptr[7] + 2) >> 2;
141
142    }
143    break;
144    case B_RD_PRED:
145    {
146
147        unsigned char pp[9];
148
149        pp[0] = Left[3];
150        pp[1] = Left[2];
151        pp[2] = Left[1];
152        pp[3] = Left[0];
153        pp[4] = top_left;
154        pp[5] = Above[0];
155        pp[6] = Above[1];
156        pp[7] = Above[2];
157        pp[8] = Above[3];
158
159        dst[3 * dst_stride + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
160        dst[3 * dst_stride + 1] =
161            dst[2 * dst_stride + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
162        dst[3 * dst_stride + 2] =
163            dst[2 * dst_stride + 1] =
164                dst[1 * dst_stride + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
165        dst[3 * dst_stride + 3] =
166            dst[2 * dst_stride + 2] =
167                dst[1 * dst_stride + 1] =
168                    dst[0 * dst_stride + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
169        dst[2 * dst_stride + 3] =
170            dst[1 * dst_stride + 2] =
171                dst[0 * dst_stride + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
172        dst[1 * dst_stride + 3] =
173            dst[0 * dst_stride + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
174        dst[0 * dst_stride + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
175
176    }
177    break;
178    case B_VR_PRED:
179    {
180
181        unsigned char pp[9];
182
183        pp[0] = Left[3];
184        pp[1] = Left[2];
185        pp[2] = Left[1];
186        pp[3] = Left[0];
187        pp[4] = top_left;
188        pp[5] = Above[0];
189        pp[6] = Above[1];
190        pp[7] = Above[2];
191        pp[8] = Above[3];
192
193
194        dst[3 * dst_stride + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
195        dst[2 * dst_stride + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
196        dst[3 * dst_stride + 1] =
197            dst[1 * dst_stride + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
198        dst[2 * dst_stride + 1] =
199            dst[0 * dst_stride + 0] = (pp[4] + pp[5] + 1) >> 1;
200        dst[3 * dst_stride + 2] =
201            dst[1 * dst_stride + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
202        dst[2 * dst_stride + 2] =
203            dst[0 * dst_stride + 1] = (pp[5] + pp[6] + 1) >> 1;
204        dst[3 * dst_stride + 3] =
205            dst[1 * dst_stride + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
206        dst[2 * dst_stride + 3] =
207            dst[0 * dst_stride + 2] = (pp[6] + pp[7] + 1) >> 1;
208        dst[1 * dst_stride + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
209        dst[0 * dst_stride + 3] = (pp[7] + pp[8] + 1) >> 1;
210
211    }
212    break;
213    case B_VL_PRED:
214    {
215
216        unsigned char *pp = Above;
217
218        dst[0 * dst_stride + 0] = (pp[0] + pp[1] + 1) >> 1;
219        dst[1 * dst_stride + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
220        dst[2 * dst_stride + 0] =
221            dst[0 * dst_stride + 1] = (pp[1] + pp[2] + 1) >> 1;
222        dst[1 * dst_stride + 1] =
223            dst[3 * dst_stride + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
224        dst[2 * dst_stride + 1] =
225            dst[0 * dst_stride + 2] = (pp[2] + pp[3] + 1) >> 1;
226        dst[3 * dst_stride + 1] =
227            dst[1 * dst_stride + 2] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
228        dst[0 * dst_stride + 3] =
229            dst[2 * dst_stride + 2] = (pp[3] + pp[4] + 1) >> 1;
230        dst[1 * dst_stride + 3] =
231            dst[3 * dst_stride + 2] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
232        dst[2 * dst_stride + 3] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
233        dst[3 * dst_stride + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
234    }
235    break;
236
237    case B_HD_PRED:
238    {
239        unsigned char pp[9];
240        pp[0] = Left[3];
241        pp[1] = Left[2];
242        pp[2] = Left[1];
243        pp[3] = Left[0];
244        pp[4] = top_left;
245        pp[5] = Above[0];
246        pp[6] = Above[1];
247        pp[7] = Above[2];
248        pp[8] = Above[3];
249
250
251        dst[3 * dst_stride + 0] = (pp[0] + pp[1] + 1) >> 1;
252        dst[3 * dst_stride + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
253        dst[2 * dst_stride + 0] =
254            dst[3 * dst_stride + 2] = (pp[1] + pp[2] + 1) >> 1;
255        dst[2 * dst_stride + 1] =
256            dst[3 * dst_stride + 3] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
257        dst[2 * dst_stride + 2] =
258            dst[1 * dst_stride + 0] = (pp[2] + pp[3] + 1) >> 1;
259        dst[2 * dst_stride + 3] =
260            dst[1 * dst_stride + 1] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
261        dst[1 * dst_stride + 2] =
262            dst[0 * dst_stride + 0] = (pp[3] + pp[4] + 1) >> 1;
263        dst[1 * dst_stride + 3] =
264            dst[0 * dst_stride + 1] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
265        dst[0 * dst_stride + 2] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
266        dst[0 * dst_stride + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
267    }
268    break;
269
270
271    case B_HU_PRED:
272    {
273        unsigned char *pp = Left;
274        dst[0 * dst_stride + 0] = (pp[0] + pp[1] + 1) >> 1;
275        dst[0 * dst_stride + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
276        dst[0 * dst_stride + 2] =
277            dst[1 * dst_stride + 0] = (pp[1] + pp[2] + 1) >> 1;
278        dst[0 * dst_stride + 3] =
279            dst[1 * dst_stride + 1] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
280        dst[1 * dst_stride + 2] =
281            dst[2 * dst_stride + 0] = (pp[2] + pp[3] + 1) >> 1;
282        dst[1 * dst_stride + 3] =
283            dst[2 * dst_stride + 1] = (pp[2] + pp[3] * 2 + pp[3] + 2) >> 2;
284        dst[2 * dst_stride + 2] =
285            dst[2 * dst_stride + 3] =
286                dst[3 * dst_stride + 0] =
287                    dst[3 * dst_stride + 1] =
288                        dst[3 * dst_stride + 2] =
289                            dst[3 * dst_stride + 3] = pp[3];
290    }
291    break;
292
293    default:
294    break;
295
296    }
297}
298