Line data Source code
1 : /*
2 : * Copyright 2012 The LibYuv Project Authors. All rights reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "libyuv/convert_from_argb.h"
12 :
13 : #include "libyuv/basic_types.h"
14 : #include "libyuv/cpu_id.h"
15 : #include "libyuv/planar_functions.h"
16 : #include "libyuv/row.h"
17 :
18 : #ifdef __cplusplus
19 : namespace libyuv {
20 : extern "C" {
21 : #endif
22 :
23 : // ARGB little endian (bgra in memory) to I444
24 : LIBYUV_API
25 0 : int ARGBToI444(const uint8* src_argb,
26 : int src_stride_argb,
27 : uint8* dst_y,
28 : int dst_stride_y,
29 : uint8* dst_u,
30 : int dst_stride_u,
31 : uint8* dst_v,
32 : int dst_stride_v,
33 : int width,
34 : int height) {
35 : int y;
36 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
37 0 : ARGBToYRow_C;
38 : void (*ARGBToUV444Row)(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
39 0 : int width) = ARGBToUV444Row_C;
40 0 : if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) {
41 0 : return -1;
42 : }
43 0 : if (height < 0) {
44 0 : height = -height;
45 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
46 0 : src_stride_argb = -src_stride_argb;
47 : }
48 : // Coalesce rows.
49 0 : if (src_stride_argb == width * 4 && dst_stride_y == width &&
50 0 : dst_stride_u == width && dst_stride_v == width) {
51 0 : width *= height;
52 0 : height = 1;
53 0 : src_stride_argb = dst_stride_y = dst_stride_u = dst_stride_v = 0;
54 : }
55 : #if defined(HAS_ARGBTOUV444ROW_SSSE3)
56 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
57 0 : ARGBToUV444Row = ARGBToUV444Row_Any_SSSE3;
58 0 : if (IS_ALIGNED(width, 16)) {
59 0 : ARGBToUV444Row = ARGBToUV444Row_SSSE3;
60 : }
61 : }
62 : #endif
63 : #if defined(HAS_ARGBTOUV444ROW_NEON)
64 : if (TestCpuFlag(kCpuHasNEON)) {
65 : ARGBToUV444Row = ARGBToUV444Row_Any_NEON;
66 : if (IS_ALIGNED(width, 8)) {
67 : ARGBToUV444Row = ARGBToUV444Row_NEON;
68 : }
69 : }
70 : #endif
71 : #if defined(HAS_ARGBTOUV444ROW_MSA)
72 : if (TestCpuFlag(kCpuHasMSA)) {
73 : ARGBToUV444Row = ARGBToUV444Row_Any_MSA;
74 : if (IS_ALIGNED(width, 16)) {
75 : ARGBToUV444Row = ARGBToUV444Row_MSA;
76 : }
77 : }
78 : #endif
79 : #if defined(HAS_ARGBTOYROW_SSSE3)
80 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
81 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
82 0 : if (IS_ALIGNED(width, 16)) {
83 0 : ARGBToYRow = ARGBToYRow_SSSE3;
84 : }
85 : }
86 : #endif
87 : #if defined(HAS_ARGBTOYROW_AVX2)
88 0 : if (TestCpuFlag(kCpuHasAVX2)) {
89 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
90 0 : if (IS_ALIGNED(width, 32)) {
91 0 : ARGBToYRow = ARGBToYRow_AVX2;
92 : }
93 : }
94 : #endif
95 : #if defined(HAS_ARGBTOYROW_NEON)
96 : if (TestCpuFlag(kCpuHasNEON)) {
97 : ARGBToYRow = ARGBToYRow_Any_NEON;
98 : if (IS_ALIGNED(width, 8)) {
99 : ARGBToYRow = ARGBToYRow_NEON;
100 : }
101 : }
102 : #endif
103 : #if defined(HAS_ARGBTOYROW_DSPR2)
104 : if (TestCpuFlag(kCpuHasDSPR2)) {
105 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
106 : if (IS_ALIGNED(width, 8)) {
107 : ARGBToYRow = ARGBToYRow_DSPR2;
108 : }
109 : }
110 : #endif
111 : #if defined(HAS_ARGBTOYROW_MSA)
112 : if (TestCpuFlag(kCpuHasMSA)) {
113 : ARGBToYRow = ARGBToYRow_Any_MSA;
114 : if (IS_ALIGNED(width, 16)) {
115 : ARGBToYRow = ARGBToYRow_MSA;
116 : }
117 : }
118 : #endif
119 :
120 0 : for (y = 0; y < height; ++y) {
121 0 : ARGBToUV444Row(src_argb, dst_u, dst_v, width);
122 0 : ARGBToYRow(src_argb, dst_y, width);
123 0 : src_argb += src_stride_argb;
124 0 : dst_y += dst_stride_y;
125 0 : dst_u += dst_stride_u;
126 0 : dst_v += dst_stride_v;
127 : }
128 0 : return 0;
129 : }
130 :
131 : // ARGB little endian (bgra in memory) to I422
132 : LIBYUV_API
133 0 : int ARGBToI422(const uint8* src_argb,
134 : int src_stride_argb,
135 : uint8* dst_y,
136 : int dst_stride_y,
137 : uint8* dst_u,
138 : int dst_stride_u,
139 : uint8* dst_v,
140 : int dst_stride_v,
141 : int width,
142 : int height) {
143 : int y;
144 : void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u,
145 0 : uint8* dst_v, int width) = ARGBToUVRow_C;
146 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
147 0 : ARGBToYRow_C;
148 0 : if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) {
149 0 : return -1;
150 : }
151 : // Negative height means invert the image.
152 0 : if (height < 0) {
153 0 : height = -height;
154 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
155 0 : src_stride_argb = -src_stride_argb;
156 : }
157 : // Coalesce rows.
158 0 : if (src_stride_argb == width * 4 && dst_stride_y == width &&
159 0 : dst_stride_u * 2 == width && dst_stride_v * 2 == width) {
160 0 : width *= height;
161 0 : height = 1;
162 0 : src_stride_argb = dst_stride_y = dst_stride_u = dst_stride_v = 0;
163 : }
164 : #if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
165 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
166 0 : ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
167 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
168 0 : if (IS_ALIGNED(width, 16)) {
169 0 : ARGBToUVRow = ARGBToUVRow_SSSE3;
170 0 : ARGBToYRow = ARGBToYRow_SSSE3;
171 : }
172 : }
173 : #endif
174 : #if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
175 0 : if (TestCpuFlag(kCpuHasAVX2)) {
176 0 : ARGBToUVRow = ARGBToUVRow_Any_AVX2;
177 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
178 0 : if (IS_ALIGNED(width, 32)) {
179 0 : ARGBToUVRow = ARGBToUVRow_AVX2;
180 0 : ARGBToYRow = ARGBToYRow_AVX2;
181 : }
182 : }
183 : #endif
184 : #if defined(HAS_ARGBTOYROW_NEON)
185 : if (TestCpuFlag(kCpuHasNEON)) {
186 : ARGBToYRow = ARGBToYRow_Any_NEON;
187 : if (IS_ALIGNED(width, 8)) {
188 : ARGBToYRow = ARGBToYRow_NEON;
189 : }
190 : }
191 : #endif
192 : #if defined(HAS_ARGBTOUVROW_NEON)
193 : if (TestCpuFlag(kCpuHasNEON)) {
194 : ARGBToUVRow = ARGBToUVRow_Any_NEON;
195 : if (IS_ALIGNED(width, 16)) {
196 : ARGBToUVRow = ARGBToUVRow_NEON;
197 : }
198 : }
199 : #endif
200 : #if defined(HAS_ARGBTOYROW_DSPR2)
201 : if (TestCpuFlag(kCpuHasDSPR2)) {
202 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
203 : if (IS_ALIGNED(width, 8)) {
204 : ARGBToYRow = ARGBToYRow_DSPR2;
205 : }
206 : }
207 : #endif
208 : #if defined(HAS_ARGBTOUVROW_DSPR2)
209 : if (TestCpuFlag(kCpuHasDSPR2)) {
210 : ARGBToUVRow = ARGBToUVRow_Any_DSPR2;
211 : if (IS_ALIGNED(width, 16)) {
212 : ARGBToUVRow = ARGBToUVRow_DSPR2;
213 : }
214 : }
215 : #endif
216 :
217 : #if defined(HAS_ARGBTOYROW_MSA)
218 : if (TestCpuFlag(kCpuHasMSA)) {
219 : ARGBToYRow = ARGBToYRow_Any_MSA;
220 : if (IS_ALIGNED(width, 16)) {
221 : ARGBToYRow = ARGBToYRow_MSA;
222 : }
223 : }
224 : #endif
225 : #if defined(HAS_ARGBTOUVROW_MSA)
226 : if (TestCpuFlag(kCpuHasMSA)) {
227 : ARGBToUVRow = ARGBToUVRow_Any_MSA;
228 : if (IS_ALIGNED(width, 32)) {
229 : ARGBToUVRow = ARGBToUVRow_MSA;
230 : }
231 : }
232 : #endif
233 :
234 0 : for (y = 0; y < height; ++y) {
235 0 : ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
236 0 : ARGBToYRow(src_argb, dst_y, width);
237 0 : src_argb += src_stride_argb;
238 0 : dst_y += dst_stride_y;
239 0 : dst_u += dst_stride_u;
240 0 : dst_v += dst_stride_v;
241 : }
242 0 : return 0;
243 : }
244 :
245 : LIBYUV_API
246 0 : int ARGBToNV12(const uint8* src_argb,
247 : int src_stride_argb,
248 : uint8* dst_y,
249 : int dst_stride_y,
250 : uint8* dst_uv,
251 : int dst_stride_uv,
252 : int width,
253 : int height) {
254 : int y;
255 0 : int halfwidth = (width + 1) >> 1;
256 : void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u,
257 0 : uint8* dst_v, int width) = ARGBToUVRow_C;
258 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
259 0 : ARGBToYRow_C;
260 : void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
261 0 : int width) = MergeUVRow_C;
262 0 : if (!src_argb || !dst_y || !dst_uv || width <= 0 || height == 0) {
263 0 : return -1;
264 : }
265 : // Negative height means invert the image.
266 0 : if (height < 0) {
267 0 : height = -height;
268 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
269 0 : src_stride_argb = -src_stride_argb;
270 : }
271 : #if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
272 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
273 0 : ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
274 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
275 0 : if (IS_ALIGNED(width, 16)) {
276 0 : ARGBToUVRow = ARGBToUVRow_SSSE3;
277 0 : ARGBToYRow = ARGBToYRow_SSSE3;
278 : }
279 : }
280 : #endif
281 : #if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
282 0 : if (TestCpuFlag(kCpuHasAVX2)) {
283 0 : ARGBToUVRow = ARGBToUVRow_Any_AVX2;
284 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
285 0 : if (IS_ALIGNED(width, 32)) {
286 0 : ARGBToUVRow = ARGBToUVRow_AVX2;
287 0 : ARGBToYRow = ARGBToYRow_AVX2;
288 : }
289 : }
290 : #endif
291 : #if defined(HAS_ARGBTOYROW_NEON)
292 : if (TestCpuFlag(kCpuHasNEON)) {
293 : ARGBToYRow = ARGBToYRow_Any_NEON;
294 : if (IS_ALIGNED(width, 8)) {
295 : ARGBToYRow = ARGBToYRow_NEON;
296 : }
297 : }
298 : #endif
299 : #if defined(HAS_ARGBTOUVROW_NEON)
300 : if (TestCpuFlag(kCpuHasNEON)) {
301 : ARGBToUVRow = ARGBToUVRow_Any_NEON;
302 : if (IS_ALIGNED(width, 16)) {
303 : ARGBToUVRow = ARGBToUVRow_NEON;
304 : }
305 : }
306 : #endif
307 : #if defined(HAS_ARGBTOYROW_MSA)
308 : if (TestCpuFlag(kCpuHasMSA)) {
309 : ARGBToYRow = ARGBToYRow_Any_MSA;
310 : if (IS_ALIGNED(width, 16)) {
311 : ARGBToYRow = ARGBToYRow_MSA;
312 : }
313 : }
314 : #endif
315 : #if defined(HAS_ARGBTOUVROW_MSA)
316 : if (TestCpuFlag(kCpuHasMSA)) {
317 : ARGBToUVRow = ARGBToUVRow_Any_MSA;
318 : if (IS_ALIGNED(width, 32)) {
319 : ARGBToUVRow = ARGBToUVRow_MSA;
320 : }
321 : }
322 : #endif
323 : #if defined(HAS_MERGEUVROW_SSE2)
324 0 : if (TestCpuFlag(kCpuHasSSE2)) {
325 0 : MergeUVRow_ = MergeUVRow_Any_SSE2;
326 0 : if (IS_ALIGNED(halfwidth, 16)) {
327 0 : MergeUVRow_ = MergeUVRow_SSE2;
328 : }
329 : }
330 : #endif
331 : #if defined(HAS_MERGEUVROW_AVX2)
332 0 : if (TestCpuFlag(kCpuHasAVX2)) {
333 0 : MergeUVRow_ = MergeUVRow_Any_AVX2;
334 0 : if (IS_ALIGNED(halfwidth, 32)) {
335 0 : MergeUVRow_ = MergeUVRow_AVX2;
336 : }
337 : }
338 : #endif
339 : #if defined(HAS_MERGEUVROW_NEON)
340 : if (TestCpuFlag(kCpuHasNEON)) {
341 : MergeUVRow_ = MergeUVRow_Any_NEON;
342 : if (IS_ALIGNED(halfwidth, 16)) {
343 : MergeUVRow_ = MergeUVRow_NEON;
344 : }
345 : }
346 : #endif
347 : #if defined(HAS_ARGBTOYROW_DSPR2)
348 : if (TestCpuFlag(kCpuHasDSPR2)) {
349 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
350 : if (IS_ALIGNED(width, 8)) {
351 : ARGBToYRow = ARGBToYRow_DSPR2;
352 : }
353 : }
354 : #endif
355 : #if defined(HAS_ARGBTOUVROW_DSPR2)
356 : if (TestCpuFlag(kCpuHasDSPR2)) {
357 : ARGBToUVRow = ARGBToUVRow_Any_DSPR2;
358 : if (IS_ALIGNED(width, 16)) {
359 : ARGBToUVRow = ARGBToUVRow_DSPR2;
360 : }
361 : }
362 : #endif
363 : {
364 : // Allocate a rows of uv.
365 0 : align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
366 0 : uint8* row_v = row_u + ((halfwidth + 31) & ~31);
367 :
368 0 : for (y = 0; y < height - 1; y += 2) {
369 0 : ARGBToUVRow(src_argb, src_stride_argb, row_u, row_v, width);
370 0 : MergeUVRow_(row_u, row_v, dst_uv, halfwidth);
371 0 : ARGBToYRow(src_argb, dst_y, width);
372 0 : ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width);
373 0 : src_argb += src_stride_argb * 2;
374 0 : dst_y += dst_stride_y * 2;
375 0 : dst_uv += dst_stride_uv;
376 : }
377 0 : if (height & 1) {
378 0 : ARGBToUVRow(src_argb, 0, row_u, row_v, width);
379 0 : MergeUVRow_(row_u, row_v, dst_uv, halfwidth);
380 0 : ARGBToYRow(src_argb, dst_y, width);
381 : }
382 0 : free_aligned_buffer_64(row_u);
383 : }
384 0 : return 0;
385 : }
386 :
387 : // Same as NV12 but U and V swapped.
388 : LIBYUV_API
389 0 : int ARGBToNV21(const uint8* src_argb,
390 : int src_stride_argb,
391 : uint8* dst_y,
392 : int dst_stride_y,
393 : uint8* dst_uv,
394 : int dst_stride_uv,
395 : int width,
396 : int height) {
397 : int y;
398 0 : int halfwidth = (width + 1) >> 1;
399 : void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, uint8* dst_u,
400 0 : uint8* dst_v, int width) = ARGBToUVRow_C;
401 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
402 0 : ARGBToYRow_C;
403 : void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
404 0 : int width) = MergeUVRow_C;
405 0 : if (!src_argb || !dst_y || !dst_uv || width <= 0 || height == 0) {
406 0 : return -1;
407 : }
408 : // Negative height means invert the image.
409 0 : if (height < 0) {
410 0 : height = -height;
411 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
412 0 : src_stride_argb = -src_stride_argb;
413 : }
414 : #if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
415 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
416 0 : ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
417 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
418 0 : if (IS_ALIGNED(width, 16)) {
419 0 : ARGBToUVRow = ARGBToUVRow_SSSE3;
420 0 : ARGBToYRow = ARGBToYRow_SSSE3;
421 : }
422 : }
423 : #endif
424 : #if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
425 0 : if (TestCpuFlag(kCpuHasAVX2)) {
426 0 : ARGBToUVRow = ARGBToUVRow_Any_AVX2;
427 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
428 0 : if (IS_ALIGNED(width, 32)) {
429 0 : ARGBToUVRow = ARGBToUVRow_AVX2;
430 0 : ARGBToYRow = ARGBToYRow_AVX2;
431 : }
432 : }
433 : #endif
434 : #if defined(HAS_ARGBTOYROW_NEON)
435 : if (TestCpuFlag(kCpuHasNEON)) {
436 : ARGBToYRow = ARGBToYRow_Any_NEON;
437 : if (IS_ALIGNED(width, 8)) {
438 : ARGBToYRow = ARGBToYRow_NEON;
439 : }
440 : }
441 : #endif
442 : #if defined(HAS_ARGBTOUVROW_NEON)
443 : if (TestCpuFlag(kCpuHasNEON)) {
444 : ARGBToUVRow = ARGBToUVRow_Any_NEON;
445 : if (IS_ALIGNED(width, 16)) {
446 : ARGBToUVRow = ARGBToUVRow_NEON;
447 : }
448 : }
449 : #endif
450 : #if defined(HAS_ARGBTOYROW_MSA)
451 : if (TestCpuFlag(kCpuHasMSA)) {
452 : ARGBToYRow = ARGBToYRow_Any_MSA;
453 : if (IS_ALIGNED(width, 16)) {
454 : ARGBToYRow = ARGBToYRow_MSA;
455 : }
456 : }
457 : #endif
458 : #if defined(HAS_ARGBTOUVROW_MSA)
459 : if (TestCpuFlag(kCpuHasMSA)) {
460 : ARGBToUVRow = ARGBToUVRow_Any_MSA;
461 : if (IS_ALIGNED(width, 32)) {
462 : ARGBToUVRow = ARGBToUVRow_MSA;
463 : }
464 : }
465 : #endif
466 : #if defined(HAS_MERGEUVROW_SSE2)
467 0 : if (TestCpuFlag(kCpuHasSSE2)) {
468 0 : MergeUVRow_ = MergeUVRow_Any_SSE2;
469 0 : if (IS_ALIGNED(halfwidth, 16)) {
470 0 : MergeUVRow_ = MergeUVRow_SSE2;
471 : }
472 : }
473 : #endif
474 : #if defined(HAS_MERGEUVROW_AVX2)
475 0 : if (TestCpuFlag(kCpuHasAVX2)) {
476 0 : MergeUVRow_ = MergeUVRow_Any_AVX2;
477 0 : if (IS_ALIGNED(halfwidth, 32)) {
478 0 : MergeUVRow_ = MergeUVRow_AVX2;
479 : }
480 : }
481 : #endif
482 : #if defined(HAS_MERGEUVROW_NEON)
483 : if (TestCpuFlag(kCpuHasNEON)) {
484 : MergeUVRow_ = MergeUVRow_Any_NEON;
485 : if (IS_ALIGNED(halfwidth, 16)) {
486 : MergeUVRow_ = MergeUVRow_NEON;
487 : }
488 : }
489 : #endif
490 : #if defined(HAS_ARGBTOYROW_DSPR2)
491 : if (TestCpuFlag(kCpuHasDSPR2)) {
492 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
493 : if (IS_ALIGNED(width, 8)) {
494 : ARGBToYRow = ARGBToYRow_DSPR2;
495 : }
496 : }
497 : #endif
498 : #if defined(HAS_ARGBTOUVROW_DSPR2)
499 : if (TestCpuFlag(kCpuHasDSPR2)) {
500 : ARGBToUVRow = ARGBToUVRow_Any_DSPR2;
501 : if (IS_ALIGNED(width, 16)) {
502 : ARGBToUVRow = ARGBToUVRow_DSPR2;
503 : }
504 : }
505 : #endif
506 : {
507 : // Allocate a rows of uv.
508 0 : align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
509 0 : uint8* row_v = row_u + ((halfwidth + 31) & ~31);
510 :
511 0 : for (y = 0; y < height - 1; y += 2) {
512 0 : ARGBToUVRow(src_argb, src_stride_argb, row_u, row_v, width);
513 0 : MergeUVRow_(row_v, row_u, dst_uv, halfwidth);
514 0 : ARGBToYRow(src_argb, dst_y, width);
515 0 : ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width);
516 0 : src_argb += src_stride_argb * 2;
517 0 : dst_y += dst_stride_y * 2;
518 0 : dst_uv += dst_stride_uv;
519 : }
520 0 : if (height & 1) {
521 0 : ARGBToUVRow(src_argb, 0, row_u, row_v, width);
522 0 : MergeUVRow_(row_v, row_u, dst_uv, halfwidth);
523 0 : ARGBToYRow(src_argb, dst_y, width);
524 : }
525 0 : free_aligned_buffer_64(row_u);
526 : }
527 0 : return 0;
528 : }
529 :
530 : // Convert ARGB to YUY2.
531 : LIBYUV_API
532 0 : int ARGBToYUY2(const uint8* src_argb,
533 : int src_stride_argb,
534 : uint8* dst_yuy2,
535 : int dst_stride_yuy2,
536 : int width,
537 : int height) {
538 : int y;
539 : void (*ARGBToUVRow)(const uint8* src_argb, int src_stride_argb, uint8* dst_u,
540 0 : uint8* dst_v, int width) = ARGBToUVRow_C;
541 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
542 0 : ARGBToYRow_C;
543 : void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u,
544 : const uint8* src_v, uint8* dst_yuy2, int width) =
545 0 : I422ToYUY2Row_C;
546 :
547 0 : if (!src_argb || !dst_yuy2 || width <= 0 || height == 0) {
548 0 : return -1;
549 : }
550 : // Negative height means invert the image.
551 0 : if (height < 0) {
552 0 : height = -height;
553 0 : dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2;
554 0 : dst_stride_yuy2 = -dst_stride_yuy2;
555 : }
556 : // Coalesce rows.
557 0 : if (src_stride_argb == width * 4 && dst_stride_yuy2 == width * 2) {
558 0 : width *= height;
559 0 : height = 1;
560 0 : src_stride_argb = dst_stride_yuy2 = 0;
561 : }
562 : #if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
563 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
564 0 : ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
565 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
566 0 : if (IS_ALIGNED(width, 16)) {
567 0 : ARGBToUVRow = ARGBToUVRow_SSSE3;
568 0 : ARGBToYRow = ARGBToYRow_SSSE3;
569 : }
570 : }
571 : #endif
572 : #if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
573 0 : if (TestCpuFlag(kCpuHasAVX2)) {
574 0 : ARGBToUVRow = ARGBToUVRow_Any_AVX2;
575 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
576 0 : if (IS_ALIGNED(width, 32)) {
577 0 : ARGBToUVRow = ARGBToUVRow_AVX2;
578 0 : ARGBToYRow = ARGBToYRow_AVX2;
579 : }
580 : }
581 : #endif
582 : #if defined(HAS_ARGBTOYROW_NEON)
583 : if (TestCpuFlag(kCpuHasNEON)) {
584 : ARGBToYRow = ARGBToYRow_Any_NEON;
585 : if (IS_ALIGNED(width, 8)) {
586 : ARGBToYRow = ARGBToYRow_NEON;
587 : }
588 : }
589 : #endif
590 : #if defined(HAS_ARGBTOUVROW_NEON)
591 : if (TestCpuFlag(kCpuHasNEON)) {
592 : ARGBToUVRow = ARGBToUVRow_Any_NEON;
593 : if (IS_ALIGNED(width, 16)) {
594 : ARGBToUVRow = ARGBToUVRow_NEON;
595 : }
596 : }
597 : #endif
598 : #if defined(HAS_ARGBTOYROW_MSA)
599 : if (TestCpuFlag(kCpuHasMSA)) {
600 : ARGBToYRow = ARGBToYRow_Any_MSA;
601 : if (IS_ALIGNED(width, 16)) {
602 : ARGBToYRow = ARGBToYRow_MSA;
603 : }
604 : }
605 : #endif
606 : #if defined(HAS_ARGBTOUVROW_MSA)
607 : if (TestCpuFlag(kCpuHasMSA)) {
608 : ARGBToUVRow = ARGBToUVRow_Any_MSA;
609 : if (IS_ALIGNED(width, 32)) {
610 : ARGBToUVRow = ARGBToUVRow_MSA;
611 : }
612 : }
613 : #endif
614 : #if defined(HAS_I422TOYUY2ROW_SSE2)
615 0 : if (TestCpuFlag(kCpuHasSSE2)) {
616 0 : I422ToYUY2Row = I422ToYUY2Row_Any_SSE2;
617 0 : if (IS_ALIGNED(width, 16)) {
618 0 : I422ToYUY2Row = I422ToYUY2Row_SSE2;
619 : }
620 : }
621 : #endif
622 : #if defined(HAS_I422TOYUY2ROW_NEON)
623 : if (TestCpuFlag(kCpuHasNEON)) {
624 : I422ToYUY2Row = I422ToYUY2Row_Any_NEON;
625 : if (IS_ALIGNED(width, 16)) {
626 : I422ToYUY2Row = I422ToYUY2Row_NEON;
627 : }
628 : }
629 : #endif
630 : #if defined(HAS_ARGBTOYROW_DSPR2)
631 : if (TestCpuFlag(kCpuHasDSPR2)) {
632 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
633 : if (IS_ALIGNED(width, 8)) {
634 : ARGBToYRow = ARGBToYRow_DSPR2;
635 : }
636 : }
637 : #endif
638 : #if defined(HAS_ARGBTOUVROW_DSPR2)
639 : if (TestCpuFlag(kCpuHasDSPR2)) {
640 : ARGBToUVRow = ARGBToUVRow_Any_DSPR2;
641 : if (IS_ALIGNED(width, 16)) {
642 : ARGBToUVRow = ARGBToUVRow_DSPR2;
643 : }
644 : }
645 : #endif
646 : #if defined(HAS_I422TOYUY2ROW_MSA)
647 : if (TestCpuFlag(kCpuHasMSA)) {
648 : I422ToYUY2Row = I422ToYUY2Row_Any_MSA;
649 : if (IS_ALIGNED(width, 32)) {
650 : I422ToYUY2Row = I422ToYUY2Row_MSA;
651 : }
652 : }
653 : #endif
654 :
655 : {
656 : // Allocate a rows of yuv.
657 0 : align_buffer_64(row_y, ((width + 63) & ~63) * 2);
658 0 : uint8* row_u = row_y + ((width + 63) & ~63);
659 0 : uint8* row_v = row_u + ((width + 63) & ~63) / 2;
660 :
661 0 : for (y = 0; y < height; ++y) {
662 0 : ARGBToUVRow(src_argb, 0, row_u, row_v, width);
663 0 : ARGBToYRow(src_argb, row_y, width);
664 0 : I422ToYUY2Row(row_y, row_u, row_v, dst_yuy2, width);
665 0 : src_argb += src_stride_argb;
666 0 : dst_yuy2 += dst_stride_yuy2;
667 : }
668 :
669 0 : free_aligned_buffer_64(row_y);
670 : }
671 0 : return 0;
672 : }
673 :
674 : // Convert ARGB to UYVY.
675 : LIBYUV_API
676 0 : int ARGBToUYVY(const uint8* src_argb,
677 : int src_stride_argb,
678 : uint8* dst_uyvy,
679 : int dst_stride_uyvy,
680 : int width,
681 : int height) {
682 : int y;
683 : void (*ARGBToUVRow)(const uint8* src_argb, int src_stride_argb, uint8* dst_u,
684 0 : uint8* dst_v, int width) = ARGBToUVRow_C;
685 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
686 0 : ARGBToYRow_C;
687 : void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u,
688 : const uint8* src_v, uint8* dst_uyvy, int width) =
689 0 : I422ToUYVYRow_C;
690 :
691 0 : if (!src_argb || !dst_uyvy || width <= 0 || height == 0) {
692 0 : return -1;
693 : }
694 : // Negative height means invert the image.
695 0 : if (height < 0) {
696 0 : height = -height;
697 0 : dst_uyvy = dst_uyvy + (height - 1) * dst_stride_uyvy;
698 0 : dst_stride_uyvy = -dst_stride_uyvy;
699 : }
700 : // Coalesce rows.
701 0 : if (src_stride_argb == width * 4 && dst_stride_uyvy == width * 2) {
702 0 : width *= height;
703 0 : height = 1;
704 0 : src_stride_argb = dst_stride_uyvy = 0;
705 : }
706 : #if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
707 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
708 0 : ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
709 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
710 0 : if (IS_ALIGNED(width, 16)) {
711 0 : ARGBToUVRow = ARGBToUVRow_SSSE3;
712 0 : ARGBToYRow = ARGBToYRow_SSSE3;
713 : }
714 : }
715 : #endif
716 : #if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2)
717 0 : if (TestCpuFlag(kCpuHasAVX2)) {
718 0 : ARGBToUVRow = ARGBToUVRow_Any_AVX2;
719 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
720 0 : if (IS_ALIGNED(width, 32)) {
721 0 : ARGBToUVRow = ARGBToUVRow_AVX2;
722 0 : ARGBToYRow = ARGBToYRow_AVX2;
723 : }
724 : }
725 : #endif
726 : #if defined(HAS_ARGBTOYROW_NEON)
727 : if (TestCpuFlag(kCpuHasNEON)) {
728 : ARGBToYRow = ARGBToYRow_Any_NEON;
729 : if (IS_ALIGNED(width, 8)) {
730 : ARGBToYRow = ARGBToYRow_NEON;
731 : }
732 : }
733 : #endif
734 : #if defined(HAS_ARGBTOUVROW_NEON)
735 : if (TestCpuFlag(kCpuHasNEON)) {
736 : ARGBToUVRow = ARGBToUVRow_Any_NEON;
737 : if (IS_ALIGNED(width, 16)) {
738 : ARGBToUVRow = ARGBToUVRow_NEON;
739 : }
740 : }
741 : #endif
742 : #if defined(HAS_ARGBTOYROW_MSA)
743 : if (TestCpuFlag(kCpuHasMSA)) {
744 : ARGBToYRow = ARGBToYRow_Any_MSA;
745 : if (IS_ALIGNED(width, 16)) {
746 : ARGBToYRow = ARGBToYRow_MSA;
747 : }
748 : }
749 : #endif
750 : #if defined(HAS_ARGBTOUVROW_MSA)
751 : if (TestCpuFlag(kCpuHasMSA)) {
752 : ARGBToUVRow = ARGBToUVRow_Any_MSA;
753 : if (IS_ALIGNED(width, 32)) {
754 : ARGBToUVRow = ARGBToUVRow_MSA;
755 : }
756 : }
757 : #endif
758 : #if defined(HAS_I422TOUYVYROW_SSE2)
759 0 : if (TestCpuFlag(kCpuHasSSE2)) {
760 0 : I422ToUYVYRow = I422ToUYVYRow_Any_SSE2;
761 0 : if (IS_ALIGNED(width, 16)) {
762 0 : I422ToUYVYRow = I422ToUYVYRow_SSE2;
763 : }
764 : }
765 : #endif
766 : #if defined(HAS_I422TOUYVYROW_NEON)
767 : if (TestCpuFlag(kCpuHasNEON)) {
768 : I422ToUYVYRow = I422ToUYVYRow_Any_NEON;
769 : if (IS_ALIGNED(width, 16)) {
770 : I422ToUYVYRow = I422ToUYVYRow_NEON;
771 : }
772 : }
773 : #endif
774 : #if defined(HAS_ARGBTOYROW_DSPR2)
775 : if (TestCpuFlag(kCpuHasDSPR2)) {
776 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
777 : if (IS_ALIGNED(width, 8)) {
778 : ARGBToYRow = ARGBToYRow_DSPR2;
779 : }
780 : }
781 : #endif
782 : #if defined(HAS_ARGBTOUVROW_DSPR2)
783 : if (TestCpuFlag(kCpuHasDSPR2)) {
784 : ARGBToUVRow = ARGBToUVRow_Any_DSPR2;
785 : if (IS_ALIGNED(width, 16)) {
786 : ARGBToUVRow = ARGBToUVRow_DSPR2;
787 : }
788 : }
789 : #endif
790 : #if defined(HAS_I422TOUYVYROW_MSA)
791 : if (TestCpuFlag(kCpuHasMSA)) {
792 : I422ToUYVYRow = I422ToUYVYRow_Any_MSA;
793 : if (IS_ALIGNED(width, 32)) {
794 : I422ToUYVYRow = I422ToUYVYRow_MSA;
795 : }
796 : }
797 : #endif
798 :
799 : {
800 : // Allocate a rows of yuv.
801 0 : align_buffer_64(row_y, ((width + 63) & ~63) * 2);
802 0 : uint8* row_u = row_y + ((width + 63) & ~63);
803 0 : uint8* row_v = row_u + ((width + 63) & ~63) / 2;
804 :
805 0 : for (y = 0; y < height; ++y) {
806 0 : ARGBToUVRow(src_argb, 0, row_u, row_v, width);
807 0 : ARGBToYRow(src_argb, row_y, width);
808 0 : I422ToUYVYRow(row_y, row_u, row_v, dst_uyvy, width);
809 0 : src_argb += src_stride_argb;
810 0 : dst_uyvy += dst_stride_uyvy;
811 : }
812 :
813 0 : free_aligned_buffer_64(row_y);
814 : }
815 0 : return 0;
816 : }
817 :
818 : // Convert ARGB to I400.
819 : LIBYUV_API
820 0 : int ARGBToI400(const uint8* src_argb,
821 : int src_stride_argb,
822 : uint8* dst_y,
823 : int dst_stride_y,
824 : int width,
825 : int height) {
826 : int y;
827 : void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int width) =
828 0 : ARGBToYRow_C;
829 0 : if (!src_argb || !dst_y || width <= 0 || height == 0) {
830 0 : return -1;
831 : }
832 0 : if (height < 0) {
833 0 : height = -height;
834 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
835 0 : src_stride_argb = -src_stride_argb;
836 : }
837 : // Coalesce rows.
838 0 : if (src_stride_argb == width * 4 && dst_stride_y == width) {
839 0 : width *= height;
840 0 : height = 1;
841 0 : src_stride_argb = dst_stride_y = 0;
842 : }
843 : #if defined(HAS_ARGBTOYROW_SSSE3)
844 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
845 0 : ARGBToYRow = ARGBToYRow_Any_SSSE3;
846 0 : if (IS_ALIGNED(width, 16)) {
847 0 : ARGBToYRow = ARGBToYRow_SSSE3;
848 : }
849 : }
850 : #endif
851 : #if defined(HAS_ARGBTOYROW_AVX2)
852 0 : if (TestCpuFlag(kCpuHasAVX2)) {
853 0 : ARGBToYRow = ARGBToYRow_Any_AVX2;
854 0 : if (IS_ALIGNED(width, 32)) {
855 0 : ARGBToYRow = ARGBToYRow_AVX2;
856 : }
857 : }
858 : #endif
859 : #if defined(HAS_ARGBTOYROW_NEON)
860 : if (TestCpuFlag(kCpuHasNEON)) {
861 : ARGBToYRow = ARGBToYRow_Any_NEON;
862 : if (IS_ALIGNED(width, 8)) {
863 : ARGBToYRow = ARGBToYRow_NEON;
864 : }
865 : }
866 : #endif
867 : #if defined(HAS_ARGBTOYROW_DSPR2)
868 : if (TestCpuFlag(kCpuHasDSPR2)) {
869 : ARGBToYRow = ARGBToYRow_Any_DSPR2;
870 : if (IS_ALIGNED(width, 8)) {
871 : ARGBToYRow = ARGBToYRow_DSPR2;
872 : }
873 : }
874 : #endif
875 : #if defined(HAS_ARGBTOYROW_MSA)
876 : if (TestCpuFlag(kCpuHasMSA)) {
877 : ARGBToYRow = ARGBToYRow_Any_MSA;
878 : if (IS_ALIGNED(width, 16)) {
879 : ARGBToYRow = ARGBToYRow_MSA;
880 : }
881 : }
882 : #endif
883 :
884 0 : for (y = 0; y < height; ++y) {
885 0 : ARGBToYRow(src_argb, dst_y, width);
886 0 : src_argb += src_stride_argb;
887 0 : dst_y += dst_stride_y;
888 : }
889 0 : return 0;
890 : }
891 :
892 : // Shuffle table for converting ARGB to RGBA.
893 : static uvec8 kShuffleMaskARGBToRGBA = {3u, 0u, 1u, 2u, 7u, 4u, 5u, 6u,
894 : 11u, 8u, 9u, 10u, 15u, 12u, 13u, 14u};
895 :
896 : // Convert ARGB to RGBA.
897 : LIBYUV_API
898 0 : int ARGBToRGBA(const uint8* src_argb,
899 : int src_stride_argb,
900 : uint8* dst_rgba,
901 : int dst_stride_rgba,
902 : int width,
903 : int height) {
904 : return ARGBShuffle(src_argb, src_stride_argb, dst_rgba, dst_stride_rgba,
905 0 : (const uint8*)(&kShuffleMaskARGBToRGBA), width, height);
906 : }
907 :
908 : // Convert ARGB To RGB24.
909 : LIBYUV_API
910 0 : int ARGBToRGB24(const uint8* src_argb,
911 : int src_stride_argb,
912 : uint8* dst_rgb24,
913 : int dst_stride_rgb24,
914 : int width,
915 : int height) {
916 : int y;
917 : void (*ARGBToRGB24Row)(const uint8* src_argb, uint8* dst_rgb, int width) =
918 0 : ARGBToRGB24Row_C;
919 0 : if (!src_argb || !dst_rgb24 || width <= 0 || height == 0) {
920 0 : return -1;
921 : }
922 0 : if (height < 0) {
923 0 : height = -height;
924 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
925 0 : src_stride_argb = -src_stride_argb;
926 : }
927 : // Coalesce rows.
928 0 : if (src_stride_argb == width * 4 && dst_stride_rgb24 == width * 3) {
929 0 : width *= height;
930 0 : height = 1;
931 0 : src_stride_argb = dst_stride_rgb24 = 0;
932 : }
933 : #if defined(HAS_ARGBTORGB24ROW_SSSE3)
934 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
935 0 : ARGBToRGB24Row = ARGBToRGB24Row_Any_SSSE3;
936 0 : if (IS_ALIGNED(width, 16)) {
937 0 : ARGBToRGB24Row = ARGBToRGB24Row_SSSE3;
938 : }
939 : }
940 : #endif
941 : #if defined(HAS_ARGBTORGB24ROW_NEON)
942 : if (TestCpuFlag(kCpuHasNEON)) {
943 : ARGBToRGB24Row = ARGBToRGB24Row_Any_NEON;
944 : if (IS_ALIGNED(width, 8)) {
945 : ARGBToRGB24Row = ARGBToRGB24Row_NEON;
946 : }
947 : }
948 : #endif
949 : #if defined(HAS_ARGBTORGB24ROW_MSA)
950 : if (TestCpuFlag(kCpuHasMSA)) {
951 : ARGBToRGB24Row = ARGBToRGB24Row_Any_MSA;
952 : if (IS_ALIGNED(width, 16)) {
953 : ARGBToRGB24Row = ARGBToRGB24Row_MSA;
954 : }
955 : }
956 : #endif
957 :
958 0 : for (y = 0; y < height; ++y) {
959 0 : ARGBToRGB24Row(src_argb, dst_rgb24, width);
960 0 : src_argb += src_stride_argb;
961 0 : dst_rgb24 += dst_stride_rgb24;
962 : }
963 0 : return 0;
964 : }
965 :
966 : // Convert ARGB To RAW.
967 : LIBYUV_API
968 0 : int ARGBToRAW(const uint8* src_argb,
969 : int src_stride_argb,
970 : uint8* dst_raw,
971 : int dst_stride_raw,
972 : int width,
973 : int height) {
974 : int y;
975 : void (*ARGBToRAWRow)(const uint8* src_argb, uint8* dst_rgb, int width) =
976 0 : ARGBToRAWRow_C;
977 0 : if (!src_argb || !dst_raw || width <= 0 || height == 0) {
978 0 : return -1;
979 : }
980 0 : if (height < 0) {
981 0 : height = -height;
982 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
983 0 : src_stride_argb = -src_stride_argb;
984 : }
985 : // Coalesce rows.
986 0 : if (src_stride_argb == width * 4 && dst_stride_raw == width * 3) {
987 0 : width *= height;
988 0 : height = 1;
989 0 : src_stride_argb = dst_stride_raw = 0;
990 : }
991 : #if defined(HAS_ARGBTORAWROW_SSSE3)
992 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
993 0 : ARGBToRAWRow = ARGBToRAWRow_Any_SSSE3;
994 0 : if (IS_ALIGNED(width, 16)) {
995 0 : ARGBToRAWRow = ARGBToRAWRow_SSSE3;
996 : }
997 : }
998 : #endif
999 : #if defined(HAS_ARGBTORAWROW_NEON)
1000 : if (TestCpuFlag(kCpuHasNEON)) {
1001 : ARGBToRAWRow = ARGBToRAWRow_Any_NEON;
1002 : if (IS_ALIGNED(width, 8)) {
1003 : ARGBToRAWRow = ARGBToRAWRow_NEON;
1004 : }
1005 : }
1006 : #endif
1007 : #if defined(HAS_ARGBTORAWROW_MSA)
1008 : if (TestCpuFlag(kCpuHasMSA)) {
1009 : ARGBToRAWRow = ARGBToRAWRow_Any_MSA;
1010 : if (IS_ALIGNED(width, 16)) {
1011 : ARGBToRAWRow = ARGBToRAWRow_MSA;
1012 : }
1013 : }
1014 : #endif
1015 :
1016 0 : for (y = 0; y < height; ++y) {
1017 0 : ARGBToRAWRow(src_argb, dst_raw, width);
1018 0 : src_argb += src_stride_argb;
1019 0 : dst_raw += dst_stride_raw;
1020 : }
1021 0 : return 0;
1022 : }
1023 :
1024 : // Ordered 8x8 dither for 888 to 565. Values from 0 to 7.
1025 : static const uint8 kDither565_4x4[16] = {
1026 : 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2,
1027 : };
1028 :
1029 : // Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes).
1030 : LIBYUV_API
1031 0 : int ARGBToRGB565Dither(const uint8* src_argb,
1032 : int src_stride_argb,
1033 : uint8* dst_rgb565,
1034 : int dst_stride_rgb565,
1035 : const uint8* dither4x4,
1036 : int width,
1037 : int height) {
1038 : int y;
1039 : void (*ARGBToRGB565DitherRow)(const uint8* src_argb, uint8* dst_rgb,
1040 : const uint32 dither4, int width) =
1041 0 : ARGBToRGB565DitherRow_C;
1042 0 : if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) {
1043 0 : return -1;
1044 : }
1045 0 : if (height < 0) {
1046 0 : height = -height;
1047 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1048 0 : src_stride_argb = -src_stride_argb;
1049 : }
1050 0 : if (!dither4x4) {
1051 0 : dither4x4 = kDither565_4x4;
1052 : }
1053 : #if defined(HAS_ARGBTORGB565DITHERROW_SSE2)
1054 0 : if (TestCpuFlag(kCpuHasSSE2)) {
1055 0 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2;
1056 0 : if (IS_ALIGNED(width, 4)) {
1057 0 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SSE2;
1058 : }
1059 : }
1060 : #endif
1061 : #if defined(HAS_ARGBTORGB565DITHERROW_AVX2)
1062 0 : if (TestCpuFlag(kCpuHasAVX2)) {
1063 0 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2;
1064 0 : if (IS_ALIGNED(width, 8)) {
1065 0 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2;
1066 : }
1067 : }
1068 : #endif
1069 : #if defined(HAS_ARGBTORGB565DITHERROW_NEON)
1070 : if (TestCpuFlag(kCpuHasNEON)) {
1071 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON;
1072 : if (IS_ALIGNED(width, 8)) {
1073 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON;
1074 : }
1075 : }
1076 : #endif
1077 : #if defined(HAS_ARGBTORGB565DITHERROW_MSA)
1078 : if (TestCpuFlag(kCpuHasMSA)) {
1079 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA;
1080 : if (IS_ALIGNED(width, 8)) {
1081 : ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA;
1082 : }
1083 : }
1084 : #endif
1085 :
1086 0 : for (y = 0; y < height; ++y) {
1087 0 : ARGBToRGB565DitherRow(src_argb, dst_rgb565,
1088 0 : *(uint32*)(dither4x4 + ((y & 3) << 2)),
1089 0 : width); /* NOLINT */
1090 0 : src_argb += src_stride_argb;
1091 0 : dst_rgb565 += dst_stride_rgb565;
1092 : }
1093 0 : return 0;
1094 : }
1095 :
1096 : // Convert ARGB To RGB565.
1097 : // TODO(fbarchard): Consider using dither function low level with zeros.
1098 : LIBYUV_API
1099 0 : int ARGBToRGB565(const uint8* src_argb,
1100 : int src_stride_argb,
1101 : uint8* dst_rgb565,
1102 : int dst_stride_rgb565,
1103 : int width,
1104 : int height) {
1105 : int y;
1106 : void (*ARGBToRGB565Row)(const uint8* src_argb, uint8* dst_rgb, int width) =
1107 0 : ARGBToRGB565Row_C;
1108 0 : if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) {
1109 0 : return -1;
1110 : }
1111 0 : if (height < 0) {
1112 0 : height = -height;
1113 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1114 0 : src_stride_argb = -src_stride_argb;
1115 : }
1116 : // Coalesce rows.
1117 0 : if (src_stride_argb == width * 4 && dst_stride_rgb565 == width * 2) {
1118 0 : width *= height;
1119 0 : height = 1;
1120 0 : src_stride_argb = dst_stride_rgb565 = 0;
1121 : }
1122 : #if defined(HAS_ARGBTORGB565ROW_SSE2)
1123 0 : if (TestCpuFlag(kCpuHasSSE2)) {
1124 0 : ARGBToRGB565Row = ARGBToRGB565Row_Any_SSE2;
1125 0 : if (IS_ALIGNED(width, 4)) {
1126 0 : ARGBToRGB565Row = ARGBToRGB565Row_SSE2;
1127 : }
1128 : }
1129 : #endif
1130 : #if defined(HAS_ARGBTORGB565ROW_AVX2)
1131 : if (TestCpuFlag(kCpuHasAVX2)) {
1132 : ARGBToRGB565Row = ARGBToRGB565Row_Any_AVX2;
1133 : if (IS_ALIGNED(width, 8)) {
1134 : ARGBToRGB565Row = ARGBToRGB565Row_AVX2;
1135 : }
1136 : }
1137 : #endif
1138 : #if defined(HAS_ARGBTORGB565ROW_NEON)
1139 : if (TestCpuFlag(kCpuHasNEON)) {
1140 : ARGBToRGB565Row = ARGBToRGB565Row_Any_NEON;
1141 : if (IS_ALIGNED(width, 8)) {
1142 : ARGBToRGB565Row = ARGBToRGB565Row_NEON;
1143 : }
1144 : }
1145 : #endif
1146 : #if defined(HAS_ARGBTORGB565ROW_MSA)
1147 : if (TestCpuFlag(kCpuHasMSA)) {
1148 : ARGBToRGB565Row = ARGBToRGB565Row_Any_MSA;
1149 : if (IS_ALIGNED(width, 8)) {
1150 : ARGBToRGB565Row = ARGBToRGB565Row_MSA;
1151 : }
1152 : }
1153 : #endif
1154 :
1155 0 : for (y = 0; y < height; ++y) {
1156 0 : ARGBToRGB565Row(src_argb, dst_rgb565, width);
1157 0 : src_argb += src_stride_argb;
1158 0 : dst_rgb565 += dst_stride_rgb565;
1159 : }
1160 0 : return 0;
1161 : }
1162 :
1163 : // Convert ARGB To ARGB1555.
1164 : LIBYUV_API
1165 0 : int ARGBToARGB1555(const uint8* src_argb,
1166 : int src_stride_argb,
1167 : uint8* dst_argb1555,
1168 : int dst_stride_argb1555,
1169 : int width,
1170 : int height) {
1171 : int y;
1172 : void (*ARGBToARGB1555Row)(const uint8* src_argb, uint8* dst_rgb, int width) =
1173 0 : ARGBToARGB1555Row_C;
1174 0 : if (!src_argb || !dst_argb1555 || width <= 0 || height == 0) {
1175 0 : return -1;
1176 : }
1177 0 : if (height < 0) {
1178 0 : height = -height;
1179 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1180 0 : src_stride_argb = -src_stride_argb;
1181 : }
1182 : // Coalesce rows.
1183 0 : if (src_stride_argb == width * 4 && dst_stride_argb1555 == width * 2) {
1184 0 : width *= height;
1185 0 : height = 1;
1186 0 : src_stride_argb = dst_stride_argb1555 = 0;
1187 : }
1188 : #if defined(HAS_ARGBTOARGB1555ROW_SSE2)
1189 0 : if (TestCpuFlag(kCpuHasSSE2)) {
1190 0 : ARGBToARGB1555Row = ARGBToARGB1555Row_Any_SSE2;
1191 0 : if (IS_ALIGNED(width, 4)) {
1192 0 : ARGBToARGB1555Row = ARGBToARGB1555Row_SSE2;
1193 : }
1194 : }
1195 : #endif
1196 : #if defined(HAS_ARGBTOARGB1555ROW_AVX2)
1197 : if (TestCpuFlag(kCpuHasAVX2)) {
1198 : ARGBToARGB1555Row = ARGBToARGB1555Row_Any_AVX2;
1199 : if (IS_ALIGNED(width, 8)) {
1200 : ARGBToARGB1555Row = ARGBToARGB1555Row_AVX2;
1201 : }
1202 : }
1203 : #endif
1204 : #if defined(HAS_ARGBTOARGB1555ROW_NEON)
1205 : if (TestCpuFlag(kCpuHasNEON)) {
1206 : ARGBToARGB1555Row = ARGBToARGB1555Row_Any_NEON;
1207 : if (IS_ALIGNED(width, 8)) {
1208 : ARGBToARGB1555Row = ARGBToARGB1555Row_NEON;
1209 : }
1210 : }
1211 : #endif
1212 : #if defined(HAS_ARGBTOARGB1555ROW_MSA)
1213 : if (TestCpuFlag(kCpuHasMSA)) {
1214 : ARGBToARGB1555Row = ARGBToARGB1555Row_Any_MSA;
1215 : if (IS_ALIGNED(width, 8)) {
1216 : ARGBToARGB1555Row = ARGBToARGB1555Row_MSA;
1217 : }
1218 : }
1219 : #endif
1220 :
1221 0 : for (y = 0; y < height; ++y) {
1222 0 : ARGBToARGB1555Row(src_argb, dst_argb1555, width);
1223 0 : src_argb += src_stride_argb;
1224 0 : dst_argb1555 += dst_stride_argb1555;
1225 : }
1226 0 : return 0;
1227 : }
1228 :
1229 : // Convert ARGB To ARGB4444.
1230 : LIBYUV_API
1231 0 : int ARGBToARGB4444(const uint8* src_argb,
1232 : int src_stride_argb,
1233 : uint8* dst_argb4444,
1234 : int dst_stride_argb4444,
1235 : int width,
1236 : int height) {
1237 : int y;
1238 : void (*ARGBToARGB4444Row)(const uint8* src_argb, uint8* dst_rgb, int width) =
1239 0 : ARGBToARGB4444Row_C;
1240 0 : if (!src_argb || !dst_argb4444 || width <= 0 || height == 0) {
1241 0 : return -1;
1242 : }
1243 0 : if (height < 0) {
1244 0 : height = -height;
1245 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1246 0 : src_stride_argb = -src_stride_argb;
1247 : }
1248 : // Coalesce rows.
1249 0 : if (src_stride_argb == width * 4 && dst_stride_argb4444 == width * 2) {
1250 0 : width *= height;
1251 0 : height = 1;
1252 0 : src_stride_argb = dst_stride_argb4444 = 0;
1253 : }
1254 : #if defined(HAS_ARGBTOARGB4444ROW_SSE2)
1255 0 : if (TestCpuFlag(kCpuHasSSE2)) {
1256 0 : ARGBToARGB4444Row = ARGBToARGB4444Row_Any_SSE2;
1257 0 : if (IS_ALIGNED(width, 4)) {
1258 0 : ARGBToARGB4444Row = ARGBToARGB4444Row_SSE2;
1259 : }
1260 : }
1261 : #endif
1262 : #if defined(HAS_ARGBTOARGB4444ROW_AVX2)
1263 : if (TestCpuFlag(kCpuHasAVX2)) {
1264 : ARGBToARGB4444Row = ARGBToARGB4444Row_Any_AVX2;
1265 : if (IS_ALIGNED(width, 8)) {
1266 : ARGBToARGB4444Row = ARGBToARGB4444Row_AVX2;
1267 : }
1268 : }
1269 : #endif
1270 : #if defined(HAS_ARGBTOARGB4444ROW_NEON)
1271 : if (TestCpuFlag(kCpuHasNEON)) {
1272 : ARGBToARGB4444Row = ARGBToARGB4444Row_Any_NEON;
1273 : if (IS_ALIGNED(width, 8)) {
1274 : ARGBToARGB4444Row = ARGBToARGB4444Row_NEON;
1275 : }
1276 : }
1277 : #endif
1278 : #if defined(HAS_ARGBTOARGB4444ROW_MSA)
1279 : if (TestCpuFlag(kCpuHasMSA)) {
1280 : ARGBToARGB4444Row = ARGBToARGB4444Row_Any_MSA;
1281 : if (IS_ALIGNED(width, 8)) {
1282 : ARGBToARGB4444Row = ARGBToARGB4444Row_MSA;
1283 : }
1284 : }
1285 : #endif
1286 :
1287 0 : for (y = 0; y < height; ++y) {
1288 0 : ARGBToARGB4444Row(src_argb, dst_argb4444, width);
1289 0 : src_argb += src_stride_argb;
1290 0 : dst_argb4444 += dst_stride_argb4444;
1291 : }
1292 0 : return 0;
1293 : }
1294 :
1295 : // Convert ARGB to J420. (JPeg full range I420).
1296 : LIBYUV_API
1297 0 : int ARGBToJ420(const uint8* src_argb,
1298 : int src_stride_argb,
1299 : uint8* dst_yj,
1300 : int dst_stride_yj,
1301 : uint8* dst_u,
1302 : int dst_stride_u,
1303 : uint8* dst_v,
1304 : int dst_stride_v,
1305 : int width,
1306 : int height) {
1307 : int y;
1308 : void (*ARGBToUVJRow)(const uint8* src_argb0, int src_stride_argb,
1309 0 : uint8* dst_u, uint8* dst_v, int width) = ARGBToUVJRow_C;
1310 : void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) =
1311 0 : ARGBToYJRow_C;
1312 0 : if (!src_argb || !dst_yj || !dst_u || !dst_v || width <= 0 || height == 0) {
1313 0 : return -1;
1314 : }
1315 : // Negative height means invert the image.
1316 0 : if (height < 0) {
1317 0 : height = -height;
1318 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1319 0 : src_stride_argb = -src_stride_argb;
1320 : }
1321 : #if defined(HAS_ARGBTOYJROW_SSSE3) && defined(HAS_ARGBTOUVJROW_SSSE3)
1322 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
1323 0 : ARGBToUVJRow = ARGBToUVJRow_Any_SSSE3;
1324 0 : ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
1325 0 : if (IS_ALIGNED(width, 16)) {
1326 0 : ARGBToUVJRow = ARGBToUVJRow_SSSE3;
1327 0 : ARGBToYJRow = ARGBToYJRow_SSSE3;
1328 : }
1329 : }
1330 : #endif
1331 : #if defined(HAS_ARGBTOYJROW_AVX2)
1332 0 : if (TestCpuFlag(kCpuHasAVX2)) {
1333 0 : ARGBToYJRow = ARGBToYJRow_Any_AVX2;
1334 0 : if (IS_ALIGNED(width, 32)) {
1335 0 : ARGBToYJRow = ARGBToYJRow_AVX2;
1336 : }
1337 : }
1338 : #endif
1339 : #if defined(HAS_ARGBTOYJROW_NEON)
1340 : if (TestCpuFlag(kCpuHasNEON)) {
1341 : ARGBToYJRow = ARGBToYJRow_Any_NEON;
1342 : if (IS_ALIGNED(width, 8)) {
1343 : ARGBToYJRow = ARGBToYJRow_NEON;
1344 : }
1345 : }
1346 : #endif
1347 : #if defined(HAS_ARGBTOUVJROW_NEON)
1348 : if (TestCpuFlag(kCpuHasNEON)) {
1349 : ARGBToUVJRow = ARGBToUVJRow_Any_NEON;
1350 : if (IS_ALIGNED(width, 16)) {
1351 : ARGBToUVJRow = ARGBToUVJRow_NEON;
1352 : }
1353 : }
1354 : #endif
1355 : #if defined(HAS_ARGBTOYJROW_MSA)
1356 : if (TestCpuFlag(kCpuHasMSA)) {
1357 : ARGBToYJRow = ARGBToYJRow_Any_MSA;
1358 : if (IS_ALIGNED(width, 16)) {
1359 : ARGBToYJRow = ARGBToYJRow_MSA;
1360 : }
1361 : }
1362 : #endif
1363 : #if defined(HAS_ARGBTOUVJROW_MSA)
1364 : if (TestCpuFlag(kCpuHasMSA)) {
1365 : ARGBToUVJRow = ARGBToUVJRow_Any_MSA;
1366 : if (IS_ALIGNED(width, 32)) {
1367 : ARGBToUVJRow = ARGBToUVJRow_MSA;
1368 : }
1369 : }
1370 : #endif
1371 :
1372 0 : for (y = 0; y < height - 1; y += 2) {
1373 0 : ARGBToUVJRow(src_argb, src_stride_argb, dst_u, dst_v, width);
1374 0 : ARGBToYJRow(src_argb, dst_yj, width);
1375 0 : ARGBToYJRow(src_argb + src_stride_argb, dst_yj + dst_stride_yj, width);
1376 0 : src_argb += src_stride_argb * 2;
1377 0 : dst_yj += dst_stride_yj * 2;
1378 0 : dst_u += dst_stride_u;
1379 0 : dst_v += dst_stride_v;
1380 : }
1381 0 : if (height & 1) {
1382 0 : ARGBToUVJRow(src_argb, 0, dst_u, dst_v, width);
1383 0 : ARGBToYJRow(src_argb, dst_yj, width);
1384 : }
1385 0 : return 0;
1386 : }
1387 :
1388 : // Convert ARGB to J422. (JPeg full range I422).
1389 : LIBYUV_API
1390 0 : int ARGBToJ422(const uint8* src_argb,
1391 : int src_stride_argb,
1392 : uint8* dst_yj,
1393 : int dst_stride_yj,
1394 : uint8* dst_u,
1395 : int dst_stride_u,
1396 : uint8* dst_v,
1397 : int dst_stride_v,
1398 : int width,
1399 : int height) {
1400 : int y;
1401 : void (*ARGBToUVJRow)(const uint8* src_argb0, int src_stride_argb,
1402 0 : uint8* dst_u, uint8* dst_v, int width) = ARGBToUVJRow_C;
1403 : void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) =
1404 0 : ARGBToYJRow_C;
1405 0 : if (!src_argb || !dst_yj || !dst_u || !dst_v || width <= 0 || height == 0) {
1406 0 : return -1;
1407 : }
1408 : // Negative height means invert the image.
1409 0 : if (height < 0) {
1410 0 : height = -height;
1411 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1412 0 : src_stride_argb = -src_stride_argb;
1413 : }
1414 : // Coalesce rows.
1415 0 : if (src_stride_argb == width * 4 && dst_stride_yj == width &&
1416 0 : dst_stride_u * 2 == width && dst_stride_v * 2 == width) {
1417 0 : width *= height;
1418 0 : height = 1;
1419 0 : src_stride_argb = dst_stride_yj = dst_stride_u = dst_stride_v = 0;
1420 : }
1421 : #if defined(HAS_ARGBTOYJROW_SSSE3) && defined(HAS_ARGBTOUVJROW_SSSE3)
1422 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
1423 0 : ARGBToUVJRow = ARGBToUVJRow_Any_SSSE3;
1424 0 : ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
1425 0 : if (IS_ALIGNED(width, 16)) {
1426 0 : ARGBToUVJRow = ARGBToUVJRow_SSSE3;
1427 0 : ARGBToYJRow = ARGBToYJRow_SSSE3;
1428 : }
1429 : }
1430 : #endif
1431 : #if defined(HAS_ARGBTOYJROW_AVX2)
1432 0 : if (TestCpuFlag(kCpuHasAVX2)) {
1433 0 : ARGBToYJRow = ARGBToYJRow_Any_AVX2;
1434 0 : if (IS_ALIGNED(width, 32)) {
1435 0 : ARGBToYJRow = ARGBToYJRow_AVX2;
1436 : }
1437 : }
1438 : #endif
1439 : #if defined(HAS_ARGBTOYJROW_NEON)
1440 : if (TestCpuFlag(kCpuHasNEON)) {
1441 : ARGBToYJRow = ARGBToYJRow_Any_NEON;
1442 : if (IS_ALIGNED(width, 8)) {
1443 : ARGBToYJRow = ARGBToYJRow_NEON;
1444 : }
1445 : }
1446 : #endif
1447 : #if defined(HAS_ARGBTOUVJROW_NEON)
1448 : if (TestCpuFlag(kCpuHasNEON)) {
1449 : ARGBToUVJRow = ARGBToUVJRow_Any_NEON;
1450 : if (IS_ALIGNED(width, 16)) {
1451 : ARGBToUVJRow = ARGBToUVJRow_NEON;
1452 : }
1453 : }
1454 : #endif
1455 : #if defined(HAS_ARGBTOYJROW_MSA)
1456 : if (TestCpuFlag(kCpuHasMSA)) {
1457 : ARGBToYJRow = ARGBToYJRow_Any_MSA;
1458 : if (IS_ALIGNED(width, 16)) {
1459 : ARGBToYJRow = ARGBToYJRow_MSA;
1460 : }
1461 : }
1462 : #endif
1463 : #if defined(HAS_ARGBTOUVJROW_MSA)
1464 : if (TestCpuFlag(kCpuHasMSA)) {
1465 : ARGBToUVJRow = ARGBToUVJRow_Any_MSA;
1466 : if (IS_ALIGNED(width, 32)) {
1467 : ARGBToUVJRow = ARGBToUVJRow_MSA;
1468 : }
1469 : }
1470 : #endif
1471 :
1472 0 : for (y = 0; y < height; ++y) {
1473 0 : ARGBToUVJRow(src_argb, 0, dst_u, dst_v, width);
1474 0 : ARGBToYJRow(src_argb, dst_yj, width);
1475 0 : src_argb += src_stride_argb;
1476 0 : dst_yj += dst_stride_yj;
1477 0 : dst_u += dst_stride_u;
1478 0 : dst_v += dst_stride_v;
1479 : }
1480 0 : return 0;
1481 : }
1482 :
1483 : // Convert ARGB to J400.
1484 : LIBYUV_API
1485 0 : int ARGBToJ400(const uint8* src_argb,
1486 : int src_stride_argb,
1487 : uint8* dst_yj,
1488 : int dst_stride_yj,
1489 : int width,
1490 : int height) {
1491 : int y;
1492 : void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_yj, int width) =
1493 0 : ARGBToYJRow_C;
1494 0 : if (!src_argb || !dst_yj || width <= 0 || height == 0) {
1495 0 : return -1;
1496 : }
1497 0 : if (height < 0) {
1498 0 : height = -height;
1499 0 : src_argb = src_argb + (height - 1) * src_stride_argb;
1500 0 : src_stride_argb = -src_stride_argb;
1501 : }
1502 : // Coalesce rows.
1503 0 : if (src_stride_argb == width * 4 && dst_stride_yj == width) {
1504 0 : width *= height;
1505 0 : height = 1;
1506 0 : src_stride_argb = dst_stride_yj = 0;
1507 : }
1508 : #if defined(HAS_ARGBTOYJROW_SSSE3)
1509 0 : if (TestCpuFlag(kCpuHasSSSE3)) {
1510 0 : ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
1511 0 : if (IS_ALIGNED(width, 16)) {
1512 0 : ARGBToYJRow = ARGBToYJRow_SSSE3;
1513 : }
1514 : }
1515 : #endif
1516 : #if defined(HAS_ARGBTOYJROW_AVX2)
1517 0 : if (TestCpuFlag(kCpuHasAVX2)) {
1518 0 : ARGBToYJRow = ARGBToYJRow_Any_AVX2;
1519 0 : if (IS_ALIGNED(width, 32)) {
1520 0 : ARGBToYJRow = ARGBToYJRow_AVX2;
1521 : }
1522 : }
1523 : #endif
1524 : #if defined(HAS_ARGBTOYJROW_NEON)
1525 : if (TestCpuFlag(kCpuHasNEON)) {
1526 : ARGBToYJRow = ARGBToYJRow_Any_NEON;
1527 : if (IS_ALIGNED(width, 8)) {
1528 : ARGBToYJRow = ARGBToYJRow_NEON;
1529 : }
1530 : }
1531 : #endif
1532 : #if defined(HAS_ARGBTOYJROW_MSA)
1533 : if (TestCpuFlag(kCpuHasMSA)) {
1534 : ARGBToYJRow = ARGBToYJRow_Any_MSA;
1535 : if (IS_ALIGNED(width, 16)) {
1536 : ARGBToYJRow = ARGBToYJRow_MSA;
1537 : }
1538 : }
1539 : #endif
1540 :
1541 0 : for (y = 0; y < height; ++y) {
1542 0 : ARGBToYJRow(src_argb, dst_yj, width);
1543 0 : src_argb += src_stride_argb;
1544 0 : dst_yj += dst_stride_yj;
1545 : }
1546 0 : return 0;
1547 : }
1548 :
1549 : #ifdef __cplusplus
1550 : } // extern "C"
1551 : } // namespace libyuv
1552 : #endif
|