Coverage Report

Created: 2026-10-27 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavif/ext/libyuv/source/convert_from_argb.cc
Line
Count
Source
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 <limits.h>
14
#include <string.h>  // For memcpy.
15
16
#include "libyuv/basic_types.h"
17
#include "libyuv/cpu_id.h"
18
#include "libyuv/planar_functions.h"
19
#include "libyuv/row.h"
20
21
#ifdef __cplusplus
22
namespace libyuv {
23
extern "C" {
24
#endif
25
26
// ARGB little endian (bgra in memory) to I444
27
LIBYUV_API
28
int ARGBToI444(const uint8_t* src_argb,
29
               int src_stride_argb,
30
               uint8_t* dst_y,
31
               int dst_stride_y,
32
               uint8_t* dst_u,
33
               int dst_stride_u,
34
               uint8_t* dst_v,
35
               int dst_stride_v,
36
               int width,
37
0
               int height) {
38
0
  return ARGBToI444Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u,
39
0
                          dst_stride_u, dst_v, dst_stride_v,
40
0
                          &kArgbI601Constants, width, height);
41
0
}
42
43
LIBYUV_API
44
int ARGBToI444Matrix(const uint8_t* src_argb,
45
                     int src_stride_argb,
46
                     uint8_t* dst_y,
47
                     int dst_stride_y,
48
                     uint8_t* dst_u,
49
                     int dst_stride_u,
50
                     uint8_t* dst_v,
51
                     int dst_stride_v,
52
                     const struct ArgbConstants* argbconstants,
53
                     int width,
54
0
                     int height) {
55
0
  int y;
56
0
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
57
0
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
58
0
  void (*ARGBToUV444MatrixRow)(
59
0
      const uint8_t* src_argb, uint8_t* dst_u, uint8_t* dst_v, int width,
60
0
      const struct ArgbConstants* c) = ARGBToUV444MatrixRow_C;
61
62
0
#if defined(HAS_ARGBTOYMATRIXROW_SSSE3)
63
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
64
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3;
65
0
    if (IS_ALIGNED(width, 16)) {
66
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_SSSE3;
67
0
    }
68
0
  }
69
0
#endif
70
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
71
0
  if (TestCpuFlag(kCpuHasAVX2)) {
72
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
73
0
    if (IS_ALIGNED(width, 32)) {
74
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
75
0
    }
76
0
  }
77
0
#endif
78
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
79
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
80
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
81
0
    if (IS_ALIGNED(width, 64)) {
82
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
83
0
    }
84
0
  }
85
0
#endif
86
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
87
  if (TestCpuFlag(kCpuHasNEON)) {
88
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
89
    if (IS_ALIGNED(width, 16)) {
90
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
91
    }
92
  }
93
#endif
94
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
95
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
96
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
97
    if (IS_ALIGNED(width, 16)) {
98
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
99
    }
100
  }
101
#endif
102
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
103
  if (TestCpuFlag(kCpuHasSVE2)) {
104
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
105
  }
106
#endif
107
#if defined(HAS_ARGBTOYMATRIXROW_SME)
108
  if (TestCpuFlag(kCpuHasSME)) {
109
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
110
  }
111
#endif
112
#if defined(HAS_ARGBTOYMATRIXROW_LSX)
113
  if (TestCpuFlag(kCpuHasLSX)) {
114
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LSX;
115
    if (IS_ALIGNED(width, 16)) {
116
      ARGBToYMatrixRow = ARGBToYMatrixRow_LSX;
117
    }
118
  }
119
#endif
120
#if defined(HAS_ARGBTOYMATRIXROW_LASX)
121
  if (TestCpuFlag(kCpuHasLASX)) {
122
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LASX;
123
    if (IS_ALIGNED(width, 32)) {
124
      ARGBToYMatrixRow = ARGBToYMatrixRow_LASX;
125
    }
126
  }
127
#endif
128
#if defined(HAS_ARGBTOYMATRIXROW_RVV)
129
  if (TestCpuFlag(kCpuHasRVV)) {
130
    ARGBToYMatrixRow = ARGBToYMatrixRow_RVV;
131
  }
132
#endif
133
134
0
#if defined(HAS_ARGBTOUV444MATRIXROW_SSSE3)
135
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
136
0
    ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_SSSE3;
137
0
    if (IS_ALIGNED(width, 16)) {
138
0
      ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_SSSE3;
139
0
    }
140
0
  }
141
0
#endif
142
0
#if defined(HAS_ARGBTOUV444MATRIXROW_AVX2)
143
0
  if (TestCpuFlag(kCpuHasAVX2)) {
144
0
    ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_AVX2;
145
0
    if (IS_ALIGNED(width, 32)) {
146
0
      ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_AVX2;
147
0
    }
148
0
  }
149
0
#endif
150
0
#if defined(HAS_ARGBTOUV444MATRIXROW_AVX512BW)
151
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
152
0
    ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_AVX512BW;
153
0
    if (IS_ALIGNED(width, 64)) {
154
0
      ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_AVX512BW;
155
0
    }
156
0
  }
157
0
#endif
158
#if defined(HAS_ARGBTOUV444MATRIXROW_NEON)
159
  if (TestCpuFlag(kCpuHasNEON)) {
160
    ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_NEON;
161
    if (IS_ALIGNED(width, 8)) {
162
      ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_NEON;
163
    }
164
  }
165
#endif
166
#if defined(HAS_ARGBTOUV444MATRIXROW_NEON_I8MM)
167
  if (TestCpuFlag(kCpuHasNeonI8MM)) {
168
    ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_NEON_I8MM;
169
    if (IS_ALIGNED(width, 8)) {
170
      ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_NEON_I8MM;
171
    }
172
  }
173
#endif
174
#if defined(HAS_ARGBTOUV444MATRIXROW_RVV)
175
  if (TestCpuFlag(kCpuHasRVV)) {
176
    ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_RVV;
177
  }
178
#endif
179
0
  if (!src_argb || !dst_y || !dst_u || !dst_v || !argbconstants || width <= 0 ||
180
0
      height == 0 || height == INT_MIN) {
181
0
    return -1;
182
0
  }
183
  // Negative height means invert the image.
184
0
  if (height < 0) {
185
0
    height = -height;
186
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
187
0
    src_stride_argb = -src_stride_argb;
188
0
  }
189
190
0
  for (y = 0; y < height; ++y) {
191
0
    ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants);
192
0
    ARGBToUV444MatrixRow(src_argb, dst_u, dst_v, width, argbconstants);
193
0
    src_argb += src_stride_argb;
194
0
    dst_y += dst_stride_y;
195
0
    dst_u += dst_stride_u;
196
0
    dst_v += dst_stride_v;
197
0
  }
198
0
  return 0;
199
0
}
200
201
// ARGB little endian (bgra in memory) to I422
202
LIBYUV_API
203
int ARGBToI422(const uint8_t* src_argb,
204
               int src_stride_argb,
205
               uint8_t* dst_y,
206
               int dst_stride_y,
207
               uint8_t* dst_u,
208
               int dst_stride_u,
209
               uint8_t* dst_v,
210
               int dst_stride_v,
211
               int width,
212
0
               int height) {
213
0
  return ARGBToI422Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u,
214
0
                          dst_stride_u, dst_v, dst_stride_v,
215
0
                          &kArgbI601Constants, width, height);
216
0
}
217
218
LIBYUV_API
219
int ARGBToI422Matrix(const uint8_t* src_argb,
220
                     int src_stride_argb,
221
                     uint8_t* dst_y,
222
                     int dst_stride_y,
223
                     uint8_t* dst_u,
224
                     int dst_stride_u,
225
                     uint8_t* dst_v,
226
                     int dst_stride_v,
227
                     const struct ArgbConstants* argbconstants,
228
                     int width,
229
184k
                     int height) {
230
184k
  int y;
231
184k
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
232
184k
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
233
184k
  void (*ARGBToUVMatrixRow)(const uint8_t* src_argb, int src_stride_argb,
234
184k
                            uint8_t* dst_u, uint8_t* dst_v, int width,
235
184k
                            const struct ArgbConstants* c) =
236
184k
      ARGBToUVMatrixRow_C;
237
238
184k
#if defined(HAS_ARGBTOYMATRIXROW_SSSE3)
239
184k
  if (TestCpuFlag(kCpuHasSSSE3)) {
240
184k
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3;
241
184k
    if (IS_ALIGNED(width, 16)) {
242
883
      ARGBToYMatrixRow = ARGBToYMatrixRow_SSSE3;
243
883
    }
244
184k
  }
245
184k
#endif
246
184k
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
247
184k
  if (TestCpuFlag(kCpuHasAVX2)) {
248
184k
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
249
184k
    if (IS_ALIGNED(width, 32)) {
250
423
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
251
423
    }
252
184k
  }
253
184k
#endif
254
184k
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
255
184k
  if (TestCpuFlag(kCpuHasAVX512BW)) {
256
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
257
0
    if (IS_ALIGNED(width, 64)) {
258
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
259
0
    }
260
0
  }
261
184k
#endif
262
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
263
  if (TestCpuFlag(kCpuHasNEON)) {
264
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
265
    if (IS_ALIGNED(width, 16)) {
266
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
267
    }
268
  }
269
#endif
270
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
271
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
272
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
273
    if (IS_ALIGNED(width, 16)) {
274
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
275
    }
276
  }
277
#endif
278
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
279
  if (TestCpuFlag(kCpuHasSVE2)) {
280
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
281
  }
282
#endif
283
#if defined(HAS_ARGBTOYMATRIXROW_SME)
284
  if (TestCpuFlag(kCpuHasSME)) {
285
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
286
  }
287
#endif
288
#if defined(HAS_ARGBTOYMATRIXROW_LSX)
289
  if (TestCpuFlag(kCpuHasLSX)) {
290
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LSX;
291
    if (IS_ALIGNED(width, 16)) {
292
      ARGBToYMatrixRow = ARGBToYMatrixRow_LSX;
293
    }
294
  }
295
#endif
296
#if defined(HAS_ARGBTOYMATRIXROW_LASX)
297
  if (TestCpuFlag(kCpuHasLASX)) {
298
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LASX;
299
    if (IS_ALIGNED(width, 32)) {
300
      ARGBToYMatrixRow = ARGBToYMatrixRow_LASX;
301
    }
302
  }
303
#endif
304
#if defined(HAS_ARGBTOYMATRIXROW_RVV)
305
  if (TestCpuFlag(kCpuHasRVV)) {
306
    ARGBToYMatrixRow = ARGBToYMatrixRow_RVV;
307
  }
308
#endif
309
310
#if defined(HAS_ARGBTOUVMATRIXROW_NEON)
311
  if (TestCpuFlag(kCpuHasNEON)) {
312
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON;
313
    if (IS_ALIGNED(width, 16)) {
314
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON;
315
    }
316
  }
317
#endif
318
#if defined(HAS_ARGBTOUVMATRIXROW_NEON_I8MM)
319
  if (TestCpuFlag(kCpuHasNEON) && TestCpuFlag(kCpuHasNeonI8MM)) {
320
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON_I8MM;
321
    if (IS_ALIGNED(width, 16)) {
322
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON_I8MM;
323
    }
324
  }
325
#endif
326
#if defined(HAS_ARGBTOUVMATRIXROW_SVE2)
327
  if (TestCpuFlag(kCpuHasSVE2)) {
328
    if (IS_ALIGNED(width, 2)) {
329
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SVE2;
330
    }
331
  }
332
#endif
333
#if defined(HAS_ARGBTOUVMATRIXROW_SME)
334
  if (TestCpuFlag(kCpuHasSME)) {
335
    if (IS_ALIGNED(width, 2)) {
336
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SME;
337
    }
338
  }
339
#endif
340
184k
#if defined(HAS_ARGBTOUVMATRIXROW_SSSE3)
341
184k
  if (TestCpuFlag(kCpuHasSSSE3)) {
342
184k
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_SSSE3;
343
184k
    if (IS_ALIGNED(width, 8)) {
344
2.12k
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SSSE3;
345
2.12k
    }
346
184k
  }
347
184k
#endif
348
184k
#if defined(HAS_ARGBTOUVMATRIXROW_AVX2)
349
184k
  if (TestCpuFlag(kCpuHasAVX2)) {
350
184k
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX2;
351
184k
    if (IS_ALIGNED(width, 32)) {
352
423
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX2;
353
423
    }
354
184k
  }
355
184k
#endif
356
184k
#if defined(HAS_ARGBTOUVMATRIXROW_AVX512BW)
357
184k
  if (TestCpuFlag(kCpuHasAVX512BW)) {
358
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX512BW;
359
0
    if (IS_ALIGNED(width, 64)) {
360
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX512BW;
361
0
    }
362
0
  }
363
184k
#endif
364
#if defined(HAS_ARGBTOUVMATRIXROW_RVV)
365
  if (TestCpuFlag(kCpuHasRVV)) {
366
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_RVV;
367
  }
368
#endif
369
184k
  if (!src_argb || !dst_y || !dst_u || !dst_v || !argbconstants || width <= 0 ||
370
184k
      height == 0 || height == INT_MIN) {
371
0
    return -1;
372
0
  }
373
  // Negative height means invert the image.
374
184k
  if (height < 0) {
375
0
    height = -height;
376
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
377
0
    src_stride_argb = -src_stride_argb;
378
0
  }
379
380
1.49M
  for (y = 0; y < height; ++y) {
381
1.31M
    ARGBToUVMatrixRow(src_argb, 0, dst_u, dst_v, width, argbconstants);
382
1.31M
    ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants);
383
1.31M
    src_argb += src_stride_argb;
384
1.31M
    dst_y += dst_stride_y;
385
1.31M
    dst_u += dst_stride_u;
386
1.31M
    dst_v += dst_stride_v;
387
1.31M
  }
388
184k
  return 0;
389
184k
}
390
391
LIBYUV_API
392
int ARGBToNV12(const uint8_t* src_argb,
393
               int src_stride_argb,
394
               uint8_t* dst_y,
395
               int dst_stride_y,
396
               uint8_t* dst_uv,
397
               int dst_stride_uv,
398
               int width,
399
0
               int height) {
400
0
  return ARGBToNV12Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y,
401
0
                          dst_uv, dst_stride_uv, &kArgbI601Constants, width,
402
0
                          height);
403
0
}
404
405
LIBYUV_API
406
int ARGBToNV12Matrix(const uint8_t* src_argb,
407
                     int src_stride_argb,
408
                     uint8_t* dst_y,
409
                     int dst_stride_y,
410
                     uint8_t* dst_uv,
411
                     int dst_stride_uv,
412
                     const struct ArgbConstants* argbconstants,
413
                     int width,
414
0
                     int height) {
415
0
  int y;
416
0
  int halfwidth = (width + 1) >> 1;
417
0
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
418
0
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
419
0
  void (*ARGBToUVMatrixRow)(const uint8_t* src_argb, int src_stride_argb,
420
0
                            uint8_t* dst_u, uint8_t* dst_v, int width,
421
0
                            const struct ArgbConstants* c) =
422
0
      ARGBToUVMatrixRow_C;
423
424
0
#if defined(HAS_ARGBTOYMATRIXROW_SSSE3)
425
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
426
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3;
427
0
    if (IS_ALIGNED(width, 16)) {
428
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_SSSE3;
429
0
    }
430
0
  }
431
0
#endif
432
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
433
0
  if (TestCpuFlag(kCpuHasAVX2)) {
434
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
435
0
    if (IS_ALIGNED(width, 32)) {
436
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
437
0
    }
438
0
  }
439
0
#endif
440
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
441
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
442
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
443
0
    if (IS_ALIGNED(width, 64)) {
444
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
445
0
    }
446
0
  }
447
0
#endif
448
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
449
  if (TestCpuFlag(kCpuHasNEON)) {
450
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
451
    if (IS_ALIGNED(width, 16)) {
452
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
453
    }
454
  }
455
#endif
456
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
457
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
458
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
459
    if (IS_ALIGNED(width, 16)) {
460
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
461
    }
462
  }
463
#endif
464
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
465
  if (TestCpuFlag(kCpuHasSVE2)) {
466
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
467
  }
468
#endif
469
#if defined(HAS_ARGBTOYMATRIXROW_SME)
470
  if (TestCpuFlag(kCpuHasSME)) {
471
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
472
  }
473
#endif
474
#if defined(HAS_ARGBTOYMATRIXROW_LSX)
475
  if (TestCpuFlag(kCpuHasLSX)) {
476
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LSX;
477
    if (IS_ALIGNED(width, 16)) {
478
      ARGBToYMatrixRow = ARGBToYMatrixRow_LSX;
479
    }
480
  }
481
#endif
482
#if defined(HAS_ARGBTOYMATRIXROW_LASX)
483
  if (TestCpuFlag(kCpuHasLASX)) {
484
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LASX;
485
    if (IS_ALIGNED(width, 32)) {
486
      ARGBToYMatrixRow = ARGBToYMatrixRow_LASX;
487
    }
488
  }
489
#endif
490
#if defined(HAS_ARGBTOYMATRIXROW_RVV)
491
  if (TestCpuFlag(kCpuHasRVV)) {
492
    ARGBToYMatrixRow = ARGBToYMatrixRow_RVV;
493
  }
494
#endif
495
496
#if defined(HAS_ARGBTOUVMATRIXROW_NEON)
497
  if (TestCpuFlag(kCpuHasNEON)) {
498
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON;
499
    if (IS_ALIGNED(width, 16)) {
500
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON;
501
    }
502
  }
503
#endif
504
#if defined(HAS_ARGBTOUVMATRIXROW_NEON_I8MM)
505
  if (TestCpuFlag(kCpuHasNEON) && TestCpuFlag(kCpuHasNeonI8MM)) {
506
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON_I8MM;
507
    if (IS_ALIGNED(width, 16)) {
508
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON_I8MM;
509
    }
510
  }
511
#endif
512
#if defined(HAS_ARGBTOUVMATRIXROW_SVE2)
513
  if (TestCpuFlag(kCpuHasSVE2)) {
514
    if (IS_ALIGNED(width, 2)) {
515
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SVE2;
516
    }
517
  }
518
#endif
519
#if defined(HAS_ARGBTOUVMATRIXROW_SME)
520
  if (TestCpuFlag(kCpuHasSME)) {
521
    if (IS_ALIGNED(width, 2)) {
522
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SME;
523
    }
524
  }
525
#endif
526
0
#if defined(HAS_ARGBTOUVMATRIXROW_SSSE3)
527
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
528
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_SSSE3;
529
0
    if (IS_ALIGNED(width, 8)) {
530
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SSSE3;
531
0
    }
532
0
  }
533
0
#endif
534
0
#if defined(HAS_ARGBTOUVMATRIXROW_AVX2)
535
0
  if (TestCpuFlag(kCpuHasAVX2)) {
536
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX2;
537
0
    if (IS_ALIGNED(width, 32)) {
538
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX2;
539
0
    }
540
0
  }
541
0
#endif
542
#if defined(HAS_ARGBTOUVMATRIXROW_RVV)
543
  if (TestCpuFlag(kCpuHasRVV)) {
544
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_RVV;
545
  }
546
#endif
547
0
  void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,
548
0
                     uint8_t* dst_uv, int width) = MergeUVRow_C;
549
0
  if (!src_argb || !dst_y || !dst_uv || !argbconstants || width <= 0 ||
550
0
      height == 0 || height == INT_MIN) {
551
0
    return -1;
552
0
  }
553
  // Negative height means invert the image.
554
0
  if (height < 0) {
555
0
    height = -height;
556
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
557
0
    src_stride_argb = -src_stride_argb;
558
0
  }
559
0
#if defined(HAS_MERGEUVROW_SSE2)
560
0
  if (TestCpuFlag(kCpuHasSSE2)) {
561
0
    MergeUVRow = MergeUVRow_Any_SSE2;
562
0
    if (IS_ALIGNED(halfwidth, 16)) {
563
0
      MergeUVRow = MergeUVRow_SSE2;
564
0
    }
565
0
  }
566
0
#endif
567
0
#if defined(HAS_MERGEUVROW_AVX2)
568
0
  if (TestCpuFlag(kCpuHasAVX2)) {
569
0
    MergeUVRow = MergeUVRow_Any_AVX2;
570
0
    if (IS_ALIGNED(halfwidth, 32)) {
571
0
      MergeUVRow = MergeUVRow_AVX2;
572
0
    }
573
0
  }
574
0
#endif
575
0
#if defined(HAS_MERGEUVROW_AVX512BW)
576
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
577
0
    MergeUVRow = MergeUVRow_Any_AVX512BW;
578
0
    if (IS_ALIGNED(halfwidth, 32)) {
579
0
      MergeUVRow = MergeUVRow_AVX512BW;
580
0
    }
581
0
  }
582
0
#endif
583
#if defined(HAS_MERGEUVROW_NEON)
584
  if (TestCpuFlag(kCpuHasNEON)) {
585
    MergeUVRow = MergeUVRow_Any_NEON;
586
    if (IS_ALIGNED(halfwidth, 16)) {
587
      MergeUVRow = MergeUVRow_NEON;
588
    }
589
  }
590
#endif
591
#if defined(HAS_MERGEUVROW_SVE2)
592
  if (TestCpuFlag(kCpuHasSVE2)) {
593
    MergeUVRow = MergeUVRow_SVE2;
594
  }
595
#endif
596
#if defined(HAS_MERGEUVROW_SME)
597
  if (TestCpuFlag(kCpuHasSME)) {
598
    MergeUVRow = MergeUVRow_SME;
599
  }
600
#endif
601
#if defined(HAS_MERGEUVROW_LSX)
602
  if (TestCpuFlag(kCpuHasLSX)) {
603
    MergeUVRow = MergeUVRow_Any_LSX;
604
    if (IS_ALIGNED(halfwidth, 16)) {
605
      MergeUVRow = MergeUVRow_LSX;
606
    }
607
  }
608
#endif
609
#if defined(HAS_MERGEUVROW_RVV)
610
  if (TestCpuFlag(kCpuHasRVV)) {
611
    MergeUVRow = MergeUVRow_RVV;
612
  }
613
#endif
614
615
  // Allocate a rows of uv.
616
0
  align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
617
0
  uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
618
0
  if (!row_u)
619
0
    return 1;
620
621
0
  for (y = 0; y < height - 1; y += 2) {
622
0
    ARGBToUVMatrixRow(src_argb, src_stride_argb, row_u, row_v, width,
623
0
                      argbconstants);
624
0
    MergeUVRow(row_u, row_v, dst_uv, halfwidth);
625
0
    ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants);
626
0
    ARGBToYMatrixRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width,
627
0
                     argbconstants);
628
0
    src_argb += src_stride_argb * 2;
629
0
    dst_y += dst_stride_y * 2;
630
0
    dst_uv += dst_stride_uv;
631
0
  }
632
0
  if (height & 1) {
633
0
    ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, argbconstants);
634
0
    MergeUVRow(row_u, row_v, dst_uv, halfwidth);
635
0
    ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants);
636
0
  }
637
0
  free_aligned_buffer_64(row_u);
638
0
  return 0;
639
0
}
640
641
LIBYUV_API
642
int ARGBToNV21Matrix(const uint8_t* src_argb,
643
                     int src_stride_argb,
644
                     uint8_t* dst_y,
645
                     int dst_stride_y,
646
                     uint8_t* dst_vu,
647
                     int dst_stride_vu,
648
                     const struct ArgbConstants* argbconstants,
649
                     int width,
650
0
                     int height) {
651
0
  int y;
652
0
  int halfwidth = (width + 1) >> 1;
653
0
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
654
0
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
655
0
  void (*ARGBToUVMatrixRow)(const uint8_t* src_argb, int src_stride_argb,
656
0
                            uint8_t* dst_u, uint8_t* dst_v, int width,
657
0
                            const struct ArgbConstants* c) =
658
0
      ARGBToUVMatrixRow_C;
659
660
0
#if defined(HAS_ARGBTOYMATRIXROW_SSSE3)
661
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
662
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3;
663
0
    if (IS_ALIGNED(width, 16)) {
664
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_SSSE3;
665
0
    }
666
0
  }
667
0
#endif
668
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
669
0
  if (TestCpuFlag(kCpuHasAVX2)) {
670
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
671
0
    if (IS_ALIGNED(width, 32)) {
672
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
673
0
    }
674
0
  }
675
0
#endif
676
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
677
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
678
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
679
0
    if (IS_ALIGNED(width, 64)) {
680
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
681
0
    }
682
0
  }
683
0
#endif
684
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
685
  if (TestCpuFlag(kCpuHasNEON)) {
686
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
687
    if (IS_ALIGNED(width, 16)) {
688
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
689
    }
690
  }
691
#endif
692
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
693
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
694
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
695
    if (IS_ALIGNED(width, 16)) {
696
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
697
    }
698
  }
699
#endif
700
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
701
  if (TestCpuFlag(kCpuHasSVE2)) {
702
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
703
  }
704
#endif
705
#if defined(HAS_ARGBTOYMATRIXROW_SME)
706
  if (TestCpuFlag(kCpuHasSME)) {
707
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
708
  }
709
#endif
710
#if defined(HAS_ARGBTOYMATRIXROW_LSX)
711
  if (TestCpuFlag(kCpuHasLSX)) {
712
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LSX;
713
    if (IS_ALIGNED(width, 16)) {
714
      ARGBToYMatrixRow = ARGBToYMatrixRow_LSX;
715
    }
716
  }
717
#endif
718
#if defined(HAS_ARGBTOYMATRIXROW_LASX)
719
  if (TestCpuFlag(kCpuHasLASX)) {
720
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_LASX;
721
    if (IS_ALIGNED(width, 32)) {
722
      ARGBToYMatrixRow = ARGBToYMatrixRow_LASX;
723
    }
724
  }
725
#endif
726
#if defined(HAS_ARGBTOYMATRIXROW_RVV)
727
  if (TestCpuFlag(kCpuHasRVV)) {
728
    ARGBToYMatrixRow = ARGBToYMatrixRow_RVV;
729
  }
730
#endif
731
732
#if defined(HAS_ARGBTOUVMATRIXROW_NEON)
733
  if (TestCpuFlag(kCpuHasNEON)) {
734
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON;
735
    if (IS_ALIGNED(width, 16)) {
736
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON;
737
    }
738
  }
739
#endif
740
#if defined(HAS_ARGBTOUVMATRIXROW_NEON_I8MM)
741
  if (TestCpuFlag(kCpuHasNEON) && TestCpuFlag(kCpuHasNeonI8MM)) {
742
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON_I8MM;
743
    if (IS_ALIGNED(width, 16)) {
744
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON_I8MM;
745
    }
746
  }
747
#endif
748
#if defined(HAS_ARGBTOUVMATRIXROW_SVE2)
749
  if (TestCpuFlag(kCpuHasSVE2)) {
750
    if (IS_ALIGNED(width, 2)) {
751
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SVE2;
752
    }
753
  }
754
#endif
755
#if defined(HAS_ARGBTOUVMATRIXROW_SME)
756
  if (TestCpuFlag(kCpuHasSME)) {
757
    if (IS_ALIGNED(width, 2)) {
758
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SME;
759
    }
760
  }
761
#endif
762
0
#if defined(HAS_ARGBTOUVMATRIXROW_SSSE3)
763
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
764
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_SSSE3;
765
0
    if (IS_ALIGNED(width, 8)) {
766
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SSSE3;
767
0
    }
768
0
  }
769
0
#endif
770
0
#if defined(HAS_ARGBTOUVMATRIXROW_AVX2)
771
0
  if (TestCpuFlag(kCpuHasAVX2)) {
772
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX2;
773
0
    if (IS_ALIGNED(width, 32)) {
774
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX2;
775
0
    }
776
0
  }
777
0
#endif
778
#if defined(HAS_ARGBTOUVMATRIXROW_RVV)
779
  if (TestCpuFlag(kCpuHasRVV)) {
780
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_RVV;
781
  }
782
#endif
783
0
  void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,
784
0
                     uint8_t* dst_vu, int width) = MergeUVRow_C;
785
0
  if (!src_argb || !dst_y || !dst_vu || !argbconstants || width <= 0 ||
786
0
      height == 0 || height == INT_MIN) {
787
0
    return -1;
788
0
  }
789
  // Negative height means invert the image.
790
0
  if (height < 0) {
791
0
    height = -height;
792
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
793
0
    src_stride_argb = -src_stride_argb;
794
0
  }
795
0
#if defined(HAS_MERGEUVROW_SSE2)
796
0
  if (TestCpuFlag(kCpuHasSSE2)) {
797
0
    MergeUVRow = MergeUVRow_Any_SSE2;
798
0
    if (IS_ALIGNED(halfwidth, 16)) {
799
0
      MergeUVRow = MergeUVRow_SSE2;
800
0
    }
801
0
  }
802
0
#endif
803
0
#if defined(HAS_MERGEUVROW_AVX2)
804
0
  if (TestCpuFlag(kCpuHasAVX2)) {
805
0
    MergeUVRow = MergeUVRow_Any_AVX2;
806
0
    if (IS_ALIGNED(halfwidth, 32)) {
807
0
      MergeUVRow = MergeUVRow_AVX2;
808
0
    }
809
0
  }
810
0
#endif
811
0
#if defined(HAS_MERGEUVROW_AVX512BW)
812
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
813
0
    MergeUVRow = MergeUVRow_Any_AVX512BW;
814
0
    if (IS_ALIGNED(halfwidth, 32)) {
815
0
      MergeUVRow = MergeUVRow_AVX512BW;
816
0
    }
817
0
  }
818
0
#endif
819
#if defined(HAS_MERGEUVROW_NEON)
820
  if (TestCpuFlag(kCpuHasNEON)) {
821
    MergeUVRow = MergeUVRow_Any_NEON;
822
    if (IS_ALIGNED(halfwidth, 16)) {
823
      MergeUVRow = MergeUVRow_NEON;
824
    }
825
  }
826
#endif
827
#if defined(HAS_MERGEUVROW_SVE2)
828
  if (TestCpuFlag(kCpuHasSVE2)) {
829
    MergeUVRow = MergeUVRow_SVE2;
830
  }
831
#endif
832
#if defined(HAS_MERGEUVROW_SME)
833
  if (TestCpuFlag(kCpuHasSME)) {
834
    MergeUVRow = MergeUVRow_SME;
835
  }
836
#endif
837
#if defined(HAS_MERGEUVROW_LSX)
838
  if (TestCpuFlag(kCpuHasLSX)) {
839
    MergeUVRow = MergeUVRow_Any_LSX;
840
    if (IS_ALIGNED(halfwidth, 16)) {
841
      MergeUVRow = MergeUVRow_LSX;
842
    }
843
  }
844
#endif
845
#if defined(HAS_MERGEUVROW_RVV)
846
  if (TestCpuFlag(kCpuHasRVV)) {
847
    MergeUVRow = MergeUVRow_RVV;
848
  }
849
#endif
850
851
  // Allocate a rows of uv.
852
0
  align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
853
0
  uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
854
0
  if (!row_u)
855
0
    return 1;
856
857
0
  for (y = 0; y < height - 1; y += 2) {
858
0
    ARGBToUVMatrixRow(src_argb, src_stride_argb, row_u, row_v, width,
859
0
                      argbconstants);
860
0
    MergeUVRow(row_v, row_u, dst_vu, halfwidth);
861
0
    ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants);
862
0
    ARGBToYMatrixRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width,
863
0
                     argbconstants);
864
0
    src_argb += src_stride_argb * 2;
865
0
    dst_y += dst_stride_y * 2;
866
0
    dst_vu += dst_stride_vu;
867
0
  }
868
0
  if (height & 1) {
869
0
    ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, argbconstants);
870
0
    MergeUVRow(row_v, row_u, dst_vu, halfwidth);
871
0
    ARGBToYMatrixRow(src_argb, dst_y, width, argbconstants);
872
0
  }
873
0
  free_aligned_buffer_64(row_u);
874
0
  return 0;
875
0
}
876
LIBYUV_API
877
int ARGBToI400Matrix(const uint8_t* src_argb,
878
                     int src_stride_argb,
879
                     uint8_t* dst_y,
880
                     int dst_stride_y,
881
                     const struct ArgbConstants* constants,
882
                     int width,
883
5
                     int height) {
884
5
  int y;
885
5
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
886
5
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
887
5
  if (!src_argb || !dst_y || !constants || width <= 0 || height == 0 ||
888
5
      height == INT_MIN) {
889
0
    return -1;
890
0
  }
891
5
  if (height < 0) {
892
0
    height = -height;
893
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
894
0
    src_stride_argb = -src_stride_argb;
895
0
  }
896
5
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
897
5
  if (TestCpuFlag(kCpuHasAVX2)) {
898
5
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
899
5
    if (IS_ALIGNED(width, 32)) {
900
1
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
901
1
    }
902
5
  }
903
5
#endif
904
5
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
905
5
  if (TestCpuFlag(kCpuHasAVX512BW)) {
906
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
907
0
    if (IS_ALIGNED(width, 64)) {
908
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
909
0
    }
910
0
  }
911
5
#endif
912
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
913
  if (TestCpuFlag(kCpuHasNEON)) {
914
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
915
    if (IS_ALIGNED(width, 16)) {
916
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
917
    }
918
  }
919
#endif
920
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
921
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
922
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
923
    if (IS_ALIGNED(width, 16)) {
924
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
925
    }
926
  }
927
#endif
928
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
929
  if (TestCpuFlag(kCpuHasSVE2)) {
930
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
931
  }
932
#endif
933
#if defined(HAS_ARGBTOYMATRIXROW_SME)
934
  if (TestCpuFlag(kCpuHasSME)) {
935
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
936
  }
937
#endif
938
939
354
  for (y = 0; y < height; ++y) {
940
349
    ARGBToYMatrixRow(src_argb, dst_y, width, constants);
941
349
    src_argb += src_stride_argb;
942
349
    dst_y += dst_stride_y;
943
349
  }
944
5
  return 0;
945
5
}
946
LIBYUV_API
947
int ARGBToYUY2Matrix(const uint8_t* src_argb,
948
                     int src_stride_argb,
949
                     uint8_t* dst_yuy2,
950
                     int dst_stride_yuy2,
951
                     const struct ArgbConstants* constants,
952
                     int width,
953
0
                     int height) {
954
0
  int y;
955
0
  void (*ARGBToUVMatrixRow)(const uint8_t* src_argb, int src_stride_argb,
956
0
                            uint8_t* dst_u, uint8_t* dst_v, int width,
957
0
                            const struct ArgbConstants* c) =
958
0
      ARGBToUVMatrixRow_C;
959
0
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
960
0
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
961
0
  void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u,
962
0
                        const uint8_t* src_v, uint8_t* dst_yuy2, int width) =
963
0
      I422ToYUY2Row_C;
964
965
0
  if (!src_argb || !dst_yuy2 || !constants || width <= 0 || height == 0 ||
966
0
      height == INT_MIN) {
967
0
    return -1;
968
0
  }
969
0
  if (height < 0) {
970
0
    height = -height;
971
0
    dst_yuy2 = dst_yuy2 + (ptrdiff_t)(height - 1) * dst_stride_yuy2;
972
0
    dst_stride_yuy2 = -dst_stride_yuy2;
973
0
  }
974
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
975
0
  if (TestCpuFlag(kCpuHasAVX2)) {
976
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
977
0
    if (IS_ALIGNED(width, 32)) {
978
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
979
0
    }
980
0
  }
981
0
#endif
982
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
983
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
984
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
985
0
    if (IS_ALIGNED(width, 64)) {
986
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
987
0
    }
988
0
  }
989
0
#endif
990
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
991
  if (TestCpuFlag(kCpuHasNEON)) {
992
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
993
    if (IS_ALIGNED(width, 16)) {
994
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
995
    }
996
  }
997
#endif
998
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
999
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
1000
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
1001
    if (IS_ALIGNED(width, 16)) {
1002
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
1003
    }
1004
  }
1005
#endif
1006
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
1007
  if (TestCpuFlag(kCpuHasSVE2)) {
1008
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
1009
  }
1010
#endif
1011
#if defined(HAS_ARGBTOYMATRIXROW_SME)
1012
  if (TestCpuFlag(kCpuHasSME)) {
1013
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
1014
  }
1015
#endif
1016
0
#if defined(HAS_ARGBTOUVMATRIXROW_AVX2)
1017
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1018
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX2;
1019
0
    if (IS_ALIGNED(width, 32)) {
1020
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX2;
1021
0
    }
1022
0
  }
1023
0
#endif
1024
0
#if defined(HAS_ARGBTOUVMATRIXROW_AVX512BW)
1025
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
1026
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX512BW;
1027
0
    if (IS_ALIGNED(width, 64)) {
1028
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX512BW;
1029
0
    }
1030
0
  }
1031
0
#endif
1032
#if defined(HAS_ARGBTOUVMATRIXROW_NEON)
1033
  if (TestCpuFlag(kCpuHasNEON)) {
1034
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON;
1035
    if (IS_ALIGNED(width, 16)) {
1036
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON;
1037
    }
1038
  }
1039
#endif
1040
#if defined(HAS_ARGBTOUVMATRIXROW_NEON_I8MM)
1041
  if (TestCpuFlag(kCpuHasNeonI8MM)) {
1042
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON_I8MM;
1043
    if (IS_ALIGNED(width, 16)) {
1044
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON_I8MM;
1045
    }
1046
  }
1047
#endif
1048
#if defined(HAS_ARGBTOUVMATRIXROW_SVE2)
1049
  if (TestCpuFlag(kCpuHasSVE2)) {
1050
    if (IS_ALIGNED(width, 2)) {
1051
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SVE2;
1052
    }
1053
  }
1054
#endif
1055
#if defined(HAS_ARGBTOUVMATRIXROW_SME)
1056
  if (TestCpuFlag(kCpuHasSME)) {
1057
    if (IS_ALIGNED(width, 2)) {
1058
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SME;
1059
    }
1060
  }
1061
#endif
1062
0
#if defined(HAS_I422TOYUY2ROW_AVX2)
1063
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1064
0
    I422ToYUY2Row = I422ToYUY2Row_Any_AVX2;
1065
0
    if (IS_ALIGNED(width, 32)) {
1066
0
      I422ToYUY2Row = I422ToYUY2Row_AVX2;
1067
0
    }
1068
0
  }
1069
0
#endif
1070
#if defined(HAS_I422TOYUY2ROW_NEON)
1071
  if (TestCpuFlag(kCpuHasNEON)) {
1072
    I422ToYUY2Row = I422ToYUY2Row_Any_NEON;
1073
    if (IS_ALIGNED(width, 16)) {
1074
      I422ToYUY2Row = I422ToYUY2Row_NEON;
1075
    }
1076
  }
1077
#endif
1078
1079
0
  {
1080
0
    align_buffer_64(row_y, ((width + 63) & ~63) * 2);
1081
0
    uint8_t* row_u = row_y + ((width + 63) & ~63);
1082
0
    uint8_t* row_v = row_u + ((width + 63) & ~63) / 2;
1083
0
    if (!row_y)
1084
0
      return 1;
1085
1086
0
    for (y = 0; y < height; ++y) {
1087
0
      ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, constants);
1088
0
      ARGBToYMatrixRow(src_argb, row_y, width, constants);
1089
0
      I422ToYUY2Row(row_y, row_u, row_v, dst_yuy2, width);
1090
0
      src_argb += src_stride_argb;
1091
0
      dst_yuy2 += dst_stride_yuy2;
1092
0
    }
1093
1094
0
    free_aligned_buffer_64(row_y);
1095
0
  }
1096
0
  return 0;
1097
0
}
1098
1099
LIBYUV_API
1100
int ARGBToUYVYMatrix(const uint8_t* src_argb,
1101
                     int src_stride_argb,
1102
                     uint8_t* dst_uyvy,
1103
                     int dst_stride_uyvy,
1104
                     const struct ArgbConstants* constants,
1105
                     int width,
1106
0
                     int height) {
1107
0
  int y;
1108
0
  void (*ARGBToUVMatrixRow)(const uint8_t* src_argb, int src_stride_argb,
1109
0
                            uint8_t* dst_u, uint8_t* dst_v, int width,
1110
0
                            const struct ArgbConstants* c) =
1111
0
      ARGBToUVMatrixRow_C;
1112
0
  void (*ARGBToYMatrixRow)(const uint8_t* src_argb, uint8_t* dst_y, int width,
1113
0
                           const struct ArgbConstants* c) = ARGBToYMatrixRow_C;
1114
0
  void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u,
1115
0
                        const uint8_t* src_v, uint8_t* dst_uyvy, int width) =
1116
0
      I422ToUYVYRow_C;
1117
1118
0
  if (!src_argb || !dst_uyvy || !constants || width <= 0 || height == 0 ||
1119
0
      height == INT_MIN) {
1120
0
    return -1;
1121
0
  }
1122
0
  if (height < 0) {
1123
0
    height = -height;
1124
0
    dst_uyvy = dst_uyvy + (ptrdiff_t)(height - 1) * dst_stride_uyvy;
1125
0
    dst_stride_uyvy = -dst_stride_uyvy;
1126
0
  }
1127
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX2)
1128
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1129
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX2;
1130
0
    if (IS_ALIGNED(width, 32)) {
1131
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX2;
1132
0
    }
1133
0
  }
1134
0
#endif
1135
0
#if defined(HAS_ARGBTOYMATRIXROW_AVX512BW)
1136
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
1137
0
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_AVX512BW;
1138
0
    if (IS_ALIGNED(width, 64)) {
1139
0
      ARGBToYMatrixRow = ARGBToYMatrixRow_AVX512BW;
1140
0
    }
1141
0
  }
1142
0
#endif
1143
#if defined(HAS_ARGBTOYMATRIXROW_NEON)
1144
  if (TestCpuFlag(kCpuHasNEON)) {
1145
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON;
1146
    if (IS_ALIGNED(width, 16)) {
1147
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON;
1148
    }
1149
  }
1150
#endif
1151
#if defined(HAS_ARGBTOYMATRIXROW_NEON_DOTPROD)
1152
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
1153
    ARGBToYMatrixRow = ARGBToYMatrixRow_Any_NEON_DotProd;
1154
    if (IS_ALIGNED(width, 16)) {
1155
      ARGBToYMatrixRow = ARGBToYMatrixRow_NEON_DotProd;
1156
    }
1157
  }
1158
#endif
1159
#if defined(HAS_ARGBTOYMATRIXROW_SVE2)
1160
  if (TestCpuFlag(kCpuHasSVE2)) {
1161
    ARGBToYMatrixRow = ARGBToYMatrixRow_SVE2;
1162
  }
1163
#endif
1164
#if defined(HAS_ARGBTOYMATRIXROW_SME)
1165
  if (TestCpuFlag(kCpuHasSME)) {
1166
    ARGBToYMatrixRow = ARGBToYMatrixRow_SME;
1167
  }
1168
#endif
1169
0
#if defined(HAS_ARGBTOUVMATRIXROW_AVX2)
1170
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1171
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX2;
1172
0
    if (IS_ALIGNED(width, 32)) {
1173
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX2;
1174
0
    }
1175
0
  }
1176
0
#endif
1177
0
#if defined(HAS_ARGBTOUVMATRIXROW_AVX512BW)
1178
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
1179
0
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_AVX512BW;
1180
0
    if (IS_ALIGNED(width, 64)) {
1181
0
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_AVX512BW;
1182
0
    }
1183
0
  }
1184
0
#endif
1185
#if defined(HAS_ARGBTOUVMATRIXROW_NEON)
1186
  if (TestCpuFlag(kCpuHasNEON)) {
1187
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON;
1188
    if (IS_ALIGNED(width, 16)) {
1189
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON;
1190
    }
1191
  }
1192
#endif
1193
#if defined(HAS_ARGBTOUVMATRIXROW_NEON_I8MM)
1194
  if (TestCpuFlag(kCpuHasNeonI8MM)) {
1195
    ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_NEON_I8MM;
1196
    if (IS_ALIGNED(width, 16)) {
1197
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_NEON_I8MM;
1198
    }
1199
  }
1200
#endif
1201
#if defined(HAS_ARGBTOUVMATRIXROW_SVE2)
1202
  if (TestCpuFlag(kCpuHasSVE2)) {
1203
    if (IS_ALIGNED(width, 2)) {
1204
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SVE2;
1205
    }
1206
  }
1207
#endif
1208
#if defined(HAS_ARGBTOUVMATRIXROW_SME)
1209
  if (TestCpuFlag(kCpuHasSME)) {
1210
    if (IS_ALIGNED(width, 2)) {
1211
      ARGBToUVMatrixRow = ARGBToUVMatrixRow_SME;
1212
    }
1213
  }
1214
#endif
1215
0
#if defined(HAS_I422TOUYVYROW_AVX2)
1216
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1217
0
    I422ToUYVYRow = I422ToUYVYRow_Any_AVX2;
1218
0
    if (IS_ALIGNED(width, 32)) {
1219
0
      I422ToUYVYRow = I422ToUYVYRow_AVX2;
1220
0
    }
1221
0
  }
1222
0
#endif
1223
#if defined(HAS_I422TOUYVYROW_NEON)
1224
  if (TestCpuFlag(kCpuHasNEON)) {
1225
    I422ToUYVYRow = I422ToUYVYRow_Any_NEON;
1226
    if (IS_ALIGNED(width, 16)) {
1227
      I422ToUYVYRow = I422ToUYVYRow_NEON;
1228
    }
1229
  }
1230
#endif
1231
1232
0
  {
1233
0
    align_buffer_64(row_y, ((width + 63) & ~63) * 2);
1234
0
    uint8_t* row_u = row_y + ((width + 63) & ~63);
1235
0
    uint8_t* row_v = row_u + ((width + 63) & ~63) / 2;
1236
0
    if (!row_y)
1237
0
      return 1;
1238
1239
0
    for (y = 0; y < height; ++y) {
1240
0
      ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, constants);
1241
0
      ARGBToYMatrixRow(src_argb, row_y, width, constants);
1242
0
      I422ToUYVYRow(row_y, row_u, row_v, dst_uyvy, width);
1243
0
      src_argb += src_stride_argb;
1244
0
      dst_uyvy += dst_stride_uyvy;
1245
0
    }
1246
1247
0
    free_aligned_buffer_64(row_y);
1248
0
  }
1249
0
  return 0;
1250
0
}
1251
1252
// Same as NV12 but U and V swapped.
1253
LIBYUV_API
1254
int ARGBToNV21(const uint8_t* src_argb,
1255
               int src_stride_argb,
1256
               uint8_t* dst_y,
1257
               int dst_stride_y,
1258
               uint8_t* dst_vu,
1259
               int dst_stride_vu,
1260
               int width,
1261
0
               int height) {
1262
0
  return ARGBToNV21Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y,
1263
0
                          dst_vu, dst_stride_vu, &kArgbI601Constants, width,
1264
0
                          height);
1265
0
}
1266
1267
LIBYUV_API
1268
int ABGRToNV12(const uint8_t* src_abgr,
1269
               int src_stride_abgr,
1270
               uint8_t* dst_y,
1271
               int dst_stride_y,
1272
               uint8_t* dst_uv,
1273
               int dst_stride_uv,
1274
               int width,
1275
0
               int height) {
1276
0
  return ARGBToNV12Matrix(src_abgr, src_stride_abgr, dst_y, dst_stride_y,
1277
0
                          dst_uv, dst_stride_uv, &kAbgrI601Constants, width,
1278
0
                          height);
1279
0
}
1280
1281
// Same as NV12 but U and V swapped.
1282
LIBYUV_API
1283
int ABGRToNV21(const uint8_t* src_abgr,
1284
               int src_stride_abgr,
1285
               uint8_t* dst_y,
1286
               int dst_stride_y,
1287
               uint8_t* dst_vu,
1288
               int dst_stride_vu,
1289
               int width,
1290
0
               int height) {
1291
0
  return ARGBToNV21Matrix(src_abgr, src_stride_abgr, dst_y, dst_stride_y,
1292
0
                          dst_vu, dst_stride_vu, &kAbgrI601Constants, width,
1293
0
                          height);
1294
0
}
1295
1296
// Convert ARGB to YUY2.
1297
LIBYUV_API
1298
int ARGBToYUY2(const uint8_t* src_argb,
1299
               int src_stride_argb,
1300
               uint8_t* dst_yuy2,
1301
               int dst_stride_yuy2,
1302
               int width,
1303
0
               int height) {
1304
0
  return ARGBToYUY2Matrix(src_argb, src_stride_argb, dst_yuy2, dst_stride_yuy2,
1305
0
                          &kArgbI601Constants, width, height);
1306
0
}
1307
1308
// Convert ARGB to UYVY.
1309
LIBYUV_API
1310
int ARGBToUYVY(const uint8_t* src_argb,
1311
               int src_stride_argb,
1312
               uint8_t* dst_uyvy,
1313
               int dst_stride_uyvy,
1314
               int width,
1315
0
               int height) {
1316
0
  return ARGBToUYVYMatrix(src_argb, src_stride_argb, dst_uyvy, dst_stride_uyvy,
1317
0
                          &kArgbI601Constants, width, height);
1318
0
}
1319
1320
// Convert ARGB to I400.
1321
LIBYUV_API
1322
int ARGBToI400(const uint8_t* src_argb,
1323
               int src_stride_argb,
1324
               uint8_t* dst_y,
1325
               int dst_stride_y,
1326
               int width,
1327
0
               int height) {
1328
0
  return ARGBToI400Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y,
1329
0
                          &kArgbI601Constants, width, height);
1330
0
}
1331
1332
#ifndef __riscv
1333
// Shuffle table for converting ARGB to RGBA.
1334
static const uvec8 kShuffleMaskARGBToRGBA = {
1335
    3u, 0u, 1u, 2u, 7u, 4u, 5u, 6u, 11u, 8u, 9u, 10u, 15u, 12u, 13u, 14u};
1336
1337
// Convert ARGB to RGBA.
1338
LIBYUV_API
1339
int ARGBToRGBA(const uint8_t* src_argb,
1340
               int src_stride_argb,
1341
               uint8_t* dst_rgba,
1342
               int dst_stride_rgba,
1343
               int width,
1344
0
               int height) {
1345
0
  return ARGBShuffle(src_argb, src_stride_argb, dst_rgba, dst_stride_rgba,
1346
0
                     (const uint8_t*)(&kShuffleMaskARGBToRGBA), width, height);
1347
0
}
1348
#else
1349
// Convert ARGB to RGBA.
1350
LIBYUV_API
1351
int ARGBToRGBA(const uint8_t* src_argb,
1352
               int src_stride_argb,
1353
               uint8_t* dst_rgba,
1354
               int dst_stride_rgba,
1355
               int width,
1356
               int height) {
1357
  int y;
1358
  void (*ARGBToRGBARow)(const uint8_t* src_argb, uint8_t* dst_rgba, int width) =
1359
      ARGBToRGBARow_C;
1360
  if (!src_argb || !dst_rgba || width <= 0 || height == 0 ||
1361
      height == INT_MIN) {
1362
    return -1;
1363
  }
1364
  if (height < 0) {
1365
    height = -height;
1366
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1367
    src_stride_argb = -src_stride_argb;
1368
  }
1369
  // Coalesce rows.
1370
  if (src_stride_argb == width * 4 && dst_stride_rgba == width * 4 &&
1371
      (ptrdiff_t)width * height <= INT_MAX) {
1372
    width *= height;
1373
    height = 1;
1374
    src_stride_argb = dst_stride_rgba = 0;
1375
  }
1376
1377
#if defined(HAS_ARGBTORGBAROW_RVV)
1378
  if (TestCpuFlag(kCpuHasRVV)) {
1379
    ARGBToRGBARow = ARGBToRGBARow_RVV;
1380
  }
1381
#endif
1382
1383
  for (y = 0; y < height; ++y) {
1384
    ARGBToRGBARow(src_argb, dst_rgba, width);
1385
    src_argb += src_stride_argb;
1386
    dst_rgba += dst_stride_rgba;
1387
  }
1388
  return 0;
1389
}
1390
#endif
1391
1392
// Convert ARGB To RGB24.
1393
LIBYUV_API
1394
int ARGBToRGB24(const uint8_t* src_argb,
1395
                int src_stride_argb,
1396
                uint8_t* dst_rgb24,
1397
                int dst_stride_rgb24,
1398
                int width,
1399
0
                int height) {
1400
0
  int y;
1401
0
  void (*ARGBToRGB24Row)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) =
1402
0
      ARGBToRGB24Row_C;
1403
0
  if (!src_argb || !dst_rgb24 || width <= 0 || height == 0 ||
1404
0
      height == INT_MIN) {
1405
0
    return -1;
1406
0
  }
1407
0
  if (height < 0) {
1408
0
    height = -height;
1409
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1410
0
    src_stride_argb = -src_stride_argb;
1411
0
  }
1412
  // Coalesce rows.
1413
0
  if (src_stride_argb == width * 4 && dst_stride_rgb24 == width * 3 &&
1414
0
      (ptrdiff_t)width * height <= INT_MAX) {
1415
0
    width *= height;
1416
0
    height = 1;
1417
0
    src_stride_argb = dst_stride_rgb24 = 0;
1418
0
  }
1419
0
#if defined(HAS_ARGBTORGB24ROW_SSSE3)
1420
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
1421
0
    ARGBToRGB24Row = ARGBToRGB24Row_Any_SSSE3;
1422
0
    if (IS_ALIGNED(width, 16)) {
1423
0
      ARGBToRGB24Row = ARGBToRGB24Row_SSSE3;
1424
0
    }
1425
0
  }
1426
0
#endif
1427
0
#if defined(HAS_ARGBTORGB24ROW_AVX2)
1428
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1429
0
    ARGBToRGB24Row = ARGBToRGB24Row_Any_AVX2;
1430
0
    if (IS_ALIGNED(width, 32)) {
1431
0
      ARGBToRGB24Row = ARGBToRGB24Row_AVX2;
1432
0
    }
1433
0
  }
1434
0
#endif
1435
0
#if defined(HAS_ARGBTORGB24ROW_AVX512VBMI)
1436
0
  if (TestCpuFlag(kCpuHasAVX512VBMI)) {
1437
0
    ARGBToRGB24Row = ARGBToRGB24Row_Any_AVX512VBMI;
1438
0
    if (IS_ALIGNED(width, 32)) {
1439
0
      ARGBToRGB24Row = ARGBToRGB24Row_AVX512VBMI;
1440
0
    }
1441
0
  }
1442
0
#endif
1443
#if defined(HAS_ARGBTORGB24ROW_NEON)
1444
  if (TestCpuFlag(kCpuHasNEON)) {
1445
    ARGBToRGB24Row = ARGBToRGB24Row_Any_NEON;
1446
    if (IS_ALIGNED(width, 16)) {
1447
      ARGBToRGB24Row = ARGBToRGB24Row_NEON;
1448
    }
1449
  }
1450
#endif
1451
#if defined(HAS_ARGBTORGB24ROW_SVE2)
1452
  if (TestCpuFlag(kCpuHasSVE2)) {
1453
    ARGBToRGB24Row = ARGBToRGB24Row_SVE2;
1454
  }
1455
#endif
1456
#if defined(HAS_ARGBTORGB24ROW_LSX)
1457
  if (TestCpuFlag(kCpuHasLSX)) {
1458
    ARGBToRGB24Row = ARGBToRGB24Row_Any_LSX;
1459
    if (IS_ALIGNED(width, 16)) {
1460
      ARGBToRGB24Row = ARGBToRGB24Row_LSX;
1461
    }
1462
  }
1463
#endif
1464
#if defined(HAS_ARGBTORGB24ROW_LASX)
1465
  if (TestCpuFlag(kCpuHasLASX)) {
1466
    ARGBToRGB24Row = ARGBToRGB24Row_Any_LASX;
1467
    if (IS_ALIGNED(width, 32)) {
1468
      ARGBToRGB24Row = ARGBToRGB24Row_LASX;
1469
    }
1470
  }
1471
#endif
1472
#if defined(HAS_ARGBTORGB24ROW_RVV)
1473
  if (TestCpuFlag(kCpuHasRVV)) {
1474
    ARGBToRGB24Row = ARGBToRGB24Row_RVV;
1475
  }
1476
#endif
1477
1478
0
  for (y = 0; y < height; ++y) {
1479
0
    ARGBToRGB24Row(src_argb, dst_rgb24, width);
1480
0
    src_argb += src_stride_argb;
1481
0
    dst_rgb24 += dst_stride_rgb24;
1482
0
  }
1483
0
  return 0;
1484
0
}
1485
1486
// Convert ARGB To RAW.
1487
LIBYUV_API
1488
int ARGBToRAW(const uint8_t* src_argb,
1489
              int src_stride_argb,
1490
              uint8_t* dst_raw,
1491
              int dst_stride_raw,
1492
              int width,
1493
0
              int height) {
1494
0
  int y;
1495
0
  void (*ARGBToRAWRow)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) =
1496
0
      ARGBToRAWRow_C;
1497
0
  if (!src_argb || !dst_raw || width <= 0 || height == 0 || height == INT_MIN) {
1498
0
    return -1;
1499
0
  }
1500
0
  if (height < 0) {
1501
0
    height = -height;
1502
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1503
0
    src_stride_argb = -src_stride_argb;
1504
0
  }
1505
  // Coalesce rows.
1506
0
  if (src_stride_argb == width * 4 && dst_stride_raw == width * 3 &&
1507
0
      (ptrdiff_t)width * height <= INT_MAX) {
1508
0
    width *= height;
1509
0
    height = 1;
1510
0
    src_stride_argb = dst_stride_raw = 0;
1511
0
  }
1512
0
#if defined(HAS_ARGBTORAWROW_SSSE3)
1513
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
1514
0
    ARGBToRAWRow = ARGBToRAWRow_Any_SSSE3;
1515
0
    if (IS_ALIGNED(width, 16)) {
1516
0
      ARGBToRAWRow = ARGBToRAWRow_SSSE3;
1517
0
    }
1518
0
  }
1519
0
#endif
1520
0
#if defined(HAS_ARGBTORAWROW_AVX2)
1521
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1522
0
    ARGBToRAWRow = ARGBToRAWRow_Any_AVX2;
1523
0
    if (IS_ALIGNED(width, 32)) {
1524
0
      ARGBToRAWRow = ARGBToRAWRow_AVX2;
1525
0
    }
1526
0
  }
1527
0
#endif
1528
#if defined(HAS_ARGBTORAWROW_NEON)
1529
  if (TestCpuFlag(kCpuHasNEON)) {
1530
    ARGBToRAWRow = ARGBToRAWRow_Any_NEON;
1531
    if (IS_ALIGNED(width, 8)) {
1532
      ARGBToRAWRow = ARGBToRAWRow_NEON;
1533
    }
1534
  }
1535
#endif
1536
#if defined(HAS_ARGBTORAWROW_SVE2)
1537
  if (TestCpuFlag(kCpuHasSVE2)) {
1538
    ARGBToRAWRow = ARGBToRAWRow_SVE2;
1539
  }
1540
#endif
1541
#if defined(HAS_ARGBTORAWROW_LSX)
1542
  if (TestCpuFlag(kCpuHasLSX)) {
1543
    ARGBToRAWRow = ARGBToRAWRow_Any_LSX;
1544
    if (IS_ALIGNED(width, 16)) {
1545
      ARGBToRAWRow = ARGBToRAWRow_LSX;
1546
    }
1547
  }
1548
#endif
1549
#if defined(HAS_ARGBTORAWROW_LASX)
1550
  if (TestCpuFlag(kCpuHasLASX)) {
1551
    ARGBToRAWRow = ARGBToRAWRow_Any_LASX;
1552
    if (IS_ALIGNED(width, 32)) {
1553
      ARGBToRAWRow = ARGBToRAWRow_LASX;
1554
    }
1555
  }
1556
#endif
1557
#if defined(HAS_ARGBTORAWROW_RVV)
1558
  if (TestCpuFlag(kCpuHasRVV)) {
1559
    ARGBToRAWRow = ARGBToRAWRow_RVV;
1560
  }
1561
#endif
1562
1563
0
  for (y = 0; y < height; ++y) {
1564
0
    ARGBToRAWRow(src_argb, dst_raw, width);
1565
0
    src_argb += src_stride_argb;
1566
0
    dst_raw += dst_stride_raw;
1567
0
  }
1568
0
  return 0;
1569
0
}
1570
1571
// Ordered 8x8 dither for 888 to 565.  Values from 0 to 7.
1572
static const uint8_t kDither565_4x4[16] = {
1573
    0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2,
1574
};
1575
1576
// Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes).
1577
LIBYUV_API
1578
int ARGBToRGB565Dither(const uint8_t* src_argb,
1579
                       int src_stride_argb,
1580
                       uint8_t* dst_rgb565,
1581
                       int dst_stride_rgb565,
1582
                       const uint8_t* dither4x4,
1583
                       int width,
1584
0
                       int height) {
1585
0
  int y;
1586
0
  uint32_t dither4[4];
1587
0
  void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb,
1588
0
                                uint32_t dither4, int width) =
1589
0
      ARGBToRGB565DitherRow_C;
1590
0
  if (!src_argb || !dst_rgb565 || width <= 0 || height == 0 ||
1591
0
      height == INT_MIN) {
1592
0
    return -1;
1593
0
  }
1594
0
  if (height < 0) {
1595
0
    height = -height;
1596
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1597
0
    src_stride_argb = -src_stride_argb;
1598
0
  }
1599
0
  if (!dither4x4) {
1600
0
    dither4x4 = kDither565_4x4;
1601
0
  }
1602
0
  memcpy(dither4, dither4x4, 16);
1603
1604
0
#if defined(HAS_ARGBTORGB565DITHERROW_AVX2)
1605
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1606
0
    ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2;
1607
0
    if (IS_ALIGNED(width, 8)) {
1608
0
      ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2;
1609
0
    }
1610
0
  }
1611
0
#endif
1612
#if defined(HAS_ARGBTORGB565DITHERROW_NEON)
1613
  if (TestCpuFlag(kCpuHasNEON)) {
1614
    ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON;
1615
    if (IS_ALIGNED(width, 8)) {
1616
      ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON;
1617
    }
1618
  }
1619
#endif
1620
#if defined(HAS_ARGBTORGB565DITHERROW_SVE2)
1621
  if (TestCpuFlag(kCpuHasSVE2)) {
1622
    ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SVE2;
1623
  }
1624
#endif
1625
#if defined(HAS_ARGBTORGB565DITHERROW_LSX)
1626
  if (TestCpuFlag(kCpuHasLSX)) {
1627
    ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_LSX;
1628
    if (IS_ALIGNED(width, 8)) {
1629
      ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_LSX;
1630
    }
1631
  }
1632
#endif
1633
#if defined(HAS_ARGBTORGB565DITHERROW_LASX)
1634
  if (TestCpuFlag(kCpuHasLASX)) {
1635
    ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_LASX;
1636
    if (IS_ALIGNED(width, 16)) {
1637
      ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_LASX;
1638
    }
1639
  }
1640
#endif
1641
1642
0
  for (y = 0; y < height; ++y) {
1643
0
    ARGBToRGB565DitherRow(src_argb, dst_rgb565, dither4[y & 3], width);
1644
0
    src_argb += src_stride_argb;
1645
0
    dst_rgb565 += dst_stride_rgb565;
1646
0
  }
1647
0
  return 0;
1648
0
}
1649
1650
// Convert ARGB To RGB565.
1651
// TODO(fbarchard): Consider using dither function low level with zeros.
1652
LIBYUV_API
1653
int ARGBToRGB565(const uint8_t* src_argb,
1654
                 int src_stride_argb,
1655
                 uint8_t* dst_rgb565,
1656
                 int dst_stride_rgb565,
1657
                 int width,
1658
0
                 int height) {
1659
0
  int y;
1660
0
  void (*ARGBToRGB565Row)(const uint8_t* src_argb, uint8_t* dst_rgb,
1661
0
                          int width) = ARGBToRGB565Row_C;
1662
0
  if (!src_argb || !dst_rgb565 || width <= 0 || height == 0 ||
1663
0
      height == INT_MIN) {
1664
0
    return -1;
1665
0
  }
1666
0
  if (height < 0) {
1667
0
    height = -height;
1668
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1669
0
    src_stride_argb = -src_stride_argb;
1670
0
  }
1671
  // Coalesce rows.
1672
0
  if (src_stride_argb == width * 4 && dst_stride_rgb565 == width * 2 &&
1673
0
      (ptrdiff_t)width * height <= INT_MAX) {
1674
0
    width *= height;
1675
0
    height = 1;
1676
0
    src_stride_argb = dst_stride_rgb565 = 0;
1677
0
  }
1678
1679
#if defined(HAS_ARGBTORGB565ROW_AVX2)
1680
  if (TestCpuFlag(kCpuHasAVX2)) {
1681
    ARGBToRGB565Row = ARGBToRGB565Row_Any_AVX2;
1682
    if (IS_ALIGNED(width, 8)) {
1683
      ARGBToRGB565Row = ARGBToRGB565Row_AVX2;
1684
    }
1685
  }
1686
#endif
1687
#if defined(HAS_ARGBTORGB565ROW_NEON)
1688
  if (TestCpuFlag(kCpuHasNEON)) {
1689
    ARGBToRGB565Row = ARGBToRGB565Row_Any_NEON;
1690
    if (IS_ALIGNED(width, 8)) {
1691
      ARGBToRGB565Row = ARGBToRGB565Row_NEON;
1692
    }
1693
  }
1694
#endif
1695
#if defined(HAS_ARGBTORGB565ROW_SVE2)
1696
  if (TestCpuFlag(kCpuHasSVE2)) {
1697
    ARGBToRGB565Row = ARGBToRGB565Row_SVE2;
1698
  }
1699
#endif
1700
#if defined(HAS_ARGBTORGB565ROW_LSX)
1701
  if (TestCpuFlag(kCpuHasLSX)) {
1702
    ARGBToRGB565Row = ARGBToRGB565Row_Any_LSX;
1703
    if (IS_ALIGNED(width, 8)) {
1704
      ARGBToRGB565Row = ARGBToRGB565Row_LSX;
1705
    }
1706
  }
1707
#endif
1708
1709
#if defined(HAS_ARGBTORGB565ROW_LASX)
1710
  if (TestCpuFlag(kCpuHasLASX)) {
1711
    ARGBToRGB565Row = ARGBToRGB565Row_Any_LASX;
1712
    if (IS_ALIGNED(width, 16)) {
1713
      ARGBToRGB565Row = ARGBToRGB565Row_LASX;
1714
    }
1715
  }
1716
#endif
1717
1718
0
  for (y = 0; y < height; ++y) {
1719
0
    ARGBToRGB565Row(src_argb, dst_rgb565, width);
1720
0
    src_argb += src_stride_argb;
1721
0
    dst_rgb565 += dst_stride_rgb565;
1722
0
  }
1723
0
  return 0;
1724
0
}
1725
1726
// Convert ARGB To ARGB1555.
1727
LIBYUV_API
1728
int ARGBToARGB1555(const uint8_t* src_argb,
1729
                   int src_stride_argb,
1730
                   uint8_t* dst_argb1555,
1731
                   int dst_stride_argb1555,
1732
                   int width,
1733
0
                   int height) {
1734
0
  int y;
1735
0
  void (*ARGBToARGB1555Row)(const uint8_t* src_argb, uint8_t* dst_rgb,
1736
0
                            int width) = ARGBToARGB1555Row_C;
1737
0
  if (!src_argb || !dst_argb1555 || width <= 0 || height == 0 ||
1738
0
      height == INT_MIN) {
1739
0
    return -1;
1740
0
  }
1741
0
  if (height < 0) {
1742
0
    height = -height;
1743
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1744
0
    src_stride_argb = -src_stride_argb;
1745
0
  }
1746
  // Coalesce rows.
1747
0
  if (src_stride_argb == width * 4 && dst_stride_argb1555 == width * 2 &&
1748
0
      (ptrdiff_t)width * height <= INT_MAX) {
1749
0
    width *= height;
1750
0
    height = 1;
1751
0
    src_stride_argb = dst_stride_argb1555 = 0;
1752
0
  }
1753
1754
#if defined(HAS_ARGBTOARGB1555ROW_AVX2)
1755
  if (TestCpuFlag(kCpuHasAVX2)) {
1756
    ARGBToARGB1555Row = ARGBToARGB1555Row_Any_AVX2;
1757
    if (IS_ALIGNED(width, 8)) {
1758
      ARGBToARGB1555Row = ARGBToARGB1555Row_AVX2;
1759
    }
1760
  }
1761
#endif
1762
#if defined(HAS_ARGBTOARGB1555ROW_NEON)
1763
  if (TestCpuFlag(kCpuHasNEON)) {
1764
    ARGBToARGB1555Row = ARGBToARGB1555Row_Any_NEON;
1765
    if (IS_ALIGNED(width, 8)) {
1766
      ARGBToARGB1555Row = ARGBToARGB1555Row_NEON;
1767
    }
1768
  }
1769
#endif
1770
#if defined(HAS_ARGBTOARGB1555ROW_LSX)
1771
  if (TestCpuFlag(kCpuHasLSX)) {
1772
    ARGBToARGB1555Row = ARGBToARGB1555Row_Any_LSX;
1773
    if (IS_ALIGNED(width, 8)) {
1774
      ARGBToARGB1555Row = ARGBToARGB1555Row_LSX;
1775
    }
1776
  }
1777
#endif
1778
#if defined(HAS_ARGBTOARGB1555ROW_LASX)
1779
  if (TestCpuFlag(kCpuHasLASX)) {
1780
    ARGBToARGB1555Row = ARGBToARGB1555Row_Any_LASX;
1781
    if (IS_ALIGNED(width, 16)) {
1782
      ARGBToARGB1555Row = ARGBToARGB1555Row_LASX;
1783
    }
1784
  }
1785
#endif
1786
1787
0
  for (y = 0; y < height; ++y) {
1788
0
    ARGBToARGB1555Row(src_argb, dst_argb1555, width);
1789
0
    src_argb += src_stride_argb;
1790
0
    dst_argb1555 += dst_stride_argb1555;
1791
0
  }
1792
0
  return 0;
1793
0
}
1794
1795
// Convert ARGB To ARGB4444.
1796
LIBYUV_API
1797
int ARGBToARGB4444(const uint8_t* src_argb,
1798
                   int src_stride_argb,
1799
                   uint8_t* dst_argb4444,
1800
                   int dst_stride_argb4444,
1801
                   int width,
1802
0
                   int height) {
1803
0
  int y;
1804
0
  void (*ARGBToARGB4444Row)(const uint8_t* src_argb, uint8_t* dst_rgb,
1805
0
                            int width) = ARGBToARGB4444Row_C;
1806
0
  if (!src_argb || !dst_argb4444 || width <= 0 || height == 0 ||
1807
0
      height == INT_MIN) {
1808
0
    return -1;
1809
0
  }
1810
0
  if (height < 0) {
1811
0
    height = -height;
1812
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1813
0
    src_stride_argb = -src_stride_argb;
1814
0
  }
1815
  // Coalesce rows.
1816
0
  if (src_stride_argb == width * 4 && dst_stride_argb4444 == width * 2 &&
1817
0
      (ptrdiff_t)width * height <= INT_MAX) {
1818
0
    width *= height;
1819
0
    height = 1;
1820
0
    src_stride_argb = dst_stride_argb4444 = 0;
1821
0
  }
1822
1823
#if defined(HAS_ARGBTOARGB4444ROW_AVX2)
1824
  if (TestCpuFlag(kCpuHasAVX2)) {
1825
    ARGBToARGB4444Row = ARGBToARGB4444Row_Any_AVX2;
1826
    if (IS_ALIGNED(width, 8)) {
1827
      ARGBToARGB4444Row = ARGBToARGB4444Row_AVX2;
1828
    }
1829
  }
1830
#endif
1831
#if defined(HAS_ARGBTOARGB4444ROW_NEON)
1832
  if (TestCpuFlag(kCpuHasNEON)) {
1833
    ARGBToARGB4444Row = ARGBToARGB4444Row_Any_NEON;
1834
    if (IS_ALIGNED(width, 8)) {
1835
      ARGBToARGB4444Row = ARGBToARGB4444Row_NEON;
1836
    }
1837
  }
1838
#endif
1839
#if defined(HAS_ARGBTOARGB4444ROW_LSX)
1840
  if (TestCpuFlag(kCpuHasLSX)) {
1841
    ARGBToARGB4444Row = ARGBToARGB4444Row_Any_LSX;
1842
    if (IS_ALIGNED(width, 8)) {
1843
      ARGBToARGB4444Row = ARGBToARGB4444Row_LSX;
1844
    }
1845
  }
1846
#endif
1847
#if defined(HAS_ARGBTOARGB4444ROW_LASX)
1848
  if (TestCpuFlag(kCpuHasLASX)) {
1849
    ARGBToARGB4444Row = ARGBToARGB4444Row_Any_LASX;
1850
    if (IS_ALIGNED(width, 16)) {
1851
      ARGBToARGB4444Row = ARGBToARGB4444Row_LASX;
1852
    }
1853
  }
1854
#endif
1855
1856
0
  for (y = 0; y < height; ++y) {
1857
0
    ARGBToARGB4444Row(src_argb, dst_argb4444, width);
1858
0
    src_argb += src_stride_argb;
1859
0
    dst_argb4444 += dst_stride_argb4444;
1860
0
  }
1861
0
  return 0;
1862
0
}
1863
1864
// Convert ABGR To AR30.
1865
LIBYUV_API
1866
int ABGRToAR30(const uint8_t* src_abgr,
1867
               int src_stride_abgr,
1868
               uint8_t* dst_ar30,
1869
               int dst_stride_ar30,
1870
               int width,
1871
0
               int height) {
1872
0
  int y;
1873
0
  void (*ABGRToAR30Row)(const uint8_t* src_abgr, uint8_t* dst_rgb, int width) =
1874
0
      ABGRToAR30Row_C;
1875
0
  if (!src_abgr || !dst_ar30 || width <= 0 || height == 0 ||
1876
0
      height == INT_MIN) {
1877
0
    return -1;
1878
0
  }
1879
0
  if (height < 0) {
1880
0
    height = -height;
1881
0
    src_abgr = src_abgr + (ptrdiff_t)(height - 1) * src_stride_abgr;
1882
0
    src_stride_abgr = -src_stride_abgr;
1883
0
  }
1884
  // Coalesce rows.
1885
0
  if (src_stride_abgr == width * 4 && dst_stride_ar30 == width * 4 &&
1886
0
      (ptrdiff_t)width * height <= INT_MAX) {
1887
0
    width *= height;
1888
0
    height = 1;
1889
0
    src_stride_abgr = dst_stride_ar30 = 0;
1890
0
  }
1891
#if defined(HAS_ABGRTOAR30ROW_NEON)
1892
  if (TestCpuFlag(kCpuHasNEON)) {
1893
    ABGRToAR30Row = ABGRToAR30Row_Any_NEON;
1894
    if (IS_ALIGNED(width, 8)) {
1895
      ABGRToAR30Row = ABGRToAR30Row_NEON;
1896
    }
1897
  }
1898
#endif
1899
0
#if defined(HAS_ABGRTOAR30ROW_SSSE3)
1900
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
1901
0
    ABGRToAR30Row = ABGRToAR30Row_Any_SSSE3;
1902
0
    if (IS_ALIGNED(width, 4)) {
1903
0
      ABGRToAR30Row = ABGRToAR30Row_SSSE3;
1904
0
    }
1905
0
  }
1906
0
#endif
1907
0
#if defined(HAS_ABGRTOAR30ROW_AVX2)
1908
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1909
0
    ABGRToAR30Row = ABGRToAR30Row_Any_AVX2;
1910
0
    if (IS_ALIGNED(width, 8)) {
1911
0
      ABGRToAR30Row = ABGRToAR30Row_AVX2;
1912
0
    }
1913
0
  }
1914
0
#endif
1915
0
  for (y = 0; y < height; ++y) {
1916
0
    ABGRToAR30Row(src_abgr, dst_ar30, width);
1917
0
    src_abgr += src_stride_abgr;
1918
0
    dst_ar30 += dst_stride_ar30;
1919
0
  }
1920
0
  return 0;
1921
0
}
1922
1923
// Convert ARGB To AR30.
1924
LIBYUV_API
1925
int ARGBToAR30(const uint8_t* src_argb,
1926
               int src_stride_argb,
1927
               uint8_t* dst_ar30,
1928
               int dst_stride_ar30,
1929
               int width,
1930
0
               int height) {
1931
0
  int y;
1932
0
  void (*ARGBToAR30Row)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) =
1933
0
      ARGBToAR30Row_C;
1934
0
  if (!src_argb || !dst_ar30 || width <= 0 || height == 0 ||
1935
0
      height == INT_MIN) {
1936
0
    return -1;
1937
0
  }
1938
0
  if (height < 0) {
1939
0
    height = -height;
1940
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
1941
0
    src_stride_argb = -src_stride_argb;
1942
0
  }
1943
  // Coalesce rows.
1944
0
  if (src_stride_argb == width * 4 && dst_stride_ar30 == width * 4 &&
1945
0
      (ptrdiff_t)width * height <= INT_MAX) {
1946
0
    width *= height;
1947
0
    height = 1;
1948
0
    src_stride_argb = dst_stride_ar30 = 0;
1949
0
  }
1950
#if defined(HAS_ARGBTOAR30ROW_NEON)
1951
  if (TestCpuFlag(kCpuHasNEON)) {
1952
    ARGBToAR30Row = ARGBToAR30Row_Any_NEON;
1953
    if (IS_ALIGNED(width, 8)) {
1954
      ARGBToAR30Row = ARGBToAR30Row_NEON;
1955
    }
1956
  }
1957
#endif
1958
0
#if defined(HAS_ARGBTOAR30ROW_SSSE3)
1959
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
1960
0
    ARGBToAR30Row = ARGBToAR30Row_Any_SSSE3;
1961
0
    if (IS_ALIGNED(width, 4)) {
1962
0
      ARGBToAR30Row = ARGBToAR30Row_SSSE3;
1963
0
    }
1964
0
  }
1965
0
#endif
1966
0
#if defined(HAS_ARGBTOAR30ROW_AVX2)
1967
0
  if (TestCpuFlag(kCpuHasAVX2)) {
1968
0
    ARGBToAR30Row = ARGBToAR30Row_Any_AVX2;
1969
0
    if (IS_ALIGNED(width, 8)) {
1970
0
      ARGBToAR30Row = ARGBToAR30Row_AVX2;
1971
0
    }
1972
0
  }
1973
0
#endif
1974
0
  for (y = 0; y < height; ++y) {
1975
0
    ARGBToAR30Row(src_argb, dst_ar30, width);
1976
0
    src_argb += src_stride_argb;
1977
0
    dst_ar30 += dst_stride_ar30;
1978
0
  }
1979
0
  return 0;
1980
0
}
1981
1982
// ARGB little endian (bgra in memory) to J444
1983
LIBYUV_API
1984
int ARGBToJ444(const uint8_t* src_argb,
1985
               int src_stride_argb,
1986
               uint8_t* dst_y,
1987
               int dst_stride_y,
1988
               uint8_t* dst_u,
1989
               int dst_stride_u,
1990
               uint8_t* dst_v,
1991
               int dst_stride_v,
1992
               int width,
1993
0
               int height) {
1994
0
  return ARGBToI444Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u,
1995
0
                          dst_stride_u, dst_v, dst_stride_v,
1996
0
                          &kArgbJPEGConstants, width, height);
1997
0
}
1998
1999
// Convert ARGB to J420. (JPeg full range I420).
2000
LIBYUV_API
2001
int ARGBToJ420(const uint8_t* src_argb,
2002
               int src_stride_argb,
2003
               uint8_t* dst_y,
2004
               int dst_stride_y,
2005
               uint8_t* dst_u,
2006
               int dst_stride_u,
2007
               uint8_t* dst_v,
2008
               int dst_stride_v,
2009
               int width,
2010
0
               int height) {
2011
0
  return ARGBToI420Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u,
2012
0
                          dst_stride_u, dst_v, dst_stride_v,
2013
0
                          &kArgbJPEGConstants, width, height);
2014
0
}
2015
2016
// Convert ARGB to J422. (JPeg full range I422).
2017
LIBYUV_API
2018
int ARGBToJ422(const uint8_t* src_argb,
2019
               int src_stride_argb,
2020
               uint8_t* dst_y,
2021
               int dst_stride_y,
2022
               uint8_t* dst_u,
2023
               int dst_stride_u,
2024
               uint8_t* dst_v,
2025
               int dst_stride_v,
2026
               int width,
2027
184k
               int height) {
2028
184k
  return ARGBToI422Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u,
2029
184k
                          dst_stride_u, dst_v, dst_stride_v,
2030
184k
                          &kArgbJPEGConstants, width, height);
2031
184k
}
2032
2033
// Convert ARGB to J400.
2034
LIBYUV_API
2035
int ARGBToJ400(const uint8_t* src_argb,
2036
               int src_stride_argb,
2037
               uint8_t* dst_y,
2038
               int dst_stride_y,
2039
               int width,
2040
0
               int height) {
2041
0
  return ARGBToI400Matrix(src_argb, src_stride_argb, dst_y, dst_stride_y,
2042
0
                          &kArgbJPEGConstants, width, height);
2043
0
}
2044
2045
// Convert RGBA to J400.
2046
LIBYUV_API
2047
int RGBAToJ400(const uint8_t* src_rgba,
2048
               int src_stride_rgba,
2049
               uint8_t* dst_yj,
2050
               int dst_stride_yj,
2051
               int width,
2052
0
               int height) {
2053
0
  return ARGBToI400Matrix(src_rgba, src_stride_rgba, dst_yj, dst_stride_yj,
2054
0
                          &kRgbaJPEGConstants, width, height);
2055
0
}
2056
2057
2058
// Convert ABGR to J420. (JPeg full range I420).
2059
LIBYUV_API
2060
int ABGRToJ420(const uint8_t* src_abgr,
2061
               int src_stride_abgr,
2062
               uint8_t* dst_y,
2063
               int dst_stride_y,
2064
               uint8_t* dst_u,
2065
               int dst_stride_u,
2066
               uint8_t* dst_v,
2067
               int dst_stride_v,
2068
               int width,
2069
7
               int height) {
2070
7
  return ARGBToI420Matrix(src_abgr, src_stride_abgr, dst_y, dst_stride_y, dst_u,
2071
7
                          dst_stride_u, dst_v, dst_stride_v,
2072
7
                          &kAbgrJPEGConstants, width, height);
2073
7
}
2074
2075
// Convert ABGR to J422. (JPeg full range I422).
2076
LIBYUV_API
2077
int ABGRToJ422(const uint8_t* src_abgr,
2078
               int src_stride_abgr,
2079
               uint8_t* dst_y,
2080
               int dst_stride_y,
2081
               uint8_t* dst_u,
2082
               int dst_stride_u,
2083
               uint8_t* dst_v,
2084
               int dst_stride_v,
2085
               int width,
2086
2
               int height) {
2087
2
  return ARGBToI422Matrix(src_abgr, src_stride_abgr, dst_y, dst_stride_y, dst_u,
2088
2
                          dst_stride_u, dst_v, dst_stride_v,
2089
2
                          &kAbgrJPEGConstants, width, height);
2090
2
}
2091
2092
// Convert ABGR to J400.
2093
LIBYUV_API
2094
int ABGRToJ400(const uint8_t* src_abgr,
2095
               int src_stride_abgr,
2096
               uint8_t* dst_yj,
2097
               int dst_stride_yj,
2098
               int width,
2099
5
               int height) {
2100
5
  return ARGBToI400Matrix(src_abgr, src_stride_abgr, dst_yj, dst_stride_yj,
2101
5
                          &kAbgrJPEGConstants, width, height);
2102
5
}
2103
2104
// Convert ARGB to AR64.
2105
LIBYUV_API
2106
int ARGBToAR64(const uint8_t* src_argb,
2107
               int src_stride_argb,
2108
               uint16_t* dst_ar64,
2109
               int dst_stride_ar64,
2110
               int width,
2111
0
               int height) {
2112
0
  int y;
2113
0
  void (*ARGBToAR64Row)(const uint8_t* src_argb, uint16_t* dst_ar64,
2114
0
                        int width) = ARGBToAR64Row_C;
2115
0
  if (!src_argb || !dst_ar64 || width <= 0 || height == 0 ||
2116
0
      height == INT_MIN) {
2117
0
    return -1;
2118
0
  }
2119
  // Negative height means invert the image.
2120
0
  if (height < 0) {
2121
0
    height = -height;
2122
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
2123
0
    src_stride_argb = -src_stride_argb;
2124
0
  }
2125
  // Coalesce rows.
2126
0
  if (src_stride_argb == width * 4 && dst_stride_ar64 == width * 4 &&
2127
0
      (ptrdiff_t)width * height <= INT_MAX) {
2128
0
    width *= height;
2129
0
    height = 1;
2130
0
    src_stride_argb = dst_stride_ar64 = 0;
2131
0
  }
2132
0
#if defined(HAS_ARGBTOAR64ROW_SSSE3)
2133
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
2134
0
    ARGBToAR64Row = ARGBToAR64Row_Any_SSSE3;
2135
0
    if (IS_ALIGNED(width, 4)) {
2136
0
      ARGBToAR64Row = ARGBToAR64Row_SSSE3;
2137
0
    }
2138
0
  }
2139
0
#endif
2140
0
#if defined(HAS_ARGBTOAR64ROW_AVX2)
2141
0
  if (TestCpuFlag(kCpuHasAVX2)) {
2142
0
    ARGBToAR64Row = ARGBToAR64Row_Any_AVX2;
2143
0
    if (IS_ALIGNED(width, 8)) {
2144
0
      ARGBToAR64Row = ARGBToAR64Row_AVX2;
2145
0
    }
2146
0
  }
2147
0
#endif
2148
#if defined(HAS_ARGBTOAR64ROW_NEON)
2149
  if (TestCpuFlag(kCpuHasNEON)) {
2150
    ARGBToAR64Row = ARGBToAR64Row_Any_NEON;
2151
    if (IS_ALIGNED(width, 8)) {
2152
      ARGBToAR64Row = ARGBToAR64Row_NEON;
2153
    }
2154
  }
2155
#endif
2156
#if defined(HAS_ARGBTOAR64ROW_RVV)
2157
  if (TestCpuFlag(kCpuHasRVV)) {
2158
    ARGBToAR64Row = ARGBToAR64Row_RVV;
2159
  }
2160
#endif
2161
2162
0
  for (y = 0; y < height; ++y) {
2163
0
    ARGBToAR64Row(src_argb, dst_ar64, width);
2164
0
    src_argb += src_stride_argb;
2165
0
    dst_ar64 += dst_stride_ar64;
2166
0
  }
2167
0
  return 0;
2168
0
}
2169
2170
// Convert ARGB to AB64.
2171
LIBYUV_API
2172
int ARGBToAB64(const uint8_t* src_argb,
2173
               int src_stride_argb,
2174
               uint16_t* dst_ab64,
2175
               int dst_stride_ab64,
2176
               int width,
2177
0
               int height) {
2178
0
  int y;
2179
0
  void (*ARGBToAB64Row)(const uint8_t* src_argb, uint16_t* dst_ar64,
2180
0
                        int width) = ARGBToAB64Row_C;
2181
0
  if (!src_argb || !dst_ab64 || width <= 0 || height == 0 ||
2182
0
      height == INT_MIN) {
2183
0
    return -1;
2184
0
  }
2185
  // Negative height means invert the image.
2186
0
  if (height < 0) {
2187
0
    height = -height;
2188
0
    src_argb = src_argb + (ptrdiff_t)(height - 1) * src_stride_argb;
2189
0
    src_stride_argb = -src_stride_argb;
2190
0
  }
2191
  // Coalesce rows.
2192
0
  if (src_stride_argb == width * 4 && dst_stride_ab64 == width * 4 &&
2193
0
      (ptrdiff_t)width * height <= INT_MAX) {
2194
0
    width *= height;
2195
0
    height = 1;
2196
0
    src_stride_argb = dst_stride_ab64 = 0;
2197
0
  }
2198
0
#if defined(HAS_ARGBTOAB64ROW_SSSE3)
2199
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
2200
0
    ARGBToAB64Row = ARGBToAB64Row_Any_SSSE3;
2201
0
    if (IS_ALIGNED(width, 4)) {
2202
0
      ARGBToAB64Row = ARGBToAB64Row_SSSE3;
2203
0
    }
2204
0
  }
2205
0
#endif
2206
0
#if defined(HAS_ARGBTOAB64ROW_AVX2)
2207
0
  if (TestCpuFlag(kCpuHasAVX2)) {
2208
0
    ARGBToAB64Row = ARGBToAB64Row_Any_AVX2;
2209
0
    if (IS_ALIGNED(width, 8)) {
2210
0
      ARGBToAB64Row = ARGBToAB64Row_AVX2;
2211
0
    }
2212
0
  }
2213
0
#endif
2214
#if defined(HAS_ARGBTOAB64ROW_NEON)
2215
  if (TestCpuFlag(kCpuHasNEON)) {
2216
    ARGBToAB64Row = ARGBToAB64Row_Any_NEON;
2217
    if (IS_ALIGNED(width, 8)) {
2218
      ARGBToAB64Row = ARGBToAB64Row_NEON;
2219
    }
2220
  }
2221
#endif
2222
#if defined(HAS_ARGBTOAB64ROW_RVV)
2223
  if (TestCpuFlag(kCpuHasRVV)) {
2224
    ARGBToAB64Row = ARGBToAB64Row_RVV;
2225
  }
2226
#endif
2227
2228
0
  for (y = 0; y < height; ++y) {
2229
0
    ARGBToAB64Row(src_argb, dst_ab64, width);
2230
0
    src_argb += src_stride_argb;
2231
0
    dst_ab64 += dst_stride_ab64;
2232
0
  }
2233
0
  return 0;
2234
0
}
2235
2236
// Convert RAW to NV21 with Matrix.
2237
static int RAWToNVMatrix(const uint8_t* src_raw,
2238
                          int src_stride_raw,
2239
                          uint8_t* dst_y,
2240
                          int dst_stride_y,
2241
                          uint8_t* dst_uv,
2242
                          int dst_stride_uv,
2243
                          const struct ArgbConstants* argbconstants,
2244
                          int width,
2245
                          int height,
2246
0
                          int is_nv21) {
2247
0
  int y;
2248
0
  int halfwidth = (width + 1) >> 1;
2249
0
  void (*RGBToUVMatrixRow)(const uint8_t* src_rgb, int src_stride_rgb,
2250
0
                           uint8_t* dst_u, uint8_t* dst_v, int width,
2251
0
                           const struct ArgbConstants* c) =
2252
0
      RGBToUVMatrixRow_C;
2253
0
  void (*RGBToYMatrixRow)(const uint8_t* src_rgb, uint8_t* dst_y, int width,
2254
0
                          const struct ArgbConstants* c) = RGBToYMatrixRow_C;
2255
0
  void (*MergeUVRow)(const uint8_t* src_uj, const uint8_t* src_vj,
2256
0
                     uint8_t* dst_vu, int width) = MergeUVRow_C;
2257
2258
0
  if (!src_raw || !dst_y || !dst_uv || !argbconstants || width <= 0 ||
2259
0
      height == 0 || height == INT_MIN) {
2260
0
    return -1;
2261
0
  }
2262
  // Negative height means invert the image.
2263
0
  if (height < 0) {
2264
0
    height = -height;
2265
0
    src_raw = src_raw + (ptrdiff_t)(height - 1) * src_stride_raw;
2266
0
    src_stride_raw = -src_stride_raw;
2267
0
  }
2268
2269
0
#if defined(HAS_RGBTOYMATRIXROW_SSSE3)
2270
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
2271
0
    RGBToYMatrixRow = RGBToYMatrixRow_Any_SSSE3;
2272
0
    if (IS_ALIGNED(width, 16)) {
2273
0
      RGBToYMatrixRow = RGBToYMatrixRow_SSSE3;
2274
0
    }
2275
0
  }
2276
0
#endif
2277
0
#if defined(HAS_RGBTOYMATRIXROW_AVX2)
2278
0
  if (TestCpuFlag(kCpuHasAVX2)) {
2279
0
    RGBToYMatrixRow = RGBToYMatrixRow_Any_AVX2;
2280
0
    if (IS_ALIGNED(width, 32)) {
2281
0
      RGBToYMatrixRow = RGBToYMatrixRow_AVX2;
2282
0
    }
2283
0
  }
2284
0
#endif
2285
0
#if defined(HAS_RGBTOYMATRIXROW_AVX512BW)
2286
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
2287
0
    RGBToYMatrixRow = RGBToYMatrixRow_Any_AVX512BW;
2288
0
    if (IS_ALIGNED(width, 64)) {
2289
0
      RGBToYMatrixRow = RGBToYMatrixRow_AVX512BW;
2290
0
    }
2291
0
  }
2292
0
#endif
2293
#if defined(HAS_RGBTOYMATRIXROW_NEON)
2294
  if (TestCpuFlag(kCpuHasNEON)) {
2295
    RGBToYMatrixRow = RGBToYMatrixRow_Any_NEON;
2296
    if (IS_ALIGNED(width, 16)) {
2297
      RGBToYMatrixRow = RGBToYMatrixRow_NEON;
2298
    }
2299
  }
2300
#endif
2301
#if defined(HAS_RGBTOYMATRIXROW_NEON_DOTPROD)
2302
  if (TestCpuFlag(kCpuHasNeonDotProd)) {
2303
    RGBToYMatrixRow = RGBToYMatrixRow_Any_NEON_DotProd;
2304
    if (IS_ALIGNED(width, 16)) {
2305
      RGBToYMatrixRow = RGBToYMatrixRow_NEON_DotProd;
2306
    }
2307
  }
2308
#endif
2309
#if defined(HAS_RGBTOYMATRIXROW_LASX)
2310
  if (TestCpuFlag(kCpuHasLASX)) {
2311
    RGBToYMatrixRow = RGBToYMatrixRow_Any_LASX;
2312
    if (IS_ALIGNED(width, 32)) {
2313
      RGBToYMatrixRow = RGBToYMatrixRow_LASX;
2314
    }
2315
  }
2316
#endif
2317
#if defined(HAS_RGBTOYMATRIXROW_RVV)
2318
  if (TestCpuFlag(kCpuHasRVV)) {
2319
    RGBToYMatrixRow = RGBToYMatrixRow_RVV;
2320
  }
2321
#endif
2322
2323
0
#if defined(HAS_RGBTOUVMATRIXROW_SSSE3)
2324
0
  if (TestCpuFlag(kCpuHasSSSE3)) {
2325
0
    RGBToUVMatrixRow = RGBToUVMatrixRow_Any_SSSE3;
2326
0
    if (IS_ALIGNED(width, 16)) {
2327
0
      RGBToUVMatrixRow = RGBToUVMatrixRow_SSSE3;
2328
0
    }
2329
0
  }
2330
0
#endif
2331
0
#if defined(HAS_RGBTOUVMATRIXROW_AVX2)
2332
0
  if (TestCpuFlag(kCpuHasAVX2)) {
2333
0
    RGBToUVMatrixRow = RGBToUVMatrixRow_Any_AVX2;
2334
0
    if (IS_ALIGNED(width, 32)) {
2335
0
      RGBToUVMatrixRow = RGBToUVMatrixRow_AVX2;
2336
0
    }
2337
0
  }
2338
0
#endif
2339
0
#if defined(HAS_RGBTOUVMATRIXROW_AVX512BW)
2340
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
2341
0
    RGBToUVMatrixRow = RGBToUVMatrixRow_Any_AVX512BW;
2342
0
    if (IS_ALIGNED(width, 64)) {
2343
0
      RGBToUVMatrixRow = RGBToUVMatrixRow_AVX512BW;
2344
0
    }
2345
0
  }
2346
0
#endif
2347
#if defined(HAS_RGBTOUVMATRIXROW_NEON)
2348
  if (TestCpuFlag(kCpuHasNEON)) {
2349
    RGBToUVMatrixRow = RGBToUVMatrixRow_Any_NEON;
2350
    if (IS_ALIGNED(width, 16)) {
2351
      RGBToUVMatrixRow = RGBToUVMatrixRow_NEON;
2352
    }
2353
  }
2354
#endif
2355
2356
0
#if defined(HAS_MERGEUVROW_SSE2)
2357
0
  if (TestCpuFlag(kCpuHasSSE2)) {
2358
0
    MergeUVRow = MergeUVRow_Any_SSE2;
2359
0
    if (IS_ALIGNED(halfwidth, 16)) {
2360
0
      MergeUVRow = MergeUVRow_SSE2;
2361
0
    }
2362
0
  }
2363
0
#endif
2364
0
#if defined(HAS_MERGEUVROW_AVX2)
2365
0
  if (TestCpuFlag(kCpuHasAVX2)) {
2366
0
    MergeUVRow = MergeUVRow_Any_AVX2;
2367
0
    if (IS_ALIGNED(halfwidth, 32)) {
2368
0
      MergeUVRow = MergeUVRow_AVX2;
2369
0
    }
2370
0
  }
2371
0
#endif
2372
0
#if defined(HAS_MERGEUVROW_AVX512BW)
2373
0
  if (TestCpuFlag(kCpuHasAVX512BW)) {
2374
0
    MergeUVRow = MergeUVRow_Any_AVX512BW;
2375
0
    if (IS_ALIGNED(halfwidth, 64)) {
2376
0
      MergeUVRow = MergeUVRow_AVX512BW;
2377
0
    }
2378
0
  }
2379
0
#endif
2380
#if defined(HAS_MERGEUVROW_NEON)
2381
  if (TestCpuFlag(kCpuHasNEON)) {
2382
    MergeUVRow = MergeUVRow_Any_NEON;
2383
    if (IS_ALIGNED(halfwidth, 16)) {
2384
      MergeUVRow = MergeUVRow_NEON;
2385
    }
2386
  }
2387
#endif
2388
#if defined(HAS_MERGEUVROW_SVE2)
2389
  if (TestCpuFlag(kCpuHasSVE2)) {
2390
    MergeUVRow = MergeUVRow_SVE2;
2391
  }
2392
#endif
2393
#if defined(HAS_MERGEUVROW_SME)
2394
  if (TestCpuFlag(kCpuHasSME)) {
2395
    MergeUVRow = MergeUVRow_SME;
2396
  }
2397
#endif
2398
#if defined(HAS_MERGEUVROW_LSX)
2399
  if (TestCpuFlag(kCpuHasLSX)) {
2400
    MergeUVRow = MergeUVRow_Any_LSX;
2401
    if (IS_ALIGNED(halfwidth, 16)) {
2402
      MergeUVRow = MergeUVRow_LSX;
2403
    }
2404
  }
2405
#endif
2406
#if defined(HAS_MERGEUVROW_RVV)
2407
  if (TestCpuFlag(kCpuHasRVV)) {
2408
    MergeUVRow = MergeUVRow_RVV;
2409
  }
2410
#endif
2411
2412
0
  {
2413
    // Allocate 1 row of U and 1 row of V.
2414
0
    align_buffer_64(row_u, halfwidth);
2415
0
    align_buffer_64(row_v, halfwidth);
2416
2417
0
    if (!row_u || !row_v) {
2418
0
      free_aligned_buffer_64(row_u);
2419
0
      free_aligned_buffer_64(row_v);
2420
0
      return 1;
2421
0
    }
2422
2423
0
    const uint8_t* first_chroma = is_nv21 ? row_v : row_u;
2424
0
    const uint8_t* second_chroma = is_nv21 ? row_u : row_v;
2425
2426
0
    for (y = 0; y < height - 1; y += 2) {
2427
0
      RGBToUVMatrixRow(src_raw, src_stride_raw, row_u, row_v, width,
2428
0
                       argbconstants);
2429
0
      MergeUVRow(first_chroma, second_chroma, dst_uv, halfwidth);
2430
0
      RGBToYMatrixRow(src_raw, dst_y, width, argbconstants);
2431
0
      RGBToYMatrixRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width,
2432
0
                      argbconstants);
2433
0
      src_raw += src_stride_raw * 2;
2434
0
      dst_y += dst_stride_y * 2;
2435
0
      dst_uv += dst_stride_uv;
2436
0
    }
2437
0
    if (height & 1) {
2438
0
      RGBToUVMatrixRow(src_raw, 0, row_u, row_v, width, argbconstants);
2439
0
      MergeUVRow(first_chroma, second_chroma, dst_uv, halfwidth);
2440
0
      RGBToYMatrixRow(src_raw, dst_y, width, argbconstants);
2441
0
    }
2442
0
    free_aligned_buffer_64(row_v);
2443
0
    free_aligned_buffer_64(row_u);
2444
0
  }
2445
0
  return 0;
2446
0
}
2447
2448
LIBYUV_API
2449
int RAWToNV21Matrix(const uint8_t* src_raw,
2450
                    int src_stride_raw,
2451
                    uint8_t* dst_y,
2452
                    int dst_stride_y,
2453
                    uint8_t* dst_vu,
2454
                    int dst_stride_vu,
2455
                    const struct ArgbConstants* argbconstants,
2456
                    int width,
2457
0
                    int height) {
2458
0
  return RAWToNVMatrix(src_raw, src_stride_raw, dst_y, dst_stride_y, dst_vu,
2459
0
                       dst_stride_vu, argbconstants, width, height, 1);
2460
0
}
2461
2462
LIBYUV_API
2463
int RAWToJNV21(const uint8_t* src_raw,
2464
               int src_stride_raw,
2465
               uint8_t* dst_y,
2466
               int dst_stride_y,
2467
               uint8_t* dst_vu,
2468
               int dst_stride_vu,
2469
               int width,
2470
0
               int height) {
2471
0
  return RAWToNV21Matrix(src_raw, src_stride_raw, dst_y, dst_stride_y, dst_vu,
2472
0
                         dst_stride_vu, &kAbgrJPEGConstants, width, height);
2473
0
}
2474
2475
LIBYUV_API
2476
int RAWToNV21(const uint8_t* src_raw,
2477
              int src_stride_raw,
2478
              uint8_t* dst_y,
2479
              int dst_stride_y,
2480
              uint8_t* dst_vu,
2481
              int dst_stride_vu,
2482
              int width,
2483
0
              int height) {
2484
0
  return RAWToNV21Matrix(src_raw, src_stride_raw, dst_y, dst_stride_y, dst_vu,
2485
0
                         dst_stride_vu, &kAbgrI601Constants, width, height);
2486
0
}
2487
2488
LIBYUV_API
2489
int RGB24ToNV12(const uint8_t* src_rgb24,
2490
                int src_stride_rgb24,
2491
                uint8_t* dst_y,
2492
                int dst_stride_y,
2493
                uint8_t* dst_uv,
2494
                int dst_stride_uv,
2495
                int width,
2496
0
                int height) {
2497
0
  return RAWToNVMatrix(src_rgb24, src_stride_rgb24, dst_y, dst_stride_y,
2498
0
                       dst_uv, dst_stride_uv, &kArgbI601Constants, width,
2499
0
                       height, 0);
2500
0
}
2501
2502
#ifdef __cplusplus
2503
}  // extern "C"
2504
}  // namespace libyuv
2505
#endif