Browse Source

Reduce errors

pull/3153/head
winscripter 1 week ago
parent
commit
a2f8fe6f2c
  1. 24
      src/ImageSharp/Formats/Jxl/Cms/JxlOpsinConstants.cs
  2. 8
      src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlContextMapDecoder.cs
  3. 10
      src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlXybDecoder.cs
  4. 5
      src/ImageSharp/Formats/Jxl/Processing/Encoder/Ans/JxlHistogram.cs
  5. 3
      src/ImageSharp/Formats/Jxl/Processing/JxlColorCorrelation.cs
  6. 4
      src/ImageSharp/Formats/Jxl/Processing/JxlDctAcImage{T}.cs
  7. 9
      src/ImageSharp/Formats/Jxl/Processing/JxlLoopFilter.cs
  8. 1
      src/ImageSharp/Formats/Jxl/Processing/JxlWeightsSeparable5.cs
  9. 16
      src/ImageSharp/Formats/Jxl/Processing/Modular/Encoding/ContextPrediction/JxlModularState.cs
  10. 15
      src/ImageSharp/Formats/Jxl/Processing/Splines/JxlQuantizedSpline.cs

24
src/ImageSharp/Formats/Jxl/Cms/JxlOpsinConstants.cs

@ -0,0 +1,24 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Formats.Jxl.Cms;
/// <summary>
/// Opsin constants used by the color management system
/// </summary>
internal static class JxlOpsinConstants
{
public const float BScale = 1f;
// The following constants are used for XYB.
// They can be adjusted to change how Y<->B ratio
// works. For example, YToBRatio works better
// with 0.50017729543783418.
public const float YToBRatio = 1f;
public const float BToYRatio = 1f / YToBRatio;
// Adjusting these constants influences the opsin absorbance.
public const float OpsinAbsorbanceBias0 = 0.0037930732552754493f;
public const float OpsinAbsorbanceBias1 = OpsinAbsorbanceBias0;
public const float OpsinAbsorbanceBias2 = OpsinAbsorbanceBias0;
}

8
src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlContextMapDecoder.cs

@ -0,0 +1,8 @@
using System;
namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Decoder;
public class JxlContextMapDecoder
{
}

10
src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlXybDecoder.cs

@ -33,9 +33,9 @@ internal static class JxlXybDecoder
ref Vector<float> linearG,
ref Vector<float> linearB)
{
Vector<float> negBiasR = new(opsinParameters.OpsinBiaases[0]);
Vector<float> negBiasG = new(opsinParameters.OpsinBiaases[1]);
Vector<float> negBiasB = new(opsinParameters.OpsinBiaases[2]);
Vector<float> negBiasR = new(opsinParameters.OpsinBiases[0]);
Vector<float> negBiasG = new(opsinParameters.OpsinBiases[1]);
Vector<float> negBiasB = new(opsinParameters.OpsinBiases[2]);
Vector<float> gammaR = opsinX + opsinY;
Vector<float> gammaG = opsinY - opsinX;
@ -49,7 +49,7 @@ internal static class JxlXybDecoder
Vector<float> mixedG = (gammaG2 * gammaG) + negBiasG;
Vector<float> mixedB = (gammaB2 * gammaB) + negBiasB;
Span<float> inverseMatrix = opsinParameters.GetInverseOpsinMatrixSpan();
Span<float> inverseMatrix = opsinParameters.InverseOpsinMatrix;
linearR = LoadDuplicate128(ref inverseMatrix[0 * 4]) * mixedR;
linearG = LoadDuplicate128(ref inverseMatrix[3 * 4]) * mixedR;
@ -66,7 +66,7 @@ internal static class JxlXybDecoder
public static bool OpsinToLinear(JxlImage3F opsin, Rectangle rect, JxlImage3F linear, JxlOpsinParameters opsinParameters)
{
if (!SameSize(rect, linear))
if (!JxlImageOperations.SameSize(rect, linear))
{
return false;
}

5
src/ImageSharp/Formats/Jxl/Processing/Encoder/Ans/JxlHistogram.cs

@ -8,11 +8,6 @@ namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Encoder.Ans;
/// </summary>
internal sealed class JxlHistogram(int length)
{
/// <summary>
/// Rounding constant
/// </summary>
private const int Rounding = 8;
public List<int> Counts { get; set; } = new(length);
public int TotalCount { get; set; }

3
src/ImageSharp/Formats/Jxl/Processing/JxlColorCorrelation.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Jxl.Cms;
using SixLabors.ImageSharp.Formats.Jxl.Fields;
using SixLabors.ImageSharp.Formats.Jxl.Processing.Decoder;
@ -9,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jxl.Processing;
internal sealed class JxlColorCorrelation
{
private float baseCorrelationX;
private float baseCorrelationB = DefaultYToBRatio;
private float baseCorrelationB = JxlOpsinConstants.YToBRatio;
private readonly float[] dcFactors = new float[4];
private uint colorFactor = JxlChromaFromLuma.DefaultColorFactor;

4
src/ImageSharp/Formats/Jxl/Processing/JxlDctAcImage{T}.cs

@ -23,9 +23,9 @@ internal sealed class JxlDctAcImage<T> : IJxlDctAcImage, IDisposable
public bool IsEmpty => this.image.XSize == 0 || this.image.YSize == 0;
public void Clear() => JxlImageOperations.ClearImage(this.image);
public void Clear() => JxlImageOperations.ZeroFillImage(this.image);
public void Clear(int plane = 0) => JxlImageOperations.ClearImage(this.image);
public void Clear(int plane = 0) => JxlImageOperations.ZeroFillImage(this.image);
public unsafe JxlDctAcPointer GetPlaneRow(int channel, int y, int xBase = 0)
{

9
src/ImageSharp/Formats/Jxl/Processing/JxlLoopFilter.cs

@ -4,6 +4,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Formats.Jxl.Fields;
using SixLabors.ImageSharp.Formats.Jxl.Processing.Decoder;
namespace SixLabors.ImageSharp.Formats.Jxl.Processing;
@ -181,13 +182,13 @@ internal sealed class JxlLoopFilter : IJxlFields
JxlAcStrategyImage acStrategy = state.Shared.AcStrategy;
float quantScale = state.Shared.Quantizer.Scale;
int sigmaStride = state.Sigma.PixelsPerRow;
int sigmaStride = state.Sigma!.PixelsPerRow;
int sharpnessStride = state.Shared.EpfSharpness.PixelsPerRow;
for (int by = 0; by < blockRect.Height; by++)
{
Span<float> sigmaRow = state.Sigma.GetRowSpan(by);
Span<byte> sharpnessRow = state.Shared.EpfSharpness.GetRowSpan(by);
Span<float> sigmaRow = state.Sigma.GetRow(by);
Span<byte> sharpnessRow = state.Shared.EpfSharpness.GetRow(by);
JxlAcStrategyRow acsRow = acStrategy.GetRow(in blockRect, by);
Span<int> rowQuant = state.Shared.RawQuantField.GetRow(by);
@ -245,7 +246,7 @@ internal sealed class JxlLoopFilter : IJxlFields
}
}
if (by + blockRect.Y + acs.CoveredBlocksX == state.Shared.FrameDimensions.YSizeBloks)
if (by + blockRect.Y + acs.CoveredBlocksX == state.Shared.FrameDimensions.YSizeBlocks)
{
for (int iy = 0; iy < SigmaBorder; iy++)
{

1
src/ImageSharp/Formats/Jxl/Processing/JxlWeightsSeparable5.cs

@ -6,7 +6,6 @@ namespace SixLabors.ImageSharp.Formats.Jxl.Processing;
internal struct JxlWeightsSeparable5
{
// Don't make these a property so we can ref into them.
public InlineArray12<float> Horizontal;
public InlineArray12<float> Vertical;

16
src/ImageSharp/Formats/Jxl/Processing/Modular/Encoding/ContextPrediction/JxlModularState.cs

@ -21,7 +21,7 @@ internal sealed class JxlModularState
private readonly int[] error;
private readonly JxlModularHeader header;
public JxlModularState(JxlModularHeader header, int width, int height)
public JxlModularState(JxlModularHeader header, int width)
{
this.header = header;
@ -104,9 +104,9 @@ internal sealed class JxlModularState
int cur_row = yIsOdd ? 0 : (width + 2);
int prev_row = yIsOdd ? (width + 2) : 0;
int pos_N = prev_row + x;
int pos_NE = x < width - 1 ? pos_N + 1 : pos_N;
int pos_NW = x > 0 ? pos_N - 1 : pos_N;
int posN = prev_row + x;
int posNE = x < width - 1 ? posN + 1 : posN;
int posNW = x > 0 ? posN - 1 : posN;
Span<uint> weights = stackalloc uint[4];
ref uint headerW = ref this.header.GetWReference();
@ -114,7 +114,7 @@ internal sealed class JxlModularState
for (int i = 0; i < 4; i++)
{
Span<uint> error = this.predErrors[i].AsSpan();
weights[i] = error[pos_N] + error[pos_NE] + error[pos_NW];
weights[i] = error[posN] + error[posNE] + error[posNW];
weights[i] = ErrorWeight((int)weights[i], Unsafe.Add(ref headerW, i));
}
@ -125,10 +125,10 @@ internal sealed class JxlModularState
nn = AddBits(nn);
long teW = x == 0 ? 0 : this.error[cur_row + x - 1];
long teN = this.error[pos_N];
long teNW = this.error[pos_NW];
long teN = this.error[posN];
long teNW = this.error[posNW];
long sumWN = teN + teW;
long teNE = this.error[pos_NE];
long teNE = this.error[posNE];
if (computeProperties)
{

15
src/ImageSharp/Formats/Jxl/Processing/Splines/JxlQuantizedSpline.cs

@ -50,10 +50,11 @@ internal sealed class JxlQuantizedSpline : IDisposable
public static JxlQuantizedSpline Create(Configuration configuration, JxlSpline original, int quantizationAdjustment, float yToX, float yToB)
{
JxlQuantizedSpline spline = new();
Span<PointF> controlPoints = original.ControlPoints.Span;
spline.ReserveControlPoints(configuration, original.ControlPoints.Count - 1);
spline.ReserveControlPoints(configuration, controlPoints.Length - 1);
PointF startingPoint = original.ControlPoints.First();
PointF startingPoint = controlPoints[0];
int previousX = (int)MathF.Round(startingPoint.X);
int previousY = (int)MathF.Round(startingPoint.Y);
int previousDx = 0; // D stands for delta
@ -65,7 +66,7 @@ internal sealed class JxlQuantizedSpline : IDisposable
for (int i = 0; i < length; i++)
{
PointF controlPoint = original.ControlPoints[i];
PointF controlPoint = controlPoints[i];
int newX = (int)MathF.Round(controlPoint.X);
int newY = (int)MathF.Round(controlPoint.Y);
@ -93,8 +94,8 @@ internal sealed class JxlQuantizedSpline : IDisposable
// for i=0 and adding a separate loop for i=1..31
for (int i = 0; i < 32; i++)
{
float dctFactor = (i == 0) ? Sqrt2 : 1.0f;
float inverseDctFactor = (i == 0) ? Sqrt05 : 1.0f;
float dctFactor = (i == 0) ? JxlDctScales.Sqrt2 : 1.0f;
float inverseDctFactor = (i == 0) ? JxlDctScales.Sqrt05 : 1.0f;
float restoredY = spline.ColorDct[1][i] * inverseDctFactor * ChannelWeight[1] * inverseQuant;
float decorrelated = spline.ColorDct[c][i] - (factor * restoredY);
spline.ColorDct[c][i] = ConvertToInteger(decorrelated * dctFactor * quant / ChannelWeight[c]);
@ -103,7 +104,7 @@ internal sealed class JxlQuantizedSpline : IDisposable
for (int i = 0; i < 32; i++)
{
float dctFactor = (i == 0) ? Sqrt2 : 1.0f;
float dctFactor = (i == 0) ? JxlDctScales.Sqrt2 : 1.0f;
spline.SigmaDct[i] = ConvertToInteger(original.SigmaDct[i] * dctFactor * quant / ChannelWeight[1]);
}
@ -190,7 +191,7 @@ internal sealed class JxlQuantizedSpline : IDisposable
{
for (int i = 0; i < 32; i++)
{
float inverseDctFactor = (i == 0) ? Sqrt05 : 1.0f;
float inverseDctFactor = (i == 0) ? JxlDctScales.Sqrt05 : 1.0f;
result.ColorDct[c][i] = this.ColorDct[c][i] * inverseDctFactor * ChannelWeight[c] * inverseQuant;
}
}

Loading…
Cancel
Save