mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
ARGBToI420Alpha function to convert ARGB to I420 with Alpha
Bug: b/281866362 Change-Id: Ic1093a887fb483f134c78909cf1ee7495e7345ba Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/4534100 Commit-Queue: Frank Barchard <fbarchard@chromium.org> Reviewed-by: Wan-Teh Chang <wtc@google.com>
This commit is contained in:
parent
11d4536002
commit
a37799344d
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1868
|
||||
Version: 1869
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -751,6 +751,21 @@ int ARGBToI420(const uint8_t* src_argb,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
// Convert ARGB to I420 with Alpha
|
||||
LIBYUV_API
|
||||
int ARGBToI420Alpha(const uint8_t* src_argb,
|
||||
int src_stride_argb,
|
||||
uint8_t* dst_y,
|
||||
int dst_stride_y,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
// BGRA little endian (argb in memory) to I420.
|
||||
LIBYUV_API
|
||||
int BGRAToI420(const uint8_t* src_bgra,
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 1868
|
||||
#define LIBYUV_VERSION 1869
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
@ -1845,6 +1845,192 @@ int ARGBToI420(const uint8_t* src_argb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_EXTRACTALPHA
|
||||
// Convert ARGB to I420 with Alpha
|
||||
// The following version calls ARGBExtractAlpha on the full image.
|
||||
LIBYUV_API
|
||||
int ARGBToI420Alpha(const uint8_t* src_argb,
|
||||
int src_stride_argb,
|
||||
uint8_t* dst_y,
|
||||
int dst_stride_y,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
int width,
|
||||
int height) {
|
||||
int r = ARGBToI420(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u,
|
||||
dst_stride_u, dst_v, dst_stride_v, width, height);
|
||||
if (r == 0) {
|
||||
r = ARGBExtractAlpha(src_argb, src_stride_argb, dst_a, dst_stride_a, width,
|
||||
height);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#else // USE_EXTRACTALPHA
|
||||
// Convert ARGB to I420 with Alpha
|
||||
LIBYUV_API
|
||||
int ARGBToI420Alpha(const uint8_t* src_argb,
|
||||
int src_stride_argb,
|
||||
uint8_t* dst_y,
|
||||
int dst_stride_y,
|
||||
uint8_t* dst_u,
|
||||
int dst_stride_u,
|
||||
uint8_t* dst_v,
|
||||
int dst_stride_v,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
int width,
|
||||
int height) {
|
||||
int y;
|
||||
void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb,
|
||||
uint8_t* dst_u, uint8_t* dst_v, int width) =
|
||||
ARGBToUVRow_C;
|
||||
void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) =
|
||||
ARGBToYRow_C;
|
||||
void (*ARGBExtractAlphaRow)(const uint8_t* src_argb, uint8_t* dst_a,
|
||||
int width) = ARGBExtractAlphaRow_C;
|
||||
if (!src_argb || !dst_y || !dst_u || !dst_v || !dst_a || width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||
src_stride_argb = -src_stride_argb;
|
||||
}
|
||||
#if defined(HAS_ARGBTOYROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
ARGBToYRow = ARGBToYRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToYRow = ARGBToYRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOUVROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
ARGBToUVRow = ARGBToUVRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToUVRow = ARGBToUVRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
ARGBToYRow = ARGBToYRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToYRow = ARGBToYRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOUVROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToUVRow = ARGBToUVRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
ARGBToYRow = ARGBToYRow_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 32)) {
|
||||
ARGBToYRow = ARGBToYRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOUVROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
ARGBToUVRow = ARGBToUVRow_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 32)) {
|
||||
ARGBToUVRow = ARGBToUVRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA)
|
||||
if (TestCpuFlag(kCpuHasMSA)) {
|
||||
ARGBToYRow = ARGBToYRow_Any_MSA;
|
||||
ARGBToUVRow = ARGBToUVRow_Any_MSA;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToYRow = ARGBToYRow_MSA;
|
||||
}
|
||||
if (IS_ALIGNED(width, 32)) {
|
||||
ARGBToUVRow = ARGBToUVRow_MSA;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYROW_LSX)
|
||||
if (TestCpuFlag(kCpuHasLSX)) {
|
||||
ARGBToYRow = ARGBToYRow_Any_LSX;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
ARGBToYRow = ARGBToYRow_LSX;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOYROW_LASX) && defined(HAS_ARGBTOUVROW_LASX)
|
||||
if (TestCpuFlag(kCpuHasLASX)) {
|
||||
ARGBToYRow = ARGBToYRow_Any_LASX;
|
||||
ARGBToUVRow = ARGBToUVRow_Any_LASX;
|
||||
if (IS_ALIGNED(width, 32)) {
|
||||
ARGBToYRow = ARGBToYRow_LASX;
|
||||
ARGBToUVRow = ARGBToUVRow_LASX;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBEXTRACTALPHAROW_SSE2)
|
||||
if (TestCpuFlag(kCpuHasSSE2)) {
|
||||
ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_SSE2
|
||||
: ARGBExtractAlphaRow_Any_SSE2;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBEXTRACTALPHAROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
ARGBExtractAlphaRow = IS_ALIGNED(width, 32) ? ARGBExtractAlphaRow_AVX2
|
||||
: ARGBExtractAlphaRow_Any_AVX2;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBEXTRACTALPHAROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_NEON
|
||||
: ARGBExtractAlphaRow_Any_NEON;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBEXTRACTALPHAROW_MSA)
|
||||
if (TestCpuFlag(kCpuHasMSA)) {
|
||||
ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_MSA
|
||||
: ARGBExtractAlphaRow_Any_MSA;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBEXTRACTALPHAROW_LSX)
|
||||
if (TestCpuFlag(kCpuHasLSX)) {
|
||||
ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_LSX
|
||||
: ARGBExtractAlphaRow_Any_LSX;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (y = 0; y < height - 1; y += 2) {
|
||||
ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width);
|
||||
ARGBToYRow(src_argb, dst_y, width);
|
||||
ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width);
|
||||
ARGBExtractAlphaRow(src_argb, dst_a, width);
|
||||
ARGBExtractAlphaRow(src_argb + src_stride_argb, dst_a + dst_stride_a, width);
|
||||
src_argb += src_stride_argb * 2;
|
||||
dst_y += dst_stride_y * 2;
|
||||
dst_u += dst_stride_u;
|
||||
dst_v += dst_stride_v;
|
||||
dst_a += dst_stride_a * 2;
|
||||
}
|
||||
if (height & 1) {
|
||||
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
|
||||
ARGBToYRow(src_argb, dst_y, width);
|
||||
ARGBExtractAlphaRow(src_argb, dst_a, width);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // USE_EXTRACTALPHA
|
||||
|
||||
// Convert BGRA to I420.
|
||||
LIBYUV_API
|
||||
int BGRAToI420(const uint8_t* src_bgra,
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "libyuv/convert_argb.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "libyuv/convert_from_argb.h"
|
||||
#include "libyuv/cpu_id.h"
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
* Contributed by Bruce Lai <bruce.lai@sifive.com>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "libyuv/row.h"
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
|
||||
#include <assert.h>
|
||||
#include <riscv_vector.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -1276,6 +1276,82 @@ TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1)
|
||||
TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2)
|
||||
TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1)
|
||||
|
||||
#define TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, \
|
||||
SUBSAMP_Y, W1280, N, NEG, OFF) \
|
||||
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \
|
||||
const int kWidth = W1280; \
|
||||
const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \
|
||||
const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \
|
||||
const int kStride = (kStrideUV * SUBSAMP_X * 8 * BPP_A + 7) / 8; \
|
||||
align_buffer_page_end(src_argb, kStride* kHeight + OFF); \
|
||||
align_buffer_page_end(dst_a_c, kWidth* kHeight); \
|
||||
align_buffer_page_end(dst_y_c, kWidth* kHeight); \
|
||||
align_buffer_page_end(dst_uv_c, \
|
||||
kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
align_buffer_page_end(dst_a_opt, kWidth* kHeight); \
|
||||
align_buffer_page_end(dst_y_opt, kWidth* kHeight); \
|
||||
align_buffer_page_end(dst_uv_opt, \
|
||||
kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
memset(dst_a_c, 1, kWidth* kHeight); \
|
||||
memset(dst_y_c, 2, kWidth* kHeight); \
|
||||
memset(dst_uv_c, 3, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
memset(dst_a_opt, 101, kWidth* kHeight); \
|
||||
memset(dst_y_opt, 102, kWidth* kHeight); \
|
||||
memset(dst_uv_opt, 103, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
|
||||
for (int i = 0; i < kHeight; ++i) \
|
||||
for (int j = 0; j < kStride; ++j) \
|
||||
src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff); \
|
||||
MaskCpuFlags(disable_cpu_flags_); \
|
||||
FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_c, kWidth, dst_uv_c, \
|
||||
kStrideUV * 2, dst_uv_c + kStrideUV, kStrideUV * 2, \
|
||||
dst_a_c, kWidth, kWidth, NEG kHeight); \
|
||||
MaskCpuFlags(benchmark_cpu_info_); \
|
||||
for (int i = 0; i < benchmark_iterations_; ++i) { \
|
||||
FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_opt, kWidth, \
|
||||
dst_uv_opt, kStrideUV * 2, dst_uv_opt + kStrideUV, \
|
||||
kStrideUV * 2, dst_a_opt, kWidth, kWidth, \
|
||||
NEG kHeight); \
|
||||
} \
|
||||
for (int i = 0; i < kHeight; ++i) { \
|
||||
for (int j = 0; j < kWidth; ++j) { \
|
||||
EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
|
||||
EXPECT_EQ(dst_a_c[i * kWidth + j], dst_a_opt[i * kWidth + j]); \
|
||||
} \
|
||||
} \
|
||||
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * 2; ++i) { \
|
||||
for (int j = 0; j < kStrideUV; ++j) { \
|
||||
EXPECT_EQ(dst_uv_c[i * kStrideUV + j], dst_uv_opt[i * kStrideUV + j]); \
|
||||
} \
|
||||
} \
|
||||
free_aligned_buffer_page_end(dst_a_c); \
|
||||
free_aligned_buffer_page_end(dst_y_c); \
|
||||
free_aligned_buffer_page_end(dst_uv_c); \
|
||||
free_aligned_buffer_page_end(dst_a_opt); \
|
||||
free_aligned_buffer_page_end(dst_y_opt); \
|
||||
free_aligned_buffer_page_end(dst_uv_opt); \
|
||||
free_aligned_buffer_page_end(src_argb); \
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FULL_TESTS)
|
||||
#define TESTATOPLANARA(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
|
||||
TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
benchmark_width_ + 1, _Any, +, 0) \
|
||||
TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
benchmark_width_, _Unaligned, +, 2) \
|
||||
TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
benchmark_width_, _Invert, -, 0) \
|
||||
TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
benchmark_width_, _Opt, +, 0)
|
||||
#else
|
||||
#define TESTATOPLANARA(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
|
||||
TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
benchmark_width_ + 1, _Any, +, 0) \
|
||||
TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
benchmark_width_, _Opt, +, 0)
|
||||
#endif
|
||||
|
||||
TESTATOPLANARA(ARGB, 4, 1, I420Alpha, 2, 2)
|
||||
|
||||
#define TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||
W1280, N, NEG, OFF) \
|
||||
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user