mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 202 additions and 1 deletions
@ -0,0 +1,46 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.Fields; |
|||
using static SixLabors.ImageSharp.Formats.Jxl.Processing.JxlFrameDimensions; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Processing; |
|||
|
|||
/// <summary>
|
|||
/// Shared constants for CFL (Chroma From Luma) functions.
|
|||
/// </summary>
|
|||
internal static class JxlChromaFromLuma |
|||
{ |
|||
/// <summary>
|
|||
/// Tiles are 64x64.
|
|||
/// </summary>
|
|||
public const int ColorTileDimension = 64; |
|||
|
|||
/// <summary>
|
|||
/// Division of the color tile dimension by the block dimension. Therefore,
|
|||
/// this is 8x8.
|
|||
/// </summary>
|
|||
public const int ColorTileDimensionInBlocks = ColorTileDimension / BlockDimensions; |
|||
|
|||
public const int DefaultColorFactor = 84; |
|||
|
|||
/// <summary>
|
|||
/// Chroma From Luma fixed point precision, which is
|
|||
/// 11 bits.
|
|||
/// </summary>
|
|||
public const int CflFixedPointPrecision = 11; |
|||
|
|||
/// <summary>
|
|||
/// 524287
|
|||
/// </summary>
|
|||
public const int CflFixedPointRatioMax = (256 << CflFixedPointPrecision) - 1; |
|||
|
|||
/// <summary>
|
|||
/// Shared variable U32 distributions for the color factor.
|
|||
/// </summary>
|
|||
public static readonly JxlU32Enc ColorFactorDistribution = new( |
|||
JxlFieldExpressions.Value(DefaultColorFactor), |
|||
JxlFieldExpressions.Value(256), |
|||
JxlFieldExpressions.BitsOffset(8, 2), |
|||
JxlFieldExpressions.BitsOffset(16, 258)); |
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.Fields; |
|||
using SixLabors.ImageSharp.Formats.Jxl.Processing.Decoder; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Processing; |
|||
|
|||
internal sealed class JxlColorCorrelation |
|||
{ |
|||
private float baseCorrelationX; |
|||
private float baseCorrelationB = DefaultYToBRatio; |
|||
|
|||
private readonly float[] dcFactors = new float[4]; |
|||
private uint colorFactor = JxlChromaFromLuma.DefaultColorFactor; |
|||
private float colorScale = 1.0f / JxlChromaFromLuma.DefaultColorFactor; |
|||
|
|||
public int YToXDc { get; private set; } |
|||
|
|||
public int YToBDc { get; private set; } |
|||
|
|||
public float ColorFactor => this.colorFactor; |
|||
|
|||
public float BaseCorrelationX |
|||
{ |
|||
get => this.baseCorrelationX; |
|||
set => this.baseCorrelationX = value; |
|||
} |
|||
|
|||
public float BaseCorrelationB |
|||
{ |
|||
get => this.baseCorrelationB; |
|||
set => this.baseCorrelationB = value; |
|||
} |
|||
|
|||
public bool IsJpegCompatible => |
|||
this.BaseCorrelationX == 0 && |
|||
this.BaseCorrelationB == 0 && |
|||
this.YToBDc == 0 && |
|||
this.YToXDc == 0 && |
|||
this.ColorFactor == JxlChromaFromLuma.DefaultColorFactor; |
|||
|
|||
public ReadOnlySpan<float> DcFactors => this.dcFactors; |
|||
|
|||
public float YToXRatio(int xFactor) => this.BaseCorrelationX + (xFactor * this.colorScale); |
|||
|
|||
public float YToBRatio(int bFactor) => this.BaseCorrelationB + (bFactor * this.colorScale); |
|||
|
|||
public void SetColorFactor(uint factor) |
|||
{ |
|||
this.colorFactor = factor; |
|||
this.colorScale = 1f / factor; |
|||
this.RecomputeDcFactors(); |
|||
} |
|||
|
|||
public void SetYToBDc(int yToBDc) |
|||
{ |
|||
this.YToBDc = yToBDc; |
|||
this.RecomputeDcFactors(); |
|||
} |
|||
|
|||
public void SetYToXDc(int yToXDc) |
|||
{ |
|||
this.YToXDc = yToXDc; |
|||
this.RecomputeDcFactors(); |
|||
} |
|||
|
|||
public void RecomputeDcFactors() |
|||
{ |
|||
this.dcFactors[0] = this.YToXRatio(this.YToXDc); |
|||
this.dcFactors[2] = this.YToBRatio(this.YToBDc); |
|||
} |
|||
|
|||
public bool DecodeDc(JxlBitReader reader) |
|||
{ |
|||
bool allDefault = reader.ReadBoolean(); |
|||
|
|||
if (allDefault) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
this.SetColorFactor(JxlU32Coder.Read(JxlChromaFromLuma.ColorFactorDistribution, reader)); |
|||
|
|||
if (!JxlF16Coder.Read(reader, ref this.baseCorrelationX)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (MathF.Abs(this.baseCorrelationX) > 4f) |
|||
{ |
|||
throw new InvalidOperationException("Base X correlation is out of range"); |
|||
} |
|||
|
|||
if (!JxlF16Coder.Read(reader, ref this.baseCorrelationB)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (MathF.Abs(this.baseCorrelationB) > 4f) |
|||
{ |
|||
throw new InvalidOperationException("Base B correlation is out of range"); |
|||
} |
|||
|
|||
this.YToXDc = (int)reader.ReadBits32(8) + sbyte.MinValue; |
|||
this.YToBDc = (int)reader.ReadBits32(8) + sbyte.MinValue; |
|||
|
|||
this.RecomputeDcFactors(); |
|||
return true; |
|||
} |
|||
|
|||
public static int RatioJpeg(int factor) => factor * (1 << JxlChromaFromLuma.CflFixedPointPrecision) / JxlChromaFromLuma.DefaultColorFactor; |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.Memory.ImageTypes; |
|||
using SixLabors.ImageSharp.Formats.Jxl.Processing.Decoder; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Processing; |
|||
|
|||
/// <summary>
|
|||
/// JPEG XL Color correlation map.
|
|||
/// </summary>
|
|||
internal sealed class JxlColorCorrelationMap |
|||
{ |
|||
public JxlColorCorrelation Base { get; set; } = new(); |
|||
|
|||
public JxlImageSB? YToXMap { get; set; } |
|||
|
|||
public JxlImageSB? YToBMap { get; set; } |
|||
|
|||
public bool DecodeDc(JxlBitReader reader) => this.Base.DecodeDc(reader); |
|||
|
|||
public static JxlColorCorrelationMap Create(Configuration configuration, int width, int height, bool xyb) |
|||
{ |
|||
JxlColorCorrelationMap map = new(); |
|||
|
|||
(int xBlocks, int yBlocks) = (DivCeil(width, JxlChromaFromLuma.ColorTileDimension), DivCeil(height, JxlChromaFromLuma.ColorTileDimension)); |
|||
|
|||
map.YToXMap = new JxlImageSB(configuration, xBlocks, yBlocks); |
|||
map.YToBMap = new JxlImageSB(configuration, xBlocks, yBlocks); |
|||
|
|||
ZeroFillImage(map.YToXMap); |
|||
ZeroFillImage(map.YToBMap); |
|||
|
|||
if (!xyb) |
|||
{ |
|||
map.Base.BaseCorrelationB = 0; |
|||
} |
|||
|
|||
map.Base.RecomputeDcFactors(); |
|||
return map; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue