using System; using System.Collections.Generic; using System.Linq; using SixLabors.ImageSharp.Processing.Processors.Transforms; namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { public partial class KernelMapTests { /// /// Simplified reference implementation for functionality. /// internal class ReferenceKernelMap { private readonly ReferenceKernel[] kernels; public ReferenceKernelMap(ReferenceKernel[] kernels) { this.kernels = kernels; } public int DestinationSize => this.kernels.Length; public ReferenceKernel GetKernel(int destinationIndex) => this.kernels[destinationIndex]; public static ReferenceKernelMap Calculate(IResampler sampler, int destinationSize, int sourceSize, bool normalize = true) { double ratio = (double)sourceSize / destinationSize; double scale = ratio; if (scale < 1F) { scale = 1F; } double radius = (double)Math.Ceiling(scale * sampler.Radius); var result = new List(); for (int i = 0; i < destinationSize; i++) { double center = ((i + .5) * ratio) - .5; // Keep inside bounds. int left = (int)Math.Ceiling(center - radius); if (left < 0) { left = 0; } int right = (int)Math.Floor(center + radius); if (right > sourceSize - 1) { right = sourceSize - 1; } double sum = 0; double[] values = new double[right - left + 1]; for (int j = left; j <= right; j++) { double weight = sampler.GetValue((float)((j - center) / scale)); sum += weight; values[j - left] = weight; } if (sum > 0 && normalize) { for (int w = 0; w < values.Length; w++) { values[w] /= sum; } } float[] floatVals = values.Select(v => (float)v).ToArray(); result.Add(new ReferenceKernel(left, floatVals)); } return new ReferenceKernelMap(result.ToArray()); } } internal struct ReferenceKernel { public ReferenceKernel(int left, float[] values) { this.Left = left; this.Values = values; } public int Left { get; } public float[] Values { get; } public int Length => this.Values.Length; public static implicit operator ReferenceKernel(ResizeKernel orig) { return new ReferenceKernel(orig.Left, orig.Values.ToArray()); } } } }