diff --git a/include/libyuv/row.h b/include/libyuv/row.h index 0a64716de..cf8a41988 100644 --- a/include/libyuv/row.h +++ b/include/libyuv/row.h @@ -316,6 +316,7 @@ extern "C" { #define HAS_I422TOUYVYROW_NEON #define HAS_I422TOYUY2ROW_NEON #define HAS_I444TOARGBROW_NEON +#define HAS_J422TOARGBROW_NEON #define HAS_MERGEUVROW_NEON #define HAS_MIRRORROW_NEON #define HAS_MIRRORUVROW_NEON @@ -603,6 +604,11 @@ void I422ToARGB4444Row_NEON(const uint8* src_y, const uint8* src_v, uint8* dst_argb4444, int width); +void J422ToARGBRow_NEON(const uint8* src_y, + const uint8* src_u, + const uint8* src_v, + uint8* dst_argb, + int width); void NV12ToARGBRow_NEON(const uint8* src_y, const uint8* src_uv, uint8* dst_argb, @@ -1669,6 +1675,11 @@ void I422ToRGB565Row_Any_NEON(const uint8* src_y, const uint8* src_v, uint8* dst_argb, int width); +void J422ToARGBRow_Any_NEON(const uint8* src_y, + const uint8* src_u, + const uint8* src_v, + uint8* dst_argb, + int width); void NV12ToARGBRow_Any_NEON(const uint8* src_y, const uint8* src_uv, uint8* dst_argb, diff --git a/source/row_any.cc b/source/row_any.cc index 9a9dffda0..3b1e41d41 100644 --- a/source/row_any.cc +++ b/source/row_any.cc @@ -119,6 +119,7 @@ ANY31(I422ToRAWRow_Any_NEON, I422ToRAWRow_NEON, 1, 0, 3, 7) ANY31(I422ToARGB4444Row_Any_NEON, I422ToARGB4444Row_NEON, 1, 0, 2, 7) ANY31(I422ToARGB1555Row_Any_NEON, I422ToARGB1555Row_NEON, 1, 0, 2, 7) ANY31(I422ToRGB565Row_Any_NEON, I422ToRGB565Row_NEON, 1, 0, 2, 7) +ANY31(J422ToARGBRow_Any_NEON, J422ToARGBRow_NEON, 1, 0, 4, 7) #endif #ifdef HAS_I422TOYUY2ROW_NEON ANY31(I422ToYUY2Row_Any_NEON, I422ToYUY2Row_NEON, 1, 1, 4, 15) diff --git a/source/row_common.cc b/source/row_common.cc index eab7e9b79..ab70d7e58 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -2277,6 +2277,7 @@ extern struct YuvConstants kYuvConstants; extern struct YuvConstants kYuvJConstants; extern struct YuvConstants kYuvHConstants; extern struct YuvConstantsNEON kYuvConstantsNEON; +extern struct YuvConstantsNEON kYuvJConstantsNEON; #define ANYYUV(NAMEANY, ANY_SIMD, YUVCONSTANTS) \ void NAMEANY(const uint8* y_buf, \ @@ -2289,7 +2290,7 @@ extern struct YuvConstantsNEON kYuvConstantsNEON; #ifdef HAS_I422TOARGBMATRIXROW_NEON ANYYUV(I422ToARGBRow_NEON, I422ToARGBMatrixRow_NEON, kYuvConstantsNEON) -//ANYYUV(J422ToARGBRow_NEON, I422ToARGBMatrixRow_NEON, kYuvJConstantsNEON) +ANYYUV(J422ToARGBRow_NEON, I422ToARGBMatrixRow_NEON, kYuvJConstantsNEON) //ANYYUV(H422ToARGBRow_NEON, I422ToARGBMatrixRow_NEON, kYuvHConstantsNEON) #endif diff --git a/source/row_neon.cc b/source/row_neon.cc index 9cc76e719..fc243d917 100644 --- a/source/row_neon.cc +++ b/source/row_neon.cc @@ -172,6 +172,46 @@ YuvConstantsNEON SIMD_ALIGNED(kYuvConstantsNEON) = { #undef BG #undef BR +// 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. +// TODO(fbarchard): Consider moving constants into a common header. +#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 subtract 16 from Y and 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. +YuvConstantsNEON SIMD_ALIGNED(kYuvJConstantsNEON) = { + { -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 } +}; + +#undef YGJ +#undef YGBJ +#undef UBJ +#undef UGJ +#undef VGJ +#undef VRJ +#undef BBJ +#undef BGJ +#undef BRJ + + void I444ToARGBRow_NEON(const uint8* src_y, const uint8* src_u, const uint8* src_v,