Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libyuv / source / row_any.cc
1 /*
2  *  Copyright 2012 The LibYuv Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS. All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "libyuv/row.h"
12
13 #include "libyuv/basic_types.h"
14
15 #ifdef __cplusplus
16 namespace libyuv {
17 extern "C" {
18 #endif
19
20 // TODO(fbarchard): Consider 'any' functions handling any quantity of pixels.
21 // TODO(fbarchard): Consider 'any' functions handling odd alignment.
22 // YUV to RGB does multiple of 8 with SIMD and remainder with C.
23 #define YANY(NAMEANY, I420TORGB_SIMD, I420TORGB_C, UV_SHIFT, BPP, MASK)        \
24     void NAMEANY(const uint8* y_buf,                                           \
25                  const uint8* u_buf,                                           \
26                  const uint8* v_buf,                                           \
27                  uint8* rgb_buf,                                               \
28                  int width) {                                                  \
29       int n = width & ~MASK;                                                   \
30       I420TORGB_SIMD(y_buf, u_buf, v_buf, rgb_buf, n);                         \
31       I420TORGB_C(y_buf + n,                                                   \
32                   u_buf + (n >> UV_SHIFT),                                     \
33                   v_buf + (n >> UV_SHIFT),                                     \
34                   rgb_buf + n * BPP, width & MASK);                            \
35     }
36
37 #ifdef HAS_I422TOARGBROW_SSSE3
38 YANY(I422ToARGBRow_Any_SSSE3, I422ToARGBRow_SSSE3, I422ToARGBRow_C,
39      1, 4, 7)
40 #endif  // HAS_I422TOARGBROW_SSSE3
41 #ifdef HAS_I444TOARGBROW_SSSE3
42 YANY(I444ToARGBRow_Any_SSSE3, I444ToARGBRow_SSSE3, I444ToARGBRow_C,
43      0, 4, 7)
44 YANY(I411ToARGBRow_Any_SSSE3, I411ToARGBRow_SSSE3, I411ToARGBRow_C,
45      2, 4, 7)
46 YANY(I422ToBGRARow_Any_SSSE3, I422ToBGRARow_SSSE3, I422ToBGRARow_C,
47      1, 4, 7)
48 YANY(I422ToABGRRow_Any_SSSE3, I422ToABGRRow_SSSE3, I422ToABGRRow_C,
49      1, 4, 7)
50 YANY(I422ToRGBARow_Any_SSSE3, I422ToRGBARow_SSSE3, I422ToRGBARow_C,
51      1, 4, 7)
52 // I422ToRGB565Row_SSSE3 is unaligned.
53 YANY(I422ToARGB4444Row_Any_SSSE3, I422ToARGB4444Row_SSSE3, I422ToARGB4444Row_C,
54      1, 2, 7)
55 YANY(I422ToARGB1555Row_Any_SSSE3, I422ToARGB1555Row_SSSE3, I422ToARGB1555Row_C,
56      1, 2, 7)
57 YANY(I422ToRGB565Row_Any_SSSE3, I422ToRGB565Row_SSSE3, I422ToRGB565Row_C,
58      1, 2, 7)
59 // I422ToRGB24Row_SSSE3 is unaligned.
60 YANY(I422ToRGB24Row_Any_SSSE3, I422ToRGB24Row_SSSE3, I422ToRGB24Row_C, 1, 3, 7)
61 YANY(I422ToRAWRow_Any_SSSE3, I422ToRAWRow_SSSE3, I422ToRAWRow_C, 1, 3, 7)
62 YANY(I422ToYUY2Row_Any_SSE2, I422ToYUY2Row_SSE2, I422ToYUY2Row_C, 1, 2, 15)
63 YANY(I422ToUYVYRow_Any_SSE2, I422ToUYVYRow_SSE2, I422ToUYVYRow_C, 1, 2, 15)
64 #endif  // HAS_I444TOARGBROW_SSSE3
65 #ifdef HAS_I422TOARGBROW_AVX2
66 YANY(I422ToARGBRow_Any_AVX2, I422ToARGBRow_AVX2, I422ToARGBRow_C, 1, 4, 15)
67 #endif  // HAS_I422TOARGBROW_AVX2
68 #ifdef HAS_I422TOBGRAROW_AVX2
69 YANY(I422ToBGRARow_Any_AVX2, I422ToBGRARow_AVX2, I422ToBGRARow_C, 1, 4, 15)
70 #endif  // HAS_I422TOBGRAROW_AVX2
71 #ifdef HAS_I422TOARGBROW_NEON
72 YANY(I444ToARGBRow_Any_NEON, I444ToARGBRow_NEON, I444ToARGBRow_C, 0, 4, 7)
73 YANY(I422ToARGBRow_Any_NEON, I422ToARGBRow_NEON, I422ToARGBRow_C, 1, 4, 7)
74 YANY(I411ToARGBRow_Any_NEON, I411ToARGBRow_NEON, I411ToARGBRow_C, 2, 4, 7)
75 YANY(I422ToBGRARow_Any_NEON, I422ToBGRARow_NEON, I422ToBGRARow_C, 1, 4, 7)
76 YANY(I422ToABGRRow_Any_NEON, I422ToABGRRow_NEON, I422ToABGRRow_C, 1, 4, 7)
77 YANY(I422ToRGBARow_Any_NEON, I422ToRGBARow_NEON, I422ToRGBARow_C, 1, 4, 7)
78 YANY(I422ToRGB24Row_Any_NEON, I422ToRGB24Row_NEON, I422ToRGB24Row_C, 1, 3, 7)
79 YANY(I422ToRAWRow_Any_NEON, I422ToRAWRow_NEON, I422ToRAWRow_C, 1, 3, 7)
80 YANY(I422ToARGB4444Row_Any_NEON, I422ToARGB4444Row_NEON, I422ToARGB4444Row_C,
81      1, 2, 7)
82 YANY(I422ToARGB1555Row_Any_NEON, I422ToARGB1555Row_NEON, I422ToARGB1555Row_C,
83      1, 2, 7)
84 YANY(I422ToRGB565Row_Any_NEON, I422ToRGB565Row_NEON, I422ToRGB565Row_C, 1, 2, 7)
85 #endif  // HAS_I422TOARGBROW_NEON
86 #ifdef HAS_I422TOYUY2ROW_NEON
87 YANY(I422ToYUY2Row_Any_NEON, I422ToYUY2Row_NEON, I422ToYUY2Row_C, 1, 2, 15)
88 #endif  // HAS_I422TOYUY2ROW_NEON
89 #ifdef HAS_I422TOUYVYROW_NEON
90 YANY(I422ToUYVYRow_Any_NEON, I422ToUYVYRow_NEON, I422ToUYVYRow_C, 1, 2, 15)
91 #endif  // HAS_I422TOUYVYROW_NEON
92 #undef YANY
93
94 // Wrappers to handle odd width
95 #define NV2NY(NAMEANY, NV12TORGB_SIMD, NV12TORGB_C, UV_SHIFT, BPP)             \
96     void NAMEANY(const uint8* y_buf,                                           \
97                  const uint8* uv_buf,                                          \
98                  uint8* rgb_buf,                                               \
99                  int width) {                                                  \
100       int n = width & ~7;                                                      \
101       NV12TORGB_SIMD(y_buf, uv_buf, rgb_buf, n);                               \
102       NV12TORGB_C(y_buf + n,                                                   \
103                   uv_buf + (n >> UV_SHIFT),                                    \
104                   rgb_buf + n * BPP, width & 7);                               \
105     }
106
107 #ifdef HAS_NV12TOARGBROW_SSSE3
108 NV2NY(NV12ToARGBRow_Any_SSSE3, NV12ToARGBRow_SSSE3, NV12ToARGBRow_C,
109       0, 4)
110 NV2NY(NV21ToARGBRow_Any_SSSE3, NV21ToARGBRow_SSSE3, NV21ToARGBRow_C,
111       0, 4)
112 #endif  // HAS_NV12TOARGBROW_SSSE3
113 #ifdef HAS_NV12TOARGBROW_NEON
114 NV2NY(NV12ToARGBRow_Any_NEON, NV12ToARGBRow_NEON, NV12ToARGBRow_C, 0, 4)
115 NV2NY(NV21ToARGBRow_Any_NEON, NV21ToARGBRow_NEON, NV21ToARGBRow_C, 0, 4)
116 #endif  // HAS_NV12TOARGBROW_NEON
117 #ifdef HAS_NV12TORGB565ROW_SSSE3
118 NV2NY(NV12ToRGB565Row_Any_SSSE3, NV12ToRGB565Row_SSSE3, NV12ToRGB565Row_C,
119       0, 2)
120 NV2NY(NV21ToRGB565Row_Any_SSSE3, NV21ToRGB565Row_SSSE3, NV21ToRGB565Row_C,
121       0, 2)
122 #endif  // HAS_NV12TORGB565ROW_SSSE3
123 #ifdef HAS_NV12TORGB565ROW_NEON
124 NV2NY(NV12ToRGB565Row_Any_NEON, NV12ToRGB565Row_NEON, NV12ToRGB565Row_C, 0, 2)
125 NV2NY(NV21ToRGB565Row_Any_NEON, NV21ToRGB565Row_NEON, NV21ToRGB565Row_C, 0, 2)
126 #endif  // HAS_NV12TORGB565ROW_NEON
127 #undef NVANY
128
129 #define RGBANY(NAMEANY, ARGBTORGB_SIMD, ARGBTORGB_C, MASK, SBPP, BPP)          \
130     void NAMEANY(const uint8* src,                                             \
131                  uint8* dst,                                                   \
132                  int width) {                                                  \
133       int n = width & ~MASK;                                                   \
134       ARGBTORGB_SIMD(src, dst, n);                                             \
135       ARGBTORGB_C(src + n * SBPP, dst + n * BPP, width & MASK);                \
136     }
137
138 #if defined(HAS_ARGBTORGB24ROW_SSSE3)
139 RGBANY(ARGBToRGB24Row_Any_SSSE3, ARGBToRGB24Row_SSSE3, ARGBToRGB24Row_C,
140        15, 4, 3)
141 RGBANY(ARGBToRAWRow_Any_SSSE3, ARGBToRAWRow_SSSE3, ARGBToRAWRow_C,
142        15, 4, 3)
143 RGBANY(ARGBToRGB565Row_Any_SSE2, ARGBToRGB565Row_SSE2, ARGBToRGB565Row_C,
144        3, 4, 2)
145 RGBANY(ARGBToARGB1555Row_Any_SSE2, ARGBToARGB1555Row_SSE2, ARGBToARGB1555Row_C,
146        3, 4, 2)
147 RGBANY(ARGBToARGB4444Row_Any_SSE2, ARGBToARGB4444Row_SSE2, ARGBToARGB4444Row_C,
148        3, 4, 2)
149 #endif
150 #if defined(HAS_I400TOARGBROW_SSE2)
151 RGBANY(I400ToARGBRow_Any_SSE2, I400ToARGBRow_SSE2, I400ToARGBRow_C,
152        7, 1, 4)
153 #endif
154 #if defined(HAS_YTOARGBROW_SSE2)
155 RGBANY(YToARGBRow_Any_SSE2, YToARGBRow_SSE2, YToARGBRow_C,
156        7, 1, 4)
157 RGBANY(YUY2ToARGBRow_Any_SSSE3, YUY2ToARGBRow_SSSE3, YUY2ToARGBRow_C,
158        15, 2, 4)
159 RGBANY(UYVYToARGBRow_Any_SSSE3, UYVYToARGBRow_SSSE3, UYVYToARGBRow_C,
160        15, 2, 4)
161 // These require alignment on ARGB, so C is used for remainder.
162 RGBANY(RGB24ToARGBRow_Any_SSSE3, RGB24ToARGBRow_SSSE3, RGB24ToARGBRow_C,
163        15, 3, 4)
164 RGBANY(RAWToARGBRow_Any_SSSE3, RAWToARGBRow_SSSE3, RAWToARGBRow_C,
165        15, 3, 4)
166 RGBANY(RGB565ToARGBRow_Any_SSE2, RGB565ToARGBRow_SSE2, RGB565ToARGBRow_C,
167        7, 2, 4)
168 RGBANY(ARGB1555ToARGBRow_Any_SSE2, ARGB1555ToARGBRow_SSE2, ARGB1555ToARGBRow_C,
169        7, 2, 4)
170 RGBANY(ARGB4444ToARGBRow_Any_SSE2, ARGB4444ToARGBRow_SSE2, ARGB4444ToARGBRow_C,
171        7, 2, 4)
172 #endif
173 #if defined(HAS_ARGBTORGB24ROW_NEON)
174 RGBANY(ARGBToRGB24Row_Any_NEON, ARGBToRGB24Row_NEON, ARGBToRGB24Row_C, 7, 4, 3)
175 RGBANY(ARGBToRAWRow_Any_NEON, ARGBToRAWRow_NEON, ARGBToRAWRow_C, 7, 4, 3)
176 RGBANY(ARGBToRGB565Row_Any_NEON, ARGBToRGB565Row_NEON, ARGBToRGB565Row_C,
177        7, 4, 2)
178 RGBANY(ARGBToARGB1555Row_Any_NEON, ARGBToARGB1555Row_NEON, ARGBToARGB1555Row_C,
179        7, 4, 2)
180 RGBANY(ARGBToARGB4444Row_Any_NEON, ARGBToARGB4444Row_NEON, ARGBToARGB4444Row_C,
181        7, 4, 2)
182 RGBANY(I400ToARGBRow_Any_NEON, I400ToARGBRow_NEON, I400ToARGBRow_C,
183        7, 1, 4)
184 RGBANY(YToARGBRow_Any_NEON, YToARGBRow_NEON, YToARGBRow_C,
185        7, 1, 4)
186 RGBANY(YUY2ToARGBRow_Any_NEON, YUY2ToARGBRow_NEON, YUY2ToARGBRow_C,
187        7, 2, 4)
188 RGBANY(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, UYVYToARGBRow_C,
189        7, 2, 4)
190 #endif
191 #undef RGBANY
192
193 // ARGB to Bayer does multiple of 4 pixels, SSSE3 aligned src, unaligned dst.
194 #define BAYERANY(NAMEANY, ARGBTORGB_SIMD, ARGBTORGB_C, MASK, SBPP, BPP)        \
195     void NAMEANY(const uint8* src,                                             \
196                  uint8* dst, uint32 selector,                                  \
197                  int width) {                                                  \
198       int n = width & ~MASK;                                                   \
199       ARGBTORGB_SIMD(src, dst, selector, n);                                   \
200       ARGBTORGB_C(src + n * SBPP, dst + n * BPP, selector, width & MASK);      \
201     }
202
203 #if defined(HAS_ARGBTOBAYERROW_SSSE3)
204 BAYERANY(ARGBToBayerRow_Any_SSSE3, ARGBToBayerRow_SSSE3, ARGBToBayerRow_C,
205          7, 4, 1)
206 #endif
207 #if defined(HAS_ARGBTOBAYERROW_NEON)
208 BAYERANY(ARGBToBayerRow_Any_NEON, ARGBToBayerRow_NEON, ARGBToBayerRow_C,
209          7, 4, 1)
210 #endif
211 #if defined(HAS_ARGBTOBAYERGGROW_SSE2)
212 BAYERANY(ARGBToBayerGGRow_Any_SSE2, ARGBToBayerGGRow_SSE2, ARGBToBayerGGRow_C,
213          7, 4, 1)
214 #endif
215 #if defined(HAS_ARGBTOBAYERGGROW_NEON)
216 BAYERANY(ARGBToBayerGGRow_Any_NEON, ARGBToBayerGGRow_NEON, ARGBToBayerGGRow_C,
217          7, 4, 1)
218 #endif
219
220 #undef BAYERANY
221
222 // RGB/YUV to Y does multiple of 16 with SIMD and last 16 with SIMD.
223 #define YANY(NAMEANY, ARGBTOY_SIMD, SBPP, BPP, NUM)                            \
224     void NAMEANY(const uint8* src_argb, uint8* dst_y, int width) {             \
225       ARGBTOY_SIMD(src_argb, dst_y, width - NUM);                              \
226       ARGBTOY_SIMD(src_argb + (width - NUM) * SBPP,                            \
227                    dst_y + (width - NUM) * BPP, NUM);                          \
228     }
229
230 #ifdef HAS_ARGBTOYROW_AVX2
231 YANY(ARGBToYRow_Any_AVX2, ARGBToYRow_AVX2, 4, 1, 32)
232 YANY(ARGBToYJRow_Any_AVX2, ARGBToYJRow_AVX2, 4, 1, 32)
233 YANY(YUY2ToYRow_Any_AVX2, YUY2ToYRow_AVX2, 2, 1, 32)
234 YANY(UYVYToYRow_Any_AVX2, UYVYToYRow_AVX2, 2, 1, 32)
235 #endif
236 #ifdef HAS_ARGBTOYROW_SSSE3
237 YANY(ARGBToYRow_Any_SSSE3, ARGBToYRow_SSSE3, 4, 1, 16)
238 #endif
239 #ifdef HAS_BGRATOYROW_SSSE3
240 YANY(BGRAToYRow_Any_SSSE3, BGRAToYRow_SSSE3, 4, 1, 16)
241 YANY(ABGRToYRow_Any_SSSE3, ABGRToYRow_SSSE3, 4, 1, 16)
242 YANY(RGBAToYRow_Any_SSSE3, RGBAToYRow_SSSE3, 4, 1, 16)
243 YANY(YUY2ToYRow_Any_SSE2, YUY2ToYRow_SSE2, 2, 1, 16)
244 YANY(UYVYToYRow_Any_SSE2, UYVYToYRow_SSE2, 2, 1, 16)
245 #endif
246 #ifdef HAS_ARGBTOYJROW_SSSE3
247 YANY(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_SSSE3, 4, 1, 16)
248 #endif
249 #ifdef HAS_ARGBTOYROW_NEON
250 YANY(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 4, 1, 8)
251 #endif
252 #ifdef HAS_ARGBTOYJROW_NEON
253 YANY(ARGBToYJRow_Any_NEON, ARGBToYJRow_NEON, 4, 1, 8)
254 #endif
255 #ifdef HAS_BGRATOYROW_NEON
256 YANY(BGRAToYRow_Any_NEON, BGRAToYRow_NEON, 4, 1, 8)
257 #endif
258 #ifdef HAS_ABGRTOYROW_NEON
259 YANY(ABGRToYRow_Any_NEON, ABGRToYRow_NEON, 4, 1, 8)
260 #endif
261 #ifdef HAS_RGBATOYROW_NEON
262 YANY(RGBAToYRow_Any_NEON, RGBAToYRow_NEON, 4, 1, 8)
263 #endif
264 #ifdef HAS_RGB24TOYROW_NEON
265 YANY(RGB24ToYRow_Any_NEON, RGB24ToYRow_NEON, 3, 1, 8)
266 #endif
267 #ifdef HAS_RAWTOYROW_NEON
268 YANY(RAWToYRow_Any_NEON, RAWToYRow_NEON, 3, 1, 8)
269 #endif
270 #ifdef HAS_RGB565TOYROW_NEON
271 YANY(RGB565ToYRow_Any_NEON, RGB565ToYRow_NEON, 2, 1, 8)
272 #endif
273 #ifdef HAS_ARGB1555TOYROW_NEON
274 YANY(ARGB1555ToYRow_Any_NEON, ARGB1555ToYRow_NEON, 2, 1, 8)
275 #endif
276 #ifdef HAS_ARGB4444TOYROW_NEON
277 YANY(ARGB4444ToYRow_Any_NEON, ARGB4444ToYRow_NEON, 2, 1, 8)
278 #endif
279 #ifdef HAS_YUY2TOYROW_NEON
280 YANY(YUY2ToYRow_Any_NEON, YUY2ToYRow_NEON, 2, 1, 16)
281 #endif
282 #ifdef HAS_UYVYTOYROW_NEON
283 YANY(UYVYToYRow_Any_NEON, UYVYToYRow_NEON, 2, 1, 16)
284 #endif
285 #ifdef HAS_RGB24TOARGBROW_NEON
286 YANY(RGB24ToARGBRow_Any_NEON, RGB24ToARGBRow_NEON, 3, 4, 8)
287 #endif
288 #ifdef HAS_RAWTOARGBROW_NEON
289 YANY(RAWToARGBRow_Any_NEON, RAWToARGBRow_NEON, 3, 4, 8)
290 #endif
291 #ifdef HAS_RGB565TOARGBROW_NEON
292 YANY(RGB565ToARGBRow_Any_NEON, RGB565ToARGBRow_NEON, 2, 4, 8)
293 #endif
294 #ifdef HAS_ARGB1555TOARGBROW_NEON
295 YANY(ARGB1555ToARGBRow_Any_NEON, ARGB1555ToARGBRow_NEON, 2, 4, 8)
296 #endif
297 #ifdef HAS_ARGB4444TOARGBROW_NEON
298 YANY(ARGB4444ToARGBRow_Any_NEON, ARGB4444ToARGBRow_NEON, 2, 4, 8)
299 #endif
300 #undef YANY
301
302 #define YANY(NAMEANY, ARGBTOY_SIMD, ARGBTOY_C, SBPP, BPP, MASK)                \
303     void NAMEANY(const uint8* src_argb, uint8* dst_y, int width) {             \
304       int n = width & ~MASK;                                                   \
305       ARGBTOY_SIMD(src_argb, dst_y, n);                                        \
306       ARGBTOY_C(src_argb + n * SBPP,                                           \
307                 dst_y  + n * BPP, width & MASK);                               \
308     }
309
310 // Attenuate is destructive so last16 method can not be used due to overlap.
311 #ifdef HAS_ARGBATTENUATEROW_SSSE3
312 YANY(ARGBAttenuateRow_Any_SSSE3, ARGBAttenuateRow_SSSE3, ARGBAttenuateRow_C,
313      4, 4, 3)
314 #endif
315 #ifdef HAS_ARGBATTENUATEROW_SSE2
316 YANY(ARGBAttenuateRow_Any_SSE2, ARGBAttenuateRow_SSE2, ARGBAttenuateRow_C,
317      4, 4, 3)
318 #endif
319 #ifdef HAS_ARGBUNATTENUATEROW_SSE2
320 YANY(ARGBUnattenuateRow_Any_SSE2, ARGBUnattenuateRow_SSE2, ARGBUnattenuateRow_C,
321      4, 4, 3)
322 #endif
323 #ifdef HAS_ARGBATTENUATEROW_AVX2
324 YANY(ARGBAttenuateRow_Any_AVX2, ARGBAttenuateRow_AVX2, ARGBAttenuateRow_C,
325      4, 4, 7)
326 #endif
327 #ifdef HAS_ARGBUNATTENUATEROW_AVX2
328 YANY(ARGBUnattenuateRow_Any_AVX2, ARGBUnattenuateRow_AVX2, ARGBUnattenuateRow_C,
329      4, 4, 7)
330 #endif
331 #ifdef HAS_ARGBATTENUATEROW_NEON
332 YANY(ARGBAttenuateRow_Any_NEON, ARGBAttenuateRow_NEON, ARGBAttenuateRow_C,
333      4, 4, 7)
334 #endif
335 #undef YANY
336
337 // RGB/YUV to UV does multiple of 16 with SIMD and remainder with C.
338 #define UVANY(NAMEANY, ANYTOUV_SIMD, ANYTOUV_C, BPP, MASK)                     \
339     void NAMEANY(const uint8* src_argb, int src_stride_argb,                   \
340                  uint8* dst_u, uint8* dst_v, int width) {                      \
341       int n = width & ~MASK;                                                   \
342       ANYTOUV_SIMD(src_argb, src_stride_argb, dst_u, dst_v, n);                \
343       ANYTOUV_C(src_argb  + n * BPP, src_stride_argb,                          \
344                 dst_u + (n >> 1),                                              \
345                 dst_v + (n >> 1),                                              \
346                 width & MASK);                                                 \
347     }
348
349 #ifdef HAS_ARGBTOUVROW_AVX2
350 UVANY(ARGBToUVRow_Any_AVX2, ARGBToUVRow_AVX2, ARGBToUVRow_C, 4, 31)
351 UVANY(YUY2ToUVRow_Any_AVX2, YUY2ToUVRow_AVX2, YUY2ToUVRow_C, 2, 31)
352 UVANY(UYVYToUVRow_Any_AVX2, UYVYToUVRow_AVX2, UYVYToUVRow_C, 2, 31)
353 #endif
354 #ifdef HAS_ARGBTOUVROW_SSSE3
355 UVANY(ARGBToUVRow_Any_SSSE3, ARGBToUVRow_SSSE3, ARGBToUVRow_C, 4, 15)
356 UVANY(ARGBToUVJRow_Any_SSSE3, ARGBToUVJRow_SSSE3, ARGBToUVJRow_C, 4, 15)
357 UVANY(BGRAToUVRow_Any_SSSE3, BGRAToUVRow_SSSE3, BGRAToUVRow_C, 4, 15)
358 UVANY(ABGRToUVRow_Any_SSSE3, ABGRToUVRow_SSSE3, ABGRToUVRow_C, 4, 15)
359 UVANY(RGBAToUVRow_Any_SSSE3, RGBAToUVRow_SSSE3, RGBAToUVRow_C, 4, 15)
360 #endif
361 #ifdef HAS_YUY2TOUVROW_SSE2
362 UVANY(YUY2ToUVRow_Any_SSE2, YUY2ToUVRow_SSE2, YUY2ToUVRow_C, 2, 15)
363 UVANY(UYVYToUVRow_Any_SSE2, UYVYToUVRow_SSE2, UYVYToUVRow_C, 2, 15)
364 #endif
365 #ifdef HAS_ARGBTOUVROW_NEON
366 UVANY(ARGBToUVRow_Any_NEON, ARGBToUVRow_NEON, ARGBToUVRow_C, 4, 15)
367 #endif
368 #ifdef HAS_ARGBTOUVJROW_NEON
369 UVANY(ARGBToUVJRow_Any_NEON, ARGBToUVJRow_NEON, ARGBToUVJRow_C, 4, 15)
370 #endif
371 #ifdef HAS_BGRATOUVROW_NEON
372 UVANY(BGRAToUVRow_Any_NEON, BGRAToUVRow_NEON, BGRAToUVRow_C, 4, 15)
373 #endif
374 #ifdef HAS_ABGRTOUVROW_NEON
375 UVANY(ABGRToUVRow_Any_NEON, ABGRToUVRow_NEON, ABGRToUVRow_C, 4, 15)
376 #endif
377 #ifdef HAS_RGBATOUVROW_NEON
378 UVANY(RGBAToUVRow_Any_NEON, RGBAToUVRow_NEON, RGBAToUVRow_C, 4, 15)
379 #endif
380 #ifdef HAS_RGB24TOUVROW_NEON
381 UVANY(RGB24ToUVRow_Any_NEON, RGB24ToUVRow_NEON, RGB24ToUVRow_C, 3, 15)
382 #endif
383 #ifdef HAS_RAWTOUVROW_NEON
384 UVANY(RAWToUVRow_Any_NEON, RAWToUVRow_NEON, RAWToUVRow_C, 3, 15)
385 #endif
386 #ifdef HAS_RGB565TOUVROW_NEON
387 UVANY(RGB565ToUVRow_Any_NEON, RGB565ToUVRow_NEON, RGB565ToUVRow_C, 2, 15)
388 #endif
389 #ifdef HAS_ARGB1555TOUVROW_NEON
390 UVANY(ARGB1555ToUVRow_Any_NEON, ARGB1555ToUVRow_NEON, ARGB1555ToUVRow_C, 2, 15)
391 #endif
392 #ifdef HAS_ARGB4444TOUVROW_NEON
393 UVANY(ARGB4444ToUVRow_Any_NEON, ARGB4444ToUVRow_NEON, ARGB4444ToUVRow_C, 2, 15)
394 #endif
395 #ifdef HAS_YUY2TOUVROW_NEON
396 UVANY(YUY2ToUVRow_Any_NEON, YUY2ToUVRow_NEON, YUY2ToUVRow_C, 2, 15)
397 #endif
398 #ifdef HAS_UYVYTOUVROW_NEON
399 UVANY(UYVYToUVRow_Any_NEON, UYVYToUVRow_NEON, UYVYToUVRow_C, 2, 15)
400 #endif
401 #undef UVANY
402
403 #define UV422ANY(NAMEANY, ANYTOUV_SIMD, ANYTOUV_C, BPP, MASK, SHIFT)           \
404     void NAMEANY(const uint8* src_uv,                                          \
405                  uint8* dst_u, uint8* dst_v, int width) {                      \
406       int n = width & ~MASK;                                                   \
407       ANYTOUV_SIMD(src_uv, dst_u, dst_v, n);                                   \
408       ANYTOUV_C(src_uv  + n * BPP,                                             \
409                 dst_u + (n >> SHIFT),                                          \
410                 dst_v + (n >> SHIFT),                                          \
411                 width & MASK);                                                 \
412     }
413
414 #ifdef HAS_ARGBTOUV444ROW_SSSE3
415 UV422ANY(ARGBToUV444Row_Any_SSSE3, ARGBToUV444Row_SSSE3,
416          ARGBToUV444Row_C, 4, 15, 0)
417 #endif
418 #ifdef HAS_YUY2TOUV422ROW_AVX2
419 UV422ANY(YUY2ToUV422Row_Any_AVX2, YUY2ToUV422Row_AVX2,
420          YUY2ToUV422Row_C, 2, 31, 1)
421 UV422ANY(UYVYToUV422Row_Any_AVX2, UYVYToUV422Row_AVX2,
422          UYVYToUV422Row_C, 2, 31, 1)
423 #endif
424 #ifdef HAS_ARGBTOUV422ROW_SSSE3
425 UV422ANY(ARGBToUV422Row_Any_SSSE3, ARGBToUV422Row_SSSE3,
426          ARGBToUV422Row_C, 4, 15, 1)
427 #endif
428 #ifdef HAS_YUY2TOUV422ROW_SSE2
429 UV422ANY(YUY2ToUV422Row_Any_SSE2, YUY2ToUV422Row_SSE2,
430          YUY2ToUV422Row_C, 2, 15, 1)
431 UV422ANY(UYVYToUV422Row_Any_SSE2, UYVYToUV422Row_SSE2,
432          UYVYToUV422Row_C, 2, 15, 1)
433 #endif
434 #ifdef HAS_YUY2TOUV422ROW_NEON
435 UV422ANY(ARGBToUV444Row_Any_NEON, ARGBToUV444Row_NEON,
436          ARGBToUV444Row_C, 4, 7, 0)
437 UV422ANY(ARGBToUV422Row_Any_NEON, ARGBToUV422Row_NEON,
438          ARGBToUV422Row_C, 4, 15, 1)
439 UV422ANY(ARGBToUV411Row_Any_NEON, ARGBToUV411Row_NEON,
440          ARGBToUV411Row_C, 4, 31, 2)
441 UV422ANY(YUY2ToUV422Row_Any_NEON, YUY2ToUV422Row_NEON,
442          YUY2ToUV422Row_C, 2, 15, 1)
443 UV422ANY(UYVYToUV422Row_Any_NEON, UYVYToUV422Row_NEON,
444          UYVYToUV422Row_C, 2, 15, 1)
445 #endif
446 #undef UV422ANY
447
448 #define SPLITUVROWANY(NAMEANY, ANYTOUV_SIMD, ANYTOUV_C, MASK)                  \
449     void NAMEANY(const uint8* src_uv,                                          \
450                  uint8* dst_u, uint8* dst_v, int width) {                      \
451       int n = width & ~MASK;                                                   \
452       ANYTOUV_SIMD(src_uv, dst_u, dst_v, n);                                   \
453       ANYTOUV_C(src_uv + n * 2,                                                \
454                 dst_u + n,                                                     \
455                 dst_v + n,                                                     \
456                 width & MASK);                                                 \
457     }
458
459 #ifdef HAS_SPLITUVROW_SSE2
460 SPLITUVROWANY(SplitUVRow_Any_SSE2, SplitUVRow_SSE2, SplitUVRow_C, 15)
461 #endif
462 #ifdef HAS_SPLITUVROW_AVX2
463 SPLITUVROWANY(SplitUVRow_Any_AVX2, SplitUVRow_AVX2, SplitUVRow_C, 31)
464 #endif
465 #ifdef HAS_SPLITUVROW_NEON
466 SPLITUVROWANY(SplitUVRow_Any_NEON, SplitUVRow_NEON, SplitUVRow_C, 15)
467 #endif
468 #ifdef HAS_SPLITUVROW_MIPS_DSPR2
469 SPLITUVROWANY(SplitUVRow_Any_MIPS_DSPR2, SplitUVRow_MIPS_DSPR2,
470               SplitUVRow_C, 15)
471 #endif
472 #undef SPLITUVROWANY
473
474 #define MERGEUVROW_ANY(NAMEANY, ANYTOUV_SIMD, ANYTOUV_C, MASK)                 \
475     void NAMEANY(const uint8* src_u, const uint8* src_v,                       \
476                  uint8* dst_uv, int width) {                                   \
477       int n = width & ~MASK;                                                   \
478       ANYTOUV_SIMD(src_u, src_v, dst_uv, n);                                   \
479       ANYTOUV_C(src_u + n,                                                     \
480                 src_v + n,                                                     \
481                 dst_uv + n * 2,                                                \
482                 width & MASK);                                                 \
483     }
484
485 #ifdef HAS_MERGEUVROW_SSE2
486 MERGEUVROW_ANY(MergeUVRow_Any_SSE2, MergeUVRow_SSE2, MergeUVRow_C, 15)
487 #endif
488 #ifdef HAS_MERGEUVROW_AVX2
489 MERGEUVROW_ANY(MergeUVRow_Any_AVX2, MergeUVRow_AVX2, MergeUVRow_C, 31)
490 #endif
491 #ifdef HAS_MERGEUVROW_NEON
492 MERGEUVROW_ANY(MergeUVRow_Any_NEON, MergeUVRow_NEON, MergeUVRow_C, 15)
493 #endif
494 #undef MERGEUVROW_ANY
495
496 #define MATHROW_ANY(NAMEANY, ARGBMATH_SIMD, ARGBMATH_C, MASK)                  \
497     void NAMEANY(const uint8* src_argb0, const uint8* src_argb1,               \
498                  uint8* dst_argb, int width) {                                 \
499       int n = width & ~MASK;                                                   \
500       ARGBMATH_SIMD(src_argb0, src_argb1, dst_argb, n);                        \
501       ARGBMATH_C(src_argb0 + n * 4,                                            \
502                  src_argb1 + n * 4,                                            \
503                  dst_argb + n * 4,                                             \
504                  width & MASK);                                                \
505     }
506
507 #ifdef HAS_ARGBMULTIPLYROW_SSE2
508 MATHROW_ANY(ARGBMultiplyRow_Any_SSE2, ARGBMultiplyRow_SSE2, ARGBMultiplyRow_C,
509             3)
510 #endif
511 #ifdef HAS_ARGBADDROW_SSE2
512 MATHROW_ANY(ARGBAddRow_Any_SSE2, ARGBAddRow_SSE2, ARGBAddRow_C, 3)
513 #endif
514 #ifdef HAS_ARGBSUBTRACTROW_SSE2
515 MATHROW_ANY(ARGBSubtractRow_Any_SSE2, ARGBSubtractRow_SSE2, ARGBSubtractRow_C,
516             3)
517 #endif
518 #ifdef HAS_ARGBMULTIPLYROW_AVX2
519 MATHROW_ANY(ARGBMultiplyRow_Any_AVX2, ARGBMultiplyRow_AVX2, ARGBMultiplyRow_C,
520             7)
521 #endif
522 #ifdef HAS_ARGBADDROW_AVX2
523 MATHROW_ANY(ARGBAddRow_Any_AVX2, ARGBAddRow_AVX2, ARGBAddRow_C, 7)
524 #endif
525 #ifdef HAS_ARGBSUBTRACTROW_AVX2
526 MATHROW_ANY(ARGBSubtractRow_Any_AVX2, ARGBSubtractRow_AVX2, ARGBSubtractRow_C,
527             7)
528 #endif
529 #ifdef HAS_ARGBMULTIPLYROW_NEON
530 MATHROW_ANY(ARGBMultiplyRow_Any_NEON, ARGBMultiplyRow_NEON, ARGBMultiplyRow_C,
531             7)
532 #endif
533 #ifdef HAS_ARGBADDROW_NEON
534 MATHROW_ANY(ARGBAddRow_Any_NEON, ARGBAddRow_NEON, ARGBAddRow_C, 7)
535 #endif
536 #ifdef HAS_ARGBSUBTRACTROW_NEON
537 MATHROW_ANY(ARGBSubtractRow_Any_NEON, ARGBSubtractRow_NEON, ARGBSubtractRow_C,
538             7)
539 #endif
540 #undef MATHROW_ANY
541
542 // Shuffle may want to work in place, so last16 method can not be used.
543 #define YANY(NAMEANY, ARGBTOY_SIMD, ARGBTOY_C, SBPP, BPP, MASK)                \
544     void NAMEANY(const uint8* src_argb, uint8* dst_argb,                       \
545                  const uint8* shuffler, int width) {                           \
546       int n = width & ~MASK;                                                   \
547       ARGBTOY_SIMD(src_argb, dst_argb, shuffler, n);                           \
548       ARGBTOY_C(src_argb + n * SBPP,                                           \
549                 dst_argb  + n * BPP, shuffler, width & MASK);                  \
550     }
551
552 #ifdef HAS_ARGBSHUFFLEROW_SSE2
553 YANY(ARGBShuffleRow_Any_SSE2, ARGBShuffleRow_SSE2,
554      ARGBShuffleRow_C, 4, 4, 3)
555 #endif
556 #ifdef HAS_ARGBSHUFFLEROW_SSSE3
557 YANY(ARGBShuffleRow_Any_SSSE3, ARGBShuffleRow_SSSE3,
558      ARGBShuffleRow_C, 4, 4, 7)
559 #endif
560 #ifdef HAS_ARGBSHUFFLEROW_AVX2
561 YANY(ARGBShuffleRow_Any_AVX2, ARGBShuffleRow_AVX2,
562      ARGBShuffleRow_C, 4, 4, 15)
563 #endif
564 #ifdef HAS_ARGBSHUFFLEROW_NEON
565 YANY(ARGBShuffleRow_Any_NEON, ARGBShuffleRow_NEON,
566      ARGBShuffleRow_C, 4, 4, 3)
567 #endif
568 #undef YANY
569
570 // Interpolate may want to work in place, so last16 method can not be used.
571 #define NANY(NAMEANY, TERP_SIMD, TERP_C, SBPP, BPP, MASK)                      \
572     void NAMEANY(uint8* dst_ptr, const uint8* src_ptr,                         \
573                  ptrdiff_t src_stride_ptr, int width,                          \
574                  int source_y_fraction) {                                      \
575       int n = width & ~MASK;                                                   \
576       TERP_SIMD(dst_ptr, src_ptr, src_stride_ptr,                              \
577                 n, source_y_fraction);                                         \
578       TERP_C(dst_ptr + n * BPP,                                                \
579              src_ptr + n * SBPP, src_stride_ptr,                               \
580              width & MASK, source_y_fraction);                                 \
581     }
582
583 #ifdef HAS_INTERPOLATEROW_AVX2
584 NANY(InterpolateRow_Any_AVX2, InterpolateRow_AVX2,
585      InterpolateRow_C, 1, 1, 32)
586 #endif
587 #ifdef HAS_INTERPOLATEROW_SSSE3
588 NANY(InterpolateRow_Any_SSSE3, InterpolateRow_SSSE3,
589      InterpolateRow_C, 1, 1, 15)
590 #endif
591 #ifdef HAS_INTERPOLATEROW_SSE2
592 NANY(InterpolateRow_Any_SSE2, InterpolateRow_SSE2,
593      InterpolateRow_C, 1, 1, 15)
594 #endif
595 #ifdef HAS_INTERPOLATEROW_NEON
596 NANY(InterpolateRow_Any_NEON, InterpolateRow_NEON,
597      InterpolateRow_C, 1, 1, 15)
598 #endif
599 #ifdef HAS_INTERPOLATEROW_MIPS_DSPR2
600 NANY(InterpolateRow_Any_MIPS_DSPR2, InterpolateRow_MIPS_DSPR2,
601      InterpolateRow_C, 1, 1, 3)
602 #endif
603 #undef NANY
604
605 #ifdef __cplusplus
606 }  // extern "C"
607 }  // namespace libyuv
608 #endif