a5ea74c5bc3f5e04e706f72143b938c2b7f21e21
[ffmpeg.git] / libavfilter / x86 / vf_blend.asm
1 ;*****************************************************************************
2 ;* x86-optimized functions for blend filter
3 ;*
4 ;* Copyright (C) 2015 Paul B Mahol
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/x86util.asm"
24
25 SECTION_RODATA
26
27 pw_1:   times 8 dw 1
28 pw_128: times 8 dw 128
29 pw_255: times 8 dw 255
30 pb_127: times 16 db 127
31 pb_128: times 16 db 128
32 pb_255: times 16 db 255
33
34 SECTION .text
35
36 %macro BLEND_INIT 2
37 %if ARCH_X86_64
38 cglobal blend_%1, 6, 9, %2, top, top_linesize, bottom, bottom_linesize, dst, dst_linesize, width, end, x
39     mov    widthd, dword widthm
40 %else
41 cglobal blend_%1, 5, 7, %2, top, top_linesize, bottom, bottom_linesize, dst, end, x
42 %define dst_linesizeq r5mp
43 %define widthq r6mp
44 %endif
45     mov      endd, dword r8m
46     add      topq, widthq
47     add   bottomq, widthq
48     add      dstq, widthq
49     sub      endd, dword r7m ; start
50     neg    widthq
51 %endmacro
52
53 %macro BLEND_END 0
54     add          topq, top_linesizeq
55     add       bottomq, bottom_linesizeq
56     add          dstq, dst_linesizeq
57     sub          endd, 1
58     jg .nextrow
59 REP_RET
60 %endmacro
61
62 %macro BLEND_SIMPLE 2
63 BLEND_INIT %1, 2
64 .nextrow:
65     mov        xq, widthq
66
67     .loop:
68         movu            m0, [topq + xq]
69         movu            m1, [bottomq + xq]
70         p%2             m0, m1
71         mova   [dstq + xq], m0
72         add             xq, mmsize
73     jl .loop
74 BLEND_END
75 %endmacro
76
77 INIT_XMM sse2
78 BLEND_SIMPLE xor,      xor
79 BLEND_SIMPLE or,       or
80 BLEND_SIMPLE and,      and
81 BLEND_SIMPLE addition, addusb
82 BLEND_SIMPLE subtract, subusb
83 BLEND_SIMPLE darken,   minub
84 BLEND_SIMPLE lighten,  maxub
85
86 BLEND_INIT difference128, 4
87     pxor       m2, m2
88     mova       m3, [pw_128]
89 .nextrow:
90     mov        xq, widthq
91
92     .loop:
93         movh            m0, [topq + xq]
94         movh            m1, [bottomq + xq]
95         punpcklbw       m0, m2
96         punpcklbw       m1, m2
97         paddw           m0, m3
98         psubw           m0, m1
99         packuswb        m0, m0
100         movh   [dstq + xq], m0
101         add             xq, mmsize / 2
102     jl .loop
103 BLEND_END
104
105 %macro MULTIPLY 3 ; a, b, pw_1
106     pmullw          %1, %2               ; xxxxxxxx  a * b
107     paddw           %1, %3
108     mova            %2, %1
109     psrlw           %2, 8
110     paddw           %1, %2
111     psrlw           %1, 8                ; 00xx00xx  a * b / 255
112 %endmacro
113
114 %macro SCREEN 4   ; a, b, pw_1, pw_255
115     pxor            %1, %4               ; 00xx00xx  255 - a
116     pxor            %2, %4
117     MULTIPLY        %1, %2, %3
118     pxor            %1, %4               ; 00xx00xx  255 - x / 255
119 %endmacro
120
121 BLEND_INIT multiply, 4
122     pxor       m2, m2
123     mova       m3, [pw_1]
124 .nextrow:
125     mov        xq, widthq
126
127     .loop:
128                                              ;     word
129                                              ;     |--|
130         movh            m0, [topq + xq]      ; 0000xxxx
131         movh            m1, [bottomq + xq]
132         punpcklbw       m0, m2               ; 00xx00xx
133         punpcklbw       m1, m2
134
135         MULTIPLY        m0, m1, m3
136
137         packuswb        m0, m0               ; 0000xxxx
138         movh   [dstq + xq], m0
139         add             xq, mmsize / 2
140
141     jl .loop
142 BLEND_END
143
144 BLEND_INIT screen, 5
145     pxor       m2, m2
146     mova       m3, [pw_1]
147     mova       m4, [pw_255]
148 .nextrow:
149     mov        xq, widthq
150
151     .loop:
152         movh            m0, [topq + xq]      ; 0000xxxx
153         movh            m1, [bottomq + xq]
154         punpcklbw       m0, m2               ; 00xx00xx
155         punpcklbw       m1, m2
156
157         SCREEN          m0, m1, m3, m4
158
159         packuswb        m0, m0               ; 0000xxxx
160         movh   [dstq + xq], m0
161         add             xq, mmsize / 2
162
163     jl .loop
164 BLEND_END
165
166 BLEND_INIT average, 3
167     pxor       m2, m2
168 .nextrow:
169     mov        xq, widthq
170
171     .loop:
172         movh            m0, [topq + xq]
173         movh            m1, [bottomq + xq]
174         punpcklbw       m0, m2
175         punpcklbw       m1, m2
176         paddw           m0, m1
177         psrlw           m0, 1
178         packuswb        m0, m0
179         movh   [dstq + xq], m0
180         add             xq, mmsize / 2
181     jl .loop
182 BLEND_END
183
184 BLEND_INIT addition128, 4
185     pxor       m2, m2
186     mova       m3, [pw_128]
187 .nextrow:
188     mov        xq, widthq
189
190     .loop:
191         movh            m0, [topq + xq]
192         movh            m1, [bottomq + xq]
193         punpcklbw       m0, m2
194         punpcklbw       m1, m2
195         paddw           m0, m1
196         psubw           m0, m3
197         packuswb        m0, m0
198         movh   [dstq + xq], m0
199         add             xq, mmsize / 2
200     jl .loop
201 BLEND_END
202
203 BLEND_INIT hardmix, 5
204     mova       m2, [pb_255]
205     mova       m3, [pb_128]
206     mova       m4, [pb_127]
207 .nextrow:
208     mov        xq, widthq
209
210     .loop:
211         movu            m0, [topq + xq]
212         movu            m1, [bottomq + xq]
213         pxor            m1, m4
214         pxor            m0, m3
215         pcmpgtb         m1, m0
216         pxor            m1, m2
217         mova   [dstq + xq], m1
218         add             xq, mmsize
219     jl .loop
220 BLEND_END
221
222 BLEND_INIT phoenix, 4
223     mova       m3, [pb_255]
224 .nextrow:
225     mov        xq, widthq
226
227     .loop:
228         movu            m0, [topq + xq]
229         movu            m1, [bottomq + xq]
230         mova            m2, m0
231         pminub          m0, m1
232         pmaxub          m1, m2
233         mova            m2, m3
234         psubusb         m2, m1
235         paddusb         m2, m0
236         mova   [dstq + xq], m2
237         add             xq, mmsize
238     jl .loop
239 BLEND_END
240
241 %macro BLEND_ABS 0
242 BLEND_INIT difference, 3
243     pxor       m2, m2
244 .nextrow:
245     mov        xq, widthq
246
247     .loop:
248         movh            m0, [topq + xq]
249         movh            m1, [bottomq + xq]
250         punpcklbw       m0, m2
251         punpcklbw       m1, m2
252         psubw           m0, m1
253         ABS1            m0, m1
254         packuswb        m0, m0
255         movh   [dstq + xq], m0
256         add             xq, mmsize / 2
257     jl .loop
258 BLEND_END
259
260 BLEND_INIT negation, 5
261     pxor       m2, m2
262     mova       m4, [pw_255]
263 .nextrow:
264     mov        xq, widthq
265
266     .loop:
267         movh            m0, [topq + xq]
268         movh            m1, [bottomq + xq]
269         punpcklbw       m0, m2
270         punpcklbw       m1, m2
271         mova            m3, m4
272         psubw           m3, m0
273         psubw           m3, m1
274         ABS1            m3, m1
275         mova            m0, m4
276         psubw           m0, m3
277         packuswb        m0, m0
278         movh   [dstq + xq], m0
279         add             xq, mmsize / 2
280     jl .loop
281 BLEND_END
282 %endmacro
283
284 INIT_XMM sse2
285 BLEND_ABS
286 INIT_XMM ssse3
287 BLEND_ABS