diff --git a/src/ImageSharp/Formats/AnimationUtilities.cs b/src/ImageSharp/Formats/AnimationUtilities.cs index 5e576c983..814e48b63 100644 --- a/src/ImageSharp/Formats/AnimationUtilities.cs +++ b/src/ImageSharp/Formats/AnimationUtilities.cs @@ -71,10 +71,10 @@ internal static class AnimationUtilities PixelOperations.Instance.ToRgba32(configuration, nextFrame.DangerousGetPixelRowMemory(y).Span, next); } - ref Vector256 previousBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(previous)); - ref Vector256 currentBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(current)); - ref Vector256 nextBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(next)); - ref Vector256 resultBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(result)); + ref Vector256 previousBase256 = ref Unsafe.As>(ref MemoryMarshal.GetReference(previous)); + ref Vector256 currentBase256 = ref Unsafe.As>(ref MemoryMarshal.GetReference(current)); + ref Vector256 nextBase256 = ref Unsafe.As>(ref MemoryMarshal.GetReference(next)); + ref Vector256 resultBase256 = ref Unsafe.As>(ref MemoryMarshal.GetReference(result)); int i = 0; uint x = 0; @@ -93,19 +93,19 @@ internal static class AnimationUtilities while (remaining >= 8) { - Vector256 p = Unsafe.Add(ref previousBase, x).AsUInt32(); - Vector256 c = Unsafe.Add(ref currentBase, x).AsUInt32(); + Vector256 p = Unsafe.Add(ref previousBase256, x).AsUInt32(); + Vector256 c = Unsafe.Add(ref currentBase256, x).AsUInt32(); Vector256 eq = Avx2.CompareEqual(p, c); Vector256 r = Avx2.BlendVariable(c, r256, Avx2.And(eq, vmb256)); if (nextFrame != null) { - Vector256 n = Avx2.ShiftRightLogical(Unsafe.Add(ref nextBase, x).AsUInt32(), 24).AsInt32(); + Vector256 n = Avx2.ShiftRightLogical(Unsafe.Add(ref nextBase256, x).AsUInt32(), 24).AsInt32(); eq = Avx2.AndNot(Avx2.CompareGreaterThan(Avx2.ShiftRightLogical(c, 24).AsInt32(), n).AsUInt32(), eq); } - Unsafe.Add(ref resultBase, x) = r.AsByte(); + Unsafe.Add(ref resultBase256, x) = r.AsByte(); uint msk = (uint)Avx2.MoveMask(eq.AsByte()); msk = ~msk; @@ -128,9 +128,10 @@ internal static class AnimationUtilities } } - // TODO: There's a bug here. See WebpEncoderTests.Encode_AnimatedLossless - if (Sse2.IsSupported && remaining >= 4 && false) + if (Sse2.IsSupported && remaining >= 4) { + // Update offset since we may be operating on the remainder previously incremented by pixel steps of 8. + x *= 2; Vector128 r128 = previousFrame != null ? Vector128.Create(bg.PackedValue) : Vector128.Zero; Vector128 vmb128 = Vector128.Zero; if (blend) @@ -140,19 +141,19 @@ internal static class AnimationUtilities while (remaining >= 4) { - Vector128 p = Unsafe.Add(ref Unsafe.As, Vector128>(ref previousBase), x); - Vector128 c = Unsafe.Add(ref Unsafe.As, Vector128>(ref currentBase), x); + Vector128 p = Unsafe.Add(ref Unsafe.As, Vector128>(ref previousBase256), x); + Vector128 c = Unsafe.Add(ref Unsafe.As, Vector128>(ref currentBase256), x); Vector128 eq = Sse2.CompareEqual(p, c); Vector128 r = SimdUtils.HwIntrinsics.BlendVariable(c, r128, Sse2.And(eq, vmb128)); if (nextFrame != null) { - Vector128 n = Sse2.ShiftRightLogical(Unsafe.Add(ref Unsafe.As, Vector128>(ref nextBase), x), 24).AsInt32(); + Vector128 n = Sse2.ShiftRightLogical(Unsafe.Add(ref Unsafe.As, Vector128>(ref nextBase256), x), 24).AsInt32(); eq = Sse2.AndNot(Sse2.CompareGreaterThan(Sse2.ShiftRightLogical(c, 24).AsInt32(), n).AsUInt32(), eq); } - Unsafe.Add(ref Unsafe.As, Vector128>(ref resultBase), x) = r; + Unsafe.Add(ref Unsafe.As, Vector128>(ref resultBase256), x) = r; ushort msk = (ushort)(uint)Sse2.MoveMask(eq.AsByte()); msk = (ushort)~msk;