]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/dwt.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / x86 / dwt.c
1 /*
2  * MMX optimized discrete wavelet transform
3  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
4  * Copyright (c) 2010 David Conrad
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "libavutil/x86_cpu.h"
24 #include "dsputil_mmx.h"
25 #include "dwt.h"
26
27 #define COMPOSE_VERTICAL(ext, align) \
28 void ff_vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
29 void ff_vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
30 void ff_vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \
31 void ff_vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \
32 void ff_vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width); \
33 \
34 static void vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
35 { \
36     int i, width_align = width&~(align-1); \
37 \
38     for(i=width_align; i<width; i++) \
39         b1[i] = COMPOSE_53iL0(b0[i], b1[i], b2[i]); \
40 \
41     ff_vertical_compose53iL0##ext(b0, b1, b2, width_align); \
42 } \
43 \
44 static void vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
45 { \
46     int i, width_align = width&~(align-1); \
47 \
48     for(i=width_align; i<width; i++) \
49         b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); \
50 \
51     ff_vertical_compose_dirac53iH0##ext(b0, b1, b2, width_align); \
52 } \
53 \
54 static void vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
55                                            IDWTELEM *b3, IDWTELEM *b4, int width) \
56 { \
57     int i, width_align = width&~(align-1); \
58 \
59     for(i=width_align; i<width; i++) \
60         b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
61 \
62     ff_vertical_compose_dd137iL0##ext(b0, b1, b2, b3, b4, width_align); \
63 } \
64 \
65 static void vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
66                                           IDWTELEM *b3, IDWTELEM *b4, int width) \
67 { \
68     int i, width_align = width&~(align-1); \
69 \
70     for(i=width_align; i<width; i++) \
71         b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
72 \
73     ff_vertical_compose_dd97iH0##ext(b0, b1, b2, b3, b4, width_align); \
74 } \
75 static void vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width) \
76 { \
77     int i, width_align = width&~(align-1); \
78 \
79     for(i=width_align; i<width; i++) { \
80         b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]); \
81         b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]); \
82     } \
83 \
84     ff_vertical_compose_haar##ext(b0, b1, width_align); \
85 } \
86 \
87
88 #if HAVE_YASM
89 #if !ARCH_X86_64
90 COMPOSE_VERTICAL(_mmx, 4)
91 #endif
92 COMPOSE_VERTICAL(_sse2, 8)
93 #endif
94
95
96 void ff_horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w);
97
98 void ff_horizontal_compose_haar0i_mmx(IDWTELEM *b, IDWTELEM *tmp, int w);
99 void ff_horizontal_compose_haar1i_mmx(IDWTELEM *b, IDWTELEM *tmp, int w);
100 void ff_horizontal_compose_haar0i_sse2(IDWTELEM *b, IDWTELEM *tmp, int w);
101 void ff_horizontal_compose_haar1i_sse2(IDWTELEM *b, IDWTELEM *tmp, int w);
102
103 void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x)
104 {
105     for (; x < w2; x++) {
106         b[2*x  ] = (tmp[x] + 1)>>1;
107         b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
108     }
109 }
110
111 void ff_horizontal_compose_haar0i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x)
112 {
113     for (; x < w2; x++) {
114         b[2*x  ] = tmp[x];
115         b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);
116     }
117 }
118
119 void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x)
120 {
121     for (; x < w2; x++) {
122         b[2*x  ] = (tmp[x] + 1)>>1;
123         b[2*x+1] = (COMPOSE_HAARiH0(b[x+w2], tmp[x]) + 1)>>1;
124     }
125 }
126
127 void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type)
128 {
129 #if HAVE_YASM
130   int mm_flags = av_get_cpu_flags();;
131
132 #if !ARCH_X86_64
133     if (!(mm_flags & AV_CPU_FLAG_MMX))
134         return;
135
136     switch (type) {
137     case DWT_DIRAC_DD9_7:
138         d->vertical_compose_l0 = vertical_compose53iL0_mmx;
139         d->vertical_compose_h0 = vertical_compose_dd97iH0_mmx;
140         break;
141     case DWT_DIRAC_LEGALL5_3:
142         d->vertical_compose_l0 = vertical_compose53iL0_mmx;
143         d->vertical_compose_h0 = vertical_compose_dirac53iH0_mmx;
144         break;
145     case DWT_DIRAC_DD13_7:
146         d->vertical_compose_l0 = vertical_compose_dd137iL0_mmx;
147         d->vertical_compose_h0 = vertical_compose_dd97iH0_mmx;
148         break;
149     case DWT_DIRAC_HAAR0:
150         d->vertical_compose   = vertical_compose_haar_mmx;
151         d->horizontal_compose = ff_horizontal_compose_haar0i_mmx;
152         break;
153     case DWT_DIRAC_HAAR1:
154         d->vertical_compose   = vertical_compose_haar_mmx;
155         d->horizontal_compose = ff_horizontal_compose_haar1i_mmx;
156         break;
157     }
158 #endif
159
160     if (!(mm_flags & AV_CPU_FLAG_SSE2))
161         return;
162
163     switch (type) {
164     case DWT_DIRAC_DD9_7:
165         d->vertical_compose_l0 = vertical_compose53iL0_sse2;
166         d->vertical_compose_h0 = vertical_compose_dd97iH0_sse2;
167         break;
168     case DWT_DIRAC_LEGALL5_3:
169         d->vertical_compose_l0 = vertical_compose53iL0_sse2;
170         d->vertical_compose_h0 = vertical_compose_dirac53iH0_sse2;
171         break;
172     case DWT_DIRAC_DD13_7:
173         d->vertical_compose_l0 = vertical_compose_dd137iL0_sse2;
174         d->vertical_compose_h0 = vertical_compose_dd97iH0_sse2;
175         break;
176     case DWT_DIRAC_HAAR0:
177         d->vertical_compose   = vertical_compose_haar_sse2;
178         d->horizontal_compose = ff_horizontal_compose_haar0i_sse2;
179         break;
180     case DWT_DIRAC_HAAR1:
181         d->vertical_compose   = vertical_compose_haar_sse2;
182         d->horizontal_compose = ff_horizontal_compose_haar1i_sse2;
183         break;
184     }
185
186     if (!(mm_flags & AV_CPU_FLAG_SSSE3))
187         return;
188
189     switch (type) {
190     case DWT_DIRAC_DD9_7:
191 //MMXDISABLED        d->horizontal_compose = ff_horizontal_compose_dd97i_ssse3;
192         break;
193     }
194 #endif // HAVE_YASM
195 }