Index: source/planar_functions.cc |
diff --git a/source/planar_functions.cc b/source/planar_functions.cc |
index 6379217862bb7cbbaab7dfa0a72031263e56d512..6717c632551f88917695ea8caa272179c30a230f 100644 |
--- a/source/planar_functions.cc |
+++ b/source/planar_functions.cc |
@@ -1681,12 +1681,12 @@ int ARGBShade(const uint8* src_argb, int src_stride_argb, |
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) { |
+// Interpolate 2 images by specified amount (0 to 255). |
+static |
+int InterpolateBpp(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 bpp) { |
int y; |
void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, |
ptrdiff_t src_stride, int dst_width, |
@@ -1701,9 +1701,9 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0, |
dst_stride_argb = -dst_stride_argb; |
} |
// Coalesce rows. |
- if (src_stride_argb0 == width * 4 && |
- src_stride_argb1 == width * 4 && |
- dst_stride_argb == width * 4) { |
+ if (src_stride_argb0 == width * bpp && |
+ src_stride_argb1 == width * bpp && |
+ dst_stride_argb == width * bpp) { |
width *= height; |
height = 1; |
src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; |
@@ -1711,7 +1711,7 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0, |
#if defined(HAS_INTERPOLATEROW_SSE2) |
if (TestCpuFlag(kCpuHasSSE2)) { |
InterpolateRow = InterpolateRow_Any_SSE2; |
- if (IS_ALIGNED(width, 4)) { |
+ if (IS_ALIGNED(width * bpp, 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 * bpp, 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 * bpp, 32)) { |
InterpolateRow = InterpolateRow_AVX2; |
} |
} |
@@ -1735,7 +1735,7 @@ 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 * bpp, 16)) { |
InterpolateRow = InterpolateRow_NEON; |
} |
} |
@@ -1744,14 +1744,15 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0, |
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(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4) && |
+ IS_ALIGNED(width * bpp, 4)) { |
InterpolateRow = InterpolateRow_MIPS_DSPR2; |
} |
#endif |
for (y = 0; y < height; ++y) { |
InterpolateRow(dst_argb, src_argb0, src_argb1 - src_argb0, |
- width * 4, interpolation); |
+ width * bpp, interpolation); |
src_argb0 += src_stride_argb0; |
src_argb1 += src_stride_argb1; |
dst_argb += dst_stride_argb; |
@@ -1759,6 +1760,66 @@ int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0, |
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 InterpolateBpp(src_argb0, src_stride_argb0, |
+ src_argb1, src_stride_argb1, |
+ dst_argb, dst_stride_argb, |
+ width, height, interpolation, 4); |
+} |
+ |
+// Interpolate 2 planes by specified amount (0 to 255). |
+LIBYUV_API |
+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) { |
+ return InterpolateBpp(src0, src_stride0, |
+ src1, src_stride1, |
+ dst, dst_stride, |
+ width, height, interpolation, 1); |
+} |
+ |
+ |
+// 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; |
+ } |
+ InterpolateBpp(src0_y, src0_stride_y, |
+ src1_y, src1_stride_y, |
+ dst_y, dst_stride_y, |
+ width, height, interpolation, 1); |
+ InterpolateBpp(src0_u, src0_stride_u, |
+ src1_u, src1_stride_u, |
+ dst_u, dst_stride_u, |
+ halfwidth, halfheight, interpolation, 1); |
+ InterpolateBpp(src0_v, src0_stride_v, |
+ src1_v, src1_stride_v, |
+ dst_v, dst_stride_v, |
+ halfwidth, halfheight, interpolation, 1); |
+ return 0; |
+} |
+ |
// Shuffle ARGB channel order. e.g. BGRA to ARGB. |
LIBYUV_API |
int ARGBShuffle(const uint8* src_bgra, int src_stride_bgra, |