Commit fce0fed5 authored by Frank Barchard's avatar Frank Barchard Committed by Commit Bot

ARGBToY use 8 bit precision instead of 7 bit.

Neon and GCC Intel optimized, but win32 and mips not optimized.

BUG=libyuv:842, b/141482243

Change-Id: Ia56fa85c8cc1db51f374bd0c89b56d21ec94afa7
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/1825642
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: 's avatarMiguel Casas <mcasas@chromium.org>
Reviewed-by: 's avatarrichard winterton <rrwinterton@gmail.com>
parent e278d461
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1735 Version: 1737
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -227,6 +227,30 @@ int H420ToRAW(const uint8_t* src_y, ...@@ -227,6 +227,30 @@ int H420ToRAW(const uint8_t* src_y,
int width, int width,
int height); int height);
LIBYUV_API
int J420ToRGB24(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_rgb24,
int dst_stride_rgb24,
int width,
int height);
LIBYUV_API
int J420ToRAW(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_raw,
int dst_stride_raw,
int width,
int height);
LIBYUV_API LIBYUV_API
int I420ToRGB565(const uint8_t* src_y, int I420ToRGB565(const uint8_t* src_y,
int src_stride_y, int src_stride_y,
......
...@@ -210,6 +210,15 @@ int ARGBToJ400(const uint8_t* src_argb, ...@@ -210,6 +210,15 @@ int ARGBToJ400(const uint8_t* src_argb,
int width, int width,
int height); int height);
// Convert RGBA to J400. (JPeg full range).
LIBYUV_API
int RGBAToJ400(const uint8_t* src_rgba,
int src_stride_rgba,
uint8_t* dst_yj,
int dst_stride_yj,
int width,
int height);
// Convert ARGB to I400. // Convert ARGB to I400.
LIBYUV_API LIBYUV_API
int ARGBToI400(const uint8_t* src_argb, int ARGBToI400(const uint8_t* src_argb,
......
...@@ -274,6 +274,7 @@ extern "C" { ...@@ -274,6 +274,7 @@ extern "C" {
#define HAS_I210TOARGBROW_SSSE3 #define HAS_I210TOARGBROW_SSSE3
#define HAS_I422TOAR30ROW_SSSE3 #define HAS_I422TOAR30ROW_SSSE3
#define HAS_MERGERGBROW_SSSE3 #define HAS_MERGERGBROW_SSSE3
#define HAS_RGBATOYJROW_SSSE3
#define HAS_SPLITRGBROW_SSSE3 #define HAS_SPLITRGBROW_SSSE3
#define HAS_SWAPUVROW_SSSE3 #define HAS_SWAPUVROW_SSSE3
#endif #endif
...@@ -298,6 +299,7 @@ extern "C" { ...@@ -298,6 +299,7 @@ extern "C" {
#define HAS_I422TOYUY2ROW_AVX2 #define HAS_I422TOYUY2ROW_AVX2
#define HAS_MERGEUVROW_16_AVX2 #define HAS_MERGEUVROW_16_AVX2
#define HAS_MULTIPLYROW_16_AVX2 #define HAS_MULTIPLYROW_16_AVX2
#define HAS_RGBATOYJROW_AVX2
#define HAS_SWAPUVROW_AVX2 #define HAS_SWAPUVROW_AVX2
// TODO(fbarchard): Fix AVX2 version of YUV24 // TODO(fbarchard): Fix AVX2 version of YUV24
// #define HAS_NV21TOYUV24ROW_AVX2 // #define HAS_NV21TOYUV24ROW_AVX2
...@@ -335,6 +337,7 @@ extern "C" { ...@@ -335,6 +337,7 @@ extern "C" {
#define HAS_ARGBTOUVJROW_NEON #define HAS_ARGBTOUVJROW_NEON
#define HAS_ARGBTOUVROW_NEON #define HAS_ARGBTOUVROW_NEON
#define HAS_ARGBTOYJROW_NEON #define HAS_ARGBTOYJROW_NEON
#define HAS_RGBATOYJROW_NEON
#define HAS_ARGBTOYROW_NEON #define HAS_ARGBTOYROW_NEON
#define HAS_AYUVTOUVROW_NEON #define HAS_AYUVTOUVROW_NEON
#define HAS_AYUVTOVUROW_NEON #define HAS_AYUVTOVUROW_NEON
...@@ -951,6 +954,9 @@ void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width); ...@@ -951,6 +954,9 @@ void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width);
void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width);
void ARGBToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width);
void RGBAToYJRow_AVX2(const uint8_t* src_rgba, uint8_t* dst_y, int width);
void RGBAToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void RGBAToYJRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width);
void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width); void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width);
void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width); void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width);
void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width); void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width);
...@@ -958,6 +964,7 @@ void RGB24ToYRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); ...@@ -958,6 +964,7 @@ void RGB24ToYRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width);
void RAWToYRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); void RAWToYRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width);
void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width);
void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width);
void RGBAToYJRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width);
void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width);
void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width);
void ARGBToYRow_MMI(const uint8_t* src_argb0, uint8_t* dst_y, int width); void ARGBToYRow_MMI(const uint8_t* src_argb0, uint8_t* dst_y, int width);
...@@ -1149,6 +1156,7 @@ void ARGB4444ToYRow_MMI(const uint8_t* src_argb4444, uint8_t* dst_y, int width); ...@@ -1149,6 +1156,7 @@ void ARGB4444ToYRow_MMI(const uint8_t* src_argb4444, uint8_t* dst_y, int width);
void ARGBToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width);
void ARGBToYJRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYJRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width);
void RGBAToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width);
void BGRAToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void BGRAToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width);
void ABGRToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void ABGRToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width);
void RGBAToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width); void RGBAToYRow_C(const uint8_t* src_argb, uint8_t* dst_y, int width);
...@@ -1159,6 +1167,7 @@ void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width); ...@@ -1159,6 +1167,7 @@ void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width);
void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width); void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width);
void ARGBToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void ARGBToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void RGBAToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void BGRAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void BGRAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void ABGRToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ABGRToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void RGBAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGBAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
...@@ -1166,6 +1175,7 @@ void RGB24ToYRow_Any_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); ...@@ -1166,6 +1175,7 @@ void RGB24ToYRow_Any_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width);
void RAWToYRow_Any_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); void RAWToYRow_Any_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width);
void ARGBToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void ARGBToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void RGBAToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void BGRAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void BGRAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void ABGRToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ABGRToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
void RGBAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void RGBAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width);
......
...@@ -11,6 +11,6 @@ ...@@ -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 1735 #define LIBYUV_VERSION 1737
#endif // INCLUDE_LIBYUV_VERSION_H_ #endif // INCLUDE_LIBYUV_VERSION_H_
...@@ -764,6 +764,42 @@ int I420ToRAW(const uint8_t* src_y, ...@@ -764,6 +764,42 @@ int I420ToRAW(const uint8_t* src_y,
width, height); width, height);
} }
// Convert J420 to RGB24.
LIBYUV_API
int J420ToRGB24(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_rgb24,
int dst_stride_rgb24,
int width,
int height) {
return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_rgb24, dst_stride_rgb24,
&kYuvJPEGConstants, width, height);
}
// Convert J420 to RAW.
LIBYUV_API
int J420ToRAW(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_raw,
int dst_stride_raw,
int width,
int height) {
return I420ToRGB24Matrix(src_y, src_stride_y, src_v,
src_stride_v, // Swap U and V
src_u, src_stride_u, dst_raw, dst_stride_raw,
&kYvuJPEGConstants, // Use Yvu matrix
width, height);
}
// Convert H420 to RGB24. // Convert H420 to RGB24.
LIBYUV_API LIBYUV_API
int H420ToRGB24(const uint8_t* src_y, int H420ToRGB24(const uint8_t* src_y,
......
...@@ -2157,6 +2157,80 @@ int ARGBToJ400(const uint8_t* src_argb, ...@@ -2157,6 +2157,80 @@ int ARGBToJ400(const uint8_t* src_argb,
return 0; return 0;
} }
// Convert RGBA to J400.
LIBYUV_API
int RGBAToJ400(const uint8_t* src_rgba,
int src_stride_rgba,
uint8_t* dst_yj,
int dst_stride_yj,
int width,
int height) {
int y;
void (*RGBAToYJRow)(const uint8_t* src_rgba, uint8_t* dst_yj, int width) =
RGBAToYJRow_C;
if (!src_rgba || !dst_yj || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_rgba = src_rgba + (height - 1) * src_stride_rgba;
src_stride_rgba = -src_stride_rgba;
}
// Coalesce rows.
if (src_stride_rgba == width * 4 && dst_stride_yj == width) {
width *= height;
height = 1;
src_stride_rgba = dst_stride_yj = 0;
}
#if defined(HAS_RGBATOYJROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
RGBAToYJRow = RGBAToYJRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
RGBAToYJRow = RGBAToYJRow_SSSE3;
}
}
#endif
#if defined(HAS_RGBATOYJROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
RGBAToYJRow = RGBAToYJRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
RGBAToYJRow = RGBAToYJRow_AVX2;
}
}
#endif
#if defined(HAS_RGBATOYJROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
RGBAToYJRow = RGBAToYJRow_Any_NEON;
if (IS_ALIGNED(width, 8)) {
RGBAToYJRow = RGBAToYJRow_NEON;
}
}
#endif
#if defined(HAS_RGBATOYJROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
RGBAToYJRow = RGBAToYJRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
RGBAToYJRow = RGBAToYJRow_MSA;
}
}
#endif
#if defined(HAS_RGBATOYJROW_MMI)
if (TestCpuFlag(kCpuHasMMI)) {
RGBAToYJRow = RGBAToYJRow_Any_MMI;
if (IS_ALIGNED(width, 8)) {
RGBAToYJRow = RGBAToYJRow_MMI;
}
}
#endif
for (y = 0; y < height; ++y) {
RGBAToYJRow(src_rgba, dst_yj, width);
src_rgba += src_stride_rgba;
dst_yj += dst_stride_yj;
}
return 0;
}
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
} // namespace libyuv } // namespace libyuv
......
...@@ -616,6 +616,9 @@ ANY11(ABGRToYRow_Any_AVX2, ABGRToYRow_AVX2, 0, 4, 1, 31) ...@@ -616,6 +616,9 @@ ANY11(ABGRToYRow_Any_AVX2, ABGRToYRow_AVX2, 0, 4, 1, 31)
#ifdef HAS_ARGBTOYJROW_AVX2 #ifdef HAS_ARGBTOYJROW_AVX2
ANY11(ARGBToYJRow_Any_AVX2, ARGBToYJRow_AVX2, 0, 4, 1, 31) ANY11(ARGBToYJRow_Any_AVX2, ARGBToYJRow_AVX2, 0, 4, 1, 31)
#endif #endif
#ifdef HAS_RGBATOYJROW_AVX2
ANY11(RGBAToYJRow_Any_AVX2, RGBAToYJRow_AVX2, 0, 4, 1, 31)
#endif
#ifdef HAS_UYVYTOYROW_AVX2 #ifdef HAS_UYVYTOYROW_AVX2
ANY11(UYVYToYRow_Any_AVX2, UYVYToYRow_AVX2, 0, 2, 1, 31) ANY11(UYVYToYRow_Any_AVX2, UYVYToYRow_AVX2, 0, 2, 1, 31)
#endif #endif
...@@ -635,6 +638,9 @@ ANY11(UYVYToYRow_Any_SSE2, UYVYToYRow_SSE2, 1, 4, 1, 15) ...@@ -635,6 +638,9 @@ ANY11(UYVYToYRow_Any_SSE2, UYVYToYRow_SSE2, 1, 4, 1, 15)
#ifdef HAS_ARGBTOYJROW_SSSE3 #ifdef HAS_ARGBTOYJROW_SSSE3
ANY11(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_SSSE3, 0, 4, 1, 15) ANY11(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_SSSE3, 0, 4, 1, 15)
#endif #endif
#ifdef HAS_RGBATOYJROW_SSSE3
ANY11(RGBAToYJRow_Any_SSSE3, RGBAToYJRow_SSSE3, 0, 4, 1, 15)
#endif
#ifdef HAS_ARGBTOYROW_NEON #ifdef HAS_ARGBTOYROW_NEON
ANY11(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 0, 4, 1, 7) ANY11(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 0, 4, 1, 7)
#endif #endif
...@@ -647,6 +653,9 @@ ANY11(ARGBToYRow_Any_MMI, ARGBToYRow_MMI, 0, 4, 1, 7) ...@@ -647,6 +653,9 @@ ANY11(ARGBToYRow_Any_MMI, ARGBToYRow_MMI, 0, 4, 1, 7)
#ifdef HAS_ARGBTOYJROW_NEON #ifdef HAS_ARGBTOYJROW_NEON
ANY11(ARGBToYJRow_Any_NEON, ARGBToYJRow_NEON, 0, 4, 1, 7) ANY11(ARGBToYJRow_Any_NEON, ARGBToYJRow_NEON, 0, 4, 1, 7)
#endif #endif
#ifdef HAS_RGBATOYJROW_NEON
ANY11(RGBAToYJRow_Any_NEON, RGBAToYJRow_NEON, 0, 4, 1, 7)
#endif
#ifdef HAS_ARGBTOYJROW_MSA #ifdef HAS_ARGBTOYJROW_MSA
ANY11(ARGBToYJRow_Any_MSA, ARGBToYJRow_MSA, 0, 4, 1, 15) ANY11(ARGBToYJRow_Any_MSA, ARGBToYJRow_MSA, 0, 4, 1, 15)
#endif #endif
......
...@@ -20,6 +20,18 @@ namespace libyuv { ...@@ -20,6 +20,18 @@ namespace libyuv {
extern "C" { extern "C" {
#endif #endif
// The following ifdef from row_win makes the C code match the row_win code,
// which is 7 bit fixed point.
#if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && \
(defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__)))
#define LIBYUV_RGB7 1
#endif
// mips use 7 bit RGBToY
#if (!defined(LIBYUV_DISABLE_MMI) && defined(_MIPS_ARCH_LOONGSON3A)) || \
(!defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa))
#define LIBYUV_RGB7 1
#endif
// llvm x86 is poor at ternary operator, so use branchless min/max. // llvm x86 is poor at ternary operator, so use branchless min/max.
#define USE_BRANCHLESS 1 #define USE_BRANCHLESS 1
...@@ -381,9 +393,22 @@ void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width) { ...@@ -381,9 +393,22 @@ void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width) {
} }
} }
#ifdef LIBYUV_RGB7
// Old 7 bit math for compatibility on unsupported platforms.
static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) {
return ((33 * r + 65 * g + 13 * b) >> 7) + 16;
}
#else
// 8 bit
// Intel SSE/AVX uses the following equivalent formula
// 0x7e80 = (66 + 129 + 25) * -128 + 0x1000 (for +16) and 0x0080 for round.
// return (66 * ((int)r - 128) + 129 * ((int)g - 128) + 25 * ((int)b - 128) +
// 0x7e80) >> 8;
static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) { static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) {
return (66 * r + 129 * g + 25 * b + 0x1080) >> 8; return (66 * r + 129 * g + 25 * b + 0x1080) >> 8;
} }
#endif
static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) { static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) {
return (112 * b - 74 * g - 38 * r + 0x8080) >> 8; return (112 * b - 74 * g - 38 * r + 0x8080) >> 8;
...@@ -448,14 +473,14 @@ MAKEROWY(RAW, 0, 1, 2, 3) ...@@ -448,14 +473,14 @@ MAKEROWY(RAW, 0, 1, 2, 3)
// b 0.1016 * 255 = 25.908 = 25 // b 0.1016 * 255 = 25.908 = 25
// g 0.5078 * 255 = 129.489 = 129 // g 0.5078 * 255 = 129.489 = 129
// r 0.2578 * 255 = 65.739 = 66 // r 0.2578 * 255 = 65.739 = 66
// JPeg 8 bit Y (not used): // JPeg 7 bit Y (deprecated)
// b 0.11400 * 256 = 29.184 = 29
// g 0.58700 * 256 = 150.272 = 150
// r 0.29900 * 256 = 76.544 = 77
// JPeg 7 bit Y:
// b 0.11400 * 128 = 14.592 = 15 // b 0.11400 * 128 = 14.592 = 15
// g 0.58700 * 128 = 75.136 = 75 // g 0.58700 * 128 = 75.136 = 75
// r 0.29900 * 128 = 38.272 = 38 // r 0.29900 * 128 = 38.272 = 38
// JPeg 8 bit Y:
// b 0.11400 * 256 = 29.184 = 29
// g 0.58700 * 256 = 150.272 = 150
// r 0.29900 * 256 = 76.544 = 77
// JPeg 8 bit U: // JPeg 8 bit U:
// b 0.50000 * 255 = 127.5 = 127 // b 0.50000 * 255 = 127.5 = 127
// g -0.33126 * 255 = -84.4713 = -84 // g -0.33126 * 255 = -84.4713 = -84
...@@ -465,9 +490,17 @@ MAKEROWY(RAW, 0, 1, 2, 3) ...@@ -465,9 +490,17 @@ MAKEROWY(RAW, 0, 1, 2, 3)
// g -0.41869 * 255 = -106.76595 = -107 // g -0.41869 * 255 = -106.76595 = -107
// r 0.50000 * 255 = 127.5 = 127 // r 0.50000 * 255 = 127.5 = 127
#ifdef LIBYUV_RGB7
// Old 7 bit math for compatibility on unsupported platforms.
static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) { static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) {
return (38 * r + 75 * g + 15 * b + 64) >> 7; return (38 * r + 75 * g + 15 * b + 64) >> 7;
} }
#else
// 8 bit
static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) {
return (77 * r + 150 * g + 29 * b + 128) >> 8;
}
#endif
static __inline int RGBToUJ(uint8_t r, uint8_t g, uint8_t b) { static __inline int RGBToUJ(uint8_t r, uint8_t g, uint8_t b) {
return (127 * b - 84 * g - 43 * r + 0x8080) >> 8; return (127 * b - 84 * g - 43 * r + 0x8080) >> 8;
...@@ -516,6 +549,7 @@ static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) { ...@@ -516,6 +549,7 @@ static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) {
} }
MAKEROWYJ(ARGB, 2, 1, 0, 4) MAKEROWYJ(ARGB, 2, 1, 0, 4)
MAKEROWYJ(RGBA, 3, 2, 1, 4)
#undef MAKEROWYJ #undef MAKEROWYJ
void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -27,13 +27,13 @@ namespace libyuv { ...@@ -27,13 +27,13 @@ namespace libyuv {
#define ERROR_G 1 #define ERROR_G 1
#define ERROR_B 3 #define ERROR_B 3
#define ERROR_FULL 6 #define ERROR_FULL 6
#define ERROR_J420 5 #define ERROR_J420 6
#else #else
#define ERROR_R 1 #define ERROR_R 1
#define ERROR_G 1 #define ERROR_G 1
#define ERROR_B 3 #define ERROR_B 3
#define ERROR_FULL 5 #define ERROR_FULL 5
#define ERROR_J420 3 #define ERROR_J420 4
#endif #endif
#define TESTCS(TESTNAME, YUVTOARGB, ARGBTOYUV, HS1, HS, HN, DIFF) \ #define TESTCS(TESTNAME, YUVTOARGB, ARGBTOYUV, HS1, HS, HN, DIFF) \
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
#define ARM_YUV_ERROR 0 #define ARM_YUV_ERROR 0
#endif #endif
// Some functions fail on big endian. Enable these tests on all cpus except PowerPC // Some functions fail on big endian. Enable these tests on all cpus except
// PowerPC
#if !defined(__powerpc__) #if !defined(__powerpc__)
#define LITTLE_ENDIAN_TEST 1 #define LITTLE_ENDIAN_TEST 1
#endif #endif
...@@ -684,6 +685,8 @@ TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1) ...@@ -684,6 +685,8 @@ TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1)
TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1) TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1)
TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1) TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1)
TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1) TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1)
TESTPLANARTOB(J420, 2, 2, RAW, 3, 3, 1)
TESTPLANARTOB(J420, 2, 2, RGB24, 3, 3, 1)
TESTPLANARTOB(H420, 2, 2, RAW, 3, 3, 1) TESTPLANARTOB(H420, 2, 2, RAW, 3, 3, 1)
TESTPLANARTOB(H420, 2, 2, RGB24, 3, 3, 1) TESTPLANARTOB(H420, 2, 2, RGB24, 3, 3, 1)
#ifdef LITTLE_ENDIAN_TEST #ifdef LITTLE_ENDIAN_TEST
...@@ -1209,8 +1212,9 @@ TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0) ...@@ -1209,8 +1212,9 @@ TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0) TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0)
TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0) TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0) TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0)
TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2) TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 0)
TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2) TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 0)
TESTATOB(RGBA, 4, 4, 1, J400, 1, 1, 1, 0)
TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0) TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0)
TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0) TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0)
#ifdef LITTLE_ENDIAN_TEST #ifdef LITTLE_ENDIAN_TEST
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
#include "libyuv/compare.h" #include "libyuv/compare.h"
#include "libyuv/convert.h" #include "libyuv/convert.h"
...@@ -281,6 +280,7 @@ TEST_F(LibYUVPlanarTest, TestARGBComputeCumulativeSum) { ...@@ -281,6 +280,7 @@ TEST_F(LibYUVPlanarTest, TestARGBComputeCumulativeSum) {
} }
} }
// near is for legacy platforms.
TEST_F(LibYUVPlanarTest, TestARGBGray) { TEST_F(LibYUVPlanarTest, TestARGBGray) {
SIMD_ALIGNED(uint8_t orig_pixels[1280][4]); SIMD_ALIGNED(uint8_t orig_pixels[1280][4]);
memset(orig_pixels, 0, sizeof(orig_pixels)); memset(orig_pixels, 0, sizeof(orig_pixels));
...@@ -317,17 +317,17 @@ TEST_F(LibYUVPlanarTest, TestARGBGray) { ...@@ -317,17 +317,17 @@ TEST_F(LibYUVPlanarTest, TestARGBGray) {
orig_pixels[5][3] = 224u; orig_pixels[5][3] = 224u;
// Do 16 to test asm version. // Do 16 to test asm version.
ARGBGray(&orig_pixels[0][0], 0, 0, 0, 16, 1); ARGBGray(&orig_pixels[0][0], 0, 0, 0, 16, 1);
EXPECT_EQ(30u, orig_pixels[0][0]); EXPECT_NEAR(29u, orig_pixels[0][0], 1);
EXPECT_EQ(30u, orig_pixels[0][1]); EXPECT_NEAR(29u, orig_pixels[0][1], 1);
EXPECT_EQ(30u, orig_pixels[0][2]); EXPECT_NEAR(29u, orig_pixels[0][2], 1);
EXPECT_EQ(128u, orig_pixels[0][3]); EXPECT_EQ(128u, orig_pixels[0][3]);
EXPECT_EQ(149u, orig_pixels[1][0]); EXPECT_EQ(149u, orig_pixels[1][0]);
EXPECT_EQ(149u, orig_pixels[1][1]); EXPECT_EQ(149u, orig_pixels[1][1]);
EXPECT_EQ(149u, orig_pixels[1][2]); EXPECT_EQ(149u, orig_pixels[1][2]);
EXPECT_EQ(0u, orig_pixels[1][3]); EXPECT_EQ(0u, orig_pixels[1][3]);
EXPECT_EQ(76u, orig_pixels[2][0]); EXPECT_NEAR(77u, orig_pixels[2][0], 1);
EXPECT_EQ(76u, orig_pixels[2][1]); EXPECT_NEAR(77u, orig_pixels[2][1], 1);
EXPECT_EQ(76u, orig_pixels[2][2]); EXPECT_NEAR(77u, orig_pixels[2][2], 1);
EXPECT_EQ(255u, orig_pixels[2][3]); EXPECT_EQ(255u, orig_pixels[2][3]);
EXPECT_EQ(0u, orig_pixels[3][0]); EXPECT_EQ(0u, orig_pixels[3][0]);
EXPECT_EQ(0u, orig_pixels[3][1]); EXPECT_EQ(0u, orig_pixels[3][1]);
...@@ -337,9 +337,9 @@ TEST_F(LibYUVPlanarTest, TestARGBGray) { ...@@ -337,9 +337,9 @@ TEST_F(LibYUVPlanarTest, TestARGBGray) {
EXPECT_EQ(255u, orig_pixels[4][1]); EXPECT_EQ(255u, orig_pixels[4][1]);
EXPECT_EQ(255u, orig_pixels[4][2]); EXPECT_EQ(255u, orig_pixels[4][2]);
EXPECT_EQ(255u, orig_pixels[4][3]); EXPECT_EQ(255u, orig_pixels[4][3]);
EXPECT_EQ(96u, orig_pixels[5][0]); EXPECT_NEAR(97u, orig_pixels[5][0], 1);
EXPECT_EQ(96u, orig_pixels[5][1]); EXPECT_NEAR(97u, orig_pixels[5][1], 1);
EXPECT_EQ(96u, orig_pixels[5][2]); EXPECT_NEAR(97u, orig_pixels[5][2], 1);
EXPECT_EQ(224u, orig_pixels[5][3]); EXPECT_EQ(224u, orig_pixels[5][3]);
for (int i = 0; i < 1280; ++i) { for (int i = 0; i < 1280; ++i) {
orig_pixels[i][0] = i; orig_pixels[i][0] = i;
...@@ -389,30 +389,30 @@ TEST_F(LibYUVPlanarTest, TestARGBGrayTo) { ...@@ -389,30 +389,30 @@ TEST_F(LibYUVPlanarTest, TestARGBGrayTo) {
orig_pixels[5][3] = 224u; orig_pixels[5][3] = 224u;
// Do 16 to test asm version. // Do 16 to test asm version.
ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 16, 1); ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 16, 1);
EXPECT_EQ(30u, gray_pixels[0][0]); EXPECT_NEAR(30u, gray_pixels[0][0], 1);
EXPECT_EQ(30u, gray_pixels[0][1]); EXPECT_NEAR(30u, gray_pixels[0][1], 1);
EXPECT_EQ(30u, gray_pixels[0][2]); EXPECT_NEAR(30u, gray_pixels[0][2], 1);
EXPECT_EQ(128u, gray_pixels[0][3]); EXPECT_NEAR(128u, gray_pixels[0][3], 1);
EXPECT_EQ(149u, gray_pixels[1][0]); EXPECT_NEAR(149u, gray_pixels[1][0], 1);
EXPECT_EQ(149u, gray_pixels[1][1]); EXPECT_NEAR(149u, gray_pixels[1][1], 1);
EXPECT_EQ(149u, gray_pixels[1][2]); EXPECT_NEAR(149u, gray_pixels[1][2], 1);
EXPECT_EQ(0u, gray_pixels[1][3]); EXPECT_NEAR(0u, gray_pixels[1][3], 1);
EXPECT_EQ(76u, gray_pixels[2][0]); EXPECT_NEAR(76u, gray_pixels[2][0], 1);
EXPECT_EQ(76u, gray_pixels[2][1]); EXPECT_NEAR(76u, gray_pixels[2][1], 1);
EXPECT_EQ(76u, gray_pixels[2][2]); EXPECT_NEAR(76u, gray_pixels[2][2], 1);
EXPECT_EQ(255u, gray_pixels[2][3]); EXPECT_NEAR(255u, gray_pixels[2][3], 1);
EXPECT_EQ(0u, gray_pixels[3][0]); EXPECT_NEAR(0u, gray_pixels[3][0], 1);
EXPECT_EQ(0u, gray_pixels[3][1]); EXPECT_NEAR(0u, gray_pixels[3][1], 1);
EXPECT_EQ(0u, gray_pixels[3][2]); EXPECT_NEAR(0u, gray_pixels[3][2], 1);
EXPECT_EQ(255u, gray_pixels[3][3]); EXPECT_NEAR(255u, gray_pixels[3][3], 1);
EXPECT_EQ(255u, gray_pixels[4][0]); EXPECT_NEAR(255u, gray_pixels[4][0], 1);
EXPECT_EQ(255u, gray_pixels[4][1]); EXPECT_NEAR(255u, gray_pixels[4][1], 1);
EXPECT_EQ(255u, gray_pixels[4][2]); EXPECT_NEAR(255u, gray_pixels[4][2], 1);
EXPECT_EQ(255u, gray_pixels[4][3]); EXPECT_NEAR(255u, gray_pixels[4][3], 1);
EXPECT_EQ(96u, gray_pixels[5][0]); EXPECT_NEAR(96u, gray_pixels[5][0], 1);
EXPECT_EQ(96u, gray_pixels[5][1]); EXPECT_NEAR(96u, gray_pixels[5][1], 1);
EXPECT_EQ(96u, gray_pixels[5][2]); EXPECT_NEAR(96u, gray_pixels[5][2], 1);
EXPECT_EQ(224u, gray_pixels[5][3]); EXPECT_NEAR(224u, gray_pixels[5][3], 1);
for (int i = 0; i < 1280; ++i) { for (int i = 0; i < 1280; ++i) {
orig_pixels[i][0] = i; orig_pixels[i][0] = i;
orig_pixels[i][1] = i / 2; orig_pixels[i][1] = i / 2;
...@@ -422,6 +422,20 @@ TEST_F(LibYUVPlanarTest, TestARGBGrayTo) { ...@@ -422,6 +422,20 @@ TEST_F(LibYUVPlanarTest, TestARGBGrayTo) {
for (int i = 0; i < benchmark_pixels_div1280_; ++i) { for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 1280, 1); ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 1280, 1);
} }
for (int i = 0; i < 256; ++i) {
orig_pixels[i][0] = i;
orig_pixels[i][1] = i;
orig_pixels[i][2] = i;
orig_pixels[i][3] = i;
}
ARGBGray(&orig_pixels[0][0], 0, 0, 0, 256, 1);
for (int i = 0; i < 256; ++i) {
EXPECT_EQ(i, orig_pixels[i][0]);
EXPECT_EQ(i, orig_pixels[i][1]);
EXPECT_EQ(i, orig_pixels[i][2]);
EXPECT_EQ(i, orig_pixels[i][3]);
}
} }
TEST_F(LibYUVPlanarTest, TestARGBSepia) { TEST_F(LibYUVPlanarTest, TestARGBSepia) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment