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
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 1868
|
Version: 1869
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -751,6 +751,21 @@ int ARGBToI420(const uint8_t* src_argb,
|
|||||||
int width,
|
int width,
|
||||||
int height);
|
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.
|
// BGRA little endian (argb in memory) to I420.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int BGRAToI420(const uint8_t* src_bgra,
|
int BGRAToI420(const uint8_t* src_bgra,
|
||||||
|
|||||||
@ -11,6 +11,6 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 1868
|
#define LIBYUV_VERSION 1869
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|||||||
@ -1845,6 +1845,192 @@ int ARGBToI420(const uint8_t* src_argb,
|
|||||||
return 0;
|
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.
|
// Convert BGRA to I420.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
int BGRAToI420(const uint8_t* src_bgra,
|
int BGRAToI420(const uint8_t* src_bgra,
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "libyuv/convert_argb.h"
|
#include "libyuv/convert_argb.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "libyuv/convert_from_argb.h"
|
#include "libyuv/convert_from_argb.h"
|
||||||
#include "libyuv/cpu_id.h"
|
#include "libyuv/cpu_id.h"
|
||||||
#ifdef HAVE_JPEG
|
#ifdef HAVE_JPEG
|
||||||
|
|||||||
@ -15,10 +15,10 @@
|
|||||||
* Contributed by Bruce Lai <bruce.lai@sifive.com>
|
* Contributed by Bruce Lai <bruce.lai@sifive.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "libyuv/row.h"
|
#include "libyuv/row.h"
|
||||||
|
|
||||||
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
|
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
|
||||||
|
#include <assert.h>
|
||||||
#include <riscv_vector.h>
|
#include <riscv_vector.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -1276,6 +1276,82 @@ TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1)
|
|||||||
TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2)
|
TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2)
|
||||||
TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1)
|
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, \
|
#define TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
|
||||||
W1280, N, NEG, OFF) \
|
W1280, N, NEG, OFF) \
|
||||||
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \
|
TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user