diff --git a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs index 4d21333e6..202df9039 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs @@ -692,16 +692,17 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy int mbw = io.MbW; int uvw = (mbw + 1) / 2; int y = io.MbY; + byte[] uvBuffer = new byte[(14 * 32) + 15]; if (y == 0) { // First line is special cased. We mirror the u/v samples at boundary. - YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst, default, mbw); + YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst, default, mbw, uvBuffer); } else { // We can finish the left-over line from previous call. - YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw); + YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw, uvBuffer); numLinesOut++; } @@ -714,7 +715,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy topV = curV; curU = curU.Slice(io.UvStride); curV = curV.Slice(io.UvStride); - YuvConversion.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw); + YuvConversion.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw, uvBuffer); curY = curY.Slice(ioStride2); dst = dst.Slice(bufferStride2); } @@ -736,7 +737,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // Process the very last row of even-sized picture. if ((yEnd & 1) == 0) { - YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst.Slice(bufferStride), default, mbw); + YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst.Slice(bufferStride), default, mbw, uvBuffer); } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs index 342fc330c..54d7ed65d 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs @@ -73,12 +73,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // we interpolate u/v as: // ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16 // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 - public static void UpSample(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len) + public static void UpSample(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len, byte[] uvBuffer) { #if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { - UpSampleSse41(topY, bottomY, topU, topV, curU, curV, topDst, bottomDst, len); + UpSampleSse41(topY, bottomY, topU, topV, curU, curV, topDst, bottomDst, len, uvBuffer); } else #endif @@ -156,10 +156,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // // Then m can be written as // m = (k + t + 1) / 2 - (((b^c) & (s^t)) | (k^t)) & 1 - public static void UpSampleSse41(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len) + public static void UpSampleSse41(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len, byte[] uvBuffer) { const int xStep = 3; - byte[] uvBuffer = new byte[(14 * 32) + 15]; + Array.Clear(uvBuffer, 0, uvBuffer.Length); Span ru = uvBuffer.AsSpan(15); Span rv = ru.Slice(32);