From 772cdda9780267e89d95e2a9d7ea504e1736745d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 16:49:46 +0100 Subject: [PATCH] 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,