diff options
author | Yuan Tong <tongyuan200097@gmail.com> | 2021-03-20 23:22:08 +0800 |
---|---|---|
committer | Frank Barchard <fbarchard@chromium.org> | 2021-03-31 20:46:02 +0000 |
commit | 8a13626e42f7fdcf3a6acbb0316760ee54cda7d8 (patch) | |
tree | ab34de049749adec1366344b02be882797ace6a4 /source/planar_functions.cc | |
parent | 2525698acba9bf9b701ba6b4d9584291a1f62257 (diff) | |
download | libyuv-8a13626e42f7fdcf3a6acbb0316760ee54cda7d8.tar.gz |
Add MergeAR30Plane, MergeAR64Plane, MergeARGB16To8Plane
These functions merge high bit depth planar RGB pixels into packed format.
Change-Id: I506935a164b069e6b2fed8bf152cb874310c0916
Bug: libyuv:886, libyuv:889
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/2780468
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Diffstat (limited to 'source/planar_functions.cc')
-rw-r--r-- | source/planar_functions.cc | 293 |
1 files changed, 272 insertions, 21 deletions
diff --git a/source/planar_functions.cc b/source/planar_functions.cc index 38287af0..3ff5dfa2 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -1026,7 +1026,7 @@ void SplitARGBPlane(const uint8_t* src_argb, dst_stride_a = 0; } -#if defined(HAS_SPLITARGBROW_SSE2) +#if defined(HAS_SPLITXRGBROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { SplitXRGBRow = SplitXRGBRow_Any_SSE2; if (IS_ALIGNED(width, 8)) { @@ -1034,7 +1034,7 @@ void SplitARGBPlane(const uint8_t* src_argb, } } #endif -#if defined(HAS_SPLITARGBROW_SSSE3) +#if defined(HAS_SPLITXRGBROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { SplitXRGBRow = SplitXRGBRow_Any_SSSE3; if (IS_ALIGNED(width, 8)) { @@ -1042,7 +1042,7 @@ void SplitARGBPlane(const uint8_t* src_argb, } } #endif -#if defined(HAS_SPLITARGBROW_AVX2) +#if defined(HAS_SPLITXRGBROW_AVX2) if (TestCpuFlag(kCpuHasAVX2)) { SplitXRGBRow = SplitXRGBRow_Any_AVX2; if (IS_ALIGNED(width, 16)) { @@ -1050,7 +1050,7 @@ void SplitARGBPlane(const uint8_t* src_argb, } } #endif -#if defined(HAS_SPLITRGBROW_NEON) +#if defined(HAS_SPLITXRGBROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { SplitXRGBRow = SplitXRGBRow_Any_NEON; if (IS_ALIGNED(width, 16)) { @@ -1112,7 +1112,7 @@ void SplitARGBPlane(const uint8_t* src_argb, } } #endif -#if defined(HAS_SPLITRGBROW_NEON) +#if defined(HAS_SPLITARGBROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { SplitARGBRow = SplitARGBRow_Any_NEON; if (IS_ALIGNED(width, 16)) { @@ -1153,13 +1153,13 @@ void MergeARGBPlane(const uint8_t* src_r, const uint8_t* src_b, uint8_t* dst_argb, int width) = MergeXRGBRow_C; + // 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 (src_a == NULL) { - // 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; - } // Coalesce rows. if (src_stride_r == width && src_stride_g == width && src_stride_b == width && dst_stride_argb == width * 4) { @@ -1167,7 +1167,7 @@ void MergeARGBPlane(const uint8_t* src_r, height = 1; src_stride_r = src_stride_g = src_stride_b = dst_stride_argb = 0; } -#if defined(HAS_MERGEARGBROW_SSE2) +#if defined(HAS_MERGEXRGBROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeXRGBRow = MergeXRGBRow_Any_SSE2; if (IS_ALIGNED(width, 8)) { @@ -1175,7 +1175,7 @@ void MergeARGBPlane(const uint8_t* src_r, } } #endif -#if defined(HAS_MERGEARGBROW_AVX2) +#if defined(HAS_MERGEXRGBROW_AVX2) if (TestCpuFlag(kCpuHasAVX2)) { MergeXRGBRow = MergeXRGBRow_Any_AVX2; if (IS_ALIGNED(width, 16)) { @@ -1183,7 +1183,7 @@ void MergeARGBPlane(const uint8_t* src_r, } } #endif -#if defined(HAS_MERGERGBROW_NEON) +#if defined(HAS_MERGEXRGBROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { MergeXRGBRow = MergeXRGBRow_Any_NEON; if (IS_ALIGNED(width, 16)) { @@ -1200,12 +1200,6 @@ void MergeARGBPlane(const uint8_t* src_r, dst_argb += dst_stride_argb; } } else { - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - if (src_stride_r == width && src_stride_g == width && src_stride_b == width && src_stride_a == width && dst_stride_argb == width * 4) { @@ -1230,7 +1224,7 @@ void MergeARGBPlane(const uint8_t* src_r, } } #endif -#if defined(HAS_MERGERGBROW_NEON) +#if defined(HAS_MERGEARGBROW_NEON) if (TestCpuFlag(kCpuHasNEON)) { MergeARGBRow = MergeARGBRow_Any_NEON; if (IS_ALIGNED(width, 16)) { @@ -1249,6 +1243,263 @@ void MergeARGBPlane(const uint8_t* src_r, } } +LIBYUV_API +void MergeXR30Plane(const uint16_t* src_r, + int src_stride_r, + const uint16_t* src_g, + int src_stride_g, + const uint16_t* src_b, + int src_stride_b, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height, + int depth) { + int y; + void (*MergeXR30Row)(const uint16_t* src_r, const uint16_t* src_g, + const uint16_t* src_b, uint8_t* dst_ar30, int depth, + int width) = MergeXR30Row_C; + + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; + dst_stride_ar30 = -dst_stride_ar30; + } + // Coalesce rows. + if (src_stride_r == width && src_stride_g == width && src_stride_b == width && + dst_stride_ar30 == width * 4) { + width *= height; + height = 1; + src_stride_r = src_stride_g = src_stride_b = dst_stride_ar30 = 0; + } +#if defined(HAS_MERGEXR30ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeXR30Row = MergeXR30Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeXR30Row = MergeXR30Row_AVX2; + } + } +#endif +#if defined(HAS_MERGEXR30ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + if (depth == 10) { + MergeXR30Row = MergeXR30Row_10_Any_NEON; + if (IS_ALIGNED(width, 8)) { + MergeXR30Row = MergeXR30Row_10_NEON; + } + } else { + MergeXR30Row = MergeXR30Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + MergeXR30Row = MergeXR30Row_NEON; + } + } + } +#endif + + for (y = 0; y < height; ++y) { + MergeXR30Row(src_r, src_g, src_b, dst_ar30, depth, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + dst_ar30 += dst_stride_ar30; + } +} + +LIBYUV_API +void MergeAR64Plane(const uint16_t* src_r, + int src_stride_r, + const uint16_t* src_g, + int src_stride_g, + const uint16_t* src_b, + int src_stride_b, + const uint16_t* src_a, + int src_stride_a, + uint16_t* dst_ar64, + int dst_stride_ar64, + int width, + int height, + int depth) { + int y; + void (*MergeAR64Row)(const uint16_t* src_r, const uint16_t* src_g, + const uint16_t* src_b, const uint16_t* src_a, + uint16_t* dst_argb, int depth, int width) = + MergeAR64Row_C; + void (*MergeXR64Row)(const uint16_t* src_r, const uint16_t* src_g, + const uint16_t* src_b, uint16_t* dst_argb, int depth, + int width) = MergeXR64Row_C; + + // Negative height means invert the image. + if (height < 0) { + height = -height; + dst_ar64 = dst_ar64 + (height - 1) * dst_stride_ar64; + dst_stride_ar64 = -dst_stride_ar64; + } + if (src_a == NULL) { + // Coalesce rows. + if (src_stride_r == width && src_stride_g == width && + src_stride_b == width && dst_stride_ar64 == width * 4) { + width *= height; + height = 1; + src_stride_r = src_stride_g = src_stride_b = dst_stride_ar64 = 0; + } +#if defined(HAS_MERGEXR64ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeXR64Row = MergeXR64Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeXR64Row = MergeXR64Row_AVX2; + } + } +#endif +#if defined(HAS_MERGEXR64ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeXR64Row = MergeXR64Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + MergeXR64Row = MergeXR64Row_NEON; + } + } +#endif + + for (y = 0; y < height; ++y) { + MergeXR64Row(src_r, src_g, src_b, dst_ar64, depth, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + dst_ar64 += dst_stride_ar64; + } + } else { + if (src_stride_r == width && src_stride_g == width && + src_stride_b == width && src_stride_a == width && + dst_stride_ar64 == width * 4) { + width *= height; + height = 1; + src_stride_r = src_stride_g = src_stride_b = src_stride_a = + dst_stride_ar64 = 0; + } +#if defined(HAS_MERGEAR64ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeAR64Row = MergeAR64Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeAR64Row = MergeAR64Row_AVX2; + } + } +#endif +#if defined(HAS_MERGEAR64ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeAR64Row = MergeAR64Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + MergeAR64Row = MergeAR64Row_NEON; + } + } +#endif + + for (y = 0; y < height; ++y) { + MergeAR64Row(src_r, src_g, src_b, src_a, dst_ar64, depth, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + dst_ar64 += dst_stride_ar64; + } + } +} + +LIBYUV_API +void MergeARGB16To8Plane(const uint16_t* src_r, + int src_stride_r, + const uint16_t* src_g, + int src_stride_g, + const uint16_t* src_b, + int src_stride_b, + const uint16_t* src_a, + int src_stride_a, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height, + int depth) { + int y; + void (*MergeARGB16To8Row)(const uint16_t* src_r, const uint16_t* src_g, + const uint16_t* src_b, const uint16_t* src_a, + uint8_t* dst_argb, int depth, int width) = + MergeARGB16To8Row_C; + void (*MergeXRGB16To8Row)(const uint16_t* src_r, const uint16_t* src_g, + const uint16_t* src_b, uint8_t* dst_argb, int depth, + int width) = MergeXRGB16To8Row_C; + + // 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 (src_a == NULL) { + // Coalesce rows. + if (src_stride_r == width && src_stride_g == width && + src_stride_b == width && dst_stride_argb == width * 4) { + width *= height; + height = 1; + src_stride_r = src_stride_g = src_stride_b = dst_stride_argb = 0; + } +#if defined(HAS_MERGEXRGB16TO8ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeXRGB16To8Row = MergeXRGB16To8Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeXRGB16To8Row = MergeXRGB16To8Row_AVX2; + } + } +#endif +#if defined(HAS_MERGEXRGB16TO8ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeXRGB16To8Row = MergeXRGB16To8Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + MergeXRGB16To8Row = MergeXRGB16To8Row_NEON; + } + } +#endif + + for (y = 0; y < height; ++y) { + MergeXRGB16To8Row(src_r, src_g, src_b, dst_argb, depth, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + dst_argb += dst_stride_argb; + } + } else { + if (src_stride_r == width && src_stride_g == width && + src_stride_b == width && src_stride_a == width && + dst_stride_argb == width * 4) { + width *= height; + height = 1; + src_stride_r = src_stride_g = src_stride_b = src_stride_a = + dst_stride_argb = 0; + } +#if defined(HAS_MERGEARGB16TO8ROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeARGB16To8Row = MergeARGB16To8Row_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeARGB16To8Row = MergeARGB16To8Row_AVX2; + } + } +#endif +#if defined(HAS_MERGEARGB16TO8ROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeARGB16To8Row = MergeARGB16To8Row_Any_NEON; + if (IS_ALIGNED(width, 8)) { + MergeARGB16To8Row = MergeARGB16To8Row_NEON; + } + } +#endif + + for (y = 0; y < height; ++y) { + MergeARGB16To8Row(src_r, src_g, src_b, src_a, dst_argb, depth, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + dst_argb += dst_stride_argb; + } + } +} + // Convert YUY2 to I422. LIBYUV_API int YUY2ToI422(const uint8_t* src_yuy2, |