Browse Source

robust ResizeKernelMap calculations using TolerantMath

af/merge-core
Anton Firszov 8 years ago
parent
commit
0c7aee9f5d
  1. 2
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs
  2. 15
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs
  3. 3
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  4. 16
      tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs
  5. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs

2
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs

@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
for (int i = startOfFirstRepeatedMosaic; i < bottomStartDest; i++) for (int i = startOfFirstRepeatedMosaic; i < bottomStartDest; i++)
{ {
double center = ((i + .5) * this.ratio) - .5; double center = ((i + .5) * this.ratio) - .5;
int left = (int)Math.Ceiling(center - this.radius); int left = (int)TolerantMath.Ceiling(center - this.radius);
ResizeKernel kernel = this.kernels[i - this.period]; ResizeKernel kernel = this.kernels[i - this.period];
this.kernels[i] = kernel.AlterLeftValue(left); this.kernels[i] = kernel.AlterLeftValue(left);
} }

15
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs

@ -17,6 +17,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// </summary> /// </summary>
internal partial class ResizeKernelMap : IDisposable internal partial class ResizeKernelMap : IDisposable
{ {
private static readonly TolerantMath TolerantMath = TolerantMath.Default;
private readonly IResampler sampler; private readonly IResampler sampler;
private readonly int sourceLength; private readonly int sourceLength;
@ -107,15 +109,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
scale = 1F; scale = 1F;
} }
int radius = (int)Math.Ceiling(scale * sampler.Radius); int radius = (int)TolerantMath.Ceiling(scale * sampler.Radius);
int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize;
double center0 = (ratio - 1) * 0.5f; double center0 = (ratio - 1) * 0.5;
double firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; double firstNonNegativeLeftVal = (radius - center0 - 1) / ratio;
int cornerInterval = (int)Math.Ceiling(firstNonNegativeLeftVal); int cornerInterval = (int)TolerantMath.Ceiling(firstNonNegativeLeftVal);
// corner case for cornerInteval: // corner case for cornerInteval:
// TODO: Implement library-wide utils for tolerant comparison if (TolerantMath.AreEqual(firstNonNegativeLeftVal, cornerInterval))
if (Math.Abs(firstNonNegativeLeftVal - cornerInterval) < 1e-8)
{ {
cornerInterval++; cornerInterval++;
} }
@ -167,13 +168,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
double center = ((destRowIndex + .5) * this.ratio) - .5; double center = ((destRowIndex + .5) * this.ratio) - .5;
// Keep inside bounds. // Keep inside bounds.
int left = (int)Math.Ceiling(center - this.radius); int left = (int)TolerantMath.Ceiling(center - this.radius);
if (left < 0) if (left < 0)
{ {
left = 0; left = 0;
} }
int right = (int)Math.Floor(center + this.radius); int right = (int)TolerantMath.Floor(center + this.radius);
if (right > this.sourceLength - 1) if (right > this.sourceLength - 1)
{ {
right = this.sourceLength - 1; right = this.sourceLength - 1;

3
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<!--<TargetFrameworks>net462;net472;netcoreapp2.1</TargetFrameworks>--> <TargetFrameworks>net462;net472;netcoreapp2.1</TargetFrameworks>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks> <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<DebugType Condition="$(codecov) != ''">full</DebugType> <DebugType Condition="$(codecov) != ''">full</DebugType>

16
tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs

@ -35,27 +35,29 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
scale = 1F; scale = 1F;
} }
double radius = (double)Math.Ceiling(scale * sampler.Radius); TolerantMath tolerantMath = TolerantMath.Default;
double radius = tolerantMath.Ceiling(scale * sampler.Radius);
var result = new List<ReferenceKernel>(); var result = new List<ReferenceKernel>();
for (int i = 0; i < destinationSize; i++) for (int i = 0; i < destinationSize; i++)
{ {
if (i == 21 || i == 64) //if (i == 21 || i == 64)
{ //{
Debug.Print("lol"); // Debug.Print("lol");
} //}
double center = ((i + .5) * ratio) - .5; double center = ((i + .5) * ratio) - .5;
// Keep inside bounds. // Keep inside bounds.
int left = (int)Math.Ceiling(center - radius); int left = (int)tolerantMath.Ceiling(center - radius);
if (left < 0) if (left < 0)
{ {
left = 0; left = 0;
} }
int right = (int)Math.Floor(center + radius); int right = (int)tolerantMath.Floor(center + radius);
if (right > sourceSize - 1) if (right > sourceSize - 1)
{ {
right = sourceSize - 1; right = sourceSize - 1;

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs

@ -119,7 +119,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
} }
#endif #endif
private void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) private void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize)
{ {
IResampler resampler = TestUtils.GetResampler(resamplerName); IResampler resampler = TestUtils.GetResampler(resamplerName);

Loading…
Cancel
Save