| Index: source/planar_functions.cc
|
| diff --git a/source/planar_functions.cc b/source/planar_functions.cc
|
| index 6379217862bb7cbbaab7dfa0a72031263e56d512..b15b6e523b35229a7e162a1b239b8ef23194b718 100644
|
| --- a/source/planar_functions.cc
|
| +++ b/source/planar_functions.cc
|
| @@ -1681,37 +1681,37 @@ int ARGBShade(const uint8* src_argb, int src_stride_argb,
|
| return 0;
|
| }
|
|
|
| -// Interpolate 2 ARGB images by specified amount (0 to 255).
|
| +// Interpolate 2 planes by specified amount (0 to 255).
|
| LIBYUV_API
|
| -int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0,
|
| - const uint8* src_argb1, int src_stride_argb1,
|
| - uint8* dst_argb, int dst_stride_argb,
|
| - int width, int height, int interpolation) {
|
| +int InterpolatePlane(const uint8* src0, int src_stride0,
|
| + const uint8* src1, int src_stride1,
|
| + uint8* dst, int dst_stride,
|
| + int width, int height, int interpolation) {
|
| int y;
|
| void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
|
| ptrdiff_t src_stride, int dst_width,
|
| int source_y_fraction) = InterpolateRow_C;
|
| - if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) {
|
| + if (!src0 || !src1 || !dst || 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;
|
| + dst = dst + (height - 1) * dst_stride;
|
| + dst_stride = -dst_stride;
|
| }
|
| // Coalesce rows.
|
| - if (src_stride_argb0 == width * 4 &&
|
| - src_stride_argb1 == width * 4 &&
|
| - dst_stride_argb == width * 4) {
|
| + if (src_stride0 == width &&
|
| + src_stride1 == width &&
|
| + dst_stride == width) {
|
| width *= height;
|
| height = 1;
|
| - src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0;
|
| + src_stride0 = src_stride1 = dst_stride = 0;
|
| }
|
| #if defined(HAS_INTERPOLATEROW_SSE2)
|
| if (TestCpuFlag(kCpuHasSSE2)) {
|
| InterpolateRow = InterpolateRow_Any_SSE2;
|
| - if (IS_ALIGNED(width, 4)) {
|
| + if (IS_ALIGNED(width, 16)) {
|
| InterpolateRow = InterpolateRow_SSE2;
|
| }
|
| }
|
| @@ -1719,7 +1719,7 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0,
|
| #if defined(HAS_INTERPOLATEROW_SSSE3)
|
| if (TestCpuFlag(kCpuHasSSSE3)) {
|
| InterpolateRow = InterpolateRow_Any_SSSE3;
|
| - if (IS_ALIGNED(width, 4)) {
|
| + if (IS_ALIGNED(width, 16)) {
|
| InterpolateRow = InterpolateRow_SSSE3;
|
| }
|
| }
|
| @@ -1727,7 +1727,7 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0,
|
| #if defined(HAS_INTERPOLATEROW_AVX2)
|
| if (TestCpuFlag(kCpuHasAVX2)) {
|
| InterpolateRow = InterpolateRow_Any_AVX2;
|
| - if (IS_ALIGNED(width, 8)) {
|
| + if (IS_ALIGNED(width, 32)) {
|
| InterpolateRow = InterpolateRow_AVX2;
|
| }
|
| }
|
| @@ -1735,27 +1735,75 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0,
|
| #if defined(HAS_INTERPOLATEROW_NEON)
|
| if (TestCpuFlag(kCpuHasNEON)) {
|
| InterpolateRow = InterpolateRow_Any_NEON;
|
| - if (IS_ALIGNED(width, 4)) {
|
| + if (IS_ALIGNED(width, 16)) {
|
| InterpolateRow = InterpolateRow_NEON;
|
| }
|
| }
|
| #endif
|
| #if defined(HAS_INTERPOLATEROW_MIPS_DSPR2)
|
| if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
|
| - IS_ALIGNED(src_argb0, 4) && IS_ALIGNED(src_stride_argb0, 4) &&
|
| - IS_ALIGNED(src_argb1, 4) && IS_ALIGNED(src_stride_argb1, 4) &&
|
| - IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
|
| + IS_ALIGNED(src0, 4) && IS_ALIGNED(src_stride0, 4) &&
|
| + IS_ALIGNED(src1, 4) && IS_ALIGNED(src_stride1, 4) &&
|
| + IS_ALIGNED(dst, 4) && IS_ALIGNED(dst_stride, 4) &&
|
| + IS_ALIGNED(width, 4)) {
|
| InterpolateRow = InterpolateRow_MIPS_DSPR2;
|
| }
|
| #endif
|
|
|
| for (y = 0; y < height; ++y) {
|
| - InterpolateRow(dst_argb, src_argb0, src_argb1 - src_argb0,
|
| - width * 4, interpolation);
|
| - src_argb0 += src_stride_argb0;
|
| - src_argb1 += src_stride_argb1;
|
| - dst_argb += dst_stride_argb;
|
| + InterpolateRow(dst, src0, src1 - src0,
|
| + width, interpolation);
|
| + src0 += src_stride0;
|
| + src1 += src_stride1;
|
| + dst += dst_stride;
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +// Interpolate 2 ARGB images by specified amount (0 to 255).
|
| +LIBYUV_API
|
| +int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0,
|
| + const uint8* src_argb1, int src_stride_argb1,
|
| + uint8* dst_argb, int dst_stride_argb,
|
| + int width, int height, int interpolation) {
|
| + return InterpolatePlane(src_argb0, src_stride_argb0,
|
| + src_argb1, src_stride_argb1,
|
| + dst_argb, dst_stride_argb,
|
| + width * 4, height, interpolation);
|
| +}
|
| +
|
| +// Interpolate 2 YUV images by specified amount (0 to 255).
|
| +LIBYUV_API
|
| +int I420Interpolate(const uint8* src0_y, int src0_stride_y,
|
| + const uint8* src0_u, int src0_stride_u,
|
| + const uint8* src0_v, int src0_stride_v,
|
| + const uint8* src1_y, int src1_stride_y,
|
| + const uint8* src1_u, int src1_stride_u,
|
| + const uint8* src1_v, int src1_stride_v,
|
| + uint8* dst_y, int dst_stride_y,
|
| + uint8* dst_u, int dst_stride_u,
|
| + uint8* dst_v, int dst_stride_v,
|
| + int width, int height, int interpolation) {
|
| + int halfwidth = (width + 1) >> 1;
|
| + int halfheight = (height + 1) >> 1;
|
| + if (!src0_y || !src0_u || !src0_v ||
|
| + !src1_y || !src1_u || !src1_v ||
|
| + !dst_y || !dst_u || !dst_v ||
|
| + width <= 0 || height == 0) {
|
| + return -1;
|
| }
|
| + InterpolatePlane(src0_y, src0_stride_y,
|
| + src1_y, src1_stride_y,
|
| + dst_y, dst_stride_y,
|
| + width, height, interpolation);
|
| + InterpolatePlane(src0_u, src0_stride_u,
|
| + src1_u, src1_stride_u,
|
| + dst_u, dst_stride_u,
|
| + halfwidth, halfheight, interpolation);
|
| + InterpolatePlane(src0_v, src0_stride_v,
|
| + src1_v, src1_stride_v,
|
| + dst_v, dst_stride_v,
|
| + halfwidth, halfheight, interpolation);
|
| return 0;
|
| }
|
|
|
|
|