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