More 4:2:2 asm functions
[x262.git] / common / dct.c
1 /*****************************************************************************
2  * dct.c: transform and zigzag
3  *****************************************************************************
4  * Copyright (C) 2003-2011 x264 project
5  *
6  * Authors: Loren Merritt <lorenm@u.washington.edu>
7  *          Laurent Aimar <fenrir@via.ecp.fr>
8  *          Henrik Gramner <hengar-6@student.ltu.se>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23  *
24  * This program is also available under a commercial proprietary license.
25  * For more information, contact us at licensing@x264.com.
26  *****************************************************************************/
27
28 #include "common.h"
29 #if HAVE_MMX
30 #   include "x86/dct.h"
31 #endif
32 #if ARCH_PPC
33 #   include "ppc/dct.h"
34 #endif
35 #if ARCH_ARM
36 #   include "arm/dct.h"
37 #endif
38
39 uint16_t x264_dct4_weight2_zigzag[2][16];
40 uint16_t x264_dct8_weight2_zigzag[2][64];
41
42 static void dct4x4dc( dctcoef d[16] )
43 {
44     dctcoef tmp[16];
45
46     for( int i = 0; i < 4; i++ )
47     {
48         int s01 = d[i*4+0] + d[i*4+1];
49         int d01 = d[i*4+0] - d[i*4+1];
50         int s23 = d[i*4+2] + d[i*4+3];
51         int d23 = d[i*4+2] - d[i*4+3];
52
53         tmp[0*4+i] = s01 + s23;
54         tmp[1*4+i] = s01 - s23;
55         tmp[2*4+i] = d01 - d23;
56         tmp[3*4+i] = d01 + d23;
57     }
58
59     for( int i = 0; i < 4; i++ )
60     {
61         int s01 = tmp[i*4+0] + tmp[i*4+1];
62         int d01 = tmp[i*4+0] - tmp[i*4+1];
63         int s23 = tmp[i*4+2] + tmp[i*4+3];
64         int d23 = tmp[i*4+2] - tmp[i*4+3];
65
66         d[i*4+0] = ( s01 + s23 + 1 ) >> 1;
67         d[i*4+1] = ( s01 - s23 + 1 ) >> 1;
68         d[i*4+2] = ( d01 - d23 + 1 ) >> 1;
69         d[i*4+3] = ( d01 + d23 + 1 ) >> 1;
70     }
71 }
72
73 static void idct4x4dc( dctcoef d[16] )
74 {
75     dctcoef tmp[16];
76
77     for( int i = 0; i < 4; i++ )
78     {
79         int s01 = d[i*4+0] + d[i*4+1];
80         int d01 = d[i*4+0] - d[i*4+1];
81         int s23 = d[i*4+2] + d[i*4+3];
82         int d23 = d[i*4+2] - d[i*4+3];
83
84         tmp[0*4+i] = s01 + s23;
85         tmp[1*4+i] = s01 - s23;
86         tmp[2*4+i] = d01 - d23;
87         tmp[3*4+i] = d01 + d23;
88     }
89
90     for( int i = 0; i < 4; i++ )
91     {
92         int s01 = tmp[i*4+0] + tmp[i*4+1];
93         int d01 = tmp[i*4+0] - tmp[i*4+1];
94         int s23 = tmp[i*4+2] + tmp[i*4+3];
95         int d23 = tmp[i*4+2] - tmp[i*4+3];
96
97         d[i*4+0] = s01 + s23;
98         d[i*4+1] = s01 - s23;
99         d[i*4+2] = d01 - d23;
100         d[i*4+3] = d01 + d23;
101     }
102 }
103
104 static void dct2x4dc( dctcoef dct[8], dctcoef dct4x4[8][16] )
105 {
106     int a0 = dct4x4[0][0] + dct4x4[1][0];
107     int a1 = dct4x4[2][0] + dct4x4[3][0];
108     int a2 = dct4x4[4][0] + dct4x4[5][0];
109     int a3 = dct4x4[6][0] + dct4x4[7][0];
110     int a4 = dct4x4[0][0] - dct4x4[1][0];
111     int a5 = dct4x4[2][0] - dct4x4[3][0];
112     int a6 = dct4x4[4][0] - dct4x4[5][0];
113     int a7 = dct4x4[6][0] - dct4x4[7][0];
114     int b0 = a0 + a1;
115     int b1 = a2 + a3;
116     int b2 = a4 + a5;
117     int b3 = a6 + a7;
118     int b4 = a0 - a1;
119     int b5 = a2 - a3;
120     int b6 = a4 - a5;
121     int b7 = a6 - a7;
122     dct[0] = b0 + b1;
123     dct[1] = b2 + b3;
124     dct[2] = b0 - b1;
125     dct[3] = b2 - b3;
126     dct[4] = b4 - b5;
127     dct[5] = b6 - b7;
128     dct[6] = b4 + b5;
129     dct[7] = b6 + b7;
130     dct4x4[0][0] = 0;
131     dct4x4[1][0] = 0;
132     dct4x4[2][0] = 0;
133     dct4x4[3][0] = 0;
134     dct4x4[4][0] = 0;
135     dct4x4[5][0] = 0;
136     dct4x4[6][0] = 0;
137     dct4x4[7][0] = 0;
138 }
139
140 static inline void pixel_sub_wxh( dctcoef *diff, int i_size,
141                                   pixel *pix1, int i_pix1, pixel *pix2, int i_pix2 )
142 {
143     for( int y = 0; y < i_size; y++ )
144     {
145         for( int x = 0; x < i_size; x++ )
146             diff[x + y*i_size] = pix1[x] - pix2[x];
147         pix1 += i_pix1;
148         pix2 += i_pix2;
149     }
150 }
151
152 static void sub4x4_dct( dctcoef dct[16], pixel *pix1, pixel *pix2 )
153 {
154     dctcoef d[16];
155     dctcoef tmp[16];
156
157     pixel_sub_wxh( d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
158
159     for( int i = 0; i < 4; i++ )
160     {
161         int s03 = d[i*4+0] + d[i*4+3];
162         int s12 = d[i*4+1] + d[i*4+2];
163         int d03 = d[i*4+0] - d[i*4+3];
164         int d12 = d[i*4+1] - d[i*4+2];
165
166         tmp[0*4+i] =   s03 +   s12;
167         tmp[1*4+i] = 2*d03 +   d12;
168         tmp[2*4+i] =   s03 -   s12;
169         tmp[3*4+i] =   d03 - 2*d12;
170     }
171
172     for( int i = 0; i < 4; i++ )
173     {
174         int s03 = tmp[i*4+0] + tmp[i*4+3];
175         int s12 = tmp[i*4+1] + tmp[i*4+2];
176         int d03 = tmp[i*4+0] - tmp[i*4+3];
177         int d12 = tmp[i*4+1] - tmp[i*4+2];
178
179         dct[i*4+0] =   s03 +   s12;
180         dct[i*4+1] = 2*d03 +   d12;
181         dct[i*4+2] =   s03 -   s12;
182         dct[i*4+3] =   d03 - 2*d12;
183     }
184 }
185
186 static void sub8x8_dct( dctcoef dct[4][16], pixel *pix1, pixel *pix2 )
187 {
188     sub4x4_dct( dct[0], &pix1[0], &pix2[0] );
189     sub4x4_dct( dct[1], &pix1[4], &pix2[4] );
190     sub4x4_dct( dct[2], &pix1[4*FENC_STRIDE+0], &pix2[4*FDEC_STRIDE+0] );
191     sub4x4_dct( dct[3], &pix1[4*FENC_STRIDE+4], &pix2[4*FDEC_STRIDE+4] );
192 }
193
194 static void sub16x16_dct( dctcoef dct[16][16], pixel *pix1, pixel *pix2 )
195 {
196     sub8x8_dct( &dct[ 0], &pix1[0], &pix2[0] );
197     sub8x8_dct( &dct[ 4], &pix1[8], &pix2[8] );
198     sub8x8_dct( &dct[ 8], &pix1[8*FENC_STRIDE+0], &pix2[8*FDEC_STRIDE+0] );
199     sub8x8_dct( &dct[12], &pix1[8*FENC_STRIDE+8], &pix2[8*FDEC_STRIDE+8] );
200 }
201
202 static int sub4x4_dct_dc( pixel *pix1, pixel *pix2 )
203 {
204     int sum = 0;
205     for( int i=0; i<4; i++, pix1 += FENC_STRIDE, pix2 += FDEC_STRIDE )
206         sum += pix1[0] + pix1[1] + pix1[2] + pix1[3]
207              - pix2[0] - pix2[1] - pix2[2] - pix2[3];
208     return sum;
209 }
210
211 static void sub8x8_dct_dc( dctcoef dct[4], pixel *pix1, pixel *pix2 )
212 {
213     dct[0] = sub4x4_dct_dc( &pix1[0], &pix2[0] );
214     dct[1] = sub4x4_dct_dc( &pix1[4], &pix2[4] );
215     dct[2] = sub4x4_dct_dc( &pix1[4*FENC_STRIDE+0], &pix2[4*FDEC_STRIDE+0] );
216     dct[3] = sub4x4_dct_dc( &pix1[4*FENC_STRIDE+4], &pix2[4*FDEC_STRIDE+4] );
217
218     /* 2x2 DC transform */
219     int d0 = dct[0] + dct[1];
220     int d1 = dct[2] + dct[3];
221     int d2 = dct[0] - dct[1];
222     int d3 = dct[2] - dct[3];
223     dct[0] = d0 + d1;
224     dct[1] = d0 - d1;
225     dct[2] = d2 + d3;
226     dct[3] = d2 - d3;
227 }
228
229 static void sub8x16_dct_dc( dctcoef dct[8], pixel *pix1, pixel *pix2 )
230 {
231     int a0 = sub4x4_dct_dc( &pix1[ 0*FENC_STRIDE+0], &pix2[ 0*FDEC_STRIDE+0] );
232     int a1 = sub4x4_dct_dc( &pix1[ 0*FENC_STRIDE+4], &pix2[ 0*FDEC_STRIDE+4] );
233     int a2 = sub4x4_dct_dc( &pix1[ 4*FENC_STRIDE+0], &pix2[ 4*FDEC_STRIDE+0] );
234     int a3 = sub4x4_dct_dc( &pix1[ 4*FENC_STRIDE+4], &pix2[ 4*FDEC_STRIDE+4] );
235     int a4 = sub4x4_dct_dc( &pix1[ 8*FENC_STRIDE+0], &pix2[ 8*FDEC_STRIDE+0] );
236     int a5 = sub4x4_dct_dc( &pix1[ 8*FENC_STRIDE+4], &pix2[ 8*FDEC_STRIDE+4] );
237     int a6 = sub4x4_dct_dc( &pix1[12*FENC_STRIDE+0], &pix2[12*FDEC_STRIDE+0] );
238     int a7 = sub4x4_dct_dc( &pix1[12*FENC_STRIDE+4], &pix2[12*FDEC_STRIDE+4] );
239
240     /* 2x4 DC transform */
241     int b0 = a0 + a1;
242     int b1 = a2 + a3;
243     int b2 = a4 + a5;
244     int b3 = a6 + a7;
245     int b4 = a0 - a1;
246     int b5 = a2 - a3;
247     int b6 = a4 - a5;
248     int b7 = a6 - a7;
249     a0 = b0 + b1;
250     a1 = b2 + b3;
251     a2 = b4 + b5;
252     a3 = b6 + b7;
253     a4 = b0 - b1;
254     a5 = b2 - b3;
255     a6 = b4 - b5;
256     a7 = b6 - b7;
257     dct[0] = a0 + a1;
258     dct[1] = a2 + a3;
259     dct[2] = a0 - a1;
260     dct[3] = a2 - a3;
261     dct[4] = a4 - a5;
262     dct[5] = a6 - a7;
263     dct[6] = a4 + a5;
264     dct[7] = a6 + a7;
265 }
266
267 static void add4x4_idct( pixel *p_dst, dctcoef dct[16] )
268 {
269     dctcoef d[16];
270     dctcoef tmp[16];
271
272     for( int i = 0; i < 4; i++ )
273     {
274         int s02 =  dct[0*4+i]     +  dct[2*4+i];
275         int d02 =  dct[0*4+i]     -  dct[2*4+i];
276         int s13 =  dct[1*4+i]     + (dct[3*4+i]>>1);
277         int d13 = (dct[1*4+i]>>1) -  dct[3*4+i];
278
279         tmp[i*4+0] = s02 + s13;
280         tmp[i*4+1] = d02 + d13;
281         tmp[i*4+2] = d02 - d13;
282         tmp[i*4+3] = s02 - s13;
283     }
284
285     for( int i = 0; i < 4; i++ )
286     {
287         int s02 =  tmp[0*4+i]     +  tmp[2*4+i];
288         int d02 =  tmp[0*4+i]     -  tmp[2*4+i];
289         int s13 =  tmp[1*4+i]     + (tmp[3*4+i]>>1);
290         int d13 = (tmp[1*4+i]>>1) -  tmp[3*4+i];
291
292         d[0*4+i] = ( s02 + s13 + 32 ) >> 6;
293         d[1*4+i] = ( d02 + d13 + 32 ) >> 6;
294         d[2*4+i] = ( d02 - d13 + 32 ) >> 6;
295         d[3*4+i] = ( s02 - s13 + 32 ) >> 6;
296     }
297
298
299     for( int y = 0; y < 4; y++ )
300     {
301         for( int x = 0; x < 4; x++ )
302             p_dst[x] = x264_clip_pixel( p_dst[x] + d[y*4+x] );
303         p_dst += FDEC_STRIDE;
304     }
305 }
306
307 static void add8x8_idct( pixel *p_dst, dctcoef dct[4][16] )
308 {
309     add4x4_idct( &p_dst[0],               dct[0] );
310     add4x4_idct( &p_dst[4],               dct[1] );
311     add4x4_idct( &p_dst[4*FDEC_STRIDE+0], dct[2] );
312     add4x4_idct( &p_dst[4*FDEC_STRIDE+4], dct[3] );
313 }
314
315 static void add16x16_idct( pixel *p_dst, dctcoef dct[16][16] )
316 {
317     add8x8_idct( &p_dst[0],               &dct[0] );
318     add8x8_idct( &p_dst[8],               &dct[4] );
319     add8x8_idct( &p_dst[8*FDEC_STRIDE+0], &dct[8] );
320     add8x8_idct( &p_dst[8*FDEC_STRIDE+8], &dct[12] );
321 }
322
323 /****************************************************************************
324  * 8x8 transform:
325  ****************************************************************************/
326
327 #define DCT8_1D {\
328     int s07 = SRC(0) + SRC(7);\
329     int s16 = SRC(1) + SRC(6);\
330     int s25 = SRC(2) + SRC(5);\
331     int s34 = SRC(3) + SRC(4);\
332     int a0 = s07 + s34;\
333     int a1 = s16 + s25;\
334     int a2 = s07 - s34;\
335     int a3 = s16 - s25;\
336     int d07 = SRC(0) - SRC(7);\
337     int d16 = SRC(1) - SRC(6);\
338     int d25 = SRC(2) - SRC(5);\
339     int d34 = SRC(3) - SRC(4);\
340     int a4 = d16 + d25 + (d07 + (d07>>1));\
341     int a5 = d07 - d34 - (d25 + (d25>>1));\
342     int a6 = d07 + d34 - (d16 + (d16>>1));\
343     int a7 = d16 - d25 + (d34 + (d34>>1));\
344     DST(0) =  a0 + a1     ;\
345     DST(1) =  a4 + (a7>>2);\
346     DST(2) =  a2 + (a3>>1);\
347     DST(3) =  a5 + (a6>>2);\
348     DST(4) =  a0 - a1     ;\
349     DST(5) =  a6 - (a5>>2);\
350     DST(6) = (a2>>1) - a3 ;\
351     DST(7) = (a4>>2) - a7 ;\
352 }
353
354 static void sub8x8_dct8( dctcoef dct[64], pixel *pix1, pixel *pix2 )
355 {
356     dctcoef tmp[64];
357
358     pixel_sub_wxh( tmp, 8, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
359
360 #define SRC(x) tmp[x*8+i]
361 #define DST(x) tmp[x*8+i]
362     for( int i = 0; i < 8; i++ )
363         DCT8_1D
364 #undef SRC
365 #undef DST
366
367 #define SRC(x) tmp[i*8+x]
368 #define DST(x) dct[x*8+i]
369     for( int i = 0; i < 8; i++ )
370         DCT8_1D
371 #undef SRC
372 #undef DST
373 }
374
375 static void sub16x16_dct8( dctcoef dct[4][64], pixel *pix1, pixel *pix2 )
376 {
377     sub8x8_dct8( dct[0], &pix1[0],               &pix2[0] );
378     sub8x8_dct8( dct[1], &pix1[8],               &pix2[8] );
379     sub8x8_dct8( dct[2], &pix1[8*FENC_STRIDE+0], &pix2[8*FDEC_STRIDE+0] );
380     sub8x8_dct8( dct[3], &pix1[8*FENC_STRIDE+8], &pix2[8*FDEC_STRIDE+8] );
381 }
382
383 #define IDCT8_1D {\
384     int a0 =  SRC(0) + SRC(4);\
385     int a2 =  SRC(0) - SRC(4);\
386     int a4 = (SRC(2)>>1) - SRC(6);\
387     int a6 = (SRC(6)>>1) + SRC(2);\
388     int b0 = a0 + a6;\
389     int b2 = a2 + a4;\
390     int b4 = a2 - a4;\
391     int b6 = a0 - a6;\
392     int a1 = -SRC(3) + SRC(5) - SRC(7) - (SRC(7)>>1);\
393     int a3 =  SRC(1) + SRC(7) - SRC(3) - (SRC(3)>>1);\
394     int a5 = -SRC(1) + SRC(7) + SRC(5) + (SRC(5)>>1);\
395     int a7 =  SRC(3) + SRC(5) + SRC(1) + (SRC(1)>>1);\
396     int b1 = (a7>>2) + a1;\
397     int b3 =  a3 + (a5>>2);\
398     int b5 = (a3>>2) - a5;\
399     int b7 =  a7 - (a1>>2);\
400     DST(0, b0 + b7);\
401     DST(1, b2 + b5);\
402     DST(2, b4 + b3);\
403     DST(3, b6 + b1);\
404     DST(4, b6 - b1);\
405     DST(5, b4 - b3);\
406     DST(6, b2 - b5);\
407     DST(7, b0 - b7);\
408 }
409
410 static void add8x8_idct8( pixel *dst, dctcoef dct[64] )
411 {
412     dct[0] += 32; // rounding for the >>6 at the end
413
414 #define SRC(x)     dct[x*8+i]
415 #define DST(x,rhs) dct[x*8+i] = (rhs)
416     for( int i = 0; i < 8; i++ )
417         IDCT8_1D
418 #undef SRC
419 #undef DST
420
421 #define SRC(x)     dct[i*8+x]
422 #define DST(x,rhs) dst[i + x*FDEC_STRIDE] = x264_clip_pixel( dst[i + x*FDEC_STRIDE] + ((rhs) >> 6) );
423     for( int i = 0; i < 8; i++ )
424         IDCT8_1D
425 #undef SRC
426 #undef DST
427 }
428
429 static void add16x16_idct8( pixel *dst, dctcoef dct[4][64] )
430 {
431     add8x8_idct8( &dst[0],               dct[0] );
432     add8x8_idct8( &dst[8],               dct[1] );
433     add8x8_idct8( &dst[8*FDEC_STRIDE+0], dct[2] );
434     add8x8_idct8( &dst[8*FDEC_STRIDE+8], dct[3] );
435 }
436
437 static void inline add4x4_idct_dc( pixel *p_dst, dctcoef dc )
438 {
439     dc = (dc + 32) >> 6;
440     for( int i = 0; i < 4; i++, p_dst += FDEC_STRIDE )
441     {
442         p_dst[0] = x264_clip_pixel( p_dst[0] + dc );
443         p_dst[1] = x264_clip_pixel( p_dst[1] + dc );
444         p_dst[2] = x264_clip_pixel( p_dst[2] + dc );
445         p_dst[3] = x264_clip_pixel( p_dst[3] + dc );
446     }
447 }
448
449 static void add8x8_idct_dc( pixel *p_dst, dctcoef dct[4] )
450 {
451     add4x4_idct_dc( &p_dst[0],               dct[0] );
452     add4x4_idct_dc( &p_dst[4],               dct[1] );
453     add4x4_idct_dc( &p_dst[4*FDEC_STRIDE+0], dct[2] );
454     add4x4_idct_dc( &p_dst[4*FDEC_STRIDE+4], dct[3] );
455 }
456
457 static void add16x16_idct_dc( pixel *p_dst, dctcoef dct[16] )
458 {
459     for( int i = 0; i < 4; i++, dct += 4, p_dst += 4*FDEC_STRIDE )
460     {
461         add4x4_idct_dc( &p_dst[ 0], dct[0] );
462         add4x4_idct_dc( &p_dst[ 4], dct[1] );
463         add4x4_idct_dc( &p_dst[ 8], dct[2] );
464         add4x4_idct_dc( &p_dst[12], dct[3] );
465     }
466 }
467
468
469 /****************************************************************************
470  * x264_dct_init:
471  ****************************************************************************/
472 void x264_dct_init( int cpu, x264_dct_function_t *dctf )
473 {
474     dctf->sub4x4_dct    = sub4x4_dct;
475     dctf->add4x4_idct   = add4x4_idct;
476
477     dctf->sub8x8_dct    = sub8x8_dct;
478     dctf->sub8x8_dct_dc = sub8x8_dct_dc;
479     dctf->add8x8_idct   = add8x8_idct;
480     dctf->add8x8_idct_dc = add8x8_idct_dc;
481
482     dctf->sub8x16_dct_dc = sub8x16_dct_dc;
483
484     dctf->sub16x16_dct  = sub16x16_dct;
485     dctf->add16x16_idct = add16x16_idct;
486     dctf->add16x16_idct_dc = add16x16_idct_dc;
487
488     dctf->sub8x8_dct8   = sub8x8_dct8;
489     dctf->add8x8_idct8  = add8x8_idct8;
490
491     dctf->sub16x16_dct8  = sub16x16_dct8;
492     dctf->add16x16_idct8 = add16x16_idct8;
493
494     dctf->dct4x4dc  = dct4x4dc;
495     dctf->idct4x4dc = idct4x4dc;
496
497     dctf->dct2x4dc = dct2x4dc;
498
499 #if HIGH_BIT_DEPTH
500 #if HAVE_MMX
501     if( cpu&X264_CPU_MMX )
502     {
503         dctf->sub4x4_dct    = x264_sub4x4_dct_mmx;
504         dctf->sub8x8_dct    = x264_sub8x8_dct_mmx;
505         dctf->sub16x16_dct  = x264_sub16x16_dct_mmx;
506     }
507     if( cpu&X264_CPU_SSE2 )
508     {
509         dctf->add4x4_idct     = x264_add4x4_idct_sse2;
510         dctf->dct4x4dc        = x264_dct4x4dc_sse2;
511         dctf->idct4x4dc       = x264_idct4x4dc_sse2;
512         dctf->add8x8_idct     = x264_add8x8_idct_sse2;
513         dctf->add16x16_idct   = x264_add16x16_idct_sse2;
514         dctf->sub8x8_dct_dc   = x264_sub8x8_dct_dc_sse2;
515         dctf->add8x8_idct_dc  = x264_add8x8_idct_dc_sse2;
516         dctf->sub8x16_dct_dc  = x264_sub8x16_dct_dc_sse2;
517         dctf->add16x16_idct_dc= x264_add16x16_idct_dc_sse2;
518     }
519     if( cpu&X264_CPU_AVX )
520     {
521         dctf->add4x4_idct     = x264_add4x4_idct_avx;
522         dctf->dct4x4dc        = x264_dct4x4dc_avx;
523         dctf->idct4x4dc       = x264_idct4x4dc_avx;
524         dctf->add8x8_idct     = x264_add8x8_idct_avx;
525         dctf->add16x16_idct   = x264_add16x16_idct_avx;
526         dctf->add8x8_idct_dc  = x264_add8x8_idct_dc_avx;
527         dctf->sub8x16_dct_dc  = x264_sub8x16_dct_dc_avx;
528         dctf->add16x16_idct_dc= x264_add16x16_idct_dc_avx;
529     }
530 #endif // HAVE_MMX
531 #else // !HIGH_BIT_DEPTH
532 #if HAVE_MMX
533     if( cpu&X264_CPU_MMX )
534     {
535         dctf->sub4x4_dct    = x264_sub4x4_dct_mmx;
536         dctf->add4x4_idct   = x264_add4x4_idct_mmx;
537         dctf->add8x8_idct_dc = x264_add8x8_idct_dc_mmx;
538         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_mmx;
539         dctf->dct4x4dc      = x264_dct4x4dc_mmx;
540         dctf->idct4x4dc     = x264_idct4x4dc_mmx;
541         dctf->sub8x8_dct_dc = x264_sub8x8_dct_dc_mmx2;
542
543 #if !ARCH_X86_64
544         dctf->sub8x8_dct    = x264_sub8x8_dct_mmx;
545         dctf->sub16x16_dct  = x264_sub16x16_dct_mmx;
546         dctf->add8x8_idct   = x264_add8x8_idct_mmx;
547         dctf->add16x16_idct = x264_add16x16_idct_mmx;
548
549         dctf->sub8x8_dct8   = x264_sub8x8_dct8_mmx;
550         dctf->sub16x16_dct8 = x264_sub16x16_dct8_mmx;
551         dctf->add8x8_idct8  = x264_add8x8_idct8_mmx;
552         dctf->add16x16_idct8= x264_add16x16_idct8_mmx;
553 #endif
554     }
555
556     if( cpu&X264_CPU_SSE2 )
557     {
558         dctf->sub8x8_dct8   = x264_sub8x8_dct8_sse2;
559         dctf->sub16x16_dct8 = x264_sub16x16_dct8_sse2;
560         dctf->sub8x8_dct_dc = x264_sub8x8_dct_dc_sse2;
561         dctf->sub8x16_dct_dc= x264_sub8x16_dct_dc_sse2;
562         dctf->add8x8_idct8  = x264_add8x8_idct8_sse2;
563         dctf->add16x16_idct8= x264_add16x16_idct8_sse2;
564
565         dctf->sub8x8_dct    = x264_sub8x8_dct_sse2;
566         dctf->sub16x16_dct  = x264_sub16x16_dct_sse2;
567         dctf->add8x8_idct   = x264_add8x8_idct_sse2;
568         dctf->add16x16_idct = x264_add16x16_idct_sse2;
569         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_sse2;
570     }
571
572     if( (cpu&X264_CPU_SSSE3) && !(cpu&X264_CPU_SLOW_ATOM) )
573     {
574         dctf->sub4x4_dct    = x264_sub4x4_dct_ssse3;
575         dctf->sub8x8_dct    = x264_sub8x8_dct_ssse3;
576         dctf->sub16x16_dct  = x264_sub16x16_dct_ssse3;
577         dctf->sub8x8_dct8   = x264_sub8x8_dct8_ssse3;
578         dctf->sub16x16_dct8 = x264_sub16x16_dct8_ssse3;
579         dctf->sub8x16_dct_dc = x264_sub8x16_dct_dc_ssse3;
580         dctf->add8x8_idct_dc = x264_add8x8_idct_dc_ssse3;
581         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_ssse3;
582     }
583
584     if( cpu&X264_CPU_SSE4 )
585         dctf->add4x4_idct   = x264_add4x4_idct_sse4;
586
587     if( cpu&X264_CPU_AVX )
588     {
589         dctf->add4x4_idct      = x264_add4x4_idct_avx;
590         dctf->add8x8_idct      = x264_add8x8_idct_avx;
591         dctf->add16x16_idct    = x264_add16x16_idct_avx;
592         dctf->add8x8_idct8     = x264_add8x8_idct8_avx;
593         dctf->add16x16_idct8   = x264_add16x16_idct8_avx;
594         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_avx;
595         dctf->sub8x8_dct       = x264_sub8x8_dct_avx;
596         dctf->sub16x16_dct     = x264_sub16x16_dct_avx;
597         dctf->sub8x8_dct8      = x264_sub8x8_dct8_avx;
598         dctf->sub16x16_dct8    = x264_sub16x16_dct8_avx;
599     }
600 #endif //HAVE_MMX
601
602 #if HAVE_ALTIVEC
603     if( cpu&X264_CPU_ALTIVEC )
604     {
605         dctf->sub4x4_dct    = x264_sub4x4_dct_altivec;
606         dctf->sub8x8_dct    = x264_sub8x8_dct_altivec;
607         dctf->sub16x16_dct  = x264_sub16x16_dct_altivec;
608
609         dctf->add4x4_idct   = x264_add4x4_idct_altivec;
610         dctf->add8x8_idct   = x264_add8x8_idct_altivec;
611         dctf->add16x16_idct = x264_add16x16_idct_altivec;
612
613         dctf->sub8x8_dct8   = x264_sub8x8_dct8_altivec;
614         dctf->sub16x16_dct8 = x264_sub16x16_dct8_altivec;
615
616         dctf->add8x8_idct8  = x264_add8x8_idct8_altivec;
617         dctf->add16x16_idct8= x264_add16x16_idct8_altivec;
618     }
619 #endif
620
621 #if HAVE_ARMV6
622     if( cpu&X264_CPU_NEON )
623     {
624         dctf->sub4x4_dct    = x264_sub4x4_dct_neon;
625         dctf->sub8x8_dct    = x264_sub8x8_dct_neon;
626         dctf->sub16x16_dct  = x264_sub16x16_dct_neon;
627         dctf->add8x8_idct_dc = x264_add8x8_idct_dc_neon;
628         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_neon;
629         dctf->sub8x8_dct_dc = x264_sub8x8_dct_dc_neon;
630         dctf->dct4x4dc      = x264_dct4x4dc_neon;
631         dctf->idct4x4dc     = x264_idct4x4dc_neon;
632
633         dctf->add4x4_idct   = x264_add4x4_idct_neon;
634         dctf->add8x8_idct   = x264_add8x8_idct_neon;
635         dctf->add16x16_idct = x264_add16x16_idct_neon;
636
637         dctf->sub8x8_dct8   = x264_sub8x8_dct8_neon;
638         dctf->sub16x16_dct8 = x264_sub16x16_dct8_neon;
639
640         dctf->add8x8_idct8  = x264_add8x8_idct8_neon;
641         dctf->add16x16_idct8= x264_add16x16_idct8_neon;
642     }
643 #endif
644 #endif // HIGH_BIT_DEPTH
645 }
646
647 void x264_dct_init_weights( void )
648 {
649     for( int j = 0; j < 2; j++ )
650     {
651         for( int i = 0; i < 16; i++ )
652             x264_dct4_weight2_zigzag[j][i] = x264_dct4_weight2_tab[ x264_zigzag_scan4[j][i] ];
653         for( int i = 0; i < 64; i++ )
654             x264_dct8_weight2_zigzag[j][i] = x264_dct8_weight2_tab[ x264_zigzag_scan8[j][i] ];
655     }
656 }
657
658
659 #define ZIG(i,y,x) level[i] = dct[x*8+y];
660 #define ZIGZAG8_FRAME\
661     ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)\
662     ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)\
663     ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,4,0) ZIG(11,3,1)\
664     ZIG(12,2,2) ZIG(13,1,3) ZIG(14,0,4) ZIG(15,0,5)\
665     ZIG(16,1,4) ZIG(17,2,3) ZIG(18,3,2) ZIG(19,4,1)\
666     ZIG(20,5,0) ZIG(21,6,0) ZIG(22,5,1) ZIG(23,4,2)\
667     ZIG(24,3,3) ZIG(25,2,4) ZIG(26,1,5) ZIG(27,0,6)\
668     ZIG(28,0,7) ZIG(29,1,6) ZIG(30,2,5) ZIG(31,3,4)\
669     ZIG(32,4,3) ZIG(33,5,2) ZIG(34,6,1) ZIG(35,7,0)\
670     ZIG(36,7,1) ZIG(37,6,2) ZIG(38,5,3) ZIG(39,4,4)\
671     ZIG(40,3,5) ZIG(41,2,6) ZIG(42,1,7) ZIG(43,2,7)\
672     ZIG(44,3,6) ZIG(45,4,5) ZIG(46,5,4) ZIG(47,6,3)\
673     ZIG(48,7,2) ZIG(49,7,3) ZIG(50,6,4) ZIG(51,5,5)\
674     ZIG(52,4,6) ZIG(53,3,7) ZIG(54,4,7) ZIG(55,5,6)\
675     ZIG(56,6,5) ZIG(57,7,4) ZIG(58,7,5) ZIG(59,6,6)\
676     ZIG(60,5,7) ZIG(61,6,7) ZIG(62,7,6) ZIG(63,7,7)\
677
678 #define ZIGZAG8_FIELD\
679     ZIG( 0,0,0) ZIG( 1,1,0) ZIG( 2,2,0) ZIG( 3,0,1)\
680     ZIG( 4,1,1) ZIG( 5,3,0) ZIG( 6,4,0) ZIG( 7,2,1)\
681     ZIG( 8,0,2) ZIG( 9,3,1) ZIG(10,5,0) ZIG(11,6,0)\
682     ZIG(12,7,0) ZIG(13,4,1) ZIG(14,1,2) ZIG(15,0,3)\
683     ZIG(16,2,2) ZIG(17,5,1) ZIG(18,6,1) ZIG(19,7,1)\
684     ZIG(20,3,2) ZIG(21,1,3) ZIG(22,0,4) ZIG(23,2,3)\
685     ZIG(24,4,2) ZIG(25,5,2) ZIG(26,6,2) ZIG(27,7,2)\
686     ZIG(28,3,3) ZIG(29,1,4) ZIG(30,0,5) ZIG(31,2,4)\
687     ZIG(32,4,3) ZIG(33,5,3) ZIG(34,6,3) ZIG(35,7,3)\
688     ZIG(36,3,4) ZIG(37,1,5) ZIG(38,0,6) ZIG(39,2,5)\
689     ZIG(40,4,4) ZIG(41,5,4) ZIG(42,6,4) ZIG(43,7,4)\
690     ZIG(44,3,5) ZIG(45,1,6) ZIG(46,2,6) ZIG(47,4,5)\
691     ZIG(48,5,5) ZIG(49,6,5) ZIG(50,7,5) ZIG(51,3,6)\
692     ZIG(52,0,7) ZIG(53,1,7) ZIG(54,4,6) ZIG(55,5,6)\
693     ZIG(56,6,6) ZIG(57,7,6) ZIG(58,2,7) ZIG(59,3,7)\
694     ZIG(60,4,7) ZIG(61,5,7) ZIG(62,6,7) ZIG(63,7,7)
695
696 #define ZIGZAG4_FRAME\
697     ZIGDC( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)\
698     ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)\
699     ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,3,1) ZIG(11,2,2)\
700     ZIG(12,1,3) ZIG(13,2,3) ZIG(14,3,2) ZIG(15,3,3)
701
702 #define ZIGZAG4_FIELD\
703     ZIGDC( 0,0,0) ZIG( 1,1,0) ZIG( 2,0,1) ZIG( 3,2,0)\
704     ZIG( 4,3,0) ZIG( 5,1,1) ZIG( 6,2,1) ZIG( 7,3,1)\
705     ZIG( 8,0,2) ZIG( 9,1,2) ZIG(10,2,2) ZIG(11,3,2)\
706     ZIG(12,0,3) ZIG(13,1,3) ZIG(14,2,3) ZIG(15,3,3)
707
708 static void zigzag_scan_8x8_frame( dctcoef level[64], dctcoef dct[64] )
709 {
710     ZIGZAG8_FRAME
711 }
712
713 static void zigzag_scan_8x8_field( dctcoef level[64], dctcoef dct[64] )
714 {
715     ZIGZAG8_FIELD
716 }
717
718 #undef ZIG
719 #define ZIG(i,y,x) level[i] = dct[x*4+y];
720 #define ZIGDC(i,y,x) ZIG(i,y,x)
721
722 static void zigzag_scan_4x4_frame( dctcoef level[16], dctcoef dct[16] )
723 {
724     ZIGZAG4_FRAME
725 }
726
727 static void zigzag_scan_4x4_field( dctcoef level[16], dctcoef dct[16] )
728 {
729     memcpy( level, dct, 2 * sizeof(dctcoef) );
730     ZIG(2,0,1) ZIG(3,2,0) ZIG(4,3,0) ZIG(5,1,1)
731     memcpy( level+6, dct+6, 10 * sizeof(dctcoef) );
732 }
733
734 #undef ZIG
735 #define ZIG(i,y,x) {\
736     int oe = x+y*FENC_STRIDE;\
737     int od = x+y*FDEC_STRIDE;\
738     level[i] = p_src[oe] - p_dst[od];\
739     nz |= level[i];\
740 }
741 #define COPY4x4\
742     CPPIXEL_X4( p_dst+0*FDEC_STRIDE, p_src+0*FENC_STRIDE );\
743     CPPIXEL_X4( p_dst+1*FDEC_STRIDE, p_src+1*FENC_STRIDE );\
744     CPPIXEL_X4( p_dst+2*FDEC_STRIDE, p_src+2*FENC_STRIDE );\
745     CPPIXEL_X4( p_dst+3*FDEC_STRIDE, p_src+3*FENC_STRIDE );
746 #define CPPIXEL_X8(dst,src) ( CPPIXEL_X4(dst,src), CPPIXEL_X4(dst+4,src+4) )
747 #define COPY8x8\
748     CPPIXEL_X8( p_dst+0*FDEC_STRIDE, p_src+0*FENC_STRIDE );\
749     CPPIXEL_X8( p_dst+1*FDEC_STRIDE, p_src+1*FENC_STRIDE );\
750     CPPIXEL_X8( p_dst+2*FDEC_STRIDE, p_src+2*FENC_STRIDE );\
751     CPPIXEL_X8( p_dst+3*FDEC_STRIDE, p_src+3*FENC_STRIDE );\
752     CPPIXEL_X8( p_dst+4*FDEC_STRIDE, p_src+4*FENC_STRIDE );\
753     CPPIXEL_X8( p_dst+5*FDEC_STRIDE, p_src+5*FENC_STRIDE );\
754     CPPIXEL_X8( p_dst+6*FDEC_STRIDE, p_src+6*FENC_STRIDE );\
755     CPPIXEL_X8( p_dst+7*FDEC_STRIDE, p_src+7*FENC_STRIDE );
756
757 static int zigzag_sub_4x4_frame( dctcoef level[16], const pixel *p_src, pixel *p_dst )
758 {
759     int nz = 0;
760     ZIGZAG4_FRAME
761     COPY4x4
762     return !!nz;
763 }
764
765 static int zigzag_sub_4x4_field( dctcoef level[16], const pixel *p_src, pixel *p_dst )
766 {
767     int nz = 0;
768     ZIGZAG4_FIELD
769     COPY4x4
770     return !!nz;
771 }
772
773 #undef ZIGDC
774 #define ZIGDC(i,y,x) {\
775     int oe = x+y*FENC_STRIDE;\
776     int od = x+y*FDEC_STRIDE;\
777     *dc = p_src[oe] - p_dst[od];\
778     level[0] = 0;\
779 }
780
781 static int zigzag_sub_4x4ac_frame( dctcoef level[16], const pixel *p_src, pixel *p_dst, dctcoef *dc )
782 {
783     int nz = 0;
784     ZIGZAG4_FRAME
785     COPY4x4
786     return !!nz;
787 }
788
789 static int zigzag_sub_4x4ac_field( dctcoef level[16], const pixel *p_src, pixel *p_dst, dctcoef *dc )
790 {
791     int nz = 0;
792     ZIGZAG4_FIELD
793     COPY4x4
794     return !!nz;
795 }
796
797 static int zigzag_sub_8x8_frame( dctcoef level[64], const pixel *p_src, pixel *p_dst )
798 {
799     int nz = 0;
800     ZIGZAG8_FRAME
801     COPY8x8
802     return !!nz;
803 }
804 static int zigzag_sub_8x8_field( dctcoef level[64], const pixel *p_src, pixel *p_dst )
805 {
806     int nz = 0;
807     ZIGZAG8_FIELD
808     COPY8x8
809     return !!nz;
810 }
811
812 #undef ZIG
813 #undef COPY4x4
814
815 static void zigzag_interleave_8x8_cavlc( dctcoef *dst, dctcoef *src, uint8_t *nnz )
816 {
817     for( int i = 0; i < 4; i++ )
818     {
819         int nz = 0;
820         for( int j = 0; j < 16; j++ )
821         {
822             nz |= src[i+j*4];
823             dst[i*16+j] = src[i+j*4];
824         }
825         nnz[(i&1) + (i>>1)*8] = !!nz;
826     }
827 }
828
829 void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf_progressive, x264_zigzag_function_t *pf_interlaced )
830 {
831     pf_interlaced->scan_8x8   = zigzag_scan_8x8_field;
832     pf_progressive->scan_8x8  = zigzag_scan_8x8_frame;
833     pf_interlaced->scan_4x4   = zigzag_scan_4x4_field;
834     pf_progressive->scan_4x4  = zigzag_scan_4x4_frame;
835     pf_interlaced->sub_8x8    = zigzag_sub_8x8_field;
836     pf_progressive->sub_8x8   = zigzag_sub_8x8_frame;
837     pf_interlaced->sub_4x4    = zigzag_sub_4x4_field;
838     pf_progressive->sub_4x4   = zigzag_sub_4x4_frame;
839     pf_interlaced->sub_4x4ac  = zigzag_sub_4x4ac_field;
840     pf_progressive->sub_4x4ac = zigzag_sub_4x4ac_frame;
841
842 #if HIGH_BIT_DEPTH
843 #if HAVE_MMX
844     if( cpu&X264_CPU_SSE2 )
845     {
846         pf_interlaced->scan_4x4  = x264_zigzag_scan_4x4_field_sse2;
847         pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_sse2;
848         pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_sse2;
849     }
850     if( cpu&X264_CPU_SSE4 )
851         pf_interlaced->scan_8x8 = x264_zigzag_scan_8x8_field_sse4;
852     if( cpu&X264_CPU_AVX )
853         pf_interlaced->scan_8x8 = x264_zigzag_scan_8x8_field_avx;
854 #if ARCH_X86_64
855     if( cpu&X264_CPU_AVX )
856     {
857         pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_avx;
858         pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_avx;
859     }
860 #endif // ARCH_X86_64
861 #endif // HAVE_MMX
862 #else
863 #if HAVE_MMX
864     if( cpu&X264_CPU_MMX )
865         pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_mmx;
866     if( cpu&X264_CPU_MMX2 )
867     {
868         pf_interlaced->scan_4x4  = x264_zigzag_scan_4x4_field_mmx2;
869         pf_interlaced->scan_8x8  = x264_zigzag_scan_8x8_field_mmx2;
870         pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_mmx2;
871     }
872     if( cpu&X264_CPU_SSE2_IS_FAST )
873         pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_sse2;
874     if( cpu&X264_CPU_SSSE3 )
875     {
876         pf_interlaced->sub_4x4   = x264_zigzag_sub_4x4_field_ssse3;
877         pf_progressive->sub_4x4  = x264_zigzag_sub_4x4_frame_ssse3;
878         pf_interlaced->sub_4x4ac = x264_zigzag_sub_4x4ac_field_ssse3;
879         pf_progressive->sub_4x4ac= x264_zigzag_sub_4x4ac_frame_ssse3;
880         pf_progressive->scan_8x8 = x264_zigzag_scan_8x8_frame_ssse3;
881         if( cpu&X264_CPU_SHUFFLE_IS_FAST )
882             pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_ssse3;
883     }
884     if( cpu&X264_CPU_AVX )
885     {
886         pf_interlaced->sub_4x4   = x264_zigzag_sub_4x4_field_avx;
887         pf_progressive->sub_4x4  = x264_zigzag_sub_4x4_frame_avx;
888 #if ARCH_X86_64
889         pf_interlaced->sub_4x4ac = x264_zigzag_sub_4x4ac_field_avx;
890         pf_progressive->sub_4x4ac= x264_zigzag_sub_4x4ac_frame_avx;
891 #endif
892         if( cpu&X264_CPU_SHUFFLE_IS_FAST )
893             pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_avx;
894     }
895     if( cpu&X264_CPU_XOP )
896         pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_xop;
897 #endif // HAVE_MMX
898 #if HAVE_ALTIVEC
899     if( cpu&X264_CPU_ALTIVEC )
900     {
901         pf_interlaced->scan_4x4  = x264_zigzag_scan_4x4_field_altivec;
902         pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_altivec;
903     }
904 #endif
905 #if HAVE_ARMV6
906     if( cpu&X264_CPU_NEON )
907         pf_progressive->scan_4x4 = x264_zigzag_scan_4x4_frame_neon;
908 #endif
909 #endif // HIGH_BIT_DEPTH
910
911     pf_interlaced->interleave_8x8_cavlc =
912     pf_progressive->interleave_8x8_cavlc = zigzag_interleave_8x8_cavlc;
913 #if HAVE_MMX
914 #if HIGH_BIT_DEPTH
915     if( cpu&X264_CPU_SSE2 )
916     {
917         pf_interlaced->interleave_8x8_cavlc =
918         pf_progressive->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_sse2;
919     }
920     if( cpu&X264_CPU_AVX )
921     {
922         pf_interlaced->interleave_8x8_cavlc =
923         pf_progressive->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_avx;
924     }
925 #else
926     if( cpu&X264_CPU_MMX )
927     {
928         pf_interlaced->interleave_8x8_cavlc =
929         pf_progressive->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_mmx;
930     }
931     if( cpu&X264_CPU_SHUFFLE_IS_FAST )
932     {
933         pf_interlaced->interleave_8x8_cavlc =
934         pf_progressive->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_sse2;
935     }
936
937     if( cpu&X264_CPU_AVX )
938     {
939         pf_interlaced->interleave_8x8_cavlc =
940         pf_progressive->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_avx;
941     }
942 #endif // HIGH_BIT_DEPTH
943 #endif
944 }