2 * Copyright 2011 The LibYuv Project Authors. All rights reserved.
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.
11 #include "libyuv/convert_argb.h"
13 #include "libyuv/cpu_id.h"
15 #include "libyuv/mjpeg_decoder.h"
17 #include "libyuv/rotate_argb.h"
18 #include "libyuv/row.h"
19 #include "libyuv/video_common.h"
26 // Copy ARGB with optional flipping
28 int ARGBCopy(const uint8* src_argb, int src_stride_argb,
29 uint8* dst_argb, int dst_stride_argb,
30 int width, int height) {
31 if (!src_argb || !dst_argb ||
32 width <= 0 || height == 0) {
35 // Negative height means invert the image.
38 src_argb = src_argb + (height - 1) * src_stride_argb;
39 src_stride_argb = -src_stride_argb;
42 CopyPlane(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
47 // Convert I444 to ARGB.
49 int I444ToARGB(const uint8* src_y, int src_stride_y,
50 const uint8* src_u, int src_stride_u,
51 const uint8* src_v, int src_stride_v,
52 uint8* dst_argb, int dst_stride_argb,
53 int width, int height) {
55 void (*I444ToARGBRow)(const uint8* y_buf,
59 int width) = I444ToARGBRow_C;
60 if (!src_y || !src_u || !src_v ||
62 width <= 0 || height == 0) {
65 // Negative height means invert the image.
68 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
69 dst_stride_argb = -dst_stride_argb;
72 if (src_stride_y == width &&
73 src_stride_u == width &&
74 src_stride_v == width &&
75 dst_stride_argb == width * 4) {
78 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
80 #if defined(HAS_I444TOARGBROW_SSSE3)
81 if (TestCpuFlag(kCpuHasSSSE3)) {
82 I444ToARGBRow = I444ToARGBRow_Any_SSSE3;
83 if (IS_ALIGNED(width, 8)) {
84 I444ToARGBRow = I444ToARGBRow_SSSE3;
88 #if defined(HAS_I444TOARGBROW_AVX2)
89 if (TestCpuFlag(kCpuHasAVX2)) {
90 I444ToARGBRow = I444ToARGBRow_Any_AVX2;
91 if (IS_ALIGNED(width, 16)) {
92 I444ToARGBRow = I444ToARGBRow_AVX2;
96 #if defined(HAS_I444TOARGBROW_NEON)
97 if (TestCpuFlag(kCpuHasNEON)) {
98 I444ToARGBRow = I444ToARGBRow_Any_NEON;
99 if (IS_ALIGNED(width, 8)) {
100 I444ToARGBRow = I444ToARGBRow_NEON;
105 for (y = 0; y < height; ++y) {
106 I444ToARGBRow(src_y, src_u, src_v, dst_argb, width);
107 dst_argb += dst_stride_argb;
108 src_y += src_stride_y;
109 src_u += src_stride_u;
110 src_v += src_stride_v;
115 // Convert I422 to ARGB.
117 int I422ToARGB(const uint8* src_y, int src_stride_y,
118 const uint8* src_u, int src_stride_u,
119 const uint8* src_v, int src_stride_v,
120 uint8* dst_argb, int dst_stride_argb,
121 int width, int height) {
123 void (*I422ToARGBRow)(const uint8* y_buf,
127 int width) = I422ToARGBRow_C;
128 if (!src_y || !src_u || !src_v ||
130 width <= 0 || height == 0) {
133 // Negative height means invert the image.
136 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
137 dst_stride_argb = -dst_stride_argb;
140 if (src_stride_y == width &&
141 src_stride_u * 2 == width &&
142 src_stride_v * 2 == width &&
143 dst_stride_argb == width * 4) {
146 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
148 #if defined(HAS_I422TOARGBROW_SSSE3)
149 if (TestCpuFlag(kCpuHasSSSE3)) {
150 I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
151 if (IS_ALIGNED(width, 8)) {
152 I422ToARGBRow = I422ToARGBRow_SSSE3;
156 #if defined(HAS_I422TOARGBROW_AVX2)
157 if (TestCpuFlag(kCpuHasAVX2)) {
158 I422ToARGBRow = I422ToARGBRow_Any_AVX2;
159 if (IS_ALIGNED(width, 16)) {
160 I422ToARGBRow = I422ToARGBRow_AVX2;
164 #if defined(HAS_I422TOARGBROW_NEON)
165 if (TestCpuFlag(kCpuHasNEON)) {
166 I422ToARGBRow = I422ToARGBRow_Any_NEON;
167 if (IS_ALIGNED(width, 8)) {
168 I422ToARGBRow = I422ToARGBRow_NEON;
172 #if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
173 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
174 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
175 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
176 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
177 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
178 I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
182 for (y = 0; y < height; ++y) {
183 I422ToARGBRow(src_y, src_u, src_v, dst_argb, width);
184 dst_argb += dst_stride_argb;
185 src_y += src_stride_y;
186 src_u += src_stride_u;
187 src_v += src_stride_v;
192 // Convert I411 to ARGB.
194 int I411ToARGB(const uint8* src_y, int src_stride_y,
195 const uint8* src_u, int src_stride_u,
196 const uint8* src_v, int src_stride_v,
197 uint8* dst_argb, int dst_stride_argb,
198 int width, int height) {
200 void (*I411ToARGBRow)(const uint8* y_buf,
204 int width) = I411ToARGBRow_C;
205 if (!src_y || !src_u || !src_v ||
207 width <= 0 || height == 0) {
210 // Negative height means invert the image.
213 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
214 dst_stride_argb = -dst_stride_argb;
217 if (src_stride_y == width &&
218 src_stride_u * 4 == width &&
219 src_stride_v * 4 == width &&
220 dst_stride_argb == width * 4) {
223 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
225 #if defined(HAS_I411TOARGBROW_SSSE3)
226 if (TestCpuFlag(kCpuHasSSSE3)) {
227 I411ToARGBRow = I411ToARGBRow_Any_SSSE3;
228 if (IS_ALIGNED(width, 8)) {
229 I411ToARGBRow = I411ToARGBRow_SSSE3;
233 #if defined(HAS_I411TOARGBROW_AVX2)
234 if (TestCpuFlag(kCpuHasAVX2)) {
235 I411ToARGBRow = I411ToARGBRow_Any_AVX2;
236 if (IS_ALIGNED(width, 16)) {
237 I411ToARGBRow = I411ToARGBRow_AVX2;
241 #if defined(HAS_I411TOARGBROW_NEON)
242 if (TestCpuFlag(kCpuHasNEON)) {
243 I411ToARGBRow = I411ToARGBRow_Any_NEON;
244 if (IS_ALIGNED(width, 8)) {
245 I411ToARGBRow = I411ToARGBRow_NEON;
250 for (y = 0; y < height; ++y) {
251 I411ToARGBRow(src_y, src_u, src_v, dst_argb, width);
252 dst_argb += dst_stride_argb;
253 src_y += src_stride_y;
254 src_u += src_stride_u;
255 src_v += src_stride_v;
260 // Convert I400 to ARGB.
262 int I400ToARGB(const uint8* src_y, int src_stride_y,
263 uint8* dst_argb, int dst_stride_argb,
264 int width, int height) {
266 void (*I400ToARGBRow)(const uint8* y_buf,
268 int width) = I400ToARGBRow_C;
269 if (!src_y || !dst_argb ||
270 width <= 0 || height == 0) {
273 // Negative height means invert the image.
276 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
277 dst_stride_argb = -dst_stride_argb;
280 if (src_stride_y == width &&
281 dst_stride_argb == width * 4) {
284 src_stride_y = dst_stride_argb = 0;
286 #if defined(HAS_I400TOARGBROW_SSE2)
287 if (TestCpuFlag(kCpuHasSSE2)) {
288 I400ToARGBRow = I400ToARGBRow_Any_SSE2;
289 if (IS_ALIGNED(width, 8)) {
290 I400ToARGBRow = I400ToARGBRow_SSE2;
294 #if defined(HAS_I400TOARGBROW_AVX2)
295 if (TestCpuFlag(kCpuHasAVX2)) {
296 I400ToARGBRow = I400ToARGBRow_Any_AVX2;
297 if (IS_ALIGNED(width, 16)) {
298 I400ToARGBRow = I400ToARGBRow_AVX2;
302 #if defined(HAS_I400TOARGBROW_NEON)
303 if (TestCpuFlag(kCpuHasNEON)) {
304 I400ToARGBRow = I400ToARGBRow_Any_NEON;
305 if (IS_ALIGNED(width, 8)) {
306 I400ToARGBRow = I400ToARGBRow_NEON;
311 for (y = 0; y < height; ++y) {
312 I400ToARGBRow(src_y, dst_argb, width);
313 dst_argb += dst_stride_argb;
314 src_y += src_stride_y;
319 // Convert J400 to ARGB.
321 int J400ToARGB(const uint8* src_y, int src_stride_y,
322 uint8* dst_argb, int dst_stride_argb,
323 int width, int height) {
325 void (*J400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix) =
327 if (!src_y || !dst_argb ||
328 width <= 0 || height == 0) {
331 // Negative height means invert the image.
334 src_y = src_y + (height - 1) * src_stride_y;
335 src_stride_y = -src_stride_y;
338 if (src_stride_y == width &&
339 dst_stride_argb == width * 4) {
342 src_stride_y = dst_stride_argb = 0;
344 #if defined(HAS_J400TOARGBROW_SSE2)
345 if (TestCpuFlag(kCpuHasSSE2)) {
346 J400ToARGBRow = J400ToARGBRow_Any_SSE2;
347 if (IS_ALIGNED(width, 8)) {
348 J400ToARGBRow = J400ToARGBRow_SSE2;
352 #if defined(HAS_J400TOARGBROW_AVX2)
353 if (TestCpuFlag(kCpuHasAVX2)) {
354 J400ToARGBRow = J400ToARGBRow_Any_AVX2;
355 if (IS_ALIGNED(width, 16)) {
356 J400ToARGBRow = J400ToARGBRow_AVX2;
360 #if defined(HAS_J400TOARGBROW_NEON)
361 if (TestCpuFlag(kCpuHasNEON)) {
362 J400ToARGBRow = J400ToARGBRow_Any_NEON;
363 if (IS_ALIGNED(width, 8)) {
364 J400ToARGBRow = J400ToARGBRow_NEON;
368 for (y = 0; y < height; ++y) {
369 J400ToARGBRow(src_y, dst_argb, width);
370 src_y += src_stride_y;
371 dst_argb += dst_stride_argb;
376 // Shuffle table for converting BGRA to ARGB.
377 static uvec8 kShuffleMaskBGRAToARGB = {
378 3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u, 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u
381 // Shuffle table for converting ABGR to ARGB.
382 static uvec8 kShuffleMaskABGRToARGB = {
383 2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u, 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u
386 // Shuffle table for converting RGBA to ARGB.
387 static uvec8 kShuffleMaskRGBAToARGB = {
388 1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u, 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u
391 // Convert BGRA to ARGB.
393 int BGRAToARGB(const uint8* src_bgra, int src_stride_bgra,
394 uint8* dst_argb, int dst_stride_argb,
395 int width, int height) {
396 return ARGBShuffle(src_bgra, src_stride_bgra,
397 dst_argb, dst_stride_argb,
398 (const uint8*)(&kShuffleMaskBGRAToARGB),
402 // Convert ARGB to BGRA (same as BGRAToARGB).
404 int ARGBToBGRA(const uint8* src_bgra, int src_stride_bgra,
405 uint8* dst_argb, int dst_stride_argb,
406 int width, int height) {
407 return ARGBShuffle(src_bgra, src_stride_bgra,
408 dst_argb, dst_stride_argb,
409 (const uint8*)(&kShuffleMaskBGRAToARGB),
413 // Convert ABGR to ARGB.
415 int ABGRToARGB(const uint8* src_abgr, int src_stride_abgr,
416 uint8* dst_argb, int dst_stride_argb,
417 int width, int height) {
418 return ARGBShuffle(src_abgr, src_stride_abgr,
419 dst_argb, dst_stride_argb,
420 (const uint8*)(&kShuffleMaskABGRToARGB),
424 // Convert ARGB to ABGR to (same as ABGRToARGB).
426 int ARGBToABGR(const uint8* src_abgr, int src_stride_abgr,
427 uint8* dst_argb, int dst_stride_argb,
428 int width, int height) {
429 return ARGBShuffle(src_abgr, src_stride_abgr,
430 dst_argb, dst_stride_argb,
431 (const uint8*)(&kShuffleMaskABGRToARGB),
435 // Convert RGBA to ARGB.
437 int RGBAToARGB(const uint8* src_rgba, int src_stride_rgba,
438 uint8* dst_argb, int dst_stride_argb,
439 int width, int height) {
440 return ARGBShuffle(src_rgba, src_stride_rgba,
441 dst_argb, dst_stride_argb,
442 (const uint8*)(&kShuffleMaskRGBAToARGB),
446 // Convert RGB24 to ARGB.
448 int RGB24ToARGB(const uint8* src_rgb24, int src_stride_rgb24,
449 uint8* dst_argb, int dst_stride_argb,
450 int width, int height) {
452 void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) =
454 if (!src_rgb24 || !dst_argb ||
455 width <= 0 || height == 0) {
458 // Negative height means invert the image.
461 src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
462 src_stride_rgb24 = -src_stride_rgb24;
465 if (src_stride_rgb24 == width * 3 &&
466 dst_stride_argb == width * 4) {
469 src_stride_rgb24 = dst_stride_argb = 0;
471 #if defined(HAS_RGB24TOARGBROW_SSSE3)
472 if (TestCpuFlag(kCpuHasSSSE3)) {
473 RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3;
474 if (IS_ALIGNED(width, 16)) {
475 RGB24ToARGBRow = RGB24ToARGBRow_SSSE3;
479 #if defined(HAS_RGB24TOARGBROW_NEON)
480 if (TestCpuFlag(kCpuHasNEON)) {
481 RGB24ToARGBRow = RGB24ToARGBRow_Any_NEON;
482 if (IS_ALIGNED(width, 8)) {
483 RGB24ToARGBRow = RGB24ToARGBRow_NEON;
488 for (y = 0; y < height; ++y) {
489 RGB24ToARGBRow(src_rgb24, dst_argb, width);
490 src_rgb24 += src_stride_rgb24;
491 dst_argb += dst_stride_argb;
496 // Convert RAW to ARGB.
498 int RAWToARGB(const uint8* src_raw, int src_stride_raw,
499 uint8* dst_argb, int dst_stride_argb,
500 int width, int height) {
502 void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) =
504 if (!src_raw || !dst_argb ||
505 width <= 0 || height == 0) {
508 // Negative height means invert the image.
511 src_raw = src_raw + (height - 1) * src_stride_raw;
512 src_stride_raw = -src_stride_raw;
515 if (src_stride_raw == width * 3 &&
516 dst_stride_argb == width * 4) {
519 src_stride_raw = dst_stride_argb = 0;
521 #if defined(HAS_RAWTOARGBROW_SSSE3)
522 if (TestCpuFlag(kCpuHasSSSE3)) {
523 RAWToARGBRow = RAWToARGBRow_Any_SSSE3;
524 if (IS_ALIGNED(width, 16)) {
525 RAWToARGBRow = RAWToARGBRow_SSSE3;
529 #if defined(HAS_RAWTOARGBROW_NEON)
530 if (TestCpuFlag(kCpuHasNEON)) {
531 RAWToARGBRow = RAWToARGBRow_Any_NEON;
532 if (IS_ALIGNED(width, 8)) {
533 RAWToARGBRow = RAWToARGBRow_NEON;
538 for (y = 0; y < height; ++y) {
539 RAWToARGBRow(src_raw, dst_argb, width);
540 src_raw += src_stride_raw;
541 dst_argb += dst_stride_argb;
546 // Convert RGB565 to ARGB.
548 int RGB565ToARGB(const uint8* src_rgb565, int src_stride_rgb565,
549 uint8* dst_argb, int dst_stride_argb,
550 int width, int height) {
552 void (*RGB565ToARGBRow)(const uint8* src_rgb565, uint8* dst_argb, int pix) =
554 if (!src_rgb565 || !dst_argb ||
555 width <= 0 || height == 0) {
558 // Negative height means invert the image.
561 src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565;
562 src_stride_rgb565 = -src_stride_rgb565;
565 if (src_stride_rgb565 == width * 2 &&
566 dst_stride_argb == width * 4) {
569 src_stride_rgb565 = dst_stride_argb = 0;
571 #if defined(HAS_RGB565TOARGBROW_SSE2)
572 if (TestCpuFlag(kCpuHasSSE2)) {
573 RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2;
574 if (IS_ALIGNED(width, 8)) {
575 RGB565ToARGBRow = RGB565ToARGBRow_SSE2;
579 #if defined(HAS_RGB565TOARGBROW_AVX2)
580 if (TestCpuFlag(kCpuHasAVX2)) {
581 RGB565ToARGBRow = RGB565ToARGBRow_Any_AVX2;
582 if (IS_ALIGNED(width, 16)) {
583 RGB565ToARGBRow = RGB565ToARGBRow_AVX2;
587 #if defined(HAS_RGB565TOARGBROW_NEON)
588 if (TestCpuFlag(kCpuHasNEON)) {
589 RGB565ToARGBRow = RGB565ToARGBRow_Any_NEON;
590 if (IS_ALIGNED(width, 8)) {
591 RGB565ToARGBRow = RGB565ToARGBRow_NEON;
596 for (y = 0; y < height; ++y) {
597 RGB565ToARGBRow(src_rgb565, dst_argb, width);
598 src_rgb565 += src_stride_rgb565;
599 dst_argb += dst_stride_argb;
604 // Convert ARGB1555 to ARGB.
606 int ARGB1555ToARGB(const uint8* src_argb1555, int src_stride_argb1555,
607 uint8* dst_argb, int dst_stride_argb,
608 int width, int height) {
610 void (*ARGB1555ToARGBRow)(const uint8* src_argb1555, uint8* dst_argb,
611 int pix) = ARGB1555ToARGBRow_C;
612 if (!src_argb1555 || !dst_argb ||
613 width <= 0 || height == 0) {
616 // Negative height means invert the image.
619 src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555;
620 src_stride_argb1555 = -src_stride_argb1555;
623 if (src_stride_argb1555 == width * 2 &&
624 dst_stride_argb == width * 4) {
627 src_stride_argb1555 = dst_stride_argb = 0;
629 #if defined(HAS_ARGB1555TOARGBROW_SSE2)
630 if (TestCpuFlag(kCpuHasSSE2)) {
631 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2;
632 if (IS_ALIGNED(width, 8)) {
633 ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2;
637 #if defined(HAS_ARGB1555TOARGBROW_AVX2)
638 if (TestCpuFlag(kCpuHasAVX2)) {
639 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_AVX2;
640 if (IS_ALIGNED(width, 16)) {
641 ARGB1555ToARGBRow = ARGB1555ToARGBRow_AVX2;
645 #if defined(HAS_ARGB1555TOARGBROW_NEON)
646 if (TestCpuFlag(kCpuHasNEON)) {
647 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_NEON;
648 if (IS_ALIGNED(width, 8)) {
649 ARGB1555ToARGBRow = ARGB1555ToARGBRow_NEON;
654 for (y = 0; y < height; ++y) {
655 ARGB1555ToARGBRow(src_argb1555, dst_argb, width);
656 src_argb1555 += src_stride_argb1555;
657 dst_argb += dst_stride_argb;
662 // Convert ARGB4444 to ARGB.
664 int ARGB4444ToARGB(const uint8* src_argb4444, int src_stride_argb4444,
665 uint8* dst_argb, int dst_stride_argb,
666 int width, int height) {
668 void (*ARGB4444ToARGBRow)(const uint8* src_argb4444, uint8* dst_argb,
669 int pix) = ARGB4444ToARGBRow_C;
670 if (!src_argb4444 || !dst_argb ||
671 width <= 0 || height == 0) {
674 // Negative height means invert the image.
677 src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444;
678 src_stride_argb4444 = -src_stride_argb4444;
681 if (src_stride_argb4444 == width * 2 &&
682 dst_stride_argb == width * 4) {
685 src_stride_argb4444 = dst_stride_argb = 0;
687 #if defined(HAS_ARGB4444TOARGBROW_SSE2)
688 if (TestCpuFlag(kCpuHasSSE2)) {
689 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2;
690 if (IS_ALIGNED(width, 8)) {
691 ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2;
695 #if defined(HAS_ARGB4444TOARGBROW_AVX2)
696 if (TestCpuFlag(kCpuHasAVX2)) {
697 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_AVX2;
698 if (IS_ALIGNED(width, 16)) {
699 ARGB4444ToARGBRow = ARGB4444ToARGBRow_AVX2;
703 #if defined(HAS_ARGB4444TOARGBROW_NEON)
704 if (TestCpuFlag(kCpuHasNEON)) {
705 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_NEON;
706 if (IS_ALIGNED(width, 8)) {
707 ARGB4444ToARGBRow = ARGB4444ToARGBRow_NEON;
712 for (y = 0; y < height; ++y) {
713 ARGB4444ToARGBRow(src_argb4444, dst_argb, width);
714 src_argb4444 += src_stride_argb4444;
715 dst_argb += dst_stride_argb;
720 // Convert NV12 to ARGB.
722 int NV12ToARGB(const uint8* src_y, int src_stride_y,
723 const uint8* src_uv, int src_stride_uv,
724 uint8* dst_argb, int dst_stride_argb,
725 int width, int height) {
727 void (*NV12ToARGBRow)(const uint8* y_buf,
730 int width) = NV12ToARGBRow_C;
731 if (!src_y || !src_uv || !dst_argb ||
732 width <= 0 || height == 0) {
735 // Negative height means invert the image.
738 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
739 dst_stride_argb = -dst_stride_argb;
741 #if defined(HAS_NV12TOARGBROW_SSSE3)
742 if (TestCpuFlag(kCpuHasSSSE3)) {
743 NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3;
744 if (IS_ALIGNED(width, 8)) {
745 NV12ToARGBRow = NV12ToARGBRow_SSSE3;
749 #if defined(HAS_NV12TOARGBROW_AVX2)
750 if (TestCpuFlag(kCpuHasAVX2)) {
751 NV12ToARGBRow = NV12ToARGBRow_Any_AVX2;
752 if (IS_ALIGNED(width, 16)) {
753 NV12ToARGBRow = NV12ToARGBRow_AVX2;
757 #if defined(HAS_NV12TOARGBROW_NEON)
758 if (TestCpuFlag(kCpuHasNEON)) {
759 NV12ToARGBRow = NV12ToARGBRow_Any_NEON;
760 if (IS_ALIGNED(width, 8)) {
761 NV12ToARGBRow = NV12ToARGBRow_NEON;
766 for (y = 0; y < height; ++y) {
767 NV12ToARGBRow(src_y, src_uv, dst_argb, width);
768 dst_argb += dst_stride_argb;
769 src_y += src_stride_y;
771 src_uv += src_stride_uv;
777 // Convert NV21 to ARGB.
779 int NV21ToARGB(const uint8* src_y, int src_stride_y,
780 const uint8* src_uv, int src_stride_uv,
781 uint8* dst_argb, int dst_stride_argb,
782 int width, int height) {
784 void (*NV21ToARGBRow)(const uint8* y_buf,
787 int width) = NV21ToARGBRow_C;
788 if (!src_y || !src_uv || !dst_argb ||
789 width <= 0 || height == 0) {
792 // Negative height means invert the image.
795 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
796 dst_stride_argb = -dst_stride_argb;
798 #if defined(HAS_NV21TOARGBROW_SSSE3)
799 if (TestCpuFlag(kCpuHasSSSE3)) {
800 NV21ToARGBRow = NV21ToARGBRow_Any_SSSE3;
801 if (IS_ALIGNED(width, 8)) {
802 NV21ToARGBRow = NV21ToARGBRow_SSSE3;
806 #if defined(HAS_NV21TOARGBROW_AVX2)
807 if (TestCpuFlag(kCpuHasAVX2)) {
808 NV21ToARGBRow = NV21ToARGBRow_Any_AVX2;
809 if (IS_ALIGNED(width, 16)) {
810 NV21ToARGBRow = NV21ToARGBRow_AVX2;
814 #if defined(HAS_NV21TOARGBROW_NEON)
815 if (TestCpuFlag(kCpuHasNEON)) {
816 NV21ToARGBRow = NV21ToARGBRow_Any_NEON;
817 if (IS_ALIGNED(width, 8)) {
818 NV21ToARGBRow = NV21ToARGBRow_NEON;
823 for (y = 0; y < height; ++y) {
824 NV21ToARGBRow(src_y, src_uv, dst_argb, width);
825 dst_argb += dst_stride_argb;
826 src_y += src_stride_y;
828 src_uv += src_stride_uv;
834 // Convert M420 to ARGB.
836 int M420ToARGB(const uint8* src_m420, int src_stride_m420,
837 uint8* dst_argb, int dst_stride_argb,
838 int width, int height) {
840 void (*NV12ToARGBRow)(const uint8* y_buf,
843 int width) = NV12ToARGBRow_C;
844 if (!src_m420 || !dst_argb ||
845 width <= 0 || height == 0) {
848 // Negative height means invert the image.
851 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
852 dst_stride_argb = -dst_stride_argb;
854 #if defined(HAS_NV12TOARGBROW_SSSE3)
855 if (TestCpuFlag(kCpuHasSSSE3)) {
856 NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3;
857 if (IS_ALIGNED(width, 8)) {
858 NV12ToARGBRow = NV12ToARGBRow_SSSE3;
862 #if defined(HAS_NV12TOARGBROW_AVX2)
863 if (TestCpuFlag(kCpuHasAVX2)) {
864 NV12ToARGBRow = NV12ToARGBRow_Any_AVX2;
865 if (IS_ALIGNED(width, 16)) {
866 NV12ToARGBRow = NV12ToARGBRow_AVX2;
870 #if defined(HAS_NV12TOARGBROW_NEON)
871 if (TestCpuFlag(kCpuHasNEON)) {
872 NV12ToARGBRow = NV12ToARGBRow_Any_NEON;
873 if (IS_ALIGNED(width, 8)) {
874 NV12ToARGBRow = NV12ToARGBRow_NEON;
879 for (y = 0; y < height - 1; y += 2) {
880 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width);
881 NV12ToARGBRow(src_m420 + src_stride_m420, src_m420 + src_stride_m420 * 2,
882 dst_argb + dst_stride_argb, width);
883 dst_argb += dst_stride_argb * 2;
884 src_m420 += src_stride_m420 * 3;
887 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width);
892 // Convert YUY2 to ARGB.
894 int YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2,
895 uint8* dst_argb, int dst_stride_argb,
896 int width, int height) {
898 void (*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb, int pix) =
900 if (!src_yuy2 || !dst_argb ||
901 width <= 0 || height == 0) {
904 // Negative height means invert the image.
907 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
908 src_stride_yuy2 = -src_stride_yuy2;
911 if (src_stride_yuy2 == width * 2 &&
912 dst_stride_argb == width * 4) {
915 src_stride_yuy2 = dst_stride_argb = 0;
917 #if defined(HAS_YUY2TOARGBROW_SSSE3)
918 if (TestCpuFlag(kCpuHasSSSE3)) {
919 YUY2ToARGBRow = YUY2ToARGBRow_Any_SSSE3;
920 if (IS_ALIGNED(width, 16)) {
921 YUY2ToARGBRow = YUY2ToARGBRow_SSSE3;
925 #if defined(HAS_YUY2TOARGBROW_AVX2)
926 if (TestCpuFlag(kCpuHasAVX2)) {
927 YUY2ToARGBRow = YUY2ToARGBRow_Any_AVX2;
928 if (IS_ALIGNED(width, 32)) {
929 YUY2ToARGBRow = YUY2ToARGBRow_AVX2;
933 #if defined(HAS_YUY2TOARGBROW_NEON)
934 if (TestCpuFlag(kCpuHasNEON)) {
935 YUY2ToARGBRow = YUY2ToARGBRow_Any_NEON;
936 if (IS_ALIGNED(width, 8)) {
937 YUY2ToARGBRow = YUY2ToARGBRow_NEON;
941 for (y = 0; y < height; ++y) {
942 YUY2ToARGBRow(src_yuy2, dst_argb, width);
943 src_yuy2 += src_stride_yuy2;
944 dst_argb += dst_stride_argb;
949 // Convert UYVY to ARGB.
951 int UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy,
952 uint8* dst_argb, int dst_stride_argb,
953 int width, int height) {
955 void (*UYVYToARGBRow)(const uint8* src_uyvy, uint8* dst_argb, int pix) =
957 if (!src_uyvy || !dst_argb ||
958 width <= 0 || height == 0) {
961 // Negative height means invert the image.
964 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
965 src_stride_uyvy = -src_stride_uyvy;
968 if (src_stride_uyvy == width * 2 &&
969 dst_stride_argb == width * 4) {
972 src_stride_uyvy = dst_stride_argb = 0;
974 #if defined(HAS_UYVYTOARGBROW_SSSE3)
975 if (TestCpuFlag(kCpuHasSSSE3)) {
976 UYVYToARGBRow = UYVYToARGBRow_Any_SSSE3;
977 if (IS_ALIGNED(width, 16)) {
978 UYVYToARGBRow = UYVYToARGBRow_SSSE3;
982 #if defined(HAS_UYVYTOARGBROW_AVX2)
983 if (TestCpuFlag(kCpuHasAVX2)) {
984 UYVYToARGBRow = UYVYToARGBRow_Any_AVX2;
985 if (IS_ALIGNED(width, 32)) {
986 UYVYToARGBRow = UYVYToARGBRow_AVX2;
990 #if defined(HAS_UYVYTOARGBROW_NEON)
991 if (TestCpuFlag(kCpuHasNEON)) {
992 UYVYToARGBRow = UYVYToARGBRow_Any_NEON;
993 if (IS_ALIGNED(width, 8)) {
994 UYVYToARGBRow = UYVYToARGBRow_NEON;
998 for (y = 0; y < height; ++y) {
999 UYVYToARGBRow(src_uyvy, dst_argb, width);
1000 src_uyvy += src_stride_uyvy;
1001 dst_argb += dst_stride_argb;
1006 // Convert J420 to ARGB.
1008 int J420ToARGB(const uint8* src_y, int src_stride_y,
1009 const uint8* src_u, int src_stride_u,
1010 const uint8* src_v, int src_stride_v,
1011 uint8* dst_argb, int dst_stride_argb,
1012 int width, int height) {
1014 void (*J422ToARGBRow)(const uint8* y_buf,
1018 int width) = J422ToARGBRow_C;
1019 if (!src_y || !src_u || !src_v || !dst_argb ||
1020 width <= 0 || height == 0) {
1023 // Negative height means invert the image.
1026 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1027 dst_stride_argb = -dst_stride_argb;
1029 #if defined(HAS_J422TOARGBROW_SSSE3)
1030 if (TestCpuFlag(kCpuHasSSSE3)) {
1031 J422ToARGBRow = J422ToARGBRow_Any_SSSE3;
1032 if (IS_ALIGNED(width, 8)) {
1033 J422ToARGBRow = J422ToARGBRow_SSSE3;
1037 #if defined(HAS_J422TOARGBROW_AVX2)
1038 if (TestCpuFlag(kCpuHasAVX2)) {
1039 J422ToARGBRow = J422ToARGBRow_Any_AVX2;
1040 if (IS_ALIGNED(width, 16)) {
1041 J422ToARGBRow = J422ToARGBRow_AVX2;
1045 #if defined(HAS_J422TOARGBROW_NEON)
1046 if (TestCpuFlag(kCpuHasNEON)) {
1047 J422ToARGBRow = J422ToARGBRow_Any_NEON;
1048 if (IS_ALIGNED(width, 8)) {
1049 J422ToARGBRow = J422ToARGBRow_NEON;
1053 #if defined(HAS_J422TOARGBROW_MIPS_DSPR2)
1054 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
1055 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
1056 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
1057 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
1058 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
1059 J422ToARGBRow = J422ToARGBRow_MIPS_DSPR2;
1063 for (y = 0; y < height; ++y) {
1064 J422ToARGBRow(src_y, src_u, src_v, dst_argb, width);
1065 dst_argb += dst_stride_argb;
1066 src_y += src_stride_y;
1068 src_u += src_stride_u;
1069 src_v += src_stride_v;
1075 // Convert J422 to ARGB.
1077 int J422ToARGB(const uint8* src_y, int src_stride_y,
1078 const uint8* src_u, int src_stride_u,
1079 const uint8* src_v, int src_stride_v,
1080 uint8* dst_argb, int dst_stride_argb,
1081 int width, int height) {
1083 void (*J422ToARGBRow)(const uint8* y_buf,
1087 int width) = J422ToARGBRow_C;
1088 if (!src_y || !src_u || !src_v ||
1090 width <= 0 || height == 0) {
1093 // Negative height means invert the image.
1096 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1097 dst_stride_argb = -dst_stride_argb;
1100 if (src_stride_y == width &&
1101 src_stride_u * 2 == width &&
1102 src_stride_v * 2 == width &&
1103 dst_stride_argb == width * 4) {
1106 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
1108 #if defined(HAS_J422TOARGBROW_SSSE3)
1109 if (TestCpuFlag(kCpuHasSSSE3)) {
1110 J422ToARGBRow = J422ToARGBRow_Any_SSSE3;
1111 if (IS_ALIGNED(width, 8)) {
1112 J422ToARGBRow = J422ToARGBRow_SSSE3;
1116 #if defined(HAS_J422TOARGBROW_AVX2)
1117 if (TestCpuFlag(kCpuHasAVX2)) {
1118 J422ToARGBRow = J422ToARGBRow_Any_AVX2;
1119 if (IS_ALIGNED(width, 16)) {
1120 J422ToARGBRow = J422ToARGBRow_AVX2;
1124 #if defined(HAS_J422TOARGBROW_NEON)
1125 if (TestCpuFlag(kCpuHasNEON)) {
1126 J422ToARGBRow = J422ToARGBRow_Any_NEON;
1127 if (IS_ALIGNED(width, 8)) {
1128 J422ToARGBRow = J422ToARGBRow_NEON;
1132 #if defined(HAS_J422TOARGBROW_MIPS_DSPR2)
1133 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
1134 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
1135 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
1136 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
1137 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
1138 J422ToARGBRow = J422ToARGBRow_MIPS_DSPR2;
1142 for (y = 0; y < height; ++y) {
1143 J422ToARGBRow(src_y, src_u, src_v, dst_argb, width);
1144 dst_argb += dst_stride_argb;
1145 src_y += src_stride_y;
1146 src_u += src_stride_u;
1147 src_v += src_stride_v;
1154 } // namespace libyuv