mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-08 01:36:47 +08:00
refactor I420ToABGR to use I420ToARGBRow
Using a transposed conversion matrix, I420ToARGB can output ABGR. R=harryjin@google.com, xhwang@chromium.org BUG=libyuv:473 Review URL: https://codereview.chromium.org/1413573010 .
This commit is contained in:
parent
254ef01551
commit
5d97b93369
@ -112,7 +112,6 @@ extern "C" {
|
||||
// https://code.google.com/p/libyuv/issues/detail?id=517
|
||||
#define HAS_I422ALPHATOARGBROW_SSSE3
|
||||
#endif
|
||||
#define HAS_I422TOABGRROW_SSSE3
|
||||
#define HAS_I422TOARGB1555ROW_SSSE3
|
||||
#define HAS_I422TOARGB4444ROW_SSSE3
|
||||
#define HAS_I422TOARGBROW_SSSE3
|
||||
@ -207,7 +206,6 @@ extern "C" {
|
||||
// https://code.google.com/p/libyuv/issues/detail?id=517
|
||||
#define HAS_I422ALPHATOARGBROW_AVX2
|
||||
#endif
|
||||
#define HAS_I422TOABGRROW_AVX2
|
||||
#define HAS_I422TOARGBROW_AVX2
|
||||
#define HAS_I422TOBGRAROW_AVX2
|
||||
#define HAS_I422TORAWROW_AVX2
|
||||
@ -261,7 +259,6 @@ extern "C" {
|
||||
#if !defined(LIBYUV_DISABLE_X86) && defined (_M_X64) && \
|
||||
(!defined(__clang__) || defined(__SSSE3__))
|
||||
#define HAS_I422ALPHATOARGBROW_SSSE3
|
||||
#define HAS_I422TOABGRROW_SSSE3
|
||||
#define HAS_I422TOARGBROW_SSSE3
|
||||
#endif
|
||||
|
||||
@ -295,7 +292,6 @@ extern "C" {
|
||||
#define HAS_COPYROW_NEON
|
||||
#define HAS_I400TOARGBROW_NEON
|
||||
#define HAS_I411TOARGBROW_NEON
|
||||
#define HAS_I422TOABGRROW_NEON
|
||||
#define HAS_I422TOARGB1555ROW_NEON
|
||||
#define HAS_I422TOARGB4444ROW_NEON
|
||||
#define HAS_I422TOARGBROW_NEON
|
||||
@ -362,7 +358,6 @@ extern "C" {
|
||||
(_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6)
|
||||
#define HAS_COPYROW_MIPS
|
||||
#if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
|
||||
#define HAS_I422TOABGRROW_MIPS_DSPR2
|
||||
#define HAS_I422TOARGBROW_MIPS_DSPR2
|
||||
#define HAS_I422TOBGRAROW_MIPS_DSPR2
|
||||
#define HAS_INTERPOLATEROW_MIPS_DSPR2
|
||||
@ -460,10 +455,15 @@ struct YuvConstants {
|
||||
#define KYTORGB 192
|
||||
#endif
|
||||
|
||||
// Conversion matrix for YUV to RGB
|
||||
extern const struct YuvConstants kYuvIConstants; // BT.601
|
||||
extern const struct YuvConstants kYuvJConstants; // JPeg color space
|
||||
extern const struct YuvConstants kYuvHConstants; // BT.709
|
||||
extern const struct YuvConstants kYvuIConstants; // YVU to BGR BT.601
|
||||
|
||||
// Conversion matrix for YVU to BGR.
|
||||
extern const struct YuvConstants kYvuIConstants; // BT.601
|
||||
extern const struct YuvConstants kYvuJConstants; // JPeg color space
|
||||
extern const struct YuvConstants kYvuHConstants; // BT.709
|
||||
|
||||
#if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__)
|
||||
#define OMITFP
|
||||
@ -568,12 +568,6 @@ void I422ToARGBRow_NEON(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I411ToARGBRow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -586,12 +580,6 @@ void I422ToBGRARow_NEON(const uint8* src_y,
|
||||
uint8* dst_bgra,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToRGBARow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1058,12 +1046,6 @@ void I422AlphaToARGBRow_C(const uint8* y_buf,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_C(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I411ToARGBRow_C(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1099,12 +1081,6 @@ void I422ToBGRARow_C(const uint8* src_y,
|
||||
uint8* dst_bgra,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_C(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToRGBARow_C(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1153,12 +1129,6 @@ void I422ToARGBRow_AVX2(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_AVX2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToBGRARow_AVX2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1171,12 +1141,6 @@ void I422ToRGBARow_AVX2(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_AVX2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I444ToARGBRow_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1227,12 +1191,6 @@ void I422ToARGBRow_SSSE3(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I411ToARGBRow_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1297,12 +1255,6 @@ void I422ToBGRARow_SSSE3(const uint8* src_y,
|
||||
uint8* dst_bgra,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToRGBARow_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1387,12 +1339,6 @@ void I422ToRGBARow_Any_AVX2(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_Any_AVX2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I444ToARGBRow_Any_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1489,12 +1435,6 @@ void I422ToBGRARow_Any_SSSE3(const uint8* src_y,
|
||||
uint8* dst_bgra,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_Any_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToRGBARow_Any_SSSE3(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1681,12 +1621,6 @@ void I422ToBGRARow_Any_NEON(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_Any_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToRGBARow_Any_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1758,12 +1692,6 @@ void I422ToBGRARow_MIPS_DSPR2(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_MIPS_DSPR2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToARGBRow_MIPS_DSPR2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
@ -1776,12 +1704,6 @@ void I422ToBGRARow_MIPS_DSPR2(const uint8* src_y,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
void I422ToABGRRow_MIPS_DSPR2(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width);
|
||||
|
||||
void YUY2ToYRow_AVX2(const uint8* src_yuy2, uint8* dst_y, int width);
|
||||
void YUY2ToUVRow_AVX2(const uint8* src_yuy2, int stride_yuy2,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -450,76 +450,6 @@ int I420ToNV21(const uint8* src_y, int src_stride_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
// Convert I420 to ARGB.
|
||||
LIBYUV_API
|
||||
int I420ToARGB(const uint8* src_y, int src_stride_y,
|
||||
const uint8* src_u, int src_stride_u,
|
||||
const uint8* src_v, int src_stride_v,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
int y;
|
||||
void (*I422ToARGBRow)(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) = I422ToARGBRow_C;
|
||||
if (!src_y || !src_u || !src_v || !dst_argb ||
|
||||
width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
dst_argb = dst_argb + (height - 1) * dst_stride_argb;
|
||||
dst_stride_argb = -dst_stride_argb;
|
||||
}
|
||||
#if defined(HAS_I422TOARGBROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToARGBRow = I422ToARGBRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
I422ToARGBRow = I422ToARGBRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToARGBRow = I422ToARGBRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
|
||||
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
|
||||
IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
|
||||
IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
|
||||
IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
|
||||
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
|
||||
I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
I422ToARGBRow(src_y, src_u, src_v, dst_argb, &kYuvIConstants, width);
|
||||
dst_argb += dst_stride_argb;
|
||||
src_y += src_stride_y;
|
||||
if (y & 1) {
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I420 to BGRA.
|
||||
LIBYUV_API
|
||||
int I420ToBGRA(const uint8* src_y, int src_stride_y,
|
||||
@ -590,67 +520,6 @@ int I420ToBGRA(const uint8* src_y, int src_stride_y,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I420 to ABGR.
|
||||
LIBYUV_API
|
||||
int I420ToABGR(const uint8* src_y, int src_stride_y,
|
||||
const uint8* src_u, int src_stride_u,
|
||||
const uint8* src_v, int src_stride_v,
|
||||
uint8* dst_abgr, int dst_stride_abgr,
|
||||
int width, int height) {
|
||||
int y;
|
||||
void (*I422ToABGRRow)(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) = I422ToABGRRow_C;
|
||||
if (!src_y || !src_u || !src_v || !dst_abgr ||
|
||||
width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
dst_abgr = dst_abgr + (height - 1) * dst_stride_abgr;
|
||||
dst_stride_abgr = -dst_stride_abgr;
|
||||
}
|
||||
#if defined(HAS_I422TOABGRROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
I422ToABGRRow = I422ToABGRRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToABGRRow = I422ToABGRRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOABGRROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
I422ToABGRRow = I422ToABGRRow_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
I422ToABGRRow = I422ToABGRRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOABGRROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
I422ToABGRRow = I422ToABGRRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToABGRRow = I422ToABGRRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
I422ToABGRRow(src_y, src_u, src_v, dst_abgr, &kYuvIConstants, width);
|
||||
dst_abgr += dst_stride_abgr;
|
||||
src_y += src_stride_y;
|
||||
if (y & 1) {
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I420 to RGBA.
|
||||
LIBYUV_API
|
||||
int I420ToRGBA(const uint8* src_y, int src_stride_y,
|
||||
|
||||
@ -843,75 +843,6 @@ int I422ToBGRA(const uint8* src_y, int src_stride_y,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I422 to ABGR.
|
||||
LIBYUV_API
|
||||
int I422ToABGR(const uint8* src_y, int src_stride_y,
|
||||
const uint8* src_u, int src_stride_u,
|
||||
const uint8* src_v, int src_stride_v,
|
||||
uint8* dst_abgr, int dst_stride_abgr,
|
||||
int width, int height) {
|
||||
int y;
|
||||
void (*I422ToABGRRow)(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) = I422ToABGRRow_C;
|
||||
if (!src_y || !src_u || !src_v ||
|
||||
!dst_abgr ||
|
||||
width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
dst_abgr = dst_abgr + (height - 1) * dst_stride_abgr;
|
||||
dst_stride_abgr = -dst_stride_abgr;
|
||||
}
|
||||
// Coalesce rows.
|
||||
if (src_stride_y == width &&
|
||||
src_stride_u * 2 == width &&
|
||||
src_stride_v * 2 == width &&
|
||||
dst_stride_abgr == width * 4) {
|
||||
width *= height;
|
||||
height = 1;
|
||||
src_stride_y = src_stride_u = src_stride_v = dst_stride_abgr = 0;
|
||||
}
|
||||
#if defined(HAS_I422TOABGRROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
|
||||
I422ToABGRRow = I422ToABGRRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToABGRRow = I422ToABGRRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOABGRROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
I422ToABGRRow = I422ToABGRRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToABGRRow = I422ToABGRRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOABGRROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
I422ToABGRRow = I422ToABGRRow_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
I422ToABGRRow = I422ToABGRRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
I422ToABGRRow(src_y, src_u, src_v, dst_abgr, &kYuvIConstants, width);
|
||||
dst_abgr += dst_stride_abgr;
|
||||
src_y += src_stride_y;
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I422 to RGBA.
|
||||
LIBYUV_API
|
||||
int I422ToRGBA(const uint8* src_y, int src_stride_y,
|
||||
|
||||
@ -111,7 +111,6 @@ ANY31(I422ToUYVYRow_Any_NEON, I422ToUYVYRow_NEON, 1, 1, 4, 15)
|
||||
|
||||
#ifdef HAS_I422TOARGBROW_SSSE3
|
||||
ANY31C(I422ToARGBRow_Any_SSSE3, I422ToARGBRow_SSSE3, 1, 0, 4, 7)
|
||||
ANY31C(I422ToABGRRow_Any_SSSE3, I422ToABGRRow_SSSE3, 1, 0, 4, 7)
|
||||
#endif
|
||||
#ifdef HAS_I444TOARGBROW_SSSE3
|
||||
ANY31C(I444ToARGBRow_Any_SSSE3, I444ToARGBRow_SSSE3, 0, 0, 4, 7)
|
||||
@ -139,9 +138,6 @@ ANY31C(I422ToBGRARow_Any_AVX2, I422ToBGRARow_AVX2, 1, 0, 4, 15)
|
||||
#ifdef HAS_I422TORGBAROW_AVX2
|
||||
ANY31C(I422ToRGBARow_Any_AVX2, I422ToRGBARow_AVX2, 1, 0, 4, 15)
|
||||
#endif
|
||||
#ifdef HAS_I422TOABGRROW_AVX2
|
||||
ANY31C(I422ToABGRRow_Any_AVX2, I422ToABGRRow_AVX2, 1, 0, 4, 15)
|
||||
#endif
|
||||
#ifdef HAS_I444TOARGBROW_AVX2
|
||||
ANY31C(I444ToARGBRow_Any_AVX2, I444ToARGBRow_AVX2, 0, 0, 4, 15)
|
||||
#endif
|
||||
@ -162,7 +158,6 @@ ANY31C(I444ToARGBRow_Any_NEON, I444ToARGBRow_NEON, 0, 0, 4, 7)
|
||||
ANY31C(I422ToARGBRow_Any_NEON, I422ToARGBRow_NEON, 1, 0, 4, 7)
|
||||
ANY31C(I411ToARGBRow_Any_NEON, I411ToARGBRow_NEON, 2, 0, 4, 7)
|
||||
ANY31C(I422ToBGRARow_Any_NEON, I422ToBGRARow_NEON, 1, 0, 4, 7)
|
||||
ANY31C(I422ToABGRRow_Any_NEON, I422ToABGRRow_NEON, 1, 0, 4, 7)
|
||||
ANY31C(I422ToRGBARow_Any_NEON, I422ToRGBARow_NEON, 1, 0, 4, 7)
|
||||
ANY31C(I422ToRGB24Row_Any_NEON, I422ToRGB24Row_NEON, 1, 0, 3, 7)
|
||||
ANY31C(I422ToRAWRow_Any_NEON, I422ToRAWRow_NEON, 1, 0, 3, 7)
|
||||
|
||||
@ -995,6 +995,9 @@ void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(fbarchard): Unify these structures to be platform independent.
|
||||
// TODO(fbarchard): Generate SIMD structures from float matrix.
|
||||
|
||||
// BT.601 YUV to RGB reference
|
||||
// R = (Y - 16) * 1.164 - V * -1.596
|
||||
// G = (Y - 16) * 1.164 - U * 0.391 - V * 0.813
|
||||
@ -1015,9 +1018,6 @@ void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
|
||||
#define BG (UG * 128 + VG * 128 + YGB)
|
||||
#define BR (VR * 128 + YGB)
|
||||
|
||||
// BT.601 constants for YUV to RGB.
|
||||
// TODO(fbarchard): Unify these structures to be platform independent.
|
||||
// TODO(fbarchard): Generate SIMD structures from float matrix.
|
||||
#if defined(__aarch64__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvIConstants) = {
|
||||
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
|
||||
@ -1027,6 +1027,14 @@ const YuvConstants SIMD_ALIGNED(kYuvIConstants) = {
|
||||
{ BB, BG, BR, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuIConstants) = {
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#elif defined(__arm__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvIConstants) = {
|
||||
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
@ -1034,6 +1042,12 @@ const YuvConstants SIMD_ALIGNED(kYuvIConstants) = {
|
||||
{ BB, BG, BR, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuIConstants) = {
|
||||
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#else
|
||||
const YuvConstants SIMD_ALIGNED(kYuvIConstants) = {
|
||||
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
|
||||
@ -1047,8 +1061,205 @@ const YuvConstants SIMD_ALIGNED(kYuvIConstants) = {
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuIConstants) = {
|
||||
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
|
||||
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, UB, 0 },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
|
||||
VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
|
||||
0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, VR },
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
|
||||
{ BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef BB
|
||||
#undef BG
|
||||
#undef BR
|
||||
#undef YGB
|
||||
#undef UB
|
||||
#undef UG
|
||||
#undef VG
|
||||
#undef VR
|
||||
#undef YG
|
||||
|
||||
// JPEG YUV to RGB reference
|
||||
// * R = Y - V * -1.40200
|
||||
// * G = Y - U * 0.34414 - V * 0.71414
|
||||
// * B = Y - U * -1.77200
|
||||
|
||||
// Y contribution to R,G,B. Scale and bias.
|
||||
#define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
|
||||
#define YGB 32 /* 64 / 2 */
|
||||
|
||||
// U and V contributions to R,G,B.
|
||||
#define UB -113 /* round(-1.77200 * 64) */
|
||||
#define UG 22 /* round(0.34414 * 64) */
|
||||
#define VG 46 /* round(0.71414 * 64) */
|
||||
#define VR -90 /* round(-1.40200 * 64) */
|
||||
|
||||
// Bias values to round, and subtract 128 from U and V.
|
||||
#define BB (UB * 128 + YGB)
|
||||
#define BG (UG * 128 + VG * 128 + YGB)
|
||||
#define BR (VR * 128 + YGB)
|
||||
|
||||
#if defined(__aarch64__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvJConstants) = {
|
||||
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
|
||||
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
|
||||
{ UG, VG, UG, VG, UG, VG, UG, VG },
|
||||
{ UG, VG, UG, VG, UG, VG, UG, VG },
|
||||
{ BB, BG, BR, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuJConstants) = {
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#elif defined(__arm__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvJConstants) = {
|
||||
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BB, BG, BR, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuJConstants) = {
|
||||
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#else
|
||||
const YuvConstants SIMD_ALIGNED(kYuvJConstants) = {
|
||||
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
|
||||
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
|
||||
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
|
||||
UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG },
|
||||
{ 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR,
|
||||
0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR },
|
||||
{ BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
|
||||
{ BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuJConstants) = {
|
||||
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
|
||||
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, UB, 0 },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
|
||||
VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
|
||||
0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, VR },
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
|
||||
{ BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef BB
|
||||
#undef BG
|
||||
#undef BR
|
||||
#undef YGB
|
||||
#undef UB
|
||||
#undef UG
|
||||
#undef VG
|
||||
#undef VR
|
||||
#undef YG
|
||||
|
||||
// BT.709 YUV to RGB reference
|
||||
// * R = Y - V * -1.28033
|
||||
// * G = Y - U * 0.21482 - V * 0.38059
|
||||
// * B = Y - U * -2.12798
|
||||
|
||||
// Y contribution to R,G,B. Scale and bias.
|
||||
#define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
|
||||
#define YGB 32 /* 64 / 2 */
|
||||
|
||||
// TODO(fbarchard): Find way to express 2.12 instead of 2.0.
|
||||
// U and V contributions to R,G,B.
|
||||
#define UB -128 /* max(-128, round(-2.12798 * 64)) */
|
||||
#define UG 14 /* round(0.21482 * 64) */
|
||||
#define VG 24 /* round(0.38059 * 64) */
|
||||
#define VR -82 /* round(-1.28033 * 64) */
|
||||
|
||||
// Bias values to round, and subtract 128 from U and V.
|
||||
#define BB (UB * 128 + YGB)
|
||||
#define BG (UG * 128 + VG * 128 + YGB)
|
||||
#define BR (VR * 128 + YGB)
|
||||
|
||||
#if defined(__aarch64__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvHConstants) = {
|
||||
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
|
||||
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
|
||||
{ UG, VG, UG, VG, UG, VG, UG, VG },
|
||||
{ UG, VG, UG, VG, UG, VG, UG, VG },
|
||||
{ BB, BG, BR, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuHConstants) = {
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#elif defined(__arm__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvHConstants) = {
|
||||
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BB, BG, BR, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuHConstants) = {
|
||||
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#else
|
||||
const YuvConstants SIMD_ALIGNED(kYuvHConstants) = {
|
||||
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
|
||||
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
|
||||
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
|
||||
UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG },
|
||||
{ 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR,
|
||||
0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR },
|
||||
{ BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
|
||||
{ BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
const YuvConstants SIMD_ALIGNED(kYvuHConstants) = {
|
||||
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
|
||||
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, UB, 0 },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
|
||||
VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
|
||||
0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, VR },
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
|
||||
{ BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef BB
|
||||
#undef BG
|
||||
#undef BR
|
||||
#undef YGB
|
||||
#undef UB
|
||||
#undef UG
|
||||
#undef VG
|
||||
#undef VR
|
||||
#undef YG
|
||||
|
||||
// C reference code that mimics the YUV assembly.
|
||||
static __inline void YuvPixel(uint8 y, uint8 u, uint8 v,
|
||||
uint8* b, uint8* g, uint8* r,
|
||||
@ -1088,6 +1299,10 @@ static __inline void YuvPixel(uint8 y, uint8 u, uint8 v,
|
||||
*r = Clamp((int32)(-( v * vr) + y1 + br) >> 6);
|
||||
}
|
||||
|
||||
// Y contribution to R,G,B. Scale and bias.
|
||||
#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
|
||||
#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */
|
||||
|
||||
// C reference code that mimics the YUV assembly.
|
||||
static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) {
|
||||
uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16;
|
||||
@ -1096,190 +1311,8 @@ static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) {
|
||||
*r = Clamp((int32)(y1 + YGB) >> 6);
|
||||
}
|
||||
|
||||
// BT.601 constants for YVU to BGR.
|
||||
// Allows YUV TO RGB code to implement YUV to BGR by swapping UV and using this
|
||||
// matrix.
|
||||
|
||||
#if defined(__aarch64__)
|
||||
const YuvConstants SIMD_ALIGNED(kYvuIConstants) = {
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#elif defined(__arm__)
|
||||
const YuvConstants SIMD_ALIGNED(kYvuIConstants) = {
|
||||
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BR, BG, BB, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YG, 0, 0, 0 }
|
||||
};
|
||||
#else
|
||||
const YuvConstants SIMD_ALIGNED(kYvuIConstants) = {
|
||||
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
|
||||
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, UB, 0 },
|
||||
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
|
||||
VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG },
|
||||
{ 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB,
|
||||
0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, VR },
|
||||
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
|
||||
{ BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
|
||||
{ BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
|
||||
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef BB
|
||||
#undef BG
|
||||
#undef BR
|
||||
#undef YGB
|
||||
#undef UB
|
||||
#undef UG
|
||||
#undef VG
|
||||
#undef VR
|
||||
#undef YG
|
||||
|
||||
// JPEG YUV to RGB reference
|
||||
// * R = Y - V * -1.40200
|
||||
// * G = Y - U * 0.34414 - V * 0.71414
|
||||
// * B = Y - U * -1.77200
|
||||
|
||||
// Y contribution to R,G,B. Scale and bias.
|
||||
#define YGJ 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
|
||||
#define YGBJ 32 /* 64 / 2 */
|
||||
|
||||
// U and V contributions to R,G,B.
|
||||
#define UBJ -113 /* round(-1.77200 * 64) */
|
||||
#define UGJ 22 /* round(0.34414 * 64) */
|
||||
#define VGJ 46 /* round(0.71414 * 64) */
|
||||
#define VRJ -90 /* round(-1.40200 * 64) */
|
||||
|
||||
// Bias values to round, and subtract 128 from U and V.
|
||||
#define BBJ (UBJ * 128 + YGBJ)
|
||||
#define BGJ (UGJ * 128 + VGJ * 128 + YGBJ)
|
||||
#define BRJ (VRJ * 128 + YGBJ)
|
||||
|
||||
// JPEG constants for YUV to RGB.
|
||||
#if defined(__aarch64__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvJConstants) = {
|
||||
{ -UBJ, -VRJ, -UBJ, -VRJ, -UBJ, -VRJ, -UBJ, -VRJ },
|
||||
{ -UBJ, -VRJ, -UBJ, -VRJ, -UBJ, -VRJ, -UBJ, -VRJ },
|
||||
{ UGJ, VGJ, UGJ, VGJ, UGJ, VGJ, UGJ, VGJ },
|
||||
{ UGJ, VGJ, UGJ, VGJ, UGJ, VGJ, UGJ, VGJ },
|
||||
{ BBJ, BGJ, BRJ, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YGJ, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#elif defined(__arm__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvJConstants) = {
|
||||
{ -UBJ, -UBJ, -UBJ, -UBJ, -VRJ, -VRJ, -VRJ, -VRJ, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ UGJ, UGJ, UGJ, UGJ, VGJ, VGJ, VGJ, VGJ, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BBJ, BGJ, BRJ, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YGJ, 0, 0, 0 }
|
||||
};
|
||||
#else
|
||||
const YuvConstants SIMD_ALIGNED(kYuvJConstants) = {
|
||||
{ UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0,
|
||||
UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0, UBJ, 0 },
|
||||
{ UGJ, VGJ, UGJ, VGJ, UGJ, VGJ, UGJ, VGJ,
|
||||
UGJ, VGJ, UGJ, VGJ, UGJ, VGJ, UGJ, VGJ,
|
||||
UGJ, VGJ, UGJ, VGJ, UGJ, VGJ, UGJ, VGJ,
|
||||
UGJ, VGJ, UGJ, VGJ, UGJ, VGJ, UGJ, VGJ },
|
||||
{ 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ,
|
||||
0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ, 0, VRJ },
|
||||
{ BBJ, BBJ, BBJ, BBJ, BBJ, BBJ, BBJ, BBJ,
|
||||
BBJ, BBJ, BBJ, BBJ, BBJ, BBJ, BBJ, BBJ },
|
||||
{ BGJ, BGJ, BGJ, BGJ, BGJ, BGJ, BGJ, BGJ,
|
||||
BGJ, BGJ, BGJ, BGJ, BGJ, BGJ, BGJ, BGJ },
|
||||
{ BRJ, BRJ, BRJ, BRJ, BRJ, BRJ, BRJ, BRJ,
|
||||
BRJ, BRJ, BRJ, BRJ, BRJ, BRJ, BRJ, BRJ },
|
||||
{ YGJ, YGJ, YGJ, YGJ, YGJ, YGJ, YGJ, YGJ,
|
||||
YGJ, YGJ, YGJ, YGJ, YGJ, YGJ, YGJ, YGJ }
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef YGJ
|
||||
#undef YGBJ
|
||||
#undef UBJ
|
||||
#undef UGJ
|
||||
#undef VGJ
|
||||
#undef VRJ
|
||||
#undef BBJ
|
||||
#undef BGJ
|
||||
#undef BRJ
|
||||
|
||||
// BT.709 YUV to RGB reference
|
||||
// * R = Y - V * -1.28033
|
||||
// * G = Y - U * 0.21482 - V * 0.38059
|
||||
// * B = Y - U * -2.12798
|
||||
|
||||
// Y contribution to R,G,B. Scale and bias.
|
||||
#define YGH 16320 /* round(1.000 * 64 * 256 * 256 / 257) */
|
||||
#define YGBH 32 /* 64 / 2 */
|
||||
|
||||
// TODO(fbarchard): Find way to express 2.12 instead of 2.0.
|
||||
// U and V contributions to R,G,B.
|
||||
#define UBH -128 /* max(-128, round(-2.12798 * 64)) */
|
||||
#define UGH 14 /* round(0.21482 * 64) */
|
||||
#define VGH 24 /* round(0.38059 * 64) */
|
||||
#define VRH -82 /* round(-1.28033 * 64) */
|
||||
|
||||
// Bias values to round, and subtract 128 from U and V.
|
||||
#define BBH (UBH * 128 + YGBH)
|
||||
#define BGH (UGH * 128 + VGH * 128 + YGBH)
|
||||
#define BRH (VRH * 128 + YGBH)
|
||||
|
||||
// BT.709 constants for YUV to RGB.
|
||||
#if defined(__aarch64__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvHConstants) = {
|
||||
{ -UBH, -VRH, -UBH, -VRH, -UBH, -VRH, -UBH, -VRH },
|
||||
{ -UBH, -VRH, -UBH, -VRH, -UBH, -VRH, -UBH, -VRH },
|
||||
{ UGH, VGH, UGH, VGH, UGH, VGH, UGH, VGH },
|
||||
{ UGH, VGH, UGH, VGH, UGH, VGH, UGH, VGH },
|
||||
{ BBH, BGH, BRH, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YGH, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#elif defined(__arm__)
|
||||
const YuvConstants SIMD_ALIGNED(kYuvHConstants) = {
|
||||
{ -UBH, -UBH, -UBH, -UBH, -VRH, -VRH, -VRH, -VRH, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ UGH, UGH, UGH, UGH, VGH, VGH, VGH, VGH, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ BBH, BGH, BRH, 0, 0, 0, 0, 0 },
|
||||
{ 0x0101 * YGH, 0, 0, 0 }
|
||||
};
|
||||
#else
|
||||
const YuvConstants SIMD_ALIGNED(kYuvHConstants) = {
|
||||
{ UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0,
|
||||
UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0, UBH, 0 },
|
||||
{ UGH, VGH, UGH, VGH, UGH, VGH, UGH, VGH,
|
||||
UGH, VGH, UGH, VGH, UGH, VGH, UGH, VGH,
|
||||
UGH, VGH, UGH, VGH, UGH, VGH, UGH, VGH,
|
||||
UGH, VGH, UGH, VGH, UGH, VGH, UGH, VGH },
|
||||
{ 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH,
|
||||
0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH, 0, VRH },
|
||||
{ BBH, BBH, BBH, BBH, BBH, BBH, BBH, BBH,
|
||||
BBH, BBH, BBH, BBH, BBH, BBH, BBH, BBH },
|
||||
{ BGH, BGH, BGH, BGH, BGH, BGH, BGH, BGH,
|
||||
BGH, BGH, BGH, BGH, BGH, BGH, BGH, BGH },
|
||||
{ BRH, BRH, BRH, BRH, BRH, BRH, BRH, BRH,
|
||||
BRH, BRH, BRH, BRH, BRH, BRH, BRH, BRH },
|
||||
{ YGH, YGH, YGH, YGH, YGH, YGH, YGH, YGH,
|
||||
YGH, YGH, YGH, YGH, YGH, YGH, YGH, YGH }
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef YGH
|
||||
#undef YGBH
|
||||
#undef UBH
|
||||
#undef UGH
|
||||
#undef VGH
|
||||
#undef VRH
|
||||
#undef BBH
|
||||
#undef BGH
|
||||
#undef BRH
|
||||
#undef YGB
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_NEON) && \
|
||||
(defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON))
|
||||
@ -1387,32 +1420,6 @@ void I422AlphaToARGBRow_C(const uint8* src_y,
|
||||
}
|
||||
}
|
||||
|
||||
void I422ToABGRRow_C(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* rgb_buf,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) {
|
||||
int x;
|
||||
for (x = 0; x < width - 1; x += 2) {
|
||||
YuvPixel(src_y[0], src_u[0], src_v[0],
|
||||
rgb_buf + 2, rgb_buf + 1, rgb_buf + 0, yuvconstants);
|
||||
rgb_buf[3] = 255;
|
||||
YuvPixel(src_y[1], src_u[0], src_v[0],
|
||||
rgb_buf + 6, rgb_buf + 5, rgb_buf + 4, yuvconstants);
|
||||
rgb_buf[7] = 255;
|
||||
src_y += 2;
|
||||
src_u += 1;
|
||||
src_v += 1;
|
||||
rgb_buf += 8; // Advance 2 pixels.
|
||||
}
|
||||
if (width & 1) {
|
||||
YuvPixel(src_y[0], src_u[0], src_v[0],
|
||||
rgb_buf + 2, rgb_buf + 1, rgb_buf + 0, yuvconstants);
|
||||
rgb_buf[3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void I422ToRGB24Row_C(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
|
||||
@ -715,68 +715,6 @@ void I422ToARGBRow_MIPS_DSPR2(const uint8* y_buf,
|
||||
);
|
||||
}
|
||||
|
||||
void I422ToABGRRow_MIPS_DSPR2(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) {
|
||||
__asm__ __volatile__ (
|
||||
".set push \n"
|
||||
".set noreorder \n"
|
||||
"beqz %[width], 2f \n"
|
||||
" repl.ph $s0, 74 \n" // |YG|YG| = |74|74|
|
||||
"repl.ph $s1, -25 \n" // |UG|UG| = |-25|-25|
|
||||
"repl.ph $s2, -52 \n" // |VG|VG| = |-52|-52|
|
||||
"repl.ph $s3, 102 \n" // |VR|VR| = |102|102|
|
||||
"repl.ph $s4, 16 \n" // |0|16|0|16|
|
||||
"repl.ph $s5, 128 \n" // |128|128|
|
||||
"lui $s6, 0xff00 \n"
|
||||
"ori $s6, 0xff00 \n" // |ff|00|ff|00|
|
||||
|
||||
"1: \n"
|
||||
YUVTORGB
|
||||
// Arranging into abgr format
|
||||
"precr.qb.ph $t0, $t8, $t1 \n" // |G1|g1|R1|r1|
|
||||
"precr.qb.ph $t3, $t9, $t2 \n" // |G0|g0|R0|r0|
|
||||
"precrq.qb.ph $t8, $t0, $t3 \n" // |G1|R1|G0|R0|
|
||||
"precr.qb.ph $t9, $t0, $t3 \n" // |g1|r1|g0|r0|
|
||||
|
||||
"precr.qb.ph $t2, $t4, $t5 \n" // |B1|b1|B0|b0|
|
||||
"addiu %[width], -4 \n"
|
||||
"addiu %[y_buf], 4 \n"
|
||||
"preceu.ph.qbla $t1, $t2 \n" // |0 |B1|0 |B0|
|
||||
"preceu.ph.qbra $t2, $t2 \n" // |0 |b1|0 |b0|
|
||||
"or $t1, $t1, $s6 \n" // |ff|B1|ff|B0|
|
||||
"or $t2, $t2, $s6 \n" // |ff|b1|ff|b0|
|
||||
"precrq.ph.w $t0, $t2, $t9 \n" // |ff|b1|g1|r1|
|
||||
"precrq.ph.w $t3, $t1, $t8 \n" // |ff|B1|G1|R1|
|
||||
"sll $t9, $t9, 16 \n"
|
||||
"sll $t8, $t8, 16 \n"
|
||||
"packrl.ph $t2, $t2, $t9 \n" // |ff|b0|g0|r0|
|
||||
"packrl.ph $t1, $t1, $t8 \n" // |ff|B0|G0|R0|
|
||||
// Store results.
|
||||
"sw $t2, 0(%[rgb_buf]) \n"
|
||||
"sw $t0, 4(%[rgb_buf]) \n"
|
||||
"sw $t1, 8(%[rgb_buf]) \n"
|
||||
"sw $t3, 12(%[rgb_buf]) \n"
|
||||
"bnez %[width], 1b \n"
|
||||
" addiu %[rgb_buf], 16 \n"
|
||||
"2: \n"
|
||||
".set pop \n"
|
||||
:[y_buf] "+r" (y_buf),
|
||||
[u_buf] "+r" (u_buf),
|
||||
[v_buf] "+r" (v_buf),
|
||||
[width] "+r" (width),
|
||||
[rgb_buf] "+r" (rgb_buf)
|
||||
:
|
||||
: "t0", "t1", "t2", "t3", "t4", "t5",
|
||||
"t6", "t7", "t8", "t9",
|
||||
"s0", "s1", "s2", "s3",
|
||||
"s4", "s5", "s6"
|
||||
);
|
||||
}
|
||||
|
||||
void I422ToBGRARow_MIPS_DSPR2(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
|
||||
@ -255,37 +255,6 @@ void I422ToBGRARow_NEON(const uint8* src_y,
|
||||
);
|
||||
}
|
||||
|
||||
void I422ToABGRRow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) {
|
||||
asm volatile (
|
||||
YUVTORGB_SETUP
|
||||
"1: \n"
|
||||
READYUV422
|
||||
YUVTORGB
|
||||
"subs %4, %4, #8 \n"
|
||||
"vswp.u8 d20, d22 \n"
|
||||
"vmov.u8 d23, #255 \n"
|
||||
MEMACCESS(3)
|
||||
"vst4.8 {d20, d21, d22, d23}, [%3]! \n"
|
||||
"bgt 1b \n"
|
||||
: "+r"(src_y), // %0
|
||||
"+r"(src_u), // %1
|
||||
"+r"(src_v), // %2
|
||||
"+r"(dst_abgr), // %3
|
||||
"+r"(width) // %4
|
||||
: [kUVToRB]"r"(&yuvconstants->kUVToRB),
|
||||
[kUVToG]"r"(&yuvconstants->kUVToG),
|
||||
[kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR),
|
||||
[kYToRgb]"r"(&yuvconstants->kYToRgb)
|
||||
: "cc", "memory", "q0", "q1", "q2", "q3", "q4",
|
||||
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
||||
);
|
||||
}
|
||||
|
||||
void I422ToRGBARow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
|
||||
@ -265,39 +265,6 @@ void I422ToBGRARow_NEON(const uint8* src_y,
|
||||
}
|
||||
#endif // HAS_I422TOBGRAROW_NEON
|
||||
|
||||
// TODO(fbarchard): Switch to Matrix version of this function.
|
||||
#ifdef HAS_I422TOABGRROW_NEON
|
||||
void I422ToABGRRow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
const uint8* src_v,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) {
|
||||
asm volatile (
|
||||
YUVTORGB_SETUP
|
||||
"1: \n"
|
||||
READYUV422
|
||||
YUVTORGB(v20, v21, v22)
|
||||
"subs %w4, %w4, #8 \n"
|
||||
"movi v23.8b, #255 \n" /* A */
|
||||
MEMACCESS(3)
|
||||
"st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n"
|
||||
"b.gt 1b \n"
|
||||
: "+r"(src_y), // %0
|
||||
"+r"(src_u), // %1
|
||||
"+r"(src_v), // %2
|
||||
"+r"(dst_abgr), // %3
|
||||
"+r"(width) // %4
|
||||
: [kUVToRB]"r"(&yuvconstants->kUVToRB),
|
||||
[kUVToG]"r"(&yuvconstants->kUVToG),
|
||||
[kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR),
|
||||
[kYToRgb]"r"(&yuvconstants->kYToRgb)
|
||||
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20",
|
||||
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
|
||||
);
|
||||
}
|
||||
#endif // HAS_I422TOABGRROW_NEON
|
||||
|
||||
#ifdef HAS_I422TORGBAROW_NEON
|
||||
void I422ToRGBARow_NEON(const uint8* src_y,
|
||||
const uint8* src_u,
|
||||
|
||||
@ -115,25 +115,6 @@ void I422ToARGBRow_SSSE3(const uint8* y_buf,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAS_I422TOABGRROW_SSSE3)
|
||||
void I422ToABGRRow_SSSE3(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* dst_abgr,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) {
|
||||
__m128i xmm0, xmm1, xmm2, xmm4;
|
||||
const __m128i xmm5 = _mm_set1_epi8(-1);
|
||||
const ptrdiff_t offset = (uint8*)v_buf - (uint8*)u_buf;
|
||||
while (width > 0) {
|
||||
READYUV422
|
||||
YUVTORGB(yuvconstants)
|
||||
STOREABGR
|
||||
width -= 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAS_I422ALPHATOARGBROW_SSSE3)
|
||||
void I422AlphaToARGBRow_SSSE3(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
@ -2455,48 +2436,9 @@ void I422ToRGBARow_AVX2(const uint8* y_buf,
|
||||
}
|
||||
#endif // HAS_I422TORGBAROW_AVX2
|
||||
|
||||
#ifdef HAS_I422TOABGRROW_AVX2
|
||||
// 16 pixels
|
||||
// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ABGR (64 bytes).
|
||||
__declspec(naked)
|
||||
void I422ToABGRRow_AVX2(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* dst_argb,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width) {
|
||||
__asm {
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
mov eax, [esp + 12 + 4] // Y
|
||||
mov esi, [esp + 12 + 8] // U
|
||||
mov edi, [esp + 12 + 12] // V
|
||||
mov edx, [esp + 12 + 16] // argb
|
||||
mov ebx, [esp + 12 + 20] // yuvconstants
|
||||
mov ecx, [esp + 12 + 24] // width
|
||||
sub edi, esi
|
||||
vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha
|
||||
|
||||
convertloop:
|
||||
READYUV422_AVX2
|
||||
YUVTORGB_AVX2(ebx)
|
||||
STOREABGR_AVX2
|
||||
|
||||
sub ecx, 16
|
||||
jg convertloop
|
||||
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
vzeroupper
|
||||
ret
|
||||
}
|
||||
}
|
||||
#endif // HAS_I422TOABGRROW_AVX2
|
||||
|
||||
#if defined(HAS_I422TOARGBROW_SSSE3)
|
||||
// TODO(fbarchard): Read that does half size on Y and treats 420 as 444.
|
||||
// Allows a conversion with half size scaling.
|
||||
|
||||
// Read 8 UV from 444.
|
||||
#define READYUV444 __asm { \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user