From 64edab5721df90ee4adf86b4740444d7b41de2ad Mon Sep 17 00:00:00 2001 From: winscripter <142818255+winscripter@users.noreply.github.com> Date: Wed, 2 Sep 2026 21:20:52 +0400 Subject: [PATCH] Add patch dictionary stage --- .../Processing/Decoder/JxlPatchDictionary.cs | 2 +- .../RenderPipeline/PatchDictionaryStage.cs | 40 +++++++++++++++++++ .../RenderPipeline/RenderPipelineStageBase.cs | 6 +++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/PatchDictionaryStage.cs diff --git a/src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlPatchDictionary.cs b/src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlPatchDictionary.cs index c990288589..d91c41e38e 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlPatchDictionary.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlPatchDictionary.cs @@ -53,7 +53,7 @@ internal sealed class JxlPatchDictionary this.blendingsStride = (int)(numExtraChannels + 1); List contextMap = []; - var code = new JxlAnsCode(); + JxlAnsCode code = new(); var status = DecodeHistograms( memoryManager, diff --git a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/PatchDictionaryStage.cs b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/PatchDictionaryStage.cs new file mode 100644 index 0000000000..0e6bf82745 --- /dev/null +++ b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/PatchDictionaryStage.cs @@ -0,0 +1,40 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Drawing; +using SixLabors.ImageSharp.Formats.Jxl.IO.Metadata; +using SixLabors.ImageSharp.Formats.Jxl.Processing.Decoder; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Jxl.Processing.RenderPipeline; + +internal sealed class PatchDictionaryStage(Configuration configuration, JxlPatchDictionary patches, List extraChannelInfos) + : RenderPipelineStageBase(configuration) +{ + /// + public override string Name => "Patches"; + + /// + public override void ProcessRow(Buffer2D> inputRows, Buffer2D> outputRows, int xExtraLeft, int xExtraRight, int width, int xPos, int yPos) + { + int channels = 3 + extraChannelInfos.Count; + + Span> rowPtrs = new Memory[channels]; + + for (int i = 0; i < channels; i++) + { + rowPtrs[i] = this.GetInputRowMemory(inputRows, i, 0, xExtraLeft); + } + + return patches.AddOneRow(rowPtrs, yPos, xPos - xExtraLeft, width + xExtraLeft + xExtraRight, extraChannelInfos); + } + + /// + public override RenderPipelineChannelMode GetChannelMode(int channel) + { + int numChannels = 3 + extraChannelInfos.Count; + return channel < numChannels + ? RenderPipelineChannelMode.InPlace + : RenderPipelineChannelMode.Ignored; + } +} diff --git a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageBase.cs b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageBase.cs index b02b62db7a..07cb0f59db 100644 --- a/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageBase.cs +++ b/src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/RenderPipelineStageBase.cs @@ -71,9 +71,15 @@ internal abstract class RenderPipelineStageBase(Configuration configuration) : I public Span GetInputRow(Buffer2D> inputRows, int c, int offset) => inputRows[c, this.Settings.BorderY + offset].Span[RenderPipelineXOffset..]; + public Span GetInputRow(Buffer2D> inputRows, int c, int offset, int xExtraLeft) + => inputRows[c, this.Settings.BorderY + offset].Span[(RenderPipelineXOffset - xExtraLeft)..]; + public Memory GetInputRowMemory(Buffer2D> inputRows, int c, int offset) => inputRows[c, this.Settings.BorderY + offset][RenderPipelineXOffset..]; + public Memory GetInputRowMemory(Buffer2D> inputRows, int c, int offset, int xExtraLeft) + => inputRows[c, this.Settings.BorderY + offset][(RenderPipelineXOffset - xExtraLeft)..]; + public static Span GetOutputRow(Buffer2D> outputRows, int c, int offset) => outputRows[c, offset].Span[RenderPipelineXOffset..];