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/rotate_argb.h"
18 #include "libyuv/row.h"
19 #include "libyuv/video_common.h"
20
21 #ifdef __cplusplus
22 namespace libyuv {
23 extern "C" {
24 #endif
25
26 // Copy ARGB with optional flipping
27 LIBYUV_API
ARGBCopy(const uint8 * src_argb,int src_stride_argb,uint8 * dst_argb,int dst_stride_argb,int width,int height)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) {
33 return -1;
34 }
35 // Negative height means invert the image.
36 if (height < 0) {
37 height = -height;
38 src_argb = src_argb + (height - 1) * src_stride_argb;
39 src_stride_argb = -src_stride_argb;
40 }
41
42 CopyPlane(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
43 width * 4, height);
44 return 0;
45 }
46
47 // Convert I444 to ARGB.
48 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)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) {
54 int y;
55 void (*I444ToARGBRow)(const uint8* y_buf,
56 const uint8* u_buf,
57 const uint8* v_buf,
58 uint8* rgb_buf,
59 int width) = I444ToARGBRow_C;
60 if (!src_y || !src_u || !src_v ||
61 !dst_argb ||
62 width <= 0 || height == 0) {
63 return -1;
64 }
65 // Negative height means invert the image.
66 if (height < 0) {
67 height = -height;
68 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
69 dst_stride_argb = -dst_stride_argb;
70 }
71 // Coalesce rows.
72 if (src_stride_y == width &&
73 src_stride_u == width &&
74 src_stride_v == width &&
75 dst_stride_argb == width * 4) {
76 width *= height;
77 height = 1;
78 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
79 }
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;
85 }
86 }
87 #endif
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;
93 }
94 }
95 #endif
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;
101 }
102 }
103 #endif
104
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;
111 }
112 return 0;
113 }
114
115 // Convert I422 to ARGB.
116 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)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) {
122 int y;
123 void (*I422ToARGBRow)(const uint8* y_buf,
124 const uint8* u_buf,
125 const uint8* v_buf,
126 uint8* rgb_buf,
127 int width) = I422ToARGBRow_C;
128 if (!src_y || !src_u || !src_v ||
129 !dst_argb ||
130 width <= 0 || height == 0) {
131 return -1;
132 }
133 // Negative height means invert the image.
134 if (height < 0) {
135 height = -height;
136 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
137 dst_stride_argb = -dst_stride_argb;
138 }
139 // Coalesce rows.
140 if (src_stride_y == width &&
141 src_stride_u * 2 == width &&
142 src_stride_v * 2 == width &&
143 dst_stride_argb == width * 4) {
144 width *= height;
145 height = 1;
146 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
147 }
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;
153 }
154 }
155 #endif
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;
161 }
162 }
163 #endif
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;
169 }
170 }
171 #endif
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;
179 }
180 #endif
181
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;
188 }
189 return 0;
190 }
191
192 // Convert I411 to ARGB.
193 LIBYUV_API
I411ToARGB(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)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) {
199 int y;
200 void (*I411ToARGBRow)(const uint8* y_buf,
201 const uint8* u_buf,
202 const uint8* v_buf,
203 uint8* rgb_buf,
204 int width) = I411ToARGBRow_C;
205 if (!src_y || !src_u || !src_v ||
206 !dst_argb ||
207 width <= 0 || height == 0) {
208 return -1;
209 }
210 // Negative height means invert the image.
211 if (height < 0) {
212 height = -height;
213 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
214 dst_stride_argb = -dst_stride_argb;
215 }
216 // Coalesce rows.
217 if (src_stride_y == width &&
218 src_stride_u * 4 == width &&
219 src_stride_v * 4 == width &&
220 dst_stride_argb == width * 4) {
221 width *= height;
222 height = 1;
223 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
224 }
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;
230 }
231 }
232 #endif
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;
238 }
239 }
240 #endif
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;
246 }
247 }
248 #endif
249
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;
256 }
257 return 0;
258 }
259
260 // Convert I400 to ARGB.
261 LIBYUV_API
I400ToARGB(const uint8 * src_y,int src_stride_y,uint8 * dst_argb,int dst_stride_argb,int width,int height)262 int I400ToARGB(const uint8* src_y, int src_stride_y,
263 uint8* dst_argb, int dst_stride_argb,
264 int width, int height) {
265 int y;
266 void (*I400ToARGBRow)(const uint8* y_buf,
267 uint8* rgb_buf,
268 int width) = I400ToARGBRow_C;
269 if (!src_y || !dst_argb ||
270 width <= 0 || height == 0) {
271 return -1;
272 }
273 // Negative height means invert the image.
274 if (height < 0) {
275 height = -height;
276 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
277 dst_stride_argb = -dst_stride_argb;
278 }
279 // Coalesce rows.
280 if (src_stride_y == width &&
281 dst_stride_argb == width * 4) {
282 width *= height;
283 height = 1;
284 src_stride_y = dst_stride_argb = 0;
285 }
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;
291 }
292 }
293 #endif
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;
299 }
300 }
301 #endif
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;
307 }
308 }
309 #endif
310
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;
315 }
316 return 0;
317 }
318
319 // Convert J400 to ARGB.
320 LIBYUV_API
J400ToARGB(const uint8 * src_y,int src_stride_y,uint8 * dst_argb,int dst_stride_argb,int width,int height)321 int J400ToARGB(const uint8* src_y, int src_stride_y,
322 uint8* dst_argb, int dst_stride_argb,
323 int width, int height) {
324 int y;
325 void (*J400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix) =
326 J400ToARGBRow_C;
327 if (!src_y || !dst_argb ||
328 width <= 0 || height == 0) {
329 return -1;
330 }
331 // Negative height means invert the image.
332 if (height < 0) {
333 height = -height;
334 src_y = src_y + (height - 1) * src_stride_y;
335 src_stride_y = -src_stride_y;
336 }
337 // Coalesce rows.
338 if (src_stride_y == width &&
339 dst_stride_argb == width * 4) {
340 width *= height;
341 height = 1;
342 src_stride_y = dst_stride_argb = 0;
343 }
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;
349 }
350 }
351 #endif
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;
357 }
358 }
359 #endif
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;
365 }
366 }
367 #endif
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;
372 }
373 return 0;
374 }
375
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
379 };
380
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
384 };
385
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
389 };
390
391 // Convert BGRA to ARGB.
392 LIBYUV_API
BGRAToARGB(const uint8 * src_bgra,int src_stride_bgra,uint8 * dst_argb,int dst_stride_argb,int width,int height)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),
399 width, height);
400 }
401
402 // Convert ARGB to BGRA (same as BGRAToARGB).
403 LIBYUV_API
ARGBToBGRA(const uint8 * src_bgra,int src_stride_bgra,uint8 * dst_argb,int dst_stride_argb,int width,int height)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),
410 width, height);
411 }
412
413 // Convert ABGR to ARGB.
414 LIBYUV_API
ABGRToARGB(const uint8 * src_abgr,int src_stride_abgr,uint8 * dst_argb,int dst_stride_argb,int width,int height)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),
421 width, height);
422 }
423
424 // Convert ARGB to ABGR to (same as ABGRToARGB).
425 LIBYUV_API
ARGBToABGR(const uint8 * src_abgr,int src_stride_abgr,uint8 * dst_argb,int dst_stride_argb,int width,int height)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),
432 width, height);
433 }
434
435 // Convert RGBA to ARGB.
436 LIBYUV_API
RGBAToARGB(const uint8 * src_rgba,int src_stride_rgba,uint8 * dst_argb,int dst_stride_argb,int width,int height)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),
443 width, height);
444 }
445
446 // Convert RGB24 to ARGB.
447 LIBYUV_API
RGB24ToARGB(const uint8 * src_rgb24,int src_stride_rgb24,uint8 * dst_argb,int dst_stride_argb,int width,int height)448 int RGB24ToARGB(const uint8* src_rgb24, int src_stride_rgb24,
449 uint8* dst_argb, int dst_stride_argb,
450 int width, int height) {
451 int y;
452 void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) =
453 RGB24ToARGBRow_C;
454 if (!src_rgb24 || !dst_argb ||
455 width <= 0 || height == 0) {
456 return -1;
457 }
458 // Negative height means invert the image.
459 if (height < 0) {
460 height = -height;
461 src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
462 src_stride_rgb24 = -src_stride_rgb24;
463 }
464 // Coalesce rows.
465 if (src_stride_rgb24 == width * 3 &&
466 dst_stride_argb == width * 4) {
467 width *= height;
468 height = 1;
469 src_stride_rgb24 = dst_stride_argb = 0;
470 }
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;
476 }
477 }
478 #endif
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;
484 }
485 }
486 #endif
487
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;
492 }
493 return 0;
494 }
495
496 // Convert RAW to ARGB.
497 LIBYUV_API
RAWToARGB(const uint8 * src_raw,int src_stride_raw,uint8 * dst_argb,int dst_stride_argb,int width,int height)498 int RAWToARGB(const uint8* src_raw, int src_stride_raw,
499 uint8* dst_argb, int dst_stride_argb,
500 int width, int height) {
501 int y;
502 void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) =
503 RAWToARGBRow_C;
504 if (!src_raw || !dst_argb ||
505 width <= 0 || height == 0) {
506 return -1;
507 }
508 // Negative height means invert the image.
509 if (height < 0) {
510 height = -height;
511 src_raw = src_raw + (height - 1) * src_stride_raw;
512 src_stride_raw = -src_stride_raw;
513 }
514 // Coalesce rows.
515 if (src_stride_raw == width * 3 &&
516 dst_stride_argb == width * 4) {
517 width *= height;
518 height = 1;
519 src_stride_raw = dst_stride_argb = 0;
520 }
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;
526 }
527 }
528 #endif
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;
534 }
535 }
536 #endif
537
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;
542 }
543 return 0;
544 }
545
546 // Convert RGB565 to ARGB.
547 LIBYUV_API
RGB565ToARGB(const uint8 * src_rgb565,int src_stride_rgb565,uint8 * dst_argb,int dst_stride_argb,int width,int height)548 int RGB565ToARGB(const uint8* src_rgb565, int src_stride_rgb565,
549 uint8* dst_argb, int dst_stride_argb,
550 int width, int height) {
551 int y;
552 void (*RGB565ToARGBRow)(const uint8* src_rgb565, uint8* dst_argb, int pix) =
553 RGB565ToARGBRow_C;
554 if (!src_rgb565 || !dst_argb ||
555 width <= 0 || height == 0) {
556 return -1;
557 }
558 // Negative height means invert the image.
559 if (height < 0) {
560 height = -height;
561 src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565;
562 src_stride_rgb565 = -src_stride_rgb565;
563 }
564 // Coalesce rows.
565 if (src_stride_rgb565 == width * 2 &&
566 dst_stride_argb == width * 4) {
567 width *= height;
568 height = 1;
569 src_stride_rgb565 = dst_stride_argb = 0;
570 }
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;
576 }
577 }
578 #endif
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;
584 }
585 }
586 #endif
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;
592 }
593 }
594 #endif
595
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;
600 }
601 return 0;
602 }
603
604 // Convert ARGB1555 to ARGB.
605 LIBYUV_API
ARGB1555ToARGB(const uint8 * src_argb1555,int src_stride_argb1555,uint8 * dst_argb,int dst_stride_argb,int width,int height)606 int ARGB1555ToARGB(const uint8* src_argb1555, int src_stride_argb1555,
607 uint8* dst_argb, int dst_stride_argb,
608 int width, int height) {
609 int y;
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) {
614 return -1;
615 }
616 // Negative height means invert the image.
617 if (height < 0) {
618 height = -height;
619 src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555;
620 src_stride_argb1555 = -src_stride_argb1555;
621 }
622 // Coalesce rows.
623 if (src_stride_argb1555 == width * 2 &&
624 dst_stride_argb == width * 4) {
625 width *= height;
626 height = 1;
627 src_stride_argb1555 = dst_stride_argb = 0;
628 }
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;
634 }
635 }
636 #endif
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;
642 }
643 }
644 #endif
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;
650 }
651 }
652 #endif
653
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;
658 }
659 return 0;
660 }
661
662 // Convert ARGB4444 to ARGB.
663 LIBYUV_API
ARGB4444ToARGB(const uint8 * src_argb4444,int src_stride_argb4444,uint8 * dst_argb,int dst_stride_argb,int width,int height)664 int ARGB4444ToARGB(const uint8* src_argb4444, int src_stride_argb4444,
665 uint8* dst_argb, int dst_stride_argb,
666 int width, int height) {
667 int y;
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) {
672 return -1;
673 }
674 // Negative height means invert the image.
675 if (height < 0) {
676 height = -height;
677 src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444;
678 src_stride_argb4444 = -src_stride_argb4444;
679 }
680 // Coalesce rows.
681 if (src_stride_argb4444 == width * 2 &&
682 dst_stride_argb == width * 4) {
683 width *= height;
684 height = 1;
685 src_stride_argb4444 = dst_stride_argb = 0;
686 }
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;
692 }
693 }
694 #endif
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;
700 }
701 }
702 #endif
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;
708 }
709 }
710 #endif
711
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;
716 }
717 return 0;
718 }
719
720 // Convert NV12 to ARGB.
721 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)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) {
726 int y;
727 void (*NV12ToARGBRow)(const uint8* y_buf,
728 const uint8* uv_buf,
729 uint8* rgb_buf,
730 int width) = NV12ToARGBRow_C;
731 if (!src_y || !src_uv || !dst_argb ||
732 width <= 0 || height == 0) {
733 return -1;
734 }
735 // Negative height means invert the image.
736 if (height < 0) {
737 height = -height;
738 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
739 dst_stride_argb = -dst_stride_argb;
740 }
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;
746 }
747 }
748 #endif
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;
754 }
755 }
756 #endif
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;
762 }
763 }
764 #endif
765
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;
770 if (y & 1) {
771 src_uv += src_stride_uv;
772 }
773 }
774 return 0;
775 }
776
777 // Convert NV21 to ARGB.
778 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)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) {
783 int y;
784 void (*NV21ToARGBRow)(const uint8* y_buf,
785 const uint8* uv_buf,
786 uint8* rgb_buf,
787 int width) = NV21ToARGBRow_C;
788 if (!src_y || !src_uv || !dst_argb ||
789 width <= 0 || height == 0) {
790 return -1;
791 }
792 // Negative height means invert the image.
793 if (height < 0) {
794 height = -height;
795 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
796 dst_stride_argb = -dst_stride_argb;
797 }
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;
803 }
804 }
805 #endif
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;
811 }
812 }
813 #endif
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;
819 }
820 }
821 #endif
822
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;
827 if (y & 1) {
828 src_uv += src_stride_uv;
829 }
830 }
831 return 0;
832 }
833
834 // Convert M420 to ARGB.
835 LIBYUV_API
M420ToARGB(const uint8 * src_m420,int src_stride_m420,uint8 * dst_argb,int dst_stride_argb,int width,int height)836 int M420ToARGB(const uint8* src_m420, int src_stride_m420,
837 uint8* dst_argb, int dst_stride_argb,
838 int width, int height) {
839 int y;
840 void (*NV12ToARGBRow)(const uint8* y_buf,
841 const uint8* uv_buf,
842 uint8* rgb_buf,
843 int width) = NV12ToARGBRow_C;
844 if (!src_m420 || !dst_argb ||
845 width <= 0 || height == 0) {
846 return -1;
847 }
848 // Negative height means invert the image.
849 if (height < 0) {
850 height = -height;
851 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
852 dst_stride_argb = -dst_stride_argb;
853 }
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;
859 }
860 }
861 #endif
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;
867 }
868 }
869 #endif
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;
875 }
876 }
877 #endif
878
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;
885 }
886 if (height & 1) {
887 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width);
888 }
889 return 0;
890 }
891
892 // Convert YUY2 to ARGB.
893 LIBYUV_API
YUY2ToARGB(const uint8 * src_yuy2,int src_stride_yuy2,uint8 * dst_argb,int dst_stride_argb,int width,int height)894 int YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2,
895 uint8* dst_argb, int dst_stride_argb,
896 int width, int height) {
897 int y;
898 void (*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb, int pix) =
899 YUY2ToARGBRow_C;
900 if (!src_yuy2 || !dst_argb ||
901 width <= 0 || height == 0) {
902 return -1;
903 }
904 // Negative height means invert the image.
905 if (height < 0) {
906 height = -height;
907 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
908 src_stride_yuy2 = -src_stride_yuy2;
909 }
910 // Coalesce rows.
911 if (src_stride_yuy2 == width * 2 &&
912 dst_stride_argb == width * 4) {
913 width *= height;
914 height = 1;
915 src_stride_yuy2 = dst_stride_argb = 0;
916 }
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;
922 }
923 }
924 #endif
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;
930 }
931 }
932 #endif
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;
938 }
939 }
940 #endif
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;
945 }
946 return 0;
947 }
948
949 // Convert UYVY to ARGB.
950 LIBYUV_API
UYVYToARGB(const uint8 * src_uyvy,int src_stride_uyvy,uint8 * dst_argb,int dst_stride_argb,int width,int height)951 int UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy,
952 uint8* dst_argb, int dst_stride_argb,
953 int width, int height) {
954 int y;
955 void (*UYVYToARGBRow)(const uint8* src_uyvy, uint8* dst_argb, int pix) =
956 UYVYToARGBRow_C;
957 if (!src_uyvy || !dst_argb ||
958 width <= 0 || height == 0) {
959 return -1;
960 }
961 // Negative height means invert the image.
962 if (height < 0) {
963 height = -height;
964 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
965 src_stride_uyvy = -src_stride_uyvy;
966 }
967 // Coalesce rows.
968 if (src_stride_uyvy == width * 2 &&
969 dst_stride_argb == width * 4) {
970 width *= height;
971 height = 1;
972 src_stride_uyvy = dst_stride_argb = 0;
973 }
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;
979 }
980 }
981 #endif
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;
987 }
988 }
989 #endif
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;
995 }
996 }
997 #endif
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;
1002 }
1003 return 0;
1004 }
1005
1006 // Convert J420 to ARGB.
1007 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)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) {
1013 int y;
1014 void (*J422ToARGBRow)(const uint8* y_buf,
1015 const uint8* u_buf,
1016 const uint8* v_buf,
1017 uint8* rgb_buf,
1018 int width) = J422ToARGBRow_C;
1019 if (!src_y || !src_u || !src_v || !dst_argb ||
1020 width <= 0 || height == 0) {
1021 return -1;
1022 }
1023 // Negative height means invert the image.
1024 if (height < 0) {
1025 height = -height;
1026 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1027 dst_stride_argb = -dst_stride_argb;
1028 }
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;
1034 }
1035 }
1036 #endif
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;
1042 }
1043 }
1044 #endif
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;
1050 }
1051 }
1052 #endif
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;
1060 }
1061 #endif
1062
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;
1067 if (y & 1) {
1068 src_u += src_stride_u;
1069 src_v += src_stride_v;
1070 }
1071 }
1072 return 0;
1073 }
1074
1075 // Convert J422 to ARGB.
1076 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)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) {
1082 int y;
1083 void (*J422ToARGBRow)(const uint8* y_buf,
1084 const uint8* u_buf,
1085 const uint8* v_buf,
1086 uint8* rgb_buf,
1087 int width) = J422ToARGBRow_C;
1088 if (!src_y || !src_u || !src_v ||
1089 !dst_argb ||
1090 width <= 0 || height == 0) {
1091 return -1;
1092 }
1093 // Negative height means invert the image.
1094 if (height < 0) {
1095 height = -height;
1096 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
1097 dst_stride_argb = -dst_stride_argb;
1098 }
1099 // Coalesce rows.
1100 if (src_stride_y == width &&
1101 src_stride_u * 2 == width &&
1102 src_stride_v * 2 == width &&
1103 dst_stride_argb == width * 4) {
1104 width *= height;
1105 height = 1;
1106 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
1107 }
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;
1113 }
1114 }
1115 #endif
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;
1121 }
1122 }
1123 #endif
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;
1129 }
1130 }
1131 #endif
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;
1139 }
1140 #endif
1141
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;
1148 }
1149 return 0;
1150 }
1151
1152 #ifdef __cplusplus
1153 } // extern "C"
1154 } // namespace libyuv
1155 #endif
1156