1 /*
2 * Copyright 2011 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/convert_argb.h"
12
13 #include "libyuv/cpu_id.h"
14 #ifdef HAVE_JPEG
15 #include "libyuv/mjpeg_decoder.h"
16 #endif
17 #include "libyuv/planar_functions.h" // For CopyPlane and ARGBShuffle.
18 #include "libyuv/rotate_argb.h"
19 #include "libyuv/row.h"
20 #include "libyuv/video_common.h"
21
22 #ifdef __cplusplus
23 namespace libyuv {
24 extern "C" {
25 #endif
26
27 // Copy ARGB with optional flipping
28 LIBYUV_API
ARGBCopy(const uint8 * src_argb,int src_stride_argb,uint8 * dst_argb,int dst_stride_argb,int width,int height)29 int ARGBCopy(const uint8* src_argb,
30 int src_stride_argb,
31 uint8* dst_argb,
32 int dst_stride_argb,
33 int width,
34 int height) {
35 if (!src_argb || !dst_argb || width <= 0 || height == 0) {
36 return -1;
37 }
38 // Negative height means invert the image.
39 if (height < 0) {
40 height = -height;
41 src_argb = src_argb + (height - 1) * src_stride_argb;
42 src_stride_argb = -src_stride_argb;
43 }
44
45 CopyPlane(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width * 4,
46 height);
47 return 0;
48 }
49
50 // Convert I422 to ARGB with matrix
I420ToARGBMatrix(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,const struct YuvConstants * yuvconstants,int width,int height)51 static int I420ToARGBMatrix(const uint8* src_y,
52 int src_stride_y,
53 const uint8* src_u,
54 int src_stride_u,
55 const uint8* src_v,
56 int src_stride_v,
57 uint8* dst_argb,
58 int dst_stride_argb,
59 const struct YuvConstants* yuvconstants,
60 int width,
61 int height) {
62 int y;
63 void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf,
64 const uint8* v_buf, uint8* rgb_buf,
65 const struct YuvConstants* yuvconstants, int width) =
66 I422ToARGBRow_C;
67 if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) {
68 return -1;
69 }
70 // Negative height means invert the image.
71 if (height < 0) {
72 height = -height;
73 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
74 dst_stride_argb = -dst_stride_argb;
75 }
76 #if defined(HAS_I422TOARGBROW_SSSE3)
77 if (TestCpuFlag(kCpuHasSSSE3)) {
78 I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
79 if (IS_ALIGNED(width, 8)) {
80 I422ToARGBRow = I422ToARGBRow_SSSE3;
81 }
82 }
83 #endif
84 #if defined(HAS_I422TOARGBROW_AVX2)
85 if (TestCpuFlag(kCpuHasAVX2)) {
86 I422ToARGBRow = I422ToARGBRow_Any_AVX2;
87 if (IS_ALIGNED(width, 16)) {
88 I422ToARGBRow = I422ToARGBRow_AVX2;
89 }
90 }
91 #endif
92 #if defined(HAS_I422TOARGBROW_NEON)
93 if (TestCpuFlag(kCpuHasNEON)) {
94 I422ToARGBRow = I422ToARGBRow_Any_NEON;
95 if (IS_ALIGNED(width, 8)) {
96 I422ToARGBRow = I422ToARGBRow_NEON;
97 }
98 }
99 #endif
100 #if defined(HAS_I422TOARGBROW_DSPR2)
101 if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
102 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
103 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
104 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
105 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
106 I422ToARGBRow = I422ToARGBRow_DSPR2;
107 }
108 #endif
109 #if defined(HAS_I422TOARGBROW_MSA)
110 if (TestCpuFlag(kCpuHasMSA)) {
111 I422ToARGBRow = I422ToARGBRow_Any_MSA;
112 if (IS_ALIGNED(width, 8)) {
113 I422ToARGBRow = I422ToARGBRow_MSA;
114 }
115 }
116 #endif
117
118 for (y = 0; y < height; ++y) {
119 I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width);
120 dst_argb += dst_stride_argb;
121 src_y += src_stride_y;
122 if (y & 1) {
123 src_u += src_stride_u;
124 src_v += src_stride_v;
125 }
126 }
127 return 0;
128 }
129
130 // Convert I420 to ARGB.
131 LIBYUV_API
I420ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)132 int I420ToARGB(const uint8* src_y,
133 int src_stride_y,
134 const uint8* src_u,
135 int src_stride_u,
136 const uint8* src_v,
137 int src_stride_v,
138 uint8* dst_argb,
139 int dst_stride_argb,
140 int width,
141 int height) {
142 return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
143 src_stride_v, dst_argb, dst_stride_argb,
144 &kYuvI601Constants, width, height);
145 }
146
147 // Convert I420 to ABGR.
148 LIBYUV_API
I420ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)149 int I420ToABGR(const uint8* src_y,
150 int src_stride_y,
151 const uint8* src_u,
152 int src_stride_u,
153 const uint8* src_v,
154 int src_stride_v,
155 uint8* dst_abgr,
156 int dst_stride_abgr,
157 int width,
158 int height) {
159 return I420ToARGBMatrix(src_y, src_stride_y, src_v,
160 src_stride_v, // Swap U and V
161 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
162 &kYvuI601Constants, // Use Yvu matrix
163 width, height);
164 }
165
166 // Convert J420 to ARGB.
167 LIBYUV_API
J420ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)168 int J420ToARGB(const uint8* src_y,
169 int src_stride_y,
170 const uint8* src_u,
171 int src_stride_u,
172 const uint8* src_v,
173 int src_stride_v,
174 uint8* dst_argb,
175 int dst_stride_argb,
176 int width,
177 int height) {
178 return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
179 src_stride_v, dst_argb, dst_stride_argb,
180 &kYuvJPEGConstants, width, height);
181 }
182
183 // Convert J420 to ABGR.
184 LIBYUV_API
J420ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)185 int J420ToABGR(const uint8* src_y,
186 int src_stride_y,
187 const uint8* src_u,
188 int src_stride_u,
189 const uint8* src_v,
190 int src_stride_v,
191 uint8* dst_abgr,
192 int dst_stride_abgr,
193 int width,
194 int height) {
195 return I420ToARGBMatrix(src_y, src_stride_y, src_v,
196 src_stride_v, // Swap U and V
197 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
198 &kYvuJPEGConstants, // Use Yvu matrix
199 width, height);
200 }
201
202 // Convert H420 to ARGB.
203 LIBYUV_API
H420ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)204 int H420ToARGB(const uint8* src_y,
205 int src_stride_y,
206 const uint8* src_u,
207 int src_stride_u,
208 const uint8* src_v,
209 int src_stride_v,
210 uint8* dst_argb,
211 int dst_stride_argb,
212 int width,
213 int height) {
214 return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
215 src_stride_v, dst_argb, dst_stride_argb,
216 &kYuvH709Constants, width, height);
217 }
218
219 // Convert H420 to ABGR.
220 LIBYUV_API
H420ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)221 int H420ToABGR(const uint8* src_y,
222 int src_stride_y,
223 const uint8* src_u,
224 int src_stride_u,
225 const uint8* src_v,
226 int src_stride_v,
227 uint8* dst_abgr,
228 int dst_stride_abgr,
229 int width,
230 int height) {
231 return I420ToARGBMatrix(src_y, src_stride_y, src_v,
232 src_stride_v, // Swap U and V
233 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
234 &kYvuH709Constants, // Use Yvu matrix
235 width, height);
236 }
237
238 // Convert I422 to ARGB with matrix
I422ToARGBMatrix(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,const struct YuvConstants * yuvconstants,int width,int height)239 static int I422ToARGBMatrix(const uint8* src_y,
240 int src_stride_y,
241 const uint8* src_u,
242 int src_stride_u,
243 const uint8* src_v,
244 int src_stride_v,
245 uint8* dst_argb,
246 int dst_stride_argb,
247 const struct YuvConstants* yuvconstants,
248 int width,
249 int height) {
250 int y;
251 void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf,
252 const uint8* v_buf, uint8* rgb_buf,
253 const struct YuvConstants* yuvconstants, int width) =
254 I422ToARGBRow_C;
255 if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) {
256 return -1;
257 }
258 // Negative height means invert the image.
259 if (height < 0) {
260 height = -height;
261 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
262 dst_stride_argb = -dst_stride_argb;
263 }
264 // Coalesce rows.
265 if (src_stride_y == width && src_stride_u * 2 == width &&
266 src_stride_v * 2 == width && dst_stride_argb == width * 4) {
267 width *= height;
268 height = 1;
269 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
270 }
271 #if defined(HAS_I422TOARGBROW_SSSE3)
272 if (TestCpuFlag(kCpuHasSSSE3)) {
273 I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
274 if (IS_ALIGNED(width, 8)) {
275 I422ToARGBRow = I422ToARGBRow_SSSE3;
276 }
277 }
278 #endif
279 #if defined(HAS_I422TOARGBROW_AVX2)
280 if (TestCpuFlag(kCpuHasAVX2)) {
281 I422ToARGBRow = I422ToARGBRow_Any_AVX2;
282 if (IS_ALIGNED(width, 16)) {
283 I422ToARGBRow = I422ToARGBRow_AVX2;
284 }
285 }
286 #endif
287 #if defined(HAS_I422TOARGBROW_NEON)
288 if (TestCpuFlag(kCpuHasNEON)) {
289 I422ToARGBRow = I422ToARGBRow_Any_NEON;
290 if (IS_ALIGNED(width, 8)) {
291 I422ToARGBRow = I422ToARGBRow_NEON;
292 }
293 }
294 #endif
295 #if defined(HAS_I422TOARGBROW_DSPR2)
296 if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
297 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
298 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
299 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
300 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
301 I422ToARGBRow = I422ToARGBRow_DSPR2;
302 }
303 #endif
304 #if defined(HAS_I422TOARGBROW_MSA)
305 if (TestCpuFlag(kCpuHasMSA)) {
306 I422ToARGBRow = I422ToARGBRow_Any_MSA;
307 if (IS_ALIGNED(width, 8)) {
308 I422ToARGBRow = I422ToARGBRow_MSA;
309 }
310 }
311 #endif
312
313 for (y = 0; y < height; ++y) {
314 I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width);
315 dst_argb += dst_stride_argb;
316 src_y += src_stride_y;
317 src_u += src_stride_u;
318 src_v += src_stride_v;
319 }
320 return 0;
321 }
322
323 // Convert I422 to ARGB.
324 LIBYUV_API
I422ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)325 int I422ToARGB(const uint8* src_y,
326 int src_stride_y,
327 const uint8* src_u,
328 int src_stride_u,
329 const uint8* src_v,
330 int src_stride_v,
331 uint8* dst_argb,
332 int dst_stride_argb,
333 int width,
334 int height) {
335 return I422ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
336 src_stride_v, dst_argb, dst_stride_argb,
337 &kYuvI601Constants, width, height);
338 }
339
340 // Convert I422 to ABGR.
341 LIBYUV_API
I422ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)342 int I422ToABGR(const uint8* src_y,
343 int src_stride_y,
344 const uint8* src_u,
345 int src_stride_u,
346 const uint8* src_v,
347 int src_stride_v,
348 uint8* dst_abgr,
349 int dst_stride_abgr,
350 int width,
351 int height) {
352 return I422ToARGBMatrix(src_y, src_stride_y, src_v,
353 src_stride_v, // Swap U and V
354 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
355 &kYvuI601Constants, // Use Yvu matrix
356 width, height);
357 }
358
359 // Convert J422 to ARGB.
360 LIBYUV_API
J422ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)361 int J422ToARGB(const uint8* src_y,
362 int src_stride_y,
363 const uint8* src_u,
364 int src_stride_u,
365 const uint8* src_v,
366 int src_stride_v,
367 uint8* dst_argb,
368 int dst_stride_argb,
369 int width,
370 int height) {
371 return I422ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
372 src_stride_v, dst_argb, dst_stride_argb,
373 &kYuvJPEGConstants, width, height);
374 }
375
376 // Convert J422 to ABGR.
377 LIBYUV_API
J422ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)378 int J422ToABGR(const uint8* src_y,
379 int src_stride_y,
380 const uint8* src_u,
381 int src_stride_u,
382 const uint8* src_v,
383 int src_stride_v,
384 uint8* dst_abgr,
385 int dst_stride_abgr,
386 int width,
387 int height) {
388 return I422ToARGBMatrix(src_y, src_stride_y, src_v,
389 src_stride_v, // Swap U and V
390 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
391 &kYvuJPEGConstants, // Use Yvu matrix
392 width, height);
393 }
394
395 // Convert H422 to ARGB.
396 LIBYUV_API
H422ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)397 int H422ToARGB(const uint8* src_y,
398 int src_stride_y,
399 const uint8* src_u,
400 int src_stride_u,
401 const uint8* src_v,
402 int src_stride_v,
403 uint8* dst_argb,
404 int dst_stride_argb,
405 int width,
406 int height) {
407 return I422ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
408 src_stride_v, dst_argb, dst_stride_argb,
409 &kYuvH709Constants, width, height);
410 }
411
412 // Convert H422 to ABGR.
413 LIBYUV_API
H422ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)414 int H422ToABGR(const uint8* src_y,
415 int src_stride_y,
416 const uint8* src_u,
417 int src_stride_u,
418 const uint8* src_v,
419 int src_stride_v,
420 uint8* dst_abgr,
421 int dst_stride_abgr,
422 int width,
423 int height) {
424 return I422ToARGBMatrix(src_y, src_stride_y, src_v,
425 src_stride_v, // Swap U and V
426 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
427 &kYvuH709Constants, // Use Yvu matrix
428 width, height);
429 }
430
431 // Convert I444 to ARGB with matrix
I444ToARGBMatrix(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,const struct YuvConstants * yuvconstants,int width,int height)432 static int I444ToARGBMatrix(const uint8* src_y,
433 int src_stride_y,
434 const uint8* src_u,
435 int src_stride_u,
436 const uint8* src_v,
437 int src_stride_v,
438 uint8* dst_argb,
439 int dst_stride_argb,
440 const struct YuvConstants* yuvconstants,
441 int width,
442 int height) {
443 int y;
444 void (*I444ToARGBRow)(const uint8* y_buf, const uint8* u_buf,
445 const uint8* v_buf, uint8* rgb_buf,
446 const struct YuvConstants* yuvconstants, int width) =
447 I444ToARGBRow_C;
448 if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) {
449 return -1;
450 }
451 // Negative height means invert the image.
452 if (height < 0) {
453 height = -height;
454 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
455 dst_stride_argb = -dst_stride_argb;
456 }
457 // Coalesce rows.
458 if (src_stride_y == width && src_stride_u == width && src_stride_v == width &&
459 dst_stride_argb == width * 4) {
460 width *= height;
461 height = 1;
462 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
463 }
464 #if defined(HAS_I444TOARGBROW_SSSE3)
465 if (TestCpuFlag(kCpuHasSSSE3)) {
466 I444ToARGBRow = I444ToARGBRow_Any_SSSE3;
467 if (IS_ALIGNED(width, 8)) {
468 I444ToARGBRow = I444ToARGBRow_SSSE3;
469 }
470 }
471 #endif
472 #if defined(HAS_I444TOARGBROW_AVX2)
473 if (TestCpuFlag(kCpuHasAVX2)) {
474 I444ToARGBRow = I444ToARGBRow_Any_AVX2;
475 if (IS_ALIGNED(width, 16)) {
476 I444ToARGBRow = I444ToARGBRow_AVX2;
477 }
478 }
479 #endif
480 #if defined(HAS_I444TOARGBROW_NEON)
481 if (TestCpuFlag(kCpuHasNEON)) {
482 I444ToARGBRow = I444ToARGBRow_Any_NEON;
483 if (IS_ALIGNED(width, 8)) {
484 I444ToARGBRow = I444ToARGBRow_NEON;
485 }
486 }
487 #endif
488 #if defined(HAS_I444TOARGBROW_DSPR2)
489 if (TestCpuFlag(kCpuHasDSPR2)) {
490 I444ToARGBRow = I444ToARGBRow_Any_DSPR2;
491 if (IS_ALIGNED(width, 8)) {
492 I444ToARGBRow = I444ToARGBRow_DSPR2;
493 }
494 }
495 #endif
496 #if defined(HAS_I444TOARGBROW_MSA)
497 if (TestCpuFlag(kCpuHasMSA)) {
498 I444ToARGBRow = I444ToARGBRow_Any_MSA;
499 if (IS_ALIGNED(width, 8)) {
500 I444ToARGBRow = I444ToARGBRow_MSA;
501 }
502 }
503 #endif
504
505 for (y = 0; y < height; ++y) {
506 I444ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width);
507 dst_argb += dst_stride_argb;
508 src_y += src_stride_y;
509 src_u += src_stride_u;
510 src_v += src_stride_v;
511 }
512 return 0;
513 }
514
515 // Convert I444 to ARGB.
516 LIBYUV_API
I444ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)517 int I444ToARGB(const uint8* src_y,
518 int src_stride_y,
519 const uint8* src_u,
520 int src_stride_u,
521 const uint8* src_v,
522 int src_stride_v,
523 uint8* dst_argb,
524 int dst_stride_argb,
525 int width,
526 int height) {
527 return I444ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
528 src_stride_v, dst_argb, dst_stride_argb,
529 &kYuvI601Constants, width, height);
530 }
531
532 // Convert I444 to ABGR.
533 LIBYUV_API
I444ToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_abgr,int dst_stride_abgr,int width,int height)534 int I444ToABGR(const uint8* src_y,
535 int src_stride_y,
536 const uint8* src_u,
537 int src_stride_u,
538 const uint8* src_v,
539 int src_stride_v,
540 uint8* dst_abgr,
541 int dst_stride_abgr,
542 int width,
543 int height) {
544 return I444ToARGBMatrix(src_y, src_stride_y, src_v,
545 src_stride_v, // Swap U and V
546 src_u, src_stride_u, dst_abgr, dst_stride_abgr,
547 &kYvuI601Constants, // Use Yvu matrix
548 width, height);
549 }
550
551 // Convert J444 to ARGB.
552 LIBYUV_API
J444ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,uint8 * dst_argb,int dst_stride_argb,int width,int height)553 int J444ToARGB(const uint8* src_y,
554 int src_stride_y,
555 const uint8* src_u,
556 int src_stride_u,
557 const uint8* src_v,
558 int src_stride_v,
559 uint8* dst_argb,
560 int dst_stride_argb,
561 int width,
562 int height) {
563 return I444ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
564 src_stride_v, dst_argb, dst_stride_argb,
565 &kYuvJPEGConstants, width, height);
566 }
567
568 // Convert I420 with Alpha to preattenuated ARGB.
I420AlphaToARGBMatrix(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,const uint8 * src_a,int src_stride_a,uint8 * dst_argb,int dst_stride_argb,const struct YuvConstants * yuvconstants,int width,int height,int attenuate)569 static int I420AlphaToARGBMatrix(const uint8* src_y,
570 int src_stride_y,
571 const uint8* src_u,
572 int src_stride_u,
573 const uint8* src_v,
574 int src_stride_v,
575 const uint8* src_a,
576 int src_stride_a,
577 uint8* dst_argb,
578 int dst_stride_argb,
579 const struct YuvConstants* yuvconstants,
580 int width,
581 int height,
582 int attenuate) {
583 int y;
584 void (*I422AlphaToARGBRow)(const uint8* y_buf, const uint8* u_buf,
585 const uint8* v_buf, const uint8* a_buf,
586 uint8* dst_argb,
587 const struct YuvConstants* yuvconstants,
588 int width) = I422AlphaToARGBRow_C;
589 void (*ARGBAttenuateRow)(const uint8* src_argb, uint8* dst_argb, int width) =
590 ARGBAttenuateRow_C;
591 if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) {
592 return -1;
593 }
594 // Negative height means invert the image.
595 if (height < 0) {
596 height = -height;
597 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
598 dst_stride_argb = -dst_stride_argb;
599 }
600 #if defined(HAS_I422ALPHATOARGBROW_SSSE3)
601 if (TestCpuFlag(kCpuHasSSSE3)) {
602 I422AlphaToARGBRow = I422AlphaToARGBRow_Any_SSSE3;
603 if (IS_ALIGNED(width, 8)) {
604 I422AlphaToARGBRow = I422AlphaToARGBRow_SSSE3;
605 }
606 }
607 #endif
608 #if defined(HAS_I422ALPHATOARGBROW_AVX2)
609 if (TestCpuFlag(kCpuHasAVX2)) {
610 I422AlphaToARGBRow = I422AlphaToARGBRow_Any_AVX2;
611 if (IS_ALIGNED(width, 16)) {
612 I422AlphaToARGBRow = I422AlphaToARGBRow_AVX2;
613 }
614 }
615 #endif
616 #if defined(HAS_I422ALPHATOARGBROW_NEON)
617 if (TestCpuFlag(kCpuHasNEON)) {
618 I422AlphaToARGBRow = I422AlphaToARGBRow_Any_NEON;
619 if (IS_ALIGNED(width, 8)) {
620 I422AlphaToARGBRow = I422AlphaToARGBRow_NEON;
621 }
622 }
623 #endif
624 #if defined(HAS_I422ALPHATOARGBROW_DSPR2)
625 if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
626 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
627 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
628 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
629 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
630 I422AlphaToARGBRow = I422AlphaToARGBRow_DSPR2;
631 }
632 #endif
633 #if defined(HAS_I422ALPHATOARGBROW_MSA)
634 if (TestCpuFlag(kCpuHasMSA)) {
635 I422AlphaToARGBRow = I422AlphaToARGBRow_Any_MSA;
636 if (IS_ALIGNED(width, 8)) {
637 I422AlphaToARGBRow = I422AlphaToARGBRow_MSA;
638 }
639 }
640 #endif
641 #if defined(HAS_ARGBATTENUATEROW_SSSE3)
642 if (TestCpuFlag(kCpuHasSSSE3)) {
643 ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3;
644 if (IS_ALIGNED(width, 4)) {
645 ARGBAttenuateRow = ARGBAttenuateRow_SSSE3;
646 }
647 }
648 #endif
649 #if defined(HAS_ARGBATTENUATEROW_AVX2)
650 if (TestCpuFlag(kCpuHasAVX2)) {
651 ARGBAttenuateRow = ARGBAttenuateRow_Any_AVX2;
652 if (IS_ALIGNED(width, 8)) {
653 ARGBAttenuateRow = ARGBAttenuateRow_AVX2;
654 }
655 }
656 #endif
657 #if defined(HAS_ARGBATTENUATEROW_NEON)
658 if (TestCpuFlag(kCpuHasNEON)) {
659 ARGBAttenuateRow = ARGBAttenuateRow_Any_NEON;
660 if (IS_ALIGNED(width, 8)) {
661 ARGBAttenuateRow = ARGBAttenuateRow_NEON;
662 }
663 }
664 #endif
665 #if defined(HAS_ARGBATTENUATEROW_MSA)
666 if (TestCpuFlag(kCpuHasMSA)) {
667 ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA;
668 if (IS_ALIGNED(width, 8)) {
669 ARGBAttenuateRow = ARGBAttenuateRow_MSA;
670 }
671 }
672 #endif
673
674 for (y = 0; y < height; ++y) {
675 I422AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants,
676 width);
677 if (attenuate) {
678 ARGBAttenuateRow(dst_argb, dst_argb, width);
679 }
680 dst_argb += dst_stride_argb;
681 src_a += src_stride_a;
682 src_y += src_stride_y;
683 if (y & 1) {
684 src_u += src_stride_u;
685 src_v += src_stride_v;
686 }
687 }
688 return 0;
689 }
690
691 // Convert I420 with Alpha to ARGB.
692 LIBYUV_API
I420AlphaToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,const uint8 * src_a,int src_stride_a,uint8 * dst_argb,int dst_stride_argb,int width,int height,int attenuate)693 int I420AlphaToARGB(const uint8* src_y,
694 int src_stride_y,
695 const uint8* src_u,
696 int src_stride_u,
697 const uint8* src_v,
698 int src_stride_v,
699 const uint8* src_a,
700 int src_stride_a,
701 uint8* dst_argb,
702 int dst_stride_argb,
703 int width,
704 int height,
705 int attenuate) {
706 return I420AlphaToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
707 src_stride_v, src_a, src_stride_a, dst_argb,
708 dst_stride_argb, &kYuvI601Constants, width,
709 height, attenuate);
710 }
711
712 // Convert I420 with Alpha to ABGR.
713 LIBYUV_API
I420AlphaToABGR(const uint8 * src_y,int src_stride_y,const uint8 * src_u,int src_stride_u,const uint8 * src_v,int src_stride_v,const uint8 * src_a,int src_stride_a,uint8 * dst_abgr,int dst_stride_abgr,int width,int height,int attenuate)714 int I420AlphaToABGR(const uint8* src_y,
715 int src_stride_y,
716 const uint8* src_u,
717 int src_stride_u,
718 const uint8* src_v,
719 int src_stride_v,
720 const uint8* src_a,
721 int src_stride_a,
722 uint8* dst_abgr,
723 int dst_stride_abgr,
724 int width,
725 int height,
726 int attenuate) {
727 return I420AlphaToARGBMatrix(
728 src_y, src_stride_y, src_v, src_stride_v, // Swap U and V
729 src_u, src_stride_u, src_a, src_stride_a, dst_abgr, dst_stride_abgr,
730 &kYvuI601Constants, // Use Yvu matrix
731 width, height, attenuate);
732 }
733
734 // Convert I400 to ARGB.
735 LIBYUV_API
I400ToARGB(const uint8 * src_y,int src_stride_y,uint8 * dst_argb,int dst_stride_argb,int width,int height)736 int I400ToARGB(const uint8* src_y,
737 int src_stride_y,
738 uint8* dst_argb,
739 int dst_stride_argb,
740 int width,
741 int height) {
742 int y;
743 void (*I400ToARGBRow)(const uint8* y_buf, uint8* rgb_buf, int width) =
744 I400ToARGBRow_C;
745 if (!src_y || !dst_argb || width <= 0 || height == 0) {
746 return -1;
747 }
748 // Negative height means invert the image.
749 if (height < 0) {
750 height = -height;
751 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
752 dst_stride_argb = -dst_stride_argb;
753 }
754 // Coalesce rows.
755 if (src_stride_y == width && dst_stride_argb == width * 4) {
756 width *= height;
757 height = 1;
758 src_stride_y = dst_stride_argb = 0;
759 }
760 #if defined(HAS_I400TOARGBROW_SSE2)
761 if (TestCpuFlag(kCpuHasSSE2)) {
762 I400ToARGBRow = I400ToARGBRow_Any_SSE2;
763 if (IS_ALIGNED(width, 8)) {
764 I400ToARGBRow = I400ToARGBRow_SSE2;
765 }
766 }
767 #endif
768 #if defined(HAS_I400TOARGBROW_AVX2)
769 if (TestCpuFlag(kCpuHasAVX2)) {
770 I400ToARGBRow = I400ToARGBRow_Any_AVX2;
771 if (IS_ALIGNED(width, 16)) {
772 I400ToARGBRow = I400ToARGBRow_AVX2;
773 }
774 }
775 #endif
776 #if defined(HAS_I400TOARGBROW_NEON)
777 if (TestCpuFlag(kCpuHasNEON)) {
778 I400ToARGBRow = I400ToARGBRow_Any_NEON;
779 if (IS_ALIGNED(width, 8)) {
780 I400ToARGBRow = I400ToARGBRow_NEON;
781 }
782 }
783 #endif
784 #if defined(HAS_I400TOARGBROW_MSA)
785 if (TestCpuFlag(kCpuHasMSA)) {
786 I400ToARGBRow = I400ToARGBRow_Any_MSA;
787 if (IS_ALIGNED(width, 16)) {
788 I400ToARGBRow = I400ToARGBRow_MSA;
789 }
790 }
791 #endif
792
793 for (y = 0; y < height; ++y) {
794 I400ToARGBRow(src_y, dst_argb, width);
795 dst_argb += dst_stride_argb;
796 src_y += src_stride_y;
797 }
798 return 0;
799 }
800
801 // Convert J400 to ARGB.
802 LIBYUV_API
J400ToARGB(const uint8 * src_y,int src_stride_y,uint8 * dst_argb,int dst_stride_argb,int width,int height)803 int J400ToARGB(const uint8* src_y,
804 int src_stride_y,
805 uint8* dst_argb,
806 int dst_stride_argb,
807 int width,
808 int height) {
809 int y;
810 void (*J400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int width) =
811 J400ToARGBRow_C;
812 if (!src_y || !dst_argb || width <= 0 || height == 0) {
813 return -1;
814 }
815 // Negative height means invert the image.
816 if (height < 0) {
817 height = -height;
818 src_y = src_y + (height - 1) * src_stride_y;
819 src_stride_y = -src_stride_y;
820 }
821 // Coalesce rows.
822 if (src_stride_y == width && dst_stride_argb == width * 4) {
823 width *= height;
824 height = 1;
825 src_stride_y = dst_stride_argb = 0;
826 }
827 #if defined(HAS_J400TOARGBROW_SSE2)
828 if (TestCpuFlag(kCpuHasSSE2)) {
829 J400ToARGBRow = J400ToARGBRow_Any_SSE2;
830 if (IS_ALIGNED(width, 8)) {
831 J400ToARGBRow = J400ToARGBRow_SSE2;
832 }
833 }
834 #endif
835 #if defined(HAS_J400TOARGBROW_AVX2)
836 if (TestCpuFlag(kCpuHasAVX2)) {
837 J400ToARGBRow = J400ToARGBRow_Any_AVX2;
838 if (IS_ALIGNED(width, 16)) {
839 J400ToARGBRow = J400ToARGBRow_AVX2;
840 }
841 }
842 #endif
843 #if defined(HAS_J400TOARGBROW_NEON)
844 if (TestCpuFlag(kCpuHasNEON)) {
845 J400ToARGBRow = J400ToARGBRow_Any_NEON;
846 if (IS_ALIGNED(width, 8)) {
847 J400ToARGBRow = J400ToARGBRow_NEON;
848 }
849 }
850 #endif
851 #if defined(HAS_J400TOARGBROW_MSA)
852 if (TestCpuFlag(kCpuHasMSA)) {
853 J400ToARGBRow = J400ToARGBRow_Any_MSA;
854 if (IS_ALIGNED(width, 16)) {
855 J400ToARGBRow = J400ToARGBRow_MSA;
856 }
857 }
858 #endif
859 for (y = 0; y < height; ++y) {
860 J400ToARGBRow(src_y, dst_argb, width);
861 src_y += src_stride_y;
862 dst_argb += dst_stride_argb;
863 }
864 return 0;
865 }
866
867 // Shuffle table for converting BGRA to ARGB.
868 static uvec8 kShuffleMaskBGRAToARGB = {3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u,
869 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u};
870
871 // Shuffle table for converting ABGR to ARGB.
872 static uvec8 kShuffleMaskABGRToARGB = {2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u,
873 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u};
874
875 // Shuffle table for converting RGBA to ARGB.
876 static uvec8 kShuffleMaskRGBAToARGB = {1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u,
877 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u};
878
879 // Convert BGRA to ARGB.
880 LIBYUV_API
BGRAToARGB(const uint8 * src_bgra,int src_stride_bgra,uint8 * dst_argb,int dst_stride_argb,int width,int height)881 int BGRAToARGB(const uint8* src_bgra,
882 int src_stride_bgra,
883 uint8* dst_argb,
884 int dst_stride_argb,
885 int width,
886 int height) {
887 return ARGBShuffle(src_bgra, src_stride_bgra, dst_argb, dst_stride_argb,
888 (const uint8*)(&kShuffleMaskBGRAToARGB), width, height);
889 }
890
891 // Convert ARGB to BGRA (same as BGRAToARGB).
892 LIBYUV_API
ARGBToBGRA(const uint8 * src_bgra,int src_stride_bgra,uint8 * dst_argb,int dst_stride_argb,int width,int height)893 int ARGBToBGRA(const uint8* src_bgra,
894 int src_stride_bgra,
895 uint8* dst_argb,
896 int dst_stride_argb,
897 int width,
898 int height) {
899 return ARGBShuffle(src_bgra, src_stride_bgra, dst_argb, dst_stride_argb,
900 (const uint8*)(&kShuffleMaskBGRAToARGB), width, height);
901 }
902
903 // Convert ABGR to ARGB.
904 LIBYUV_API
ABGRToARGB(const uint8 * src_abgr,int src_stride_abgr,uint8 * dst_argb,int dst_stride_argb,int width,int height)905 int ABGRToARGB(const uint8* src_abgr,
906 int src_stride_abgr,
907 uint8* dst_argb,
908 int dst_stride_argb,
909 int width,
910 int height) {
911 return ARGBShuffle(src_abgr, src_stride_abgr, dst_argb, dst_stride_argb,
912 (const uint8*)(&kShuffleMaskABGRToARGB), width, height);
913 }
914
915 // Convert ARGB to ABGR to (same as ABGRToARGB).
916 LIBYUV_API
ARGBToABGR(const uint8 * src_abgr,int src_stride_abgr,uint8 * dst_argb,int dst_stride_argb,int width,int height)917 int ARGBToABGR(const uint8* src_abgr,
918 int src_stride_abgr,
919 uint8* dst_argb,
920 int dst_stride_argb,
921 int width,
922 int height) {
923 return ARGBShuffle(src_abgr, src_stride_abgr, dst_argb, dst_stride_argb,
924 (const uint8*)(&kShuffleMaskABGRToARGB), width, height);
925 }
926
927 // Convert RGBA to ARGB.
928 LIBYUV_API
RGBAToARGB(const uint8 * src_rgba,int src_stride_rgba,uint8 * dst_argb,int dst_stride_argb,int width,int height)929 int RGBAToARGB(const uint8* src_rgba,
930 int src_stride_rgba,
931 uint8* dst_argb,
932 int dst_stride_argb,
933 int width,
934 int height) {
935 return ARGBShuffle(src_rgba, src_stride_rgba, dst_argb, dst_stride_argb,
936 (const uint8*)(&kShuffleMaskRGBAToARGB), width, height);
937 }
938
939 // Convert RGB24 to ARGB.
940 LIBYUV_API
RGB24ToARGB(const uint8 * src_rgb24,int src_stride_rgb24,uint8 * dst_argb,int dst_stride_argb,int width,int height)941 int RGB24ToARGB(const uint8* src_rgb24,
942 int src_stride_rgb24,
943 uint8* dst_argb,
944 int dst_stride_argb,
945 int width,
946 int height) {
947 int y;
948 void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) =
949 RGB24ToARGBRow_C;
950 if (!src_rgb24 || !dst_argb || width <= 0 || height == 0) {
951 return -1;
952 }
953 // Negative height means invert the image.
954 if (height < 0) {
955 height = -height;
956 src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
957 src_stride_rgb24 = -src_stride_rgb24;
958 }
959 // Coalesce rows.
960 if (src_stride_rgb24 == width * 3 && dst_stride_argb == width * 4) {
961 width *= height;
962 height = 1;
963 src_stride_rgb24 = dst_stride_argb = 0;
964 }
965 #if defined(HAS_RGB24TOARGBROW_SSSE3)
966 if (TestCpuFlag(kCpuHasSSSE3)) {
967 RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3;
968 if (IS_ALIGNED(width, 16)) {
969 RGB24ToARGBRow = RGB24ToARGBRow_SSSE3;
970 }
971 }
972 #endif
973 #if defined(HAS_RGB24TOARGBROW_NEON)
974 if (TestCpuFlag(kCpuHasNEON)) {
975 RGB24ToARGBRow = RGB24ToARGBRow_Any_NEON;
976 if (IS_ALIGNED(width, 8)) {
977 RGB24ToARGBRow = RGB24ToARGBRow_NEON;
978 }
979 }
980 #endif
981 #if defined(HAS_RGB24TOARGBROW_DSPR2)
982 if (TestCpuFlag(kCpuHasDSPR2)) {
983 RGB24ToARGBRow = RGB24ToARGBRow_Any_DSPR2;
984 if (IS_ALIGNED(width, 8)) {
985 RGB24ToARGBRow = RGB24ToARGBRow_DSPR2;
986 }
987 }
988 #endif
989 #if defined(HAS_RGB24TOARGBROW_MSA)
990 if (TestCpuFlag(kCpuHasMSA)) {
991 RGB24ToARGBRow = RGB24ToARGBRow_Any_MSA;
992 if (IS_ALIGNED(width, 16)) {
993 RGB24ToARGBRow = RGB24ToARGBRow_MSA;
994 }
995 }
996 #endif
997
998 for (y = 0; y < height; ++y) {
999 RGB24ToARGBRow(src_rgb24, dst_argb, width);
1000 src_rgb24 += src_stride_rgb24;
1001 dst_argb += dst_stride_argb;
1002 }
1003 return 0;
1004 }
1005
1006 // Convert RAW to ARGB.
1007 LIBYUV_API
RAWToARGB(const uint8 * src_raw,int src_stride_raw,uint8 * dst_argb,int dst_stride_argb,int width,int height)1008 int RAWToARGB(const uint8* src_raw,
1009 int src_stride_raw,
1010 uint8* dst_argb,
1011 int dst_stride_argb,
1012 int width,
1013 int height) {
1014 int y;
1015 void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int width) =
1016 RAWToARGBRow_C;
1017 if (!src_raw || !dst_argb || width <= 0 || height == 0) {
1018 return -1;
1019 }
1020 // Negative height means invert the image.
1021 if (height < 0) {
1022 height = -height;
1023 src_raw = src_raw + (height - 1) * src_stride_raw;
1024 src_stride_raw = -src_stride_raw;
1025 }
1026 // Coalesce rows.
1027 if (src_stride_raw == width * 3 && dst_stride_argb == width * 4) {
1028 width *= height;
1029 height = 1;
1030 src_stride_raw = dst_stride_argb = 0;
1031 }
1032 #if defined(HAS_RAWTOARGBROW_SSSE3)
1033 if (TestCpuFlag(kCpuHasSSSE3)) {
1034 RAWToARGBRow = RAWToARGBRow_Any_SSSE3;
1035 if (IS_ALIGNED(width, 16)) {
1036 RAWToARGBRow = RAWToARGBRow_SSSE3;
1037 }
1038 }
1039 #endif
1040 #if defined(HAS_RAWTOARGBROW_NEON)
1041 if (TestCpuFlag(kCpuHasNEON)) {
1042 RAWToARGBRow = RAWToARGBRow_Any_NEON;
1043 if (IS_ALIGNED(width, 8)) {
1044 RAWToARGBRow = RAWToARGBRow_NEON;
1045 }
1046 }
1047 #endif
1048 #if defined(HAS_RAWTOARGBROW_DSPR2)
1049 if (TestCpuFlag(kCpuHasDSPR2)) {
1050 RAWToARGBRow = RAWToARGBRow_Any_DSPR2;
1051 if (IS_ALIGNED(width, 8)) {
1052 RAWToARGBRow = RAWToARGBRow_DSPR2;
1053 }
1054 }
1055 #endif
1056 #if defined(HAS_RAWTOARGBROW_MSA)
1057 if (TestCpuFlag(kCpuHasMSA)) {
1058 RAWToARGBRow = RAWToARGBRow_Any_MSA;
1059 if (IS_ALIGNED(width, 16)) {
1060 RAWToARGBRow = RAWToARGBRow_MSA;
1061 }
1062 }
1063 #endif
1064
1065 for (y = 0; y < height; ++y) {
1066 RAWToARGBRow(src_raw, dst_argb, width);
1067 src_raw += src_stride_raw;
1068 dst_argb += dst_stride_argb;
1069 }
1070 return 0;
1071 }
1072
1073 // Convert RGB565 to ARGB.
1074 LIBYUV_API
RGB565ToARGB(const uint8 * src_rgb565,int src_stride_rgb565,uint8 * dst_argb,int dst_stride_argb,int width,int height)1075 int RGB565ToARGB(const uint8* src_rgb565,
1076 int src_stride_rgb565,
1077 uint8* dst_argb,
1078 int dst_stride_argb,
1079 int width,
1080 int height) {
1081 int y;
1082 void (*RGB565ToARGBRow)(const uint8* src_rgb565, uint8* dst_argb, int width) =
1083 RGB565ToARGBRow_C;
1084 if (!src_rgb565 || !dst_argb || width <= 0 || height == 0) {
1085 return -1;
1086 }
1087 // Negative height means invert the image.
1088 if (height < 0) {
1089 height = -height;
1090 src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565;
1091 src_stride_rgb565 = -src_stride_rgb565;
1092 }
1093 // Coalesce rows.
1094 if (src_stride_rgb565 == width * 2 && dst_stride_argb == width * 4) {
1095 width *= height;
1096 height = 1;
1097 src_stride_rgb565 = dst_stride_argb = 0;
1098 }
1099 #if defined(HAS_RGB565TOARGBROW_SSE2)
1100 if (TestCpuFlag(kCpuHasSSE2)) {
1101 RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2;
1102 if (IS_ALIGNED(width, 8)) {
1103 RGB565ToARGBRow = RGB565ToARGBRow_SSE2;
1104 }
1105 }
1106 #endif
1107 #if defined(HAS_RGB565TOARGBROW_AVX2)
1108 if (TestCpuFlag(kCpuHasAVX2)) {
1109 RGB565ToARGBRow = RGB565ToARGBRow_Any_AVX2;
1110 if (IS_ALIGNED(width, 16)) {
1111 RGB565ToARGBRow = RGB565ToARGBRow_AVX2;
1112 }
1113 }
1114 #endif
1115 #if defined(HAS_RGB565TOARGBROW_NEON)
1116 if (TestCpuFlag(kCpuHasNEON)) {
1117 RGB565ToARGBRow = RGB565ToARGBRow_Any_NEON;
1118 if (IS_ALIGNED(width, 8)) {
1119 RGB565ToARGBRow = RGB565ToARGBRow_NEON;
1120 }
1121 }
1122 #endif
1123 #if defined(HAS_RGB565TOARGBROW_DSPR2)
1124 if (TestCpuFlag(kCpuHasDSPR2)) {
1125 RGB565ToARGBRow = RGB565ToARGBRow_Any_DSPR2;
1126 if (IS_ALIGNED(width, 8)) {
1127 RGB565ToARGBRow = RGB565ToARGBRow_DSPR2;
1128 }
1129 }
1130 #endif
1131 #if defined(HAS_RGB565TOARGBROW_MSA)
1132 if (TestCpuFlag(kCpuHasMSA)) {
1133 RGB565ToARGBRow = RGB565ToARGBRow_Any_MSA;
1134 if (IS_ALIGNED(width, 16)) {
1135 RGB565ToARGBRow = RGB565ToARGBRow_MSA;
1136 }
1137 }
1138 #endif
1139
1140 for (y = 0; y < height; ++y) {
1141 RGB565ToARGBRow(src_rgb565, dst_argb, width);
1142 src_rgb565 += src_stride_rgb565;
1143 dst_argb += dst_stride_argb;
1144 }
1145 return 0;
1146 }
1147
1148 // Convert ARGB1555 to ARGB.
1149 LIBYUV_API
ARGB1555ToARGB(const uint8 * src_argb1555,int src_stride_argb1555,uint8 * dst_argb,int dst_stride_argb,int width,int height)1150 int ARGB1555ToARGB(const uint8* src_argb1555,
1151 int src_stride_argb1555,
1152 uint8* dst_argb,
1153 int dst_stride_argb,
1154 int width,
1155 int height) {
1156 int y;
1157 void (*ARGB1555ToARGBRow)(const uint8* src_argb1555, uint8* dst_argb,
1158 int width) = ARGB1555ToARGBRow_C;
1159 if (!src_argb1555 || !dst_argb || width <= 0 || height == 0) {
1160 return -1;
1161 }
1162 // Negative height means invert the image.
1163 if (height < 0) {
1164 height = -height;
1165 src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555;
1166 src_stride_argb1555 = -src_stride_argb1555;
1167 }
1168 // Coalesce rows.
1169 if (src_stride_argb1555 == width * 2 && dst_stride_argb == width * 4) {
1170 width *= height;
1171 height = 1;
1172 src_stride_argb1555 = dst_stride_argb = 0;
1173 }
1174 #if defined(HAS_ARGB1555TOARGBROW_SSE2)
1175 if (TestCpuFlag(kCpuHasSSE2)) {
1176 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2;
1177 if (IS_ALIGNED(width, 8)) {
1178 ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2;
1179 }
1180 }
1181 #endif
1182 #if defined(HAS_ARGB1555TOARGBROW_AVX2)
1183 if (TestCpuFlag(kCpuHasAVX2)) {
1184 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_AVX2;
1185 if (IS_ALIGNED(width, 16)) {
1186 ARGB1555ToARGBRow = ARGB1555ToARGBRow_AVX2;
1187 }
1188 }
1189 #endif
1190 #if defined(HAS_ARGB1555TOARGBROW_NEON)
1191 if (TestCpuFlag(kCpuHasNEON)) {
1192 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_NEON;
1193 if (IS_ALIGNED(width, 8)) {
1194 ARGB1555ToARGBRow = ARGB1555ToARGBRow_NEON;
1195 }
1196 }
1197 #endif
1198 #if defined(HAS_ARGB1555TOARGBROW_DSPR2)
1199 if (TestCpuFlag(kCpuHasDSPR2)) {
1200 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_DSPR2;
1201 if (IS_ALIGNED(width, 4)) {
1202 ARGB1555ToARGBRow = ARGB1555ToARGBRow_DSPR2;
1203 }
1204 }
1205 #endif
1206 #if defined(HAS_ARGB1555TOARGBROW_MSA)
1207 if (TestCpuFlag(kCpuHasMSA)) {
1208 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_MSA;
1209 if (IS_ALIGNED(width, 16)) {
1210 ARGB1555ToARGBRow = ARGB1555ToARGBRow_MSA;
1211 }
1212 }
1213 #endif
1214
1215 for (y = 0; y < height; ++y) {
1216 ARGB1555ToARGBRow(src_argb1555, dst_argb, width);
1217 src_argb1555 += src_stride_argb1555;
1218 dst_argb += dst_stride_argb;
1219 }
1220 return 0;
1221 }
1222
1223 // Convert ARGB4444 to ARGB.
1224 LIBYUV_API
ARGB4444ToARGB(const uint8 * src_argb4444,int src_stride_argb4444,uint8 * dst_argb,int dst_stride_argb,int width,int height)1225 int ARGB4444ToARGB(const uint8* src_argb4444,
1226 int src_stride_argb4444,
1227 uint8* dst_argb,
1228 int dst_stride_argb,
1229 int width,
1230 int height) {
1231 int y;
1232 void (*ARGB4444ToARGBRow)(const uint8* src_argb4444, uint8* dst_argb,
1233 int width) = ARGB4444ToARGBRow_C;
1234 if (!src_argb4444 || !dst_argb || width <= 0 || height == 0) {
1235 return -1;
1236 }
1237 // Negative height means invert the image.
1238 if (height < 0) {
1239 height = -height;
1240 src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444;
1241 src_stride_argb4444 = -src_stride_argb4444;
1242 }
1243 // Coalesce rows.
1244 if (src_stride_argb4444 == width * 2 && dst_stride_argb == width * 4) {
1245 width *= height;
1246 height = 1;
1247 src_stride_argb4444 = dst_stride_argb = 0;
1248 }
1249 #if defined(HAS_ARGB4444TOARGBROW_SSE2)
1250 if (TestCpuFlag(kCpuHasSSE2)) {
1251 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2;
1252 if (IS_ALIGNED(width, 8)) {
1253 ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2;
1254 }
1255 }
1256 #endif
1257 #if defined(HAS_ARGB4444TOARGBROW_AVX2)
1258 if (TestCpuFlag(kCpuHasAVX2)) {
1259 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_AVX2;
1260 if (IS_ALIGNED(width, 16)) {
1261 ARGB4444ToARGBRow = ARGB4444ToARGBRow_AVX2;
1262 }
1263 }
1264 #endif
1265 #if defined(HAS_ARGB4444TOARGBROW_NEON)
1266 if (TestCpuFlag(kCpuHasNEON)) {
1267 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_NEON;
1268 if (IS_ALIGNED(width, 8)) {
1269 ARGB4444ToARGBRow = ARGB4444ToARGBRow_NEON;
1270 }
1271 }
1272 #endif
1273 #if defined(HAS_ARGB4444TOARGBROW_DSPR2)
1274 if (TestCpuFlag(kCpuHasDSPR2)) {
1275 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_DSPR2;
1276 if (IS_ALIGNED(width, 4)) {
1277 ARGB4444ToARGBRow = ARGB4444ToARGBRow_DSPR2;
1278 }
1279 }
1280 #endif
1281 #if defined(HAS_ARGB4444TOARGBROW_MSA)
1282 if (TestCpuFlag(kCpuHasMSA)) {
1283 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA;
1284 if (IS_ALIGNED(width, 16)) {
1285 ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA;
1286 }
1287 }
1288 #endif
1289
1290 for (y = 0; y < height; ++y) {
1291 ARGB4444ToARGBRow(src_argb4444, dst_argb, width);
1292 src_argb4444 += src_stride_argb4444;
1293 dst_argb += dst_stride_argb;
1294 }
1295 return 0;
1296 }
1297
1298 // Convert NV12 to ARGB.
1299 LIBYUV_API
NV12ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_uv,int src_stride_uv,uint8 * dst_argb,int dst_stride_argb,int width,int height)1300 int NV12ToARGB(const uint8* src_y,
1301 int src_stride_y,
1302 const uint8* src_uv,
1303 int src_stride_uv,
1304 uint8* dst_argb,
1305 int dst_stride_argb,
1306 int width,
1307 int height) {
1308 int y;
1309 void (*NV12ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf,
1310 const struct YuvConstants* yuvconstants, int width) =
1311 NV12ToARGBRow_C;
1312 if (!src_y || !src_uv || !dst_argb || width <= 0 || height == 0) {
1313 return -1;
1314 }
1315 // Negative height means invert the image.
1316 if (height < 0) {
1317 height = -height;
1318 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1319 dst_stride_argb = -dst_stride_argb;
1320 }
1321 #if defined(HAS_NV12TOARGBROW_SSSE3)
1322 if (TestCpuFlag(kCpuHasSSSE3)) {
1323 NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3;
1324 if (IS_ALIGNED(width, 8)) {
1325 NV12ToARGBRow = NV12ToARGBRow_SSSE3;
1326 }
1327 }
1328 #endif
1329 #if defined(HAS_NV12TOARGBROW_AVX2)
1330 if (TestCpuFlag(kCpuHasAVX2)) {
1331 NV12ToARGBRow = NV12ToARGBRow_Any_AVX2;
1332 if (IS_ALIGNED(width, 16)) {
1333 NV12ToARGBRow = NV12ToARGBRow_AVX2;
1334 }
1335 }
1336 #endif
1337 #if defined(HAS_NV12TOARGBROW_NEON)
1338 if (TestCpuFlag(kCpuHasNEON)) {
1339 NV12ToARGBRow = NV12ToARGBRow_Any_NEON;
1340 if (IS_ALIGNED(width, 8)) {
1341 NV12ToARGBRow = NV12ToARGBRow_NEON;
1342 }
1343 }
1344 #endif
1345 #if defined(HAS_NV12TOARGBROW_DSPR2)
1346 if (TestCpuFlag(kCpuHasDSPR2)) {
1347 NV12ToARGBRow = NV12ToARGBRow_Any_DSPR2;
1348 if (IS_ALIGNED(width, 8)) {
1349 NV12ToARGBRow = NV12ToARGBRow_DSPR2;
1350 }
1351 }
1352 #endif
1353 #if defined(HAS_NV12TOARGBROW_MSA)
1354 if (TestCpuFlag(kCpuHasMSA)) {
1355 NV12ToARGBRow = NV12ToARGBRow_Any_MSA;
1356 if (IS_ALIGNED(width, 8)) {
1357 NV12ToARGBRow = NV12ToARGBRow_MSA;
1358 }
1359 }
1360 #endif
1361
1362 for (y = 0; y < height; ++y) {
1363 NV12ToARGBRow(src_y, src_uv, dst_argb, &kYuvI601Constants, width);
1364 dst_argb += dst_stride_argb;
1365 src_y += src_stride_y;
1366 if (y & 1) {
1367 src_uv += src_stride_uv;
1368 }
1369 }
1370 return 0;
1371 }
1372
1373 // Convert NV21 to ARGB.
1374 LIBYUV_API
NV21ToARGB(const uint8 * src_y,int src_stride_y,const uint8 * src_uv,int src_stride_uv,uint8 * dst_argb,int dst_stride_argb,int width,int height)1375 int NV21ToARGB(const uint8* src_y,
1376 int src_stride_y,
1377 const uint8* src_uv,
1378 int src_stride_uv,
1379 uint8* dst_argb,
1380 int dst_stride_argb,
1381 int width,
1382 int height) {
1383 int y;
1384 void (*NV21ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf,
1385 const struct YuvConstants* yuvconstants, int width) =
1386 NV21ToARGBRow_C;
1387 if (!src_y || !src_uv || !dst_argb || width <= 0 || height == 0) {
1388 return -1;
1389 }
1390 // Negative height means invert the image.
1391 if (height < 0) {
1392 height = -height;
1393 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1394 dst_stride_argb = -dst_stride_argb;
1395 }
1396 #if defined(HAS_NV21TOARGBROW_SSSE3)
1397 if (TestCpuFlag(kCpuHasSSSE3)) {
1398 NV21ToARGBRow = NV21ToARGBRow_Any_SSSE3;
1399 if (IS_ALIGNED(width, 8)) {
1400 NV21ToARGBRow = NV21ToARGBRow_SSSE3;
1401 }
1402 }
1403 #endif
1404 #if defined(HAS_NV21TOARGBROW_AVX2)
1405 if (TestCpuFlag(kCpuHasAVX2)) {
1406 NV21ToARGBRow = NV21ToARGBRow_Any_AVX2;
1407 if (IS_ALIGNED(width, 16)) {
1408 NV21ToARGBRow = NV21ToARGBRow_AVX2;
1409 }
1410 }
1411 #endif
1412 #if defined(HAS_NV21TOARGBROW_NEON)
1413 if (TestCpuFlag(kCpuHasNEON)) {
1414 NV21ToARGBRow = NV21ToARGBRow_Any_NEON;
1415 if (IS_ALIGNED(width, 8)) {
1416 NV21ToARGBRow = NV21ToARGBRow_NEON;
1417 }
1418 }
1419 #endif
1420 #if defined(HAS_NV21TOARGBROW_MSA)
1421 if (TestCpuFlag(kCpuHasMSA)) {
1422 NV21ToARGBRow = NV21ToARGBRow_Any_MSA;
1423 if (IS_ALIGNED(width, 8)) {
1424 NV21ToARGBRow = NV21ToARGBRow_MSA;
1425 }
1426 }
1427 #endif
1428
1429 for (y = 0; y < height; ++y) {
1430 NV21ToARGBRow(src_y, src_uv, dst_argb, &kYuvI601Constants, width);
1431 dst_argb += dst_stride_argb;
1432 src_y += src_stride_y;
1433 if (y & 1) {
1434 src_uv += src_stride_uv;
1435 }
1436 }
1437 return 0;
1438 }
1439
1440 // Convert M420 to ARGB.
1441 LIBYUV_API
M420ToARGB(const uint8 * src_m420,int src_stride_m420,uint8 * dst_argb,int dst_stride_argb,int width,int height)1442 int M420ToARGB(const uint8* src_m420,
1443 int src_stride_m420,
1444 uint8* dst_argb,
1445 int dst_stride_argb,
1446 int width,
1447 int height) {
1448 int y;
1449 void (*NV12ToARGBRow)(const uint8* y_buf, const uint8* uv_buf, uint8* rgb_buf,
1450 const struct YuvConstants* yuvconstants, int width) =
1451 NV12ToARGBRow_C;
1452 if (!src_m420 || !dst_argb || width <= 0 || height == 0) {
1453 return -1;
1454 }
1455 // Negative height means invert the image.
1456 if (height < 0) {
1457 height = -height;
1458 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1459 dst_stride_argb = -dst_stride_argb;
1460 }
1461 #if defined(HAS_NV12TOARGBROW_SSSE3)
1462 if (TestCpuFlag(kCpuHasSSSE3)) {
1463 NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3;
1464 if (IS_ALIGNED(width, 8)) {
1465 NV12ToARGBRow = NV12ToARGBRow_SSSE3;
1466 }
1467 }
1468 #endif
1469 #if defined(HAS_NV12TOARGBROW_AVX2)
1470 if (TestCpuFlag(kCpuHasAVX2)) {
1471 NV12ToARGBRow = NV12ToARGBRow_Any_AVX2;
1472 if (IS_ALIGNED(width, 16)) {
1473 NV12ToARGBRow = NV12ToARGBRow_AVX2;
1474 }
1475 }
1476 #endif
1477 #if defined(HAS_NV12TOARGBROW_NEON)
1478 if (TestCpuFlag(kCpuHasNEON)) {
1479 NV12ToARGBRow = NV12ToARGBRow_Any_NEON;
1480 if (IS_ALIGNED(width, 8)) {
1481 NV12ToARGBRow = NV12ToARGBRow_NEON;
1482 }
1483 }
1484 #endif
1485 #if defined(HAS_NV12TOARGBROW_DSPR2)
1486 if (TestCpuFlag(kCpuHasDSPR2)) {
1487 NV12ToARGBRow = NV12ToARGBRow_Any_DSPR2;
1488 if (IS_ALIGNED(width, 8)) {
1489 NV12ToARGBRow = NV12ToARGBRow_DSPR2;
1490 }
1491 }
1492 #endif
1493 #if defined(HAS_NV12TOARGBROW_MSA)
1494 if (TestCpuFlag(kCpuHasMSA)) {
1495 NV12ToARGBRow = NV12ToARGBRow_Any_MSA;
1496 if (IS_ALIGNED(width, 8)) {
1497 NV12ToARGBRow = NV12ToARGBRow_MSA;
1498 }
1499 }
1500 #endif
1501
1502 for (y = 0; y < height - 1; y += 2) {
1503 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb,
1504 &kYuvI601Constants, width);
1505 NV12ToARGBRow(src_m420 + src_stride_m420, src_m420 + src_stride_m420 * 2,
1506 dst_argb + dst_stride_argb, &kYuvI601Constants, width);
1507 dst_argb += dst_stride_argb * 2;
1508 src_m420 += src_stride_m420 * 3;
1509 }
1510 if (height & 1) {
1511 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb,
1512 &kYuvI601Constants, width);
1513 }
1514 return 0;
1515 }
1516
1517 // Convert YUY2 to ARGB.
1518 LIBYUV_API
YUY2ToARGB(const uint8 * src_yuy2,int src_stride_yuy2,uint8 * dst_argb,int dst_stride_argb,int width,int height)1519 int YUY2ToARGB(const uint8* src_yuy2,
1520 int src_stride_yuy2,
1521 uint8* dst_argb,
1522 int dst_stride_argb,
1523 int width,
1524 int height) {
1525 int y;
1526 void (*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb,
1527 const struct YuvConstants* yuvconstants, int width) =
1528 YUY2ToARGBRow_C;
1529 if (!src_yuy2 || !dst_argb || width <= 0 || height == 0) {
1530 return -1;
1531 }
1532 // Negative height means invert the image.
1533 if (height < 0) {
1534 height = -height;
1535 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
1536 src_stride_yuy2 = -src_stride_yuy2;
1537 }
1538 // Coalesce rows.
1539 if (src_stride_yuy2 == width * 2 && dst_stride_argb == width * 4) {
1540 width *= height;
1541 height = 1;
1542 src_stride_yuy2 = dst_stride_argb = 0;
1543 }
1544 #if defined(HAS_YUY2TOARGBROW_SSSE3)
1545 if (TestCpuFlag(kCpuHasSSSE3)) {
1546 YUY2ToARGBRow = YUY2ToARGBRow_Any_SSSE3;
1547 if (IS_ALIGNED(width, 16)) {
1548 YUY2ToARGBRow = YUY2ToARGBRow_SSSE3;
1549 }
1550 }
1551 #endif
1552 #if defined(HAS_YUY2TOARGBROW_AVX2)
1553 if (TestCpuFlag(kCpuHasAVX2)) {
1554 YUY2ToARGBRow = YUY2ToARGBRow_Any_AVX2;
1555 if (IS_ALIGNED(width, 32)) {
1556 YUY2ToARGBRow = YUY2ToARGBRow_AVX2;
1557 }
1558 }
1559 #endif
1560 #if defined(HAS_YUY2TOARGBROW_NEON)
1561 if (TestCpuFlag(kCpuHasNEON)) {
1562 YUY2ToARGBRow = YUY2ToARGBRow_Any_NEON;
1563 if (IS_ALIGNED(width, 8)) {
1564 YUY2ToARGBRow = YUY2ToARGBRow_NEON;
1565 }
1566 }
1567 #endif
1568 #if defined(HAS_YUY2TOARGBROW_MSA)
1569 if (TestCpuFlag(kCpuHasMSA)) {
1570 YUY2ToARGBRow = YUY2ToARGBRow_Any_MSA;
1571 if (IS_ALIGNED(width, 8)) {
1572 YUY2ToARGBRow = YUY2ToARGBRow_MSA;
1573 }
1574 }
1575 #endif
1576 for (y = 0; y < height; ++y) {
1577 YUY2ToARGBRow(src_yuy2, dst_argb, &kYuvI601Constants, width);
1578 src_yuy2 += src_stride_yuy2;
1579 dst_argb += dst_stride_argb;
1580 }
1581 return 0;
1582 }
1583
1584 // Convert UYVY to ARGB.
1585 LIBYUV_API
UYVYToARGB(const uint8 * src_uyvy,int src_stride_uyvy,uint8 * dst_argb,int dst_stride_argb,int width,int height)1586 int UYVYToARGB(const uint8* src_uyvy,
1587 int src_stride_uyvy,
1588 uint8* dst_argb,
1589 int dst_stride_argb,
1590 int width,
1591 int height) {
1592 int y;
1593 void (*UYVYToARGBRow)(const uint8* src_uyvy, uint8* dst_argb,
1594 const struct YuvConstants* yuvconstants, int width) =
1595 UYVYToARGBRow_C;
1596 if (!src_uyvy || !dst_argb || width <= 0 || height == 0) {
1597 return -1;
1598 }
1599 // Negative height means invert the image.
1600 if (height < 0) {
1601 height = -height;
1602 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
1603 src_stride_uyvy = -src_stride_uyvy;
1604 }
1605 // Coalesce rows.
1606 if (src_stride_uyvy == width * 2 && dst_stride_argb == width * 4) {
1607 width *= height;
1608 height = 1;
1609 src_stride_uyvy = dst_stride_argb = 0;
1610 }
1611 #if defined(HAS_UYVYTOARGBROW_SSSE3)
1612 if (TestCpuFlag(kCpuHasSSSE3)) {
1613 UYVYToARGBRow = UYVYToARGBRow_Any_SSSE3;
1614 if (IS_ALIGNED(width, 16)) {
1615 UYVYToARGBRow = UYVYToARGBRow_SSSE3;
1616 }
1617 }
1618 #endif
1619 #if defined(HAS_UYVYTOARGBROW_AVX2)
1620 if (TestCpuFlag(kCpuHasAVX2)) {
1621 UYVYToARGBRow = UYVYToARGBRow_Any_AVX2;
1622 if (IS_ALIGNED(width, 32)) {
1623 UYVYToARGBRow = UYVYToARGBRow_AVX2;
1624 }
1625 }
1626 #endif
1627 #if defined(HAS_UYVYTOARGBROW_NEON)
1628 if (TestCpuFlag(kCpuHasNEON)) {
1629 UYVYToARGBRow = UYVYToARGBRow_Any_NEON;
1630 if (IS_ALIGNED(width, 8)) {
1631 UYVYToARGBRow = UYVYToARGBRow_NEON;
1632 }
1633 }
1634 #endif
1635 #if defined(HAS_UYVYTOARGBROW_MSA)
1636 if (TestCpuFlag(kCpuHasMSA)) {
1637 UYVYToARGBRow = UYVYToARGBRow_Any_MSA;
1638 if (IS_ALIGNED(width, 8)) {
1639 UYVYToARGBRow = UYVYToARGBRow_MSA;
1640 }
1641 }
1642 #endif
1643 for (y = 0; y < height; ++y) {
1644 UYVYToARGBRow(src_uyvy, dst_argb, &kYuvI601Constants, width);
1645 src_uyvy += src_stride_uyvy;
1646 dst_argb += dst_stride_argb;
1647 }
1648 return 0;
1649 }
1650
1651 #ifdef __cplusplus
1652 } // extern "C"
1653 } // namespace libyuv
1654 #endif
1655