dsputil: template get_pixels() for different bit depths
[ffmpeg.git] / libavcodec / h264pred_template.c
1 /*
2  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
3  * Copyright (c) 2003-2011 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * H.264 / AVC / MPEG4 part10 prediction functions.
25  * @author Michael Niedermayer <michaelni@gmx.at>
26  */
27
28 #include "mathops.h"
29
30 #include "bit_depth_template.c"
31
32 static void FUNCC(pred4x4_vertical)(uint8_t *_src, const uint8_t *topright, int _stride){
33     pixel *src = (pixel*)_src;
34     int stride = _stride/sizeof(pixel);
35     const pixel4 a= AV_RN4PA(src-stride);
36
37     AV_WN4PA(src+0*stride, a);
38     AV_WN4PA(src+1*stride, a);
39     AV_WN4PA(src+2*stride, a);
40     AV_WN4PA(src+3*stride, a);
41 }
42
43 static void FUNCC(pred4x4_horizontal)(uint8_t *_src, const uint8_t *topright, int _stride){
44     pixel *src = (pixel*)_src;
45     int stride = _stride/sizeof(pixel);
46     AV_WN4PA(src+0*stride, PIXEL_SPLAT_X4(src[-1+0*stride]));
47     AV_WN4PA(src+1*stride, PIXEL_SPLAT_X4(src[-1+1*stride]));
48     AV_WN4PA(src+2*stride, PIXEL_SPLAT_X4(src[-1+2*stride]));
49     AV_WN4PA(src+3*stride, PIXEL_SPLAT_X4(src[-1+3*stride]));
50 }
51
52 static void FUNCC(pred4x4_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
53     pixel *src = (pixel*)_src;
54     int stride = _stride/sizeof(pixel);
55     const int dc= (  src[-stride] + src[1-stride] + src[2-stride] + src[3-stride]
56                    + src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 4) >>3;
57     const pixel4 a = PIXEL_SPLAT_X4(dc);
58
59     AV_WN4PA(src+0*stride, a);
60     AV_WN4PA(src+1*stride, a);
61     AV_WN4PA(src+2*stride, a);
62     AV_WN4PA(src+3*stride, a);
63 }
64
65 static void FUNCC(pred4x4_left_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
66     pixel *src = (pixel*)_src;
67     int stride = _stride/sizeof(pixel);
68     const int dc= (  src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2;
69     const pixel4 a = PIXEL_SPLAT_X4(dc);
70
71     AV_WN4PA(src+0*stride, a);
72     AV_WN4PA(src+1*stride, a);
73     AV_WN4PA(src+2*stride, a);
74     AV_WN4PA(src+3*stride, a);
75 }
76
77 static void FUNCC(pred4x4_top_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
78     pixel *src = (pixel*)_src;
79     int stride = _stride/sizeof(pixel);
80     const int dc= (  src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + 2) >>2;
81     const pixel4 a = PIXEL_SPLAT_X4(dc);
82
83     AV_WN4PA(src+0*stride, a);
84     AV_WN4PA(src+1*stride, a);
85     AV_WN4PA(src+2*stride, a);
86     AV_WN4PA(src+3*stride, a);
87 }
88
89 static void FUNCC(pred4x4_128_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
90     pixel *src = (pixel*)_src;
91     int stride = _stride/sizeof(pixel);
92     const pixel4 a = PIXEL_SPLAT_X4(1<<(BIT_DEPTH-1));
93
94     AV_WN4PA(src+0*stride, a);
95     AV_WN4PA(src+1*stride, a);
96     AV_WN4PA(src+2*stride, a);
97     AV_WN4PA(src+3*stride, a);
98 }
99
100 static void FUNCC(pred4x4_127_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
101     pixel *src = (pixel*)_src;
102     int stride = _stride/sizeof(pixel);
103     const pixel4 a = PIXEL_SPLAT_X4((1<<(BIT_DEPTH-1))-1);
104
105     AV_WN4PA(src+0*stride, a);
106     AV_WN4PA(src+1*stride, a);
107     AV_WN4PA(src+2*stride, a);
108     AV_WN4PA(src+3*stride, a);
109 }
110
111 static void FUNCC(pred4x4_129_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
112     pixel *src = (pixel*)_src;
113     int stride = _stride/sizeof(pixel);
114     const pixel4 a = PIXEL_SPLAT_X4((1<<(BIT_DEPTH-1))+1);
115
116     AV_WN4PA(src+0*stride, a);
117     AV_WN4PA(src+1*stride, a);
118     AV_WN4PA(src+2*stride, a);
119     AV_WN4PA(src+3*stride, a);
120 }
121
122
123 #define LOAD_TOP_RIGHT_EDGE\
124     const int av_unused t4= topright[0];\
125     const int av_unused t5= topright[1];\
126     const int av_unused t6= topright[2];\
127     const int av_unused t7= topright[3];\
128
129 #define LOAD_DOWN_LEFT_EDGE\
130     const int av_unused l4= src[-1+4*stride];\
131     const int av_unused l5= src[-1+5*stride];\
132     const int av_unused l6= src[-1+6*stride];\
133     const int av_unused l7= src[-1+7*stride];\
134
135 #define LOAD_LEFT_EDGE\
136     const int av_unused l0= src[-1+0*stride];\
137     const int av_unused l1= src[-1+1*stride];\
138     const int av_unused l2= src[-1+2*stride];\
139     const int av_unused l3= src[-1+3*stride];\
140
141 #define LOAD_TOP_EDGE\
142     const int av_unused t0= src[ 0-1*stride];\
143     const int av_unused t1= src[ 1-1*stride];\
144     const int av_unused t2= src[ 2-1*stride];\
145     const int av_unused t3= src[ 3-1*stride];\
146
147 static void FUNCC(pred4x4_down_right)(uint8_t *_src, const uint8_t *topright, int _stride){
148     pixel *src = (pixel*)_src;
149     int stride = _stride/sizeof(pixel);
150     const int lt= src[-1-1*stride];
151     LOAD_TOP_EDGE
152     LOAD_LEFT_EDGE
153
154     src[0+3*stride]=(l3 + 2*l2 + l1 + 2)>>2;
155     src[0+2*stride]=
156     src[1+3*stride]=(l2 + 2*l1 + l0 + 2)>>2;
157     src[0+1*stride]=
158     src[1+2*stride]=
159     src[2+3*stride]=(l1 + 2*l0 + lt + 2)>>2;
160     src[0+0*stride]=
161     src[1+1*stride]=
162     src[2+2*stride]=
163     src[3+3*stride]=(l0 + 2*lt + t0 + 2)>>2;
164     src[1+0*stride]=
165     src[2+1*stride]=
166     src[3+2*stride]=(lt + 2*t0 + t1 + 2)>>2;
167     src[2+0*stride]=
168     src[3+1*stride]=(t0 + 2*t1 + t2 + 2)>>2;
169     src[3+0*stride]=(t1 + 2*t2 + t3 + 2)>>2;
170 }
171
172 static void FUNCC(pred4x4_down_left)(uint8_t *_src, const uint8_t *_topright, int _stride){
173     pixel *src = (pixel*)_src;
174     const pixel *topright = (const pixel*)_topright;
175     int stride = _stride/sizeof(pixel);
176     LOAD_TOP_EDGE
177     LOAD_TOP_RIGHT_EDGE
178 //    LOAD_LEFT_EDGE
179
180     src[0+0*stride]=(t0 + t2 + 2*t1 + 2)>>2;
181     src[1+0*stride]=
182     src[0+1*stride]=(t1 + t3 + 2*t2 + 2)>>2;
183     src[2+0*stride]=
184     src[1+1*stride]=
185     src[0+2*stride]=(t2 + t4 + 2*t3 + 2)>>2;
186     src[3+0*stride]=
187     src[2+1*stride]=
188     src[1+2*stride]=
189     src[0+3*stride]=(t3 + t5 + 2*t4 + 2)>>2;
190     src[3+1*stride]=
191     src[2+2*stride]=
192     src[1+3*stride]=(t4 + t6 + 2*t5 + 2)>>2;
193     src[3+2*stride]=
194     src[2+3*stride]=(t5 + t7 + 2*t6 + 2)>>2;
195     src[3+3*stride]=(t6 + 3*t7 + 2)>>2;
196 }
197
198 static void FUNCC(pred4x4_vertical_right)(uint8_t *_src, const uint8_t *topright, int _stride){
199     pixel *src = (pixel*)_src;
200     int stride = _stride/sizeof(pixel);
201     const int lt= src[-1-1*stride];
202     LOAD_TOP_EDGE
203     LOAD_LEFT_EDGE
204
205     src[0+0*stride]=
206     src[1+2*stride]=(lt + t0 + 1)>>1;
207     src[1+0*stride]=
208     src[2+2*stride]=(t0 + t1 + 1)>>1;
209     src[2+0*stride]=
210     src[3+2*stride]=(t1 + t2 + 1)>>1;
211     src[3+0*stride]=(t2 + t3 + 1)>>1;
212     src[0+1*stride]=
213     src[1+3*stride]=(l0 + 2*lt + t0 + 2)>>2;
214     src[1+1*stride]=
215     src[2+3*stride]=(lt + 2*t0 + t1 + 2)>>2;
216     src[2+1*stride]=
217     src[3+3*stride]=(t0 + 2*t1 + t2 + 2)>>2;
218     src[3+1*stride]=(t1 + 2*t2 + t3 + 2)>>2;
219     src[0+2*stride]=(lt + 2*l0 + l1 + 2)>>2;
220     src[0+3*stride]=(l0 + 2*l1 + l2 + 2)>>2;
221 }
222
223 static void FUNCC(pred4x4_vertical_left)(uint8_t *_src, const uint8_t *_topright, int _stride){
224     pixel *src = (pixel*)_src;
225     const pixel *topright = (const pixel*)_topright;
226     int stride = _stride/sizeof(pixel);
227     LOAD_TOP_EDGE
228     LOAD_TOP_RIGHT_EDGE
229
230     src[0+0*stride]=(t0 + t1 + 1)>>1;
231     src[1+0*stride]=
232     src[0+2*stride]=(t1 + t2 + 1)>>1;
233     src[2+0*stride]=
234     src[1+2*stride]=(t2 + t3 + 1)>>1;
235     src[3+0*stride]=
236     src[2+2*stride]=(t3 + t4+ 1)>>1;
237     src[3+2*stride]=(t4 + t5+ 1)>>1;
238     src[0+1*stride]=(t0 + 2*t1 + t2 + 2)>>2;
239     src[1+1*stride]=
240     src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2;
241     src[2+1*stride]=
242     src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2;
243     src[3+1*stride]=
244     src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2;
245     src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2;
246 }
247
248 static void FUNCC(pred4x4_horizontal_up)(uint8_t *_src, const uint8_t *topright, int _stride){
249     pixel *src = (pixel*)_src;
250     int stride = _stride/sizeof(pixel);
251     LOAD_LEFT_EDGE
252
253     src[0+0*stride]=(l0 + l1 + 1)>>1;
254     src[1+0*stride]=(l0 + 2*l1 + l2 + 2)>>2;
255     src[2+0*stride]=
256     src[0+1*stride]=(l1 + l2 + 1)>>1;
257     src[3+0*stride]=
258     src[1+1*stride]=(l1 + 2*l2 + l3 + 2)>>2;
259     src[2+1*stride]=
260     src[0+2*stride]=(l2 + l3 + 1)>>1;
261     src[3+1*stride]=
262     src[1+2*stride]=(l2 + 2*l3 + l3 + 2)>>2;
263     src[3+2*stride]=
264     src[1+3*stride]=
265     src[0+3*stride]=
266     src[2+2*stride]=
267     src[2+3*stride]=
268     src[3+3*stride]=l3;
269 }
270
271 static void FUNCC(pred4x4_horizontal_down)(uint8_t *_src, const uint8_t *topright, int _stride){
272     pixel *src = (pixel*)_src;
273     int stride = _stride/sizeof(pixel);
274     const int lt= src[-1-1*stride];
275     LOAD_TOP_EDGE
276     LOAD_LEFT_EDGE
277
278     src[0+0*stride]=
279     src[2+1*stride]=(lt + l0 + 1)>>1;
280     src[1+0*stride]=
281     src[3+1*stride]=(l0 + 2*lt + t0 + 2)>>2;
282     src[2+0*stride]=(lt + 2*t0 + t1 + 2)>>2;
283     src[3+0*stride]=(t0 + 2*t1 + t2 + 2)>>2;
284     src[0+1*stride]=
285     src[2+2*stride]=(l0 + l1 + 1)>>1;
286     src[1+1*stride]=
287     src[3+2*stride]=(lt + 2*l0 + l1 + 2)>>2;
288     src[0+2*stride]=
289     src[2+3*stride]=(l1 + l2+ 1)>>1;
290     src[1+2*stride]=
291     src[3+3*stride]=(l0 + 2*l1 + l2 + 2)>>2;
292     src[0+3*stride]=(l2 + l3 + 1)>>1;
293     src[1+3*stride]=(l1 + 2*l2 + l3 + 2)>>2;
294 }
295
296 static void FUNCC(pred16x16_vertical)(uint8_t *_src, int _stride){
297     int i;
298     pixel *src = (pixel*)_src;
299     int stride = _stride/sizeof(pixel);
300     const pixel4 a = AV_RN4PA(((pixel4*)(src-stride))+0);
301     const pixel4 b = AV_RN4PA(((pixel4*)(src-stride))+1);
302     const pixel4 c = AV_RN4PA(((pixel4*)(src-stride))+2);
303     const pixel4 d = AV_RN4PA(((pixel4*)(src-stride))+3);
304
305     for(i=0; i<16; i++){
306         AV_WN4PA(((pixel4*)(src+i*stride))+0, a);
307         AV_WN4PA(((pixel4*)(src+i*stride))+1, b);
308         AV_WN4PA(((pixel4*)(src+i*stride))+2, c);
309         AV_WN4PA(((pixel4*)(src+i*stride))+3, d);
310     }
311 }
312
313 static void FUNCC(pred16x16_horizontal)(uint8_t *_src, int stride){
314     int i;
315     pixel *src = (pixel*)_src;
316     stride /= sizeof(pixel);
317
318     for(i=0; i<16; i++){
319         const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]);
320
321         AV_WN4PA(((pixel4*)(src+i*stride))+0, a);
322         AV_WN4PA(((pixel4*)(src+i*stride))+1, a);
323         AV_WN4PA(((pixel4*)(src+i*stride))+2, a);
324         AV_WN4PA(((pixel4*)(src+i*stride))+3, a);
325     }
326 }
327
328 #define PREDICT_16x16_DC(v)\
329     for(i=0; i<16; i++){\
330         AV_WN4PA(src+ 0, v);\
331         AV_WN4PA(src+ 4, v);\
332         AV_WN4PA(src+ 8, v);\
333         AV_WN4PA(src+12, v);\
334         src += stride;\
335     }
336
337 static void FUNCC(pred16x16_dc)(uint8_t *_src, int stride){
338     int i, dc=0;
339     pixel *src = (pixel*)_src;
340     pixel4 dcsplat;
341     stride /= sizeof(pixel);
342
343     for(i=0;i<16; i++){
344         dc+= src[-1+i*stride];
345     }
346
347     for(i=0;i<16; i++){
348         dc+= src[i-stride];
349     }
350
351     dcsplat = PIXEL_SPLAT_X4((dc+16)>>5);
352     PREDICT_16x16_DC(dcsplat);
353 }
354
355 static void FUNCC(pred16x16_left_dc)(uint8_t *_src, int stride){
356     int i, dc=0;
357     pixel *src = (pixel*)_src;
358     pixel4 dcsplat;
359     stride /= sizeof(pixel);
360
361     for(i=0;i<16; i++){
362         dc+= src[-1+i*stride];
363     }
364
365     dcsplat = PIXEL_SPLAT_X4((dc+8)>>4);
366     PREDICT_16x16_DC(dcsplat);
367 }
368
369 static void FUNCC(pred16x16_top_dc)(uint8_t *_src, int stride){
370     int i, dc=0;
371     pixel *src = (pixel*)_src;
372     pixel4 dcsplat;
373     stride /= sizeof(pixel);
374
375     for(i=0;i<16; i++){
376         dc+= src[i-stride];
377     }
378
379     dcsplat = PIXEL_SPLAT_X4((dc+8)>>4);
380     PREDICT_16x16_DC(dcsplat);
381 }
382
383 #define PRED16x16_X(n, v) \
384 static void FUNCC(pred16x16_##n##_dc)(uint8_t *_src, int stride){\
385     int i;\
386     pixel *src = (pixel*)_src;\
387     stride /= sizeof(pixel);\
388     PREDICT_16x16_DC(PIXEL_SPLAT_X4(v));\
389 }
390
391 PRED16x16_X(127, (1<<(BIT_DEPTH-1))-1);
392 PRED16x16_X(128, (1<<(BIT_DEPTH-1))+0);
393 PRED16x16_X(129, (1<<(BIT_DEPTH-1))+1);
394
395 static inline void FUNCC(pred16x16_plane_compat)(uint8_t *_src, int _stride, const int svq3, const int rv40){
396   int i, j, k;
397   int a;
398   INIT_CLIP
399   pixel *src = (pixel*)_src;
400   int stride = _stride/sizeof(pixel);
401   const pixel * const src0 = src +7-stride;
402   const pixel *       src1 = src +8*stride-1;
403   const pixel *       src2 = src1-2*stride;    // == src+6*stride-1;
404   int H = src0[1] - src0[-1];
405   int V = src1[0] - src2[ 0];
406   for(k=2; k<=8; ++k) {
407     src1 += stride; src2 -= stride;
408     H += k*(src0[k] - src0[-k]);
409     V += k*(src1[0] - src2[ 0]);
410   }
411   if(svq3){
412     H = ( 5*(H/4) ) / 16;
413     V = ( 5*(V/4) ) / 16;
414
415     /* required for 100% accuracy */
416     i = H; H = V; V = i;
417   }else if(rv40){
418     H = ( H + (H>>2) ) >> 4;
419     V = ( V + (V>>2) ) >> 4;
420   }else{
421     H = ( 5*H+32 ) >> 6;
422     V = ( 5*V+32 ) >> 6;
423   }
424
425   a = 16*(src1[0] + src2[16] + 1) - 7*(V+H);
426   for(j=16; j>0; --j) {
427     int b = a;
428     a += V;
429     for(i=-16; i<0; i+=4) {
430       src[16+i] = CLIP((b    ) >> 5);
431       src[17+i] = CLIP((b+  H) >> 5);
432       src[18+i] = CLIP((b+2*H) >> 5);
433       src[19+i] = CLIP((b+3*H) >> 5);
434       b += 4*H;
435     }
436     src += stride;
437   }
438 }
439
440 static void FUNCC(pred16x16_plane)(uint8_t *src, int stride){
441     FUNCC(pred16x16_plane_compat)(src, stride, 0, 0);
442 }
443
444 static void FUNCC(pred8x8_vertical)(uint8_t *_src, int _stride){
445     int i;
446     pixel *src = (pixel*)_src;
447     int stride = _stride/sizeof(pixel);
448     const pixel4 a= AV_RN4PA(((pixel4*)(src-stride))+0);
449     const pixel4 b= AV_RN4PA(((pixel4*)(src-stride))+1);
450
451     for(i=0; i<8; i++){
452         AV_WN4PA(((pixel4*)(src+i*stride))+0, a);
453         AV_WN4PA(((pixel4*)(src+i*stride))+1, b);
454     }
455 }
456
457 static void FUNCC(pred8x8_horizontal)(uint8_t *_src, int stride){
458     int i;
459     pixel *src = (pixel*)_src;
460     stride /= sizeof(pixel);
461
462     for(i=0; i<8; i++){
463         const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]);
464         AV_WN4PA(((pixel4*)(src+i*stride))+0, a);
465         AV_WN4PA(((pixel4*)(src+i*stride))+1, a);
466     }
467 }
468
469 #define PRED8x8_X(n, v)\
470 static void FUNCC(pred8x8_##n##_dc)(uint8_t *_src, int stride){\
471     int i;\
472     const pixel4 a = PIXEL_SPLAT_X4(v);\
473     pixel *src = (pixel*)_src;\
474     stride /= sizeof(pixel);\
475     for(i=0; i<8; i++){\
476         AV_WN4PA(((pixel4*)(src+i*stride))+0, a);\
477         AV_WN4PA(((pixel4*)(src+i*stride))+1, a);\
478     }\
479 }
480
481 PRED8x8_X(127, (1<<(BIT_DEPTH-1))-1);
482 PRED8x8_X(128, (1<<(BIT_DEPTH-1))+0);
483 PRED8x8_X(129, (1<<(BIT_DEPTH-1))+1);
484
485 static void FUNCC(pred8x8_left_dc)(uint8_t *_src, int stride){
486     int i;
487     int dc0, dc2;
488     pixel4 dc0splat, dc2splat;
489     pixel *src = (pixel*)_src;
490     stride /= sizeof(pixel);
491
492     dc0=dc2=0;
493     for(i=0;i<4; i++){
494         dc0+= src[-1+i*stride];
495         dc2+= src[-1+(i+4)*stride];
496     }
497     dc0splat = PIXEL_SPLAT_X4((dc0 + 2)>>2);
498     dc2splat = PIXEL_SPLAT_X4((dc2 + 2)>>2);
499
500     for(i=0; i<4; i++){
501         AV_WN4PA(((pixel4*)(src+i*stride))+0, dc0splat);
502         AV_WN4PA(((pixel4*)(src+i*stride))+1, dc0splat);
503     }
504     for(i=4; i<8; i++){
505         AV_WN4PA(((pixel4*)(src+i*stride))+0, dc2splat);
506         AV_WN4PA(((pixel4*)(src+i*stride))+1, dc2splat);
507     }
508 }
509
510 static void FUNCC(pred8x8_top_dc)(uint8_t *_src, int stride){
511     int i;
512     int dc0, dc1;
513     pixel4 dc0splat, dc1splat;
514     pixel *src = (pixel*)_src;
515     stride /= sizeof(pixel);
516
517     dc0=dc1=0;
518     for(i=0;i<4; i++){
519         dc0+= src[i-stride];
520         dc1+= src[4+i-stride];
521     }
522     dc0splat = PIXEL_SPLAT_X4((dc0 + 2)>>2);
523     dc1splat = PIXEL_SPLAT_X4((dc1 + 2)>>2);
524
525     for(i=0; i<4; i++){
526         AV_WN4PA(((pixel4*)(src+i*stride))+0, dc0splat);
527         AV_WN4PA(((pixel4*)(src+i*stride))+1, dc1splat);
528     }
529     for(i=4; i<8; i++){
530         AV_WN4PA(((pixel4*)(src+i*stride))+0, dc0splat);
531         AV_WN4PA(((pixel4*)(src+i*stride))+1, dc1splat);
532     }
533 }
534
535 static void FUNCC(pred8x8_dc)(uint8_t *_src, int stride){
536     int i;
537     int dc0, dc1, dc2;
538     pixel4 dc0splat, dc1splat, dc2splat, dc3splat;
539     pixel *src = (pixel*)_src;
540     stride /= sizeof(pixel);
541
542     dc0=dc1=dc2=0;
543     for(i=0;i<4; i++){
544         dc0+= src[-1+i*stride] + src[i-stride];
545         dc1+= src[4+i-stride];
546         dc2+= src[-1+(i+4)*stride];
547     }
548     dc0splat = PIXEL_SPLAT_X4((dc0 + 4)>>3);
549     dc1splat = PIXEL_SPLAT_X4((dc1 + 2)>>2);
550     dc2splat = PIXEL_SPLAT_X4((dc2 + 2)>>2);
551     dc3splat = PIXEL_SPLAT_X4((dc1 + dc2 + 4)>>3);
552
553     for(i=0; i<4; i++){
554         AV_WN4PA(((pixel4*)(src+i*stride))+0, dc0splat);
555         AV_WN4PA(((pixel4*)(src+i*stride))+1, dc1splat);
556     }
557     for(i=4; i<8; i++){
558         AV_WN4PA(((pixel4*)(src+i*stride))+0, dc2splat);
559         AV_WN4PA(((pixel4*)(src+i*stride))+1, dc3splat);
560     }
561 }
562
563 //the following 4 function should not be optimized!
564 static void FUNC(pred8x8_mad_cow_dc_l0t)(uint8_t *src, int stride){
565     FUNCC(pred8x8_top_dc)(src, stride);
566     FUNCC(pred4x4_dc)(src, NULL, stride);
567 }
568
569 static void FUNC(pred8x8_mad_cow_dc_0lt)(uint8_t *src, int stride){
570     FUNCC(pred8x8_dc)(src, stride);
571     FUNCC(pred4x4_top_dc)(src, NULL, stride);
572 }
573
574 static void FUNC(pred8x8_mad_cow_dc_l00)(uint8_t *src, int stride){
575     FUNCC(pred8x8_left_dc)(src, stride);
576     FUNCC(pred4x4_128_dc)(src + 4*stride                  , NULL, stride);
577     FUNCC(pred4x4_128_dc)(src + 4*stride + 4*sizeof(pixel), NULL, stride);
578 }
579
580 static void FUNC(pred8x8_mad_cow_dc_0l0)(uint8_t *src, int stride){
581     FUNCC(pred8x8_left_dc)(src, stride);
582     FUNCC(pred4x4_128_dc)(src                  , NULL, stride);
583     FUNCC(pred4x4_128_dc)(src + 4*sizeof(pixel), NULL, stride);
584 }
585
586 static void FUNCC(pred8x8_plane)(uint8_t *_src, int _stride){
587   int j, k;
588   int a;
589   INIT_CLIP
590   pixel *src = (pixel*)_src;
591   int stride = _stride/sizeof(pixel);
592   const pixel * const src0 = src +3-stride;
593   const pixel *       src1 = src +4*stride-1;
594   const pixel *       src2 = src1-2*stride;    // == src+2*stride-1;
595   int H = src0[1] - src0[-1];
596   int V = src1[0] - src2[ 0];
597   for(k=2; k<=4; ++k) {
598     src1 += stride; src2 -= stride;
599     H += k*(src0[k] - src0[-k]);
600     V += k*(src1[0] - src2[ 0]);
601   }
602   H = ( 17*H+16 ) >> 5;
603   V = ( 17*V+16 ) >> 5;
604
605   a = 16*(src1[0] + src2[8]+1) - 3*(V+H);
606   for(j=8; j>0; --j) {
607     int b = a;
608     a += V;
609     src[0] = CLIP((b    ) >> 5);
610     src[1] = CLIP((b+  H) >> 5);
611     src[2] = CLIP((b+2*H) >> 5);
612     src[3] = CLIP((b+3*H) >> 5);
613     src[4] = CLIP((b+4*H) >> 5);
614     src[5] = CLIP((b+5*H) >> 5);
615     src[6] = CLIP((b+6*H) >> 5);
616     src[7] = CLIP((b+7*H) >> 5);
617     src += stride;
618   }
619 }
620
621 #define SRC(x,y) src[(x)+(y)*stride]
622 #define PL(y) \
623     const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2;
624 #define PREDICT_8x8_LOAD_LEFT \
625     const int l0 = ((has_topleft ? SRC(-1,-1) : SRC(-1,0)) \
626                      + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \
627     PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \
628     const int l7 av_unused = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2
629
630 #define PT(x) \
631     const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
632 #define PREDICT_8x8_LOAD_TOP \
633     const int t0 = ((has_topleft ? SRC(-1,-1) : SRC(0,-1)) \
634                      + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \
635     PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \
636     const int t7 av_unused = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \
637                      + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2
638
639 #define PTR(x) \
640     t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
641 #define PREDICT_8x8_LOAD_TOPRIGHT \
642     int t8, t9, t10, t11, t12, t13, t14, t15; \
643     if(has_topright) { \
644         PTR(8) PTR(9) PTR(10) PTR(11) PTR(12) PTR(13) PTR(14) \
645         t15 = (SRC(14,-1) + 3*SRC(15,-1) + 2) >> 2; \
646     } else t8=t9=t10=t11=t12=t13=t14=t15= SRC(7,-1);
647
648 #define PREDICT_8x8_LOAD_TOPLEFT \
649     const int lt = (SRC(-1,0) + 2*SRC(-1,-1) + SRC(0,-1) + 2) >> 2
650
651 #define PREDICT_8x8_DC(v) \
652     int y; \
653     for( y = 0; y < 8; y++ ) { \
654         AV_WN4PA(((pixel4*)src)+0, v); \
655         AV_WN4PA(((pixel4*)src)+1, v); \
656         src += stride; \
657     }
658
659 static void FUNCC(pred8x8l_128_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
660 {
661     pixel *src = (pixel*)_src;
662     int stride = _stride/sizeof(pixel);
663
664     PREDICT_8x8_DC(PIXEL_SPLAT_X4(1<<(BIT_DEPTH-1)));
665 }
666 static void FUNCC(pred8x8l_left_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
667 {
668     pixel *src = (pixel*)_src;
669     int stride = _stride/sizeof(pixel);
670
671     PREDICT_8x8_LOAD_LEFT;
672     const pixel4 dc = PIXEL_SPLAT_X4((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3);
673     PREDICT_8x8_DC(dc);
674 }
675 static void FUNCC(pred8x8l_top_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
676 {
677     pixel *src = (pixel*)_src;
678     int stride = _stride/sizeof(pixel);
679
680     PREDICT_8x8_LOAD_TOP;
681     const pixel4 dc = PIXEL_SPLAT_X4((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3);
682     PREDICT_8x8_DC(dc);
683 }
684 static void FUNCC(pred8x8l_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
685 {
686     pixel *src = (pixel*)_src;
687     int stride = _stride/sizeof(pixel);
688
689     PREDICT_8x8_LOAD_LEFT;
690     PREDICT_8x8_LOAD_TOP;
691     const pixel4 dc = PIXEL_SPLAT_X4((l0+l1+l2+l3+l4+l5+l6+l7
692                                      +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4);
693     PREDICT_8x8_DC(dc);
694 }
695 static void FUNCC(pred8x8l_horizontal)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
696 {
697     pixel *src = (pixel*)_src;
698     int stride = _stride/sizeof(pixel);
699     pixel4 a;
700
701     PREDICT_8x8_LOAD_LEFT;
702 #define ROW(y) a = PIXEL_SPLAT_X4(l##y); \
703                AV_WN4PA(src+y*stride, a); \
704                AV_WN4PA(src+y*stride+4, a);
705     ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7);
706 #undef ROW
707 }
708 static void FUNCC(pred8x8l_vertical)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
709 {
710     int y;
711     pixel *src = (pixel*)_src;
712     int stride = _stride/sizeof(pixel);
713     pixel4 a, b;
714
715     PREDICT_8x8_LOAD_TOP;
716     src[0] = t0;
717     src[1] = t1;
718     src[2] = t2;
719     src[3] = t3;
720     src[4] = t4;
721     src[5] = t5;
722     src[6] = t6;
723     src[7] = t7;
724     a = AV_RN4PA(((pixel4*)src)+0);
725     b = AV_RN4PA(((pixel4*)src)+1);
726     for( y = 1; y < 8; y++ ) {
727         AV_WN4PA(((pixel4*)(src+y*stride))+0, a);
728         AV_WN4PA(((pixel4*)(src+y*stride))+1, b);
729     }
730 }
731 static void FUNCC(pred8x8l_down_left)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
732 {
733     pixel *src = (pixel*)_src;
734     int stride = _stride/sizeof(pixel);
735     PREDICT_8x8_LOAD_TOP;
736     PREDICT_8x8_LOAD_TOPRIGHT;
737     SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2;
738     SRC(0,1)=SRC(1,0)= (t1 + 2*t2 + t3 + 2) >> 2;
739     SRC(0,2)=SRC(1,1)=SRC(2,0)= (t2 + 2*t3 + t4 + 2) >> 2;
740     SRC(0,3)=SRC(1,2)=SRC(2,1)=SRC(3,0)= (t3 + 2*t4 + t5 + 2) >> 2;
741     SRC(0,4)=SRC(1,3)=SRC(2,2)=SRC(3,1)=SRC(4,0)= (t4 + 2*t5 + t6 + 2) >> 2;
742     SRC(0,5)=SRC(1,4)=SRC(2,3)=SRC(3,2)=SRC(4,1)=SRC(5,0)= (t5 + 2*t6 + t7 + 2) >> 2;
743     SRC(0,6)=SRC(1,5)=SRC(2,4)=SRC(3,3)=SRC(4,2)=SRC(5,1)=SRC(6,0)= (t6 + 2*t7 + t8 + 2) >> 2;
744     SRC(0,7)=SRC(1,6)=SRC(2,5)=SRC(3,4)=SRC(4,3)=SRC(5,2)=SRC(6,1)=SRC(7,0)= (t7 + 2*t8 + t9 + 2) >> 2;
745     SRC(1,7)=SRC(2,6)=SRC(3,5)=SRC(4,4)=SRC(5,3)=SRC(6,2)=SRC(7,1)= (t8 + 2*t9 + t10 + 2) >> 2;
746     SRC(2,7)=SRC(3,6)=SRC(4,5)=SRC(5,4)=SRC(6,3)=SRC(7,2)= (t9 + 2*t10 + t11 + 2) >> 2;
747     SRC(3,7)=SRC(4,6)=SRC(5,5)=SRC(6,4)=SRC(7,3)= (t10 + 2*t11 + t12 + 2) >> 2;
748     SRC(4,7)=SRC(5,6)=SRC(6,5)=SRC(7,4)= (t11 + 2*t12 + t13 + 2) >> 2;
749     SRC(5,7)=SRC(6,6)=SRC(7,5)= (t12 + 2*t13 + t14 + 2) >> 2;
750     SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2;
751     SRC(7,7)= (t14 + 3*t15 + 2) >> 2;
752 }
753 static void FUNCC(pred8x8l_down_right)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
754 {
755     pixel *src = (pixel*)_src;
756     int stride = _stride/sizeof(pixel);
757     PREDICT_8x8_LOAD_TOP;
758     PREDICT_8x8_LOAD_LEFT;
759     PREDICT_8x8_LOAD_TOPLEFT;
760     SRC(0,7)= (l7 + 2*l6 + l5 + 2) >> 2;
761     SRC(0,6)=SRC(1,7)= (l6 + 2*l5 + l4 + 2) >> 2;
762     SRC(0,5)=SRC(1,6)=SRC(2,7)= (l5 + 2*l4 + l3 + 2) >> 2;
763     SRC(0,4)=SRC(1,5)=SRC(2,6)=SRC(3,7)= (l4 + 2*l3 + l2 + 2) >> 2;
764     SRC(0,3)=SRC(1,4)=SRC(2,5)=SRC(3,6)=SRC(4,7)= (l3 + 2*l2 + l1 + 2) >> 2;
765     SRC(0,2)=SRC(1,3)=SRC(2,4)=SRC(3,5)=SRC(4,6)=SRC(5,7)= (l2 + 2*l1 + l0 + 2) >> 2;
766     SRC(0,1)=SRC(1,2)=SRC(2,3)=SRC(3,4)=SRC(4,5)=SRC(5,6)=SRC(6,7)= (l1 + 2*l0 + lt + 2) >> 2;
767     SRC(0,0)=SRC(1,1)=SRC(2,2)=SRC(3,3)=SRC(4,4)=SRC(5,5)=SRC(6,6)=SRC(7,7)= (l0 + 2*lt + t0 + 2) >> 2;
768     SRC(1,0)=SRC(2,1)=SRC(3,2)=SRC(4,3)=SRC(5,4)=SRC(6,5)=SRC(7,6)= (lt + 2*t0 + t1 + 2) >> 2;
769     SRC(2,0)=SRC(3,1)=SRC(4,2)=SRC(5,3)=SRC(6,4)=SRC(7,5)= (t0 + 2*t1 + t2 + 2) >> 2;
770     SRC(3,0)=SRC(4,1)=SRC(5,2)=SRC(6,3)=SRC(7,4)= (t1 + 2*t2 + t3 + 2) >> 2;
771     SRC(4,0)=SRC(5,1)=SRC(6,2)=SRC(7,3)= (t2 + 2*t3 + t4 + 2) >> 2;
772     SRC(5,0)=SRC(6,1)=SRC(7,2)= (t3 + 2*t4 + t5 + 2) >> 2;
773     SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2;
774     SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2;
775 }
776 static void FUNCC(pred8x8l_vertical_right)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
777 {
778     pixel *src = (pixel*)_src;
779     int stride = _stride/sizeof(pixel);
780     PREDICT_8x8_LOAD_TOP;
781     PREDICT_8x8_LOAD_LEFT;
782     PREDICT_8x8_LOAD_TOPLEFT;
783     SRC(0,6)= (l5 + 2*l4 + l3 + 2) >> 2;
784     SRC(0,7)= (l6 + 2*l5 + l4 + 2) >> 2;
785     SRC(0,4)=SRC(1,6)= (l3 + 2*l2 + l1 + 2) >> 2;
786     SRC(0,5)=SRC(1,7)= (l4 + 2*l3 + l2 + 2) >> 2;
787     SRC(0,2)=SRC(1,4)=SRC(2,6)= (l1 + 2*l0 + lt + 2) >> 2;
788     SRC(0,3)=SRC(1,5)=SRC(2,7)= (l2 + 2*l1 + l0 + 2) >> 2;
789     SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (l0 + 2*lt + t0 + 2) >> 2;
790     SRC(0,0)=SRC(1,2)=SRC(2,4)=SRC(3,6)= (lt + t0 + 1) >> 1;
791     SRC(1,1)=SRC(2,3)=SRC(3,5)=SRC(4,7)= (lt + 2*t0 + t1 + 2) >> 2;
792     SRC(1,0)=SRC(2,2)=SRC(3,4)=SRC(4,6)= (t0 + t1 + 1) >> 1;
793     SRC(2,1)=SRC(3,3)=SRC(4,5)=SRC(5,7)= (t0 + 2*t1 + t2 + 2) >> 2;
794     SRC(2,0)=SRC(3,2)=SRC(4,4)=SRC(5,6)= (t1 + t2 + 1) >> 1;
795     SRC(3,1)=SRC(4,3)=SRC(5,5)=SRC(6,7)= (t1 + 2*t2 + t3 + 2) >> 2;
796     SRC(3,0)=SRC(4,2)=SRC(5,4)=SRC(6,6)= (t2 + t3 + 1) >> 1;
797     SRC(4,1)=SRC(5,3)=SRC(6,5)=SRC(7,7)= (t2 + 2*t3 + t4 + 2) >> 2;
798     SRC(4,0)=SRC(5,2)=SRC(6,4)=SRC(7,6)= (t3 + t4 + 1) >> 1;
799     SRC(5,1)=SRC(6,3)=SRC(7,5)= (t3 + 2*t4 + t5 + 2) >> 2;
800     SRC(5,0)=SRC(6,2)=SRC(7,4)= (t4 + t5 + 1) >> 1;
801     SRC(6,1)=SRC(7,3)= (t4 + 2*t5 + t6 + 2) >> 2;
802     SRC(6,0)=SRC(7,2)= (t5 + t6 + 1) >> 1;
803     SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2;
804     SRC(7,0)= (t6 + t7 + 1) >> 1;
805 }
806 static void FUNCC(pred8x8l_horizontal_down)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
807 {
808     pixel *src = (pixel*)_src;
809     int stride = _stride/sizeof(pixel);
810     PREDICT_8x8_LOAD_TOP;
811     PREDICT_8x8_LOAD_LEFT;
812     PREDICT_8x8_LOAD_TOPLEFT;
813     SRC(0,7)= (l6 + l7 + 1) >> 1;
814     SRC(1,7)= (l5 + 2*l6 + l7 + 2) >> 2;
815     SRC(0,6)=SRC(2,7)= (l5 + l6 + 1) >> 1;
816     SRC(1,6)=SRC(3,7)= (l4 + 2*l5 + l6 + 2) >> 2;
817     SRC(0,5)=SRC(2,6)=SRC(4,7)= (l4 + l5 + 1) >> 1;
818     SRC(1,5)=SRC(3,6)=SRC(5,7)= (l3 + 2*l4 + l5 + 2) >> 2;
819     SRC(0,4)=SRC(2,5)=SRC(4,6)=SRC(6,7)= (l3 + l4 + 1) >> 1;
820     SRC(1,4)=SRC(3,5)=SRC(5,6)=SRC(7,7)= (l2 + 2*l3 + l4 + 2) >> 2;
821     SRC(0,3)=SRC(2,4)=SRC(4,5)=SRC(6,6)= (l2 + l3 + 1) >> 1;
822     SRC(1,3)=SRC(3,4)=SRC(5,5)=SRC(7,6)= (l1 + 2*l2 + l3 + 2) >> 2;
823     SRC(0,2)=SRC(2,3)=SRC(4,4)=SRC(6,5)= (l1 + l2 + 1) >> 1;
824     SRC(1,2)=SRC(3,3)=SRC(5,4)=SRC(7,5)= (l0 + 2*l1 + l2 + 2) >> 2;
825     SRC(0,1)=SRC(2,2)=SRC(4,3)=SRC(6,4)= (l0 + l1 + 1) >> 1;
826     SRC(1,1)=SRC(3,2)=SRC(5,3)=SRC(7,4)= (lt + 2*l0 + l1 + 2) >> 2;
827     SRC(0,0)=SRC(2,1)=SRC(4,2)=SRC(6,3)= (lt + l0 + 1) >> 1;
828     SRC(1,0)=SRC(3,1)=SRC(5,2)=SRC(7,3)= (l0 + 2*lt + t0 + 2) >> 2;
829     SRC(2,0)=SRC(4,1)=SRC(6,2)= (t1 + 2*t0 + lt + 2) >> 2;
830     SRC(3,0)=SRC(5,1)=SRC(7,2)= (t2 + 2*t1 + t0 + 2) >> 2;
831     SRC(4,0)=SRC(6,1)= (t3 + 2*t2 + t1 + 2) >> 2;
832     SRC(5,0)=SRC(7,1)= (t4 + 2*t3 + t2 + 2) >> 2;
833     SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2;
834     SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2;
835 }
836 static void FUNCC(pred8x8l_vertical_left)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
837 {
838     pixel *src = (pixel*)_src;
839     int stride = _stride/sizeof(pixel);
840     PREDICT_8x8_LOAD_TOP;
841     PREDICT_8x8_LOAD_TOPRIGHT;
842     SRC(0,0)= (t0 + t1 + 1) >> 1;
843     SRC(0,1)= (t0 + 2*t1 + t2 + 2) >> 2;
844     SRC(0,2)=SRC(1,0)= (t1 + t2 + 1) >> 1;
845     SRC(0,3)=SRC(1,1)= (t1 + 2*t2 + t3 + 2) >> 2;
846     SRC(0,4)=SRC(1,2)=SRC(2,0)= (t2 + t3 + 1) >> 1;
847     SRC(0,5)=SRC(1,3)=SRC(2,1)= (t2 + 2*t3 + t4 + 2) >> 2;
848     SRC(0,6)=SRC(1,4)=SRC(2,2)=SRC(3,0)= (t3 + t4 + 1) >> 1;
849     SRC(0,7)=SRC(1,5)=SRC(2,3)=SRC(3,1)= (t3 + 2*t4 + t5 + 2) >> 2;
850     SRC(1,6)=SRC(2,4)=SRC(3,2)=SRC(4,0)= (t4 + t5 + 1) >> 1;
851     SRC(1,7)=SRC(2,5)=SRC(3,3)=SRC(4,1)= (t4 + 2*t5 + t6 + 2) >> 2;
852     SRC(2,6)=SRC(3,4)=SRC(4,2)=SRC(5,0)= (t5 + t6 + 1) >> 1;
853     SRC(2,7)=SRC(3,5)=SRC(4,3)=SRC(5,1)= (t5 + 2*t6 + t7 + 2) >> 2;
854     SRC(3,6)=SRC(4,4)=SRC(5,2)=SRC(6,0)= (t6 + t7 + 1) >> 1;
855     SRC(3,7)=SRC(4,5)=SRC(5,3)=SRC(6,1)= (t6 + 2*t7 + t8 + 2) >> 2;
856     SRC(4,6)=SRC(5,4)=SRC(6,2)=SRC(7,0)= (t7 + t8 + 1) >> 1;
857     SRC(4,7)=SRC(5,5)=SRC(6,3)=SRC(7,1)= (t7 + 2*t8 + t9 + 2) >> 2;
858     SRC(5,6)=SRC(6,4)=SRC(7,2)= (t8 + t9 + 1) >> 1;
859     SRC(5,7)=SRC(6,5)=SRC(7,3)= (t8 + 2*t9 + t10 + 2) >> 2;
860     SRC(6,6)=SRC(7,4)= (t9 + t10 + 1) >> 1;
861     SRC(6,7)=SRC(7,5)= (t9 + 2*t10 + t11 + 2) >> 2;
862     SRC(7,6)= (t10 + t11 + 1) >> 1;
863     SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2;
864 }
865 static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
866 {
867     pixel *src = (pixel*)_src;
868     int stride = _stride/sizeof(pixel);
869     PREDICT_8x8_LOAD_LEFT;
870     SRC(0,0)= (l0 + l1 + 1) >> 1;
871     SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2;
872     SRC(0,1)=SRC(2,0)= (l1 + l2 + 1) >> 1;
873     SRC(1,1)=SRC(3,0)= (l1 + 2*l2 + l3 + 2) >> 2;
874     SRC(0,2)=SRC(2,1)=SRC(4,0)= (l2 + l3 + 1) >> 1;
875     SRC(1,2)=SRC(3,1)=SRC(5,0)= (l2 + 2*l3 + l4 + 2) >> 2;
876     SRC(0,3)=SRC(2,2)=SRC(4,1)=SRC(6,0)= (l3 + l4 + 1) >> 1;
877     SRC(1,3)=SRC(3,2)=SRC(5,1)=SRC(7,0)= (l3 + 2*l4 + l5 + 2) >> 2;
878     SRC(0,4)=SRC(2,3)=SRC(4,2)=SRC(6,1)= (l4 + l5 + 1) >> 1;
879     SRC(1,4)=SRC(3,3)=SRC(5,2)=SRC(7,1)= (l4 + 2*l5 + l6 + 2) >> 2;
880     SRC(0,5)=SRC(2,4)=SRC(4,3)=SRC(6,2)= (l5 + l6 + 1) >> 1;
881     SRC(1,5)=SRC(3,4)=SRC(5,3)=SRC(7,2)= (l5 + 2*l6 + l7 + 2) >> 2;
882     SRC(0,6)=SRC(2,5)=SRC(4,4)=SRC(6,3)= (l6 + l7 + 1) >> 1;
883     SRC(1,6)=SRC(3,5)=SRC(5,4)=SRC(7,3)= (l6 + 3*l7 + 2) >> 2;
884     SRC(0,7)=SRC(1,7)=SRC(2,6)=SRC(2,7)=SRC(3,6)=
885     SRC(3,7)=SRC(4,5)=SRC(4,6)=SRC(4,7)=SRC(5,5)=
886     SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)=
887     SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7;
888 }
889 #undef PREDICT_8x8_LOAD_LEFT
890 #undef PREDICT_8x8_LOAD_TOP
891 #undef PREDICT_8x8_LOAD_TOPLEFT
892 #undef PREDICT_8x8_LOAD_TOPRIGHT
893 #undef PREDICT_8x8_DC
894 #undef PTR
895 #undef PT
896 #undef PL
897 #undef SRC
898
899 static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
900     int i;
901     pixel *pix = (pixel*)_pix;
902     const dctcoef *block = (const dctcoef*)_block;
903     stride /= sizeof(pixel);
904     pix -= stride;
905     for(i=0; i<4; i++){
906         pixel v = pix[0];
907         pix[1*stride]= v += block[0];
908         pix[2*stride]= v += block[4];
909         pix[3*stride]= v += block[8];
910         pix[4*stride]= v +  block[12];
911         pix++;
912         block++;
913     }
914 }
915
916 static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
917     int i;
918     pixel *pix = (pixel*)_pix;
919     const dctcoef *block = (const dctcoef*)_block;
920     stride /= sizeof(pixel);
921     for(i=0; i<4; i++){
922         pixel v = pix[-1];
923         pix[0]= v += block[0];
924         pix[1]= v += block[1];
925         pix[2]= v += block[2];
926         pix[3]= v +  block[3];
927         pix+= stride;
928         block+= 4;
929     }
930 }
931
932 static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
933     int i;
934     pixel *pix = (pixel*)_pix;
935     const dctcoef *block = (const dctcoef*)_block;
936     stride /= sizeof(pixel);
937     pix -= stride;
938     for(i=0; i<8; i++){
939         pixel v = pix[0];
940         pix[1*stride]= v += block[0];
941         pix[2*stride]= v += block[8];
942         pix[3*stride]= v += block[16];
943         pix[4*stride]= v += block[24];
944         pix[5*stride]= v += block[32];
945         pix[6*stride]= v += block[40];
946         pix[7*stride]= v += block[48];
947         pix[8*stride]= v +  block[56];
948         pix++;
949         block++;
950     }
951 }
952
953 static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
954     int i;
955     pixel *pix = (pixel*)_pix;
956     const dctcoef *block = (const dctcoef*)_block;
957     stride /= sizeof(pixel);
958     for(i=0; i<8; i++){
959         pixel v = pix[-1];
960         pix[0]= v += block[0];
961         pix[1]= v += block[1];
962         pix[2]= v += block[2];
963         pix[3]= v += block[3];
964         pix[4]= v += block[4];
965         pix[5]= v += block[5];
966         pix[6]= v += block[6];
967         pix[7]= v +  block[7];
968         pix+= stride;
969         block+= 8;
970     }
971 }
972
973 static void FUNCC(pred16x16_vertical_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
974     int i;
975     for(i=0; i<16; i++)
976         FUNCC(pred4x4_vertical_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
977 }
978
979 static void FUNCC(pred16x16_horizontal_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
980     int i;
981     for(i=0; i<16; i++)
982         FUNCC(pred4x4_horizontal_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
983 }
984
985 static void FUNCC(pred8x8_vertical_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
986     int i;
987     for(i=0; i<4; i++)
988         FUNCC(pred4x4_vertical_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
989 }
990
991 static void FUNCC(pred8x8_horizontal_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
992     int i;
993     for(i=0; i<4; i++)
994         FUNCC(pred4x4_horizontal_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
995 }