diff options
author | Yuan Tong <tongyuan200097@gmail.com> | 2021-04-07 19:50:03 +0800 |
---|---|---|
committer | Frank Barchard <fbarchard@chromium.org> | 2021-04-08 09:18:34 +0000 |
commit | 2cd098f83b446067a999bb7ab4d856892c956cdc (patch) | |
tree | bbf05cffe32409db424b1b17fdffd0884731ff10 /source/planar_functions.cc | |
parent | 2870320ac6a743fc35c2517159b8813766dc97b0 (diff) | |
download | libyuv-2cd098f83b446067a999bb7ab4d856892c956cdc.tar.gz |
Fix MergeAR64Plane on odd width
R=fbarchard@chromium.org
Bug: libyuv:898
Change-Id: I031e008ea91baba1c7598efa0eda70750cbfce85
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/2810066
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Diffstat (limited to 'source/planar_functions.cc')
-rw-r--r-- | source/planar_functions.cc | 804 |
1 files changed, 470 insertions, 334 deletions
diff --git a/source/planar_functions.cc b/source/planar_functions.cc index 3ff5dfa2..adc4eefc 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -985,151 +985,288 @@ void MergeRGBPlane(const uint8_t* src_r, } } -LIBYUV_API -void SplitARGBPlane(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_r, - int dst_stride_r, - uint8_t* dst_g, - int dst_stride_g, - uint8_t* dst_b, - int dst_stride_b, - uint8_t* dst_a, - int dst_stride_a, - int width, - int height) { +LIBYUV_NOINLINE +void SplitARGBPlaneAlpha(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_r, + int dst_stride_r, + uint8_t* dst_g, + int dst_stride_g, + uint8_t* dst_b, + int dst_stride_b, + uint8_t* dst_a, + int dst_stride_a, + int width, + int height) { int y; void (*SplitARGBRow)(const uint8_t* src_rgb, uint8_t* dst_r, uint8_t* dst_g, uint8_t* dst_b, uint8_t* dst_a, int width) = SplitARGBRow_C; + + if (src_stride_argb == width * 4 && dst_stride_r == width && + dst_stride_g == width && dst_stride_b == width && dst_stride_a == width) { + width *= height; + height = 1; + src_stride_argb = dst_stride_r = dst_stride_g = dst_stride_b = + dst_stride_a = 0; + } + +#if defined(HAS_SPLITARGBROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + SplitARGBRow = SplitARGBRow_Any_SSE2; + if (IS_ALIGNED(width, 8)) { + SplitARGBRow = SplitARGBRow_SSE2; + } + } +#endif +#if defined(HAS_SPLITARGBROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + SplitARGBRow = SplitARGBRow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + SplitARGBRow = SplitARGBRow_SSSE3; + } + } +#endif +#if defined(HAS_SPLITARGBROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + SplitARGBRow = SplitARGBRow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + SplitARGBRow = SplitARGBRow_AVX2; + } + } +#endif +#if defined(HAS_SPLITARGBROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + SplitARGBRow = SplitARGBRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + SplitARGBRow = SplitARGBRow_NEON; + } + } +#endif + + for (y = 0; y < height; ++y) { + SplitARGBRow(src_argb, dst_r, dst_g, dst_b, dst_a, width); + dst_r += dst_stride_r; + dst_g += dst_stride_g; + dst_b += dst_stride_b; + dst_a += dst_stride_a; + src_argb += src_stride_argb; + } +} + +LIBYUV_NOINLINE +void SplitARGBPlaneOpaque(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_r, + int dst_stride_r, + uint8_t* dst_g, + int dst_stride_g, + uint8_t* dst_b, + int dst_stride_b, + int width, + int height) { + int y; void (*SplitXRGBRow)(const uint8_t* src_rgb, uint8_t* dst_r, uint8_t* dst_g, uint8_t* dst_b, int width) = SplitXRGBRow_C; - if (dst_a == NULL) { - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_r = dst_r + (height - 1) * dst_stride_r; - dst_g = dst_g + (height - 1) * dst_stride_g; - dst_b = dst_b + (height - 1) * dst_stride_b; - dst_stride_r = -dst_stride_r; - dst_stride_g = -dst_stride_g; - dst_stride_b = -dst_stride_b; - } - - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_r == width && - dst_stride_g == width && dst_stride_b == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_r = dst_stride_g = dst_stride_b = - dst_stride_a = 0; - } + if (src_stride_argb == width * 4 && dst_stride_r == width && + dst_stride_g == width && dst_stride_b == width) { + width *= height; + height = 1; + src_stride_argb = dst_stride_r = dst_stride_g = dst_stride_b = 0; + } #if defined(HAS_SPLITXRGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SplitXRGBRow = SplitXRGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - SplitXRGBRow = SplitXRGBRow_SSE2; - } + if (TestCpuFlag(kCpuHasSSE2)) { + SplitXRGBRow = SplitXRGBRow_Any_SSE2; + if (IS_ALIGNED(width, 8)) { + SplitXRGBRow = SplitXRGBRow_SSE2; } + } #endif #if defined(HAS_SPLITXRGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - SplitXRGBRow = SplitXRGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - SplitXRGBRow = SplitXRGBRow_SSSE3; - } + if (TestCpuFlag(kCpuHasSSSE3)) { + SplitXRGBRow = SplitXRGBRow_Any_SSSE3; + if (IS_ALIGNED(width, 8)) { + SplitXRGBRow = SplitXRGBRow_SSSE3; } + } #endif #if defined(HAS_SPLITXRGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - SplitXRGBRow = SplitXRGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - SplitXRGBRow = SplitXRGBRow_AVX2; - } + if (TestCpuFlag(kCpuHasAVX2)) { + SplitXRGBRow = SplitXRGBRow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + SplitXRGBRow = SplitXRGBRow_AVX2; } + } #endif #if defined(HAS_SPLITXRGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitXRGBRow = SplitXRGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitXRGBRow = SplitXRGBRow_NEON; - } + if (TestCpuFlag(kCpuHasNEON)) { + SplitXRGBRow = SplitXRGBRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + SplitXRGBRow = SplitXRGBRow_NEON; } + } #endif - for (y = 0; y < height; ++y) { - SplitXRGBRow(src_argb, dst_r, dst_g, dst_b, width); - dst_r += dst_stride_r; - dst_g += dst_stride_g; - dst_b += dst_stride_b; - src_argb += src_stride_argb; - } + for (y = 0; y < height; ++y) { + SplitXRGBRow(src_argb, dst_r, dst_g, dst_b, width); + dst_r += dst_stride_r; + dst_g += dst_stride_g; + dst_b += dst_stride_b; + src_argb += src_stride_argb; + } +} + +LIBYUV_API +void SplitARGBPlane(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_r, + int dst_stride_r, + uint8_t* dst_g, + int dst_stride_g, + uint8_t* dst_b, + int dst_stride_b, + uint8_t* dst_a, + int dst_stride_a, + int width, + int height) { + if (height < 0) { + height = -height; + dst_r = dst_r + (height - 1) * dst_stride_r; + dst_g = dst_g + (height - 1) * dst_stride_g; + dst_b = dst_b + (height - 1) * dst_stride_b; + dst_a = dst_a + (height - 1) * dst_stride_a; + dst_stride_r = -dst_stride_r; + dst_stride_g = -dst_stride_g; + dst_stride_b = -dst_stride_b; + dst_stride_a = -dst_stride_a; + } + + if (dst_a == NULL) { + SplitARGBPlaneOpaque(src_argb, src_stride_argb, dst_r, dst_stride_r, dst_g, + dst_stride_g, dst_b, dst_stride_b, width, height); } else { - if (height < 0) { - height = -height; - dst_r = dst_r + (height - 1) * dst_stride_r; - dst_g = dst_g + (height - 1) * dst_stride_g; - dst_b = dst_b + (height - 1) * dst_stride_b; - dst_a = dst_a + (height - 1) * dst_stride_a; - dst_stride_r = -dst_stride_r; - dst_stride_g = -dst_stride_g; - dst_stride_b = -dst_stride_b; - dst_stride_a = -dst_stride_a; - } - - if (src_stride_argb == width * 4 && dst_stride_r == width && - dst_stride_g == width && dst_stride_b == width && - dst_stride_a == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_r = dst_stride_g = dst_stride_b = - dst_stride_a = 0; - } + SplitARGBPlaneAlpha(src_argb, src_stride_argb, dst_r, dst_stride_r, dst_g, + dst_stride_g, dst_b, dst_stride_b, dst_a, dst_stride_a, + width, height); + } +} -#if defined(HAS_SPLITARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SplitARGBRow = SplitARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - SplitARGBRow = SplitARGBRow_SSE2; - } +LIBYUV_NOINLINE +void MergeARGBPlaneAlpha(const uint8_t* src_r, + int src_stride_r, + const uint8_t* src_g, + int src_stride_g, + const uint8_t* src_b, + int src_stride_b, + const uint8_t* src_a, + int src_stride_a, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { + int y; + void (*MergeARGBRow)(const uint8_t* src_r, const uint8_t* src_g, + const uint8_t* src_b, const uint8_t* src_a, + uint8_t* dst_argb, int width) = MergeARGBRow_C; + + 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_MERGEARGBROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + MergeARGBRow = MergeARGBRow_Any_SSE2; + if (IS_ALIGNED(width, 8)) { + MergeARGBRow = MergeARGBRow_SSE2; } + } #endif -#if defined(HAS_SPLITARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - SplitARGBRow = SplitARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - SplitARGBRow = SplitARGBRow_SSSE3; - } +#if defined(HAS_MERGEARGBROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeARGBRow = MergeARGBRow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeARGBRow = MergeARGBRow_AVX2; } + } #endif -#if defined(HAS_SPLITARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - SplitARGBRow = SplitARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - SplitARGBRow = SplitARGBRow_AVX2; - } +#if defined(HAS_MERGEARGBROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeARGBRow = MergeARGBRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + MergeARGBRow = MergeARGBRow_NEON; } + } #endif -#if defined(HAS_SPLITARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitARGBRow = SplitARGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitARGBRow = SplitARGBRow_NEON; - } + + for (y = 0; y < height; ++y) { + MergeARGBRow(src_r, src_g, src_b, src_a, dst_argb, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + src_a += src_stride_a; + dst_argb += dst_stride_argb; + } +} + +LIBYUV_NOINLINE +void MergeARGBPlaneOpaque(const uint8_t* src_r, + int src_stride_r, + const uint8_t* src_g, + int src_stride_g, + const uint8_t* src_b, + int src_stride_b, + uint8_t* dst_argb, + int dst_stride_argb, + int width, + int height) { + int y; + void (*MergeXRGBRow)(const uint8_t* src_r, const uint8_t* src_g, + const uint8_t* src_b, uint8_t* dst_argb, int width) = + MergeXRGBRow_C; + + 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_MERGEXRGBROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + MergeXRGBRow = MergeXRGBRow_Any_SSE2; + if (IS_ALIGNED(width, 8)) { + MergeXRGBRow = MergeXRGBRow_SSE2; } + } #endif - - for (y = 0; y < height; ++y) { - SplitARGBRow(src_argb, dst_r, dst_g, dst_b, dst_a, width); - dst_r += dst_stride_r; - dst_g += dst_stride_g; - dst_b += dst_stride_b; - dst_a += dst_stride_a; - src_argb += src_stride_argb; +#if defined(HAS_MERGEXRGBROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + MergeXRGBRow = MergeXRGBRow_Any_AVX2; + if (IS_ALIGNED(width, 16)) { + MergeXRGBRow = MergeXRGBRow_AVX2; } } +#endif +#if defined(HAS_MERGEXRGBROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + MergeXRGBRow = MergeXRGBRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + MergeXRGBRow = MergeXRGBRow_NEON; + } + } +#endif + + for (y = 0; y < height; ++y) { + MergeXRGBRow(src_r, src_g, src_b, dst_argb, width); + src_r += src_stride_r; + src_g += src_stride_g; + src_b += src_stride_b; + dst_argb += dst_stride_argb; + } } LIBYUV_API @@ -1145,104 +1282,25 @@ void MergeARGBPlane(const uint8_t* src_r, int dst_stride_argb, int width, int height) { - int y; - void (*MergeARGBRow)(const uint8_t* src_r, const uint8_t* src_g, - const uint8_t* src_b, const uint8_t* src_a, - uint8_t* dst_argb, int width) = MergeARGBRow_C; - void (*MergeXRGBRow)(const uint8_t* src_r, const uint8_t* src_g, - 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) { - // 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_MERGEXRGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - MergeXRGBRow = MergeXRGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - MergeXRGBRow = MergeXRGBRow_SSE2; - } - } -#endif -#if defined(HAS_MERGEXRGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MergeXRGBRow = MergeXRGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - MergeXRGBRow = MergeXRGBRow_AVX2; - } - } -#endif -#if defined(HAS_MERGEXRGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeXRGBRow = MergeXRGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MergeXRGBRow = MergeXRGBRow_NEON; - } - } -#endif - for (y = 0; y < height; ++y) { - MergeXRGBRow(src_r, src_g, src_b, dst_argb, width); - src_r += src_stride_r; - src_g += src_stride_g; - src_b += src_stride_b; - dst_argb += dst_stride_argb; - } + if (src_a == NULL) { + MergeARGBPlaneOpaque(src_r, src_stride_r, src_g, src_stride_g, src_b, + src_stride_b, dst_argb, dst_stride_argb, width, + height); } 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_MERGEARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - MergeARGBRow = MergeARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - MergeARGBRow = MergeARGBRow_SSE2; - } - } -#endif -#if defined(HAS_MERGEARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MergeARGBRow = MergeARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - MergeARGBRow = MergeARGBRow_AVX2; - } - } -#endif -#if defined(HAS_MERGEARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeARGBRow = MergeARGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MergeARGBRow = MergeARGBRow_NEON; - } - } -#endif - - for (y = 0; y < height; ++y) { - MergeARGBRow(src_r, src_g, src_b, src_a, dst_argb, width); - src_r += src_stride_r; - src_g += src_stride_g; - src_b += src_stride_b; - dst_argb += dst_stride_argb; - } + MergeARGBPlaneAlpha(src_r, src_stride_r, src_g, src_stride_g, src_b, + src_stride_b, src_a, src_stride_a, dst_argb, + dst_stride_argb, width, height); } } +// TODO(yuan): Support 2 bit alpha channel. LIBYUV_API void MergeXR30Plane(const uint16_t* src_r, int src_stride_r, @@ -1306,6 +1364,110 @@ void MergeXR30Plane(const uint16_t* src_r, } } +LIBYUV_NOINLINE +static void MergeAR64PlaneAlpha(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; + + 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; + src_a += src_stride_a; + dst_ar64 += dst_stride_ar64; + } +} + +LIBYUV_NOINLINE +static void MergeAR64PlaneOpaque(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, + uint16_t* dst_ar64, + int dst_stride_ar64, + int width, + int height, + int depth) { + int y; + 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; + + // 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; + } +} + LIBYUV_API void MergeAR64Plane(const uint16_t* src_r, int src_stride_r, @@ -1320,86 +1482,125 @@ void MergeAR64Plane(const uint16_t* src_r, 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; - } + MergeAR64PlaneOpaque(src_r, src_stride_r, src_g, src_stride_g, src_b, + src_stride_b, dst_ar64, dst_stride_ar64, width, height, + depth); + } else { + MergeAR64PlaneAlpha(src_r, src_stride_r, src_g, src_stride_g, src_b, + src_stride_b, src_a, src_stride_a, dst_ar64, + dst_stride_ar64, width, height, depth); + } +} + +LIBYUV_NOINLINE +static void MergeARGB16To8PlaneAlpha(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; + + 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_MERGEXR64ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeXR64Row = MergeXR64Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - MergeXR64Row = MergeXR64Row_NEON; - } +#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) { - 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; - } + 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; + src_a += src_stride_a; + dst_argb += dst_stride_argb; + } +} + +LIBYUV_NOINLINE +static void MergeARGB16To8PlaneOpaque(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_argb, + int dst_stride_argb, + int width, + int height, + int depth) { + int y; + 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; + + // 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_MERGEAR64ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeAR64Row = MergeAR64Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - MergeAR64Row = MergeAR64Row_NEON; - } +#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) { - 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; - } + 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; } } @@ -1417,86 +1618,21 @@ void MergeARGB16To8Plane(const uint16_t* src_r, 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; - } + if (src_a == NULL) { + MergeARGB16To8PlaneOpaque(src_r, src_stride_r, src_g, src_stride_g, src_b, + src_stride_b, dst_argb, dst_stride_argb, width, + height, depth); } 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; - } + MergeARGB16To8PlaneAlpha(src_r, src_stride_r, src_g, src_stride_g, src_b, + src_stride_b, src_a, src_stride_a, dst_argb, + dst_stride_argb, width, height, depth); } } |