diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs index a5a557179..e5a6b4549 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -1033,13 +1033,4 @@ internal static class Numerics public static nuint Vector512Count(int length) where TVector : struct => (uint)length / (uint)Vector512.Count; - - /// - /// Computes the average of two integers. - /// - /// First integer - /// Second integer - /// The average of x, y. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Average(int x, int y) => (x + y + ((x > y) ? 1 : 0)) >> 1; } diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/AuxiliaryOutput/JxlAuxiliaryOutput.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/AuxiliaryOutput/JxlAuxiliaryOutput.cs index 6a34aabdc..d39b707bc 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Encoder/AuxiliaryOutput/JxlAuxiliaryOutput.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/AuxiliaryOutput/JxlAuxiliaryOutput.cs @@ -67,6 +67,16 @@ internal sealed class JxlAuxiliaryOutput this.NumberOfBlocks += victim.NumberOfBlocks; this.NumberOfSmallBlocks += victim.NumberOfSmallBlocks; - + this.NumberOfDct4x8Blocks += victim.NumberOfDct4x8Blocks; + this.NumberOfAfvBlocks += victim.NumberOfAfvBlocks; + this.NumberOfDct8Blocks += victim.NumberOfDct8Blocks; + this.NumberOfDct8x16Blocks += victim.NumberOfDct8x16Blocks; + this.NumberOfDct8x32Blocks += victim.NumberOfDct8x32Blocks; + this.NumberOfDct16Blocks += victim.NumberOfDct16Blocks; + this.NumberOfDct16x32Blocks += victim.NumberOfDct16x32Blocks; + this.NumberOfDct32Blocks += victim.NumberOfDct32Blocks; + this.NumberOfDct32x64Blocks += victim.NumberOfDct32x64Blocks; + this.NumberOfDct64Blocks += victim.NumberOfDct64Blocks; + this.NumberOfButteraugliIterations += victim.NumberOfButteraugliIterations; } } diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs index 316f1ed12..3feb60c72 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlFastLosslessEncoder.cs @@ -163,7 +163,7 @@ internal sealed class JxlFastLosslessEncoder /// A wrapper over the color data of the channel at the specified /// position. /// - public Span GetColorChannelData(int x, int y, int width, int height, out long rowOffset) + Span GetColorChannelData(int x, int y, int width, int height, out long rowOffset) where T : unmanaged; } diff --git a/src/ImageSharp/Formats/Jxl/Processing/JxlMath.cs b/src/ImageSharp/Formats/Jxl/Processing/JxlMath.cs index 0157dba4e..a0042c9c5 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/JxlMath.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/JxlMath.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; -using SixLabors.ImageSharp.Common.Helpers; namespace SixLabors.ImageSharp.Formats.Jxl.Processing; @@ -687,25 +686,7 @@ internal static class JxlMath /// X /// Y /// Hypotenuse of x and y - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Hypot(double x, double y) - { - x = Math.Abs(x); - y = Math.Abs(y); - - if (x < y) - { - RuntimeUtility.Swap(ref x, ref y); - } - - if (x == 0.0) - { - return 0.0; - } - - double ratio = y / x; - return x * Math.Sqrt(1 + (ratio * ratio)); - } + public static float Hypot(float x, float y) => Hypot(x, y); /// /// Computes the hypotenuse of x and y. @@ -713,23 +694,26 @@ internal static class JxlMath /// X /// Y /// Hypotenuse of x and y + public static double Hypot(double x, double y) => Hypot(x, y); + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Hypot(float x, float y) + private static T Hypot(T x, T y) + where T : INumber, IRootFunctions { - x = MathF.Abs(x); - y = MathF.Abs(y); + x = T.Abs(x); + y = T.Abs(y); if (x < y) { - RuntimeUtility.Swap(ref x, ref y); + (y, x) = (x, y); } - if (x == 0.0f) + if (x == T.Zero) { - return 0.0f; + return T.Zero; } - float ratio = y / x; - return x * MathF.Sqrt(1 + (ratio * ratio)); + T ratio = y / x; + return x * T.Sqrt(T.One + (ratio * ratio)); } } diff --git a/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlPalette.cs b/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlPalette.cs index bfcd683c5..4a41bc34c 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlPalette.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlPalette.cs @@ -492,7 +492,7 @@ internal static class JxlPalette if (a.Length >= 3) { - ave3 = (a[0] + b[0] + a[1] + b[1] + a[2] + b[2]) * (1.21f / 3.0f); + ave3 = ((a[0] + b[0]) + (a[1] + b[1]) + (a[2] + b[2])) * (1.21f / 3.0f); } float sumA = 0; diff --git a/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlSqueeze.cs b/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlSqueeze.cs index d21d0438c..688801582 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlSqueeze.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/Modular/Transforms/JxlSqueeze.cs @@ -27,6 +27,15 @@ internal static class JxlSqueeze { private const int MaxFirstPreviewSize = 8; + /// + /// Computes the average of two integers. + /// + /// First integer + /// Second integer + /// The average of x, y. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Average(int x, int y) => (x + y + ((x > y) ? 1 : 0)) >> 1; + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int SmoothTendency(int b, int a, int n) { @@ -534,10 +543,8 @@ internal static class JxlSqueeze int c1 = parameter.BeginC; int c2 = parameter.BeginC + parameter.NumC - 1; - if (c1 < 0 || - c1 >= numChannels || - c2 < 0 || - c2 >= numChannels || + if ((uint)c1 >= numChannels || + (uint)c2 >= numChannels || c2 < c1) { throw new InvalidOperationException("Invalid channel range"); @@ -654,7 +661,7 @@ internal static class JxlSqueeze int a = pIn[x2]; int b = pIn[x2 + 1]; - int avg = Numerics.Average(a, b); + int avg = Average(a, b); pOut[x] = avg; int diff = a - b; int nextAvg = avg; @@ -664,7 +671,7 @@ internal static class JxlSqueeze int c2 = pIn[x2 + 2]; // actually C, but 1. variable 'c' already defined 2. names should be camelCase int d = pIn[x2 + 3]; - nextAvg = Numerics.Average(c2, d); + nextAvg = Average(c2, d); } else if ((inputChannel.Width & 1) != 0) { @@ -711,7 +718,7 @@ internal static class JxlSqueeze { int a = pIn[x]; int b = pIn[x + oneRowInput]; - int avg = Numerics.Average(a, b); + int avg = Average(a, b); pOut[x] = avg; int diff = a - b; int nextAvg = avg; @@ -720,7 +727,7 @@ internal static class JxlSqueeze { int c2 = pIn[x + (2 * oneRowInput)]; // actually C, but 1. variable 'c' already defined 2. names should be camelCase int d = pIn[x + (3 * oneRowInput)]; - nextAvg = Numerics.Average(c2, d); + nextAvg = Average(c2, d); } else if ((inputChannel.Height & 1) != 0) { diff --git a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/Epf0Stage.cs b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/Epf0Stage.cs index 56f52fab8..5df7525ea 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/Epf0Stage.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/Epf0Stage.cs @@ -103,7 +103,6 @@ internal sealed class Epf0Stage : RenderPipelineStageBase Vector256 vsm = Vector256.Create(sadMul[ix..]); Vector256 inverseSigma = Vector256.Create(rowSigma[bx]) * vsm; - } } } diff --git a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageConfiguration.cs b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageConfiguration.cs index acd7b8b76..282876b6b 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageConfiguration.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageConfiguration.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Jxl.Processing.RenderPipeline; -internal record struct RenderPipelineStageConfiguration(int BorderX, int BorderY, int ShiftX, int ShiftY) +internal readonly record struct RenderPipelineStageConfiguration(int BorderX, int BorderY, int ShiftX, int ShiftY) { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RenderPipelineStageConfiguration CreateShiftX(int shift, int border) => new(border, 0, shift, 0);