Browse Source

Fix degeneracy check for resize transforms

Use exact zero determinant checks in `TransformUtilities.IsDegenerate` for `Matrix3x2` and `Matrix4x4` instead of epsilon-based near-zero detection, preventing valid transforms from being treated as degenerate during extreme downscales. Added a regression test for issue #3156 to verify resizing large square images (1024/2048) to 1x1 succeeds and preserves the expected pixel.
pull/3157/head
James Jackson-South 3 weeks ago
parent
commit
3d89f941d4
  1. 8
      src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs
  2. 14
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs

8
src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs

@ -19,7 +19,7 @@ internal static class TransformUtilities
/// </summary>
/// <param name="matrix">The transform matrix.</param>
public static bool IsDegenerate(Matrix3x2 matrix)
=> IsNaN(matrix) || IsZero(matrix.GetDeterminant());
=> IsNaN(matrix) || matrix.GetDeterminant() == 0F;
/// <summary>
/// Returns a value that indicates whether the specified matrix is degenerate
@ -28,11 +28,7 @@ internal static class TransformUtilities
/// </summary>
/// <param name="matrix">The transform matrix.</param>
public static bool IsDegenerate(Matrix4x4 matrix)
=> IsNaN(matrix) || IsZero(matrix.GetDeterminant());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsZero(float a)
=> a > -Constants.EpsilonSquared && a < Constants.EpsilonSquared;
=> IsNaN(matrix) || matrix.GetDeterminant() == 0F;
/// <summary>
/// Returns a value that indicates whether the specified matrix contains any values

14
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs

@ -699,6 +699,20 @@ public class ResizeTests
appendSourceFileOrDescription: false);
}
[Theory]
[InlineData(1024)]
[InlineData(2048)]
public void Issue3156_CanResizeLargeSquareToSinglePixel(int length)
{
Rgba32 white = Color.White.ToPixel<Rgba32>();
using Image<Rgba32> image = new(length, length, white);
image.Mutate(x => x.Resize(1, 1));
Assert.Equal(new Size(1, 1), image.Size);
Assert.Equal(white, image[0, 0]);
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void ResizeUpdatesSubject<TPixel>(TestImageProvider<TPixel> provider)

Loading…
Cancel
Save