From 772cdda9780267e89d95e2a9d7ea504e1736745d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 16:49:46 +0100 Subject: [PATCH 1/2] better comments + TolerantMath made readonly --- src/ImageSharp/Common/Helpers/TolerantMath.cs | 2 +- .../Transforms/Resize/ResizeKernelMap.cs | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/TolerantMath.cs b/src/ImageSharp/Common/Helpers/TolerantMath.cs index d95aea9de..5347efcc0 100644 --- a/src/ImageSharp/Common/Helpers/TolerantMath.cs +++ b/src/ImageSharp/Common/Helpers/TolerantMath.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp /// Implements basic math operations using tolerant comparison /// whenever an equality check is needed. /// - internal struct TolerantMath + internal readonly struct TolerantMath { private readonly double epsilon; diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 347aaf0be..f6edf9786 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -110,20 +110,33 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } int radius = (int)TolerantMath.Ceiling(scale * sampler.Radius); + + // 'ratio' is a rational number. + // Multiplying it by LCM(sourceSize, destSize)/sourceSize will result in a whole number "again". + // This value is determining the length of the periods in repeating kernel map rows. int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; + + // the center position at i == 0: double center0 = (ratio - 1) * 0.5; double firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; + + // The number of rows building a "stairway" at the top and the bottom of the kernel map + // corresponding to the corners of the image. + // If we do not normalize the kernel values, these rows also fit the periodic logic, + // however, it's just simpler to calculate them separately. int cornerInterval = (int)TolerantMath.Ceiling(firstNonNegativeLeftVal); - // corner case for cornerInteval: + // If firstNonNegativeLeftVal was an integral value, we don't need Ceiling: if (TolerantMath.AreEqual(firstNonNegativeLeftVal, cornerInterval)) { cornerInterval++; } - bool useMosaic = 2 * (cornerInterval + period) < destinationSize; + // If 'cornerInterval' is too big compared to 'period', we can't apply the periodic optimization. + // If we don't have at least 2 periods, we go with the basic implementation: + bool hasAtLeast2Periods = 2 * (cornerInterval + period) < destinationSize; - ResizeKernelMap result = useMosaic + ResizeKernelMap result = hasAtLeast2Periods ? new PeriodicKernelMap( memoryAllocator, sampler, From ab4cae48ace9d4f8d0586b49241164a43ad76a4f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 17:03:46 +0100 Subject: [PATCH 2/2] improve comments again --- .../Processors/Transforms/Resize/ResizeKernelMap.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index f6edf9786..2ab574df2 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -104,9 +104,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms double ratio = (double)sourceSize / destinationSize; double scale = ratio; - if (scale < 1F) + if (scale < 1) { - scale = 1F; + scale = 1; } int radius = (int)TolerantMath.Ceiling(scale * sampler.Radius); @@ -126,7 +126,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // however, it's just simpler to calculate them separately. int cornerInterval = (int)TolerantMath.Ceiling(firstNonNegativeLeftVal); - // If firstNonNegativeLeftVal was an integral value, we don't need Ceiling: + // If firstNonNegativeLeftVal was an integral value, we need firstNonNegativeLeftVal+1 + // instead of Ceiling: if (TolerantMath.AreEqual(firstNonNegativeLeftVal, cornerInterval)) { cornerInterval++;