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