Browse Source

Add 3 missing methods to JxlFrameDecoder, add spline and spotcolor render pipeline stages

pull/3153/head
winscripter 1 month ago
parent
commit
4476abd507
  1. 25
      src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlFrameDecoder.cs
  2. 21
      src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/SplineStage.cs
  3. 37
      src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/SpotColorStage.cs

25
src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlFrameDecoder.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Jxl.IO;
using SixLabors.ImageSharp.Formats.Jxl.IO.FrameHeader;
using SixLabors.ImageSharp.Formats.Jxl.IO.Metadata;
using SixLabors.ImageSharp.Formats.Jxl.Processing.Image;
@ -133,4 +134,28 @@ internal sealed class JxlFrameDecoder
frameDecoder.FinalizeFrame();
}
private static int BytesPerChannel(JxlDataType dataType) =>
dataType == JxlDataType.Byte ? 1
: dataType == JxlDataType.Single
? 4
: 2;
private int GetStorageLocation(int thread, int task) => this.useTaskId ? task : thread;
private void PrepareStorage(int numThreads, int numTasks)
{
int storageSize = Math.Min(numThreads, numTasks);
if (storageSize > this.groupDecoderCaches.Count)
{
this.groupDecoderCaches = [.. this.groupDecoderCaches.Take(storageSize)];
}
this.useTaskId = numThreads > numTasks;
bool useNoise = (this.frameHeader.Flags & (int)JxlFrameHeaderFlags.Noise) != 0;
bool useGroupIds = this.modularFrameDecoder.UsesFullImage && (this.frameHeader.Encoding == JxlFrameEncoding.VarDct || useNoise);
this.decoderState.RenderPipeline?.PrepareForThreads(storageSize, useGroupIds);
this.decoderState.Upsampler8x.PrepareForThreads(numThreads);
}
}

21
src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/SplineStage.cs

@ -0,0 +1,21 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Jxl.Processing.RenderPipeline;
internal sealed class SplineStage(Configuration configuration, JxlSplines splines) : RenderPipelineStageBase(configuration)
{
public override string Name => "Splines";
public override void ProcessRow(Buffer2D<Memory<float>> inputRows, Buffer2D<Memory<float>> outputRows, int xExtraLeft, int xExtraRight, int width, int xPos, int yPos)
{
Span<float> rowX = this.GetInputRow(inputRows, 0, 0, xExtraLeft);
Span<float> rowY = this.GetInputRow(inputRows, 1, 0, xExtraLeft);
Span<float> rowB = this.GetInputRow(inputRows, 2, 0, xExtraLeft);
splines.AddToRow(rowX, rowY, rowB, yPos, xPos - xExtraLeft, xPos + width + xExtraRight);
}
public override RenderPipelineChannelMode GetChannelMode(int channel) => channel < 3 ? RenderPipelineChannelMode.InPlace : RenderPipelineChannelMode.Ignored;
}

37
src/ImageSharp/Formats/Jxl/Processing/RenderPipeline/SpotColorStage.cs

@ -0,0 +1,37 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Jxl.Processing.RenderPipeline;
internal sealed class SpotColorStage(Configuration configuration, int spotColorOffset, Memory<float> spotColor)
: RenderPipelineStageBase(configuration)
{
private readonly int spotC = 3 + spotColorOffset;
public override string Name => "Spot";
public override void ProcessRow(Buffer2D<Memory<float>> inputRows, Buffer2D<Memory<float>> outputRows, int xExtraLeft, int xExtraRight, int width, int xPos, int yPos)
{
Span<float> spotColors = spotColor.Span;
float scale = 0;
for (int c = 0; c < 3; c++)
{
Span<float> p = this.GetInputRow(inputRows, c, 0);
Span<float> s = this.GetInputRow(inputRows, this.spotC, 0);
for (int x = 0; x < width; x++)
{
float mix = scale * s[x];
p[x] = (mix * spotColors[c]) + ((1.0f - mix) * p[x]);
}
}
}
public override RenderPipelineChannelMode GetChannelMode(int channel)
=> channel < 3 ? RenderPipelineChannelMode.InPlace
: channel == this.spotC ? RenderPipelineChannelMode.Input
: RenderPipelineChannelMode.Ignored;
}
Loading…
Cancel
Save