2 * MMX optimized discrete wavelet transform
3 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
4 * Copyright (c) 2010 David Conrad
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/x86_cpu.h"
24 #include "dsputil_mmx.h"
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); \
34 static void vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
36 int i, width_align = width&~(align-1); \
38 for(i=width_align; i<width; i++) \
39 b1[i] = COMPOSE_53iL0(b0[i], b1[i], b2[i]); \
41 ff_vertical_compose53iL0##ext(b0, b1, b2, width_align); \
44 static void vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
46 int i, width_align = width&~(align-1); \
48 for(i=width_align; i<width; i++) \
49 b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); \
51 ff_vertical_compose_dirac53iH0##ext(b0, b1, b2, width_align); \
54 static void vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
55 IDWTELEM *b3, IDWTELEM *b4, int width) \
57 int i, width_align = width&~(align-1); \
59 for(i=width_align; i<width; i++) \
60 b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
62 ff_vertical_compose_dd137iL0##ext(b0, b1, b2, b3, b4, width_align); \
65 static void vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
66 IDWTELEM *b3, IDWTELEM *b4, int width) \
68 int i, width_align = width&~(align-1); \
70 for(i=width_align; i<width; i++) \
71 b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
73 ff_vertical_compose_dd97iH0##ext(b0, b1, b2, b3, b4, width_align); \
75 static void vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width) \
77 int i, width_align = width&~(align-1); \
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]); \
84 ff_vertical_compose_haar##ext(b0, b1, width_align); \
90 COMPOSE_VERTICAL(_mmx, 4)
92 COMPOSE_VERTICAL(_sse2, 8)
96 void ff_horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w);
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);
103 void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x)
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;
111 void ff_horizontal_compose_haar0i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x)
113 for (; x < w2; x++) {
115 b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);
119 void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x)
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;
127 void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type)
130 int mm_flags = av_get_cpu_flags();;
133 if (!(mm_flags & AV_CPU_FLAG_MMX))
137 case DWT_DIRAC_DD9_7:
138 d->vertical_compose_l0 = vertical_compose53iL0_mmx;
139 d->vertical_compose_h0 = vertical_compose_dd97iH0_mmx;
141 case DWT_DIRAC_LEGALL5_3:
142 d->vertical_compose_l0 = vertical_compose53iL0_mmx;
143 d->vertical_compose_h0 = vertical_compose_dirac53iH0_mmx;
145 case DWT_DIRAC_DD13_7:
146 d->vertical_compose_l0 = vertical_compose_dd137iL0_mmx;
147 d->vertical_compose_h0 = vertical_compose_dd97iH0_mmx;
149 case DWT_DIRAC_HAAR0:
150 d->vertical_compose = vertical_compose_haar_mmx;
151 d->horizontal_compose = ff_horizontal_compose_haar0i_mmx;
153 case DWT_DIRAC_HAAR1:
154 d->vertical_compose = vertical_compose_haar_mmx;
155 d->horizontal_compose = ff_horizontal_compose_haar1i_mmx;
160 if (!(mm_flags & AV_CPU_FLAG_SSE2))
164 case DWT_DIRAC_DD9_7:
165 d->vertical_compose_l0 = vertical_compose53iL0_sse2;
166 d->vertical_compose_h0 = vertical_compose_dd97iH0_sse2;
168 case DWT_DIRAC_LEGALL5_3:
169 d->vertical_compose_l0 = vertical_compose53iL0_sse2;
170 d->vertical_compose_h0 = vertical_compose_dirac53iH0_sse2;
172 case DWT_DIRAC_DD13_7:
173 d->vertical_compose_l0 = vertical_compose_dd137iL0_sse2;
174 d->vertical_compose_h0 = vertical_compose_dd97iH0_sse2;
176 case DWT_DIRAC_HAAR0:
177 d->vertical_compose = vertical_compose_haar_sse2;
178 d->horizontal_compose = ff_horizontal_compose_haar0i_sse2;
180 case DWT_DIRAC_HAAR1:
181 d->vertical_compose = vertical_compose_haar_sse2;
182 d->horizontal_compose = ff_horizontal_compose_haar1i_sse2;
186 if (!(mm_flags & AV_CPU_FLAG_SSSE3))
190 case DWT_DIRAC_DD9_7:
191 //MMXDISABLED d->horizontal_compose = ff_horizontal_compose_dd97i_ssse3;