From a6a0263836f469d4fd8e810ae354e91cbe65f9ce Mon Sep 17 00:00:00 2001 From: winscripter <142818255+winscripter@users.noreply.github.com> Date: Sat, 18 Jul 2026 16:21:25 +0400 Subject: [PATCH] Implement visitor for JxlBitDepth --- .../Formats/Jxl/Metadata/JxlBitDepth.cs | 93 ++++++++++++++++++- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Jxl/Metadata/JxlBitDepth.cs b/src/ImageSharp/Formats/Jxl/Metadata/JxlBitDepth.cs index a60ac0f13..fd842b363 100644 --- a/src/ImageSharp/Formats/Jxl/Metadata/JxlBitDepth.cs +++ b/src/ImageSharp/Formats/Jxl/Metadata/JxlBitDepth.cs @@ -5,8 +5,19 @@ using SixLabors.ImageSharp.Formats.Jxl.Fields; namespace SixLabors.ImageSharp.Formats.Jxl.Metadata; +/// +/// Represents the JPEG XL Bit Depth image metadata. +/// internal sealed class JxlBitDepth : IJxlFields { + private uint bitsPerSample; + private uint exponentBitsPerSample; + + /// + /// Initializes a new instance of the class. + /// + public JxlBitDepth() => JxlBundle.Init(this); + /// /// Gets or sets a value indicating whether /// the original (uncompressed) samples are floating point or @@ -18,7 +29,11 @@ internal sealed class JxlBitDepth : IJxlFields /// Gets or sets the bit depth of the original (uncompressed) image samples. /// Must be in the range [1, 32]. /// - public int BitsPerSample { get; set; } + public uint BitsPerSample + { + get => this.bitsPerSample; + set => this.bitsPerSample = value; + } /// /// @@ -36,7 +51,79 @@ internal sealed class JxlBitDepth : IJxlFields /// [2, 8] and amount of mantissa bits must be in the range [2, 23]. /// /// - public int ExponentBitsPerSample { get; set; } + public uint ExponentBitsPerSample + { + get => this.exponentBitsPerSample; + set => this.exponentBitsPerSample = value; + } + + public bool Visit(JxlVisitor visitor) + { + if (!this.FloatingPointSample) + { + bool successful = visitor.U32( + JxlFieldExpressions.Value(8u), + JxlFieldExpressions.Value(10u), + JxlFieldExpressions.Value(12u), + JxlFieldExpressions.BitsOffset(6u, 1u), + 8u, + ref this.bitsPerSample); + + if (!successful) + { + return false; + } + + this.exponentBitsPerSample = 0; + } + else + { + if (!visitor.U32( + JxlFieldExpressions.Value(32u), + JxlFieldExpressions.Value(16u), + JxlFieldExpressions.Value(24u), + JxlFieldExpressions.BitsOffset(6u, 1u), + 32u, + ref this.bitsPerSample)) + { + return false; + } + + this.exponentBitsPerSample--; + + if (!visitor.Bits(4, 7, ref this.exponentBitsPerSample)) + { + return false; + } + + this.exponentBitsPerSample++; + } + + if (this.FloatingPointSample) + { + if (this.exponentBitsPerSample is < 2 or > 8) + { + DebugGuard.IsTrue(false, "Invalid exponent_bits_per_sample"); + + return false; + } + + int mantissaBits = (int)this.bitsPerSample - (int)this.exponentBitsPerSample - 1; + + if (mantissaBits is < 2 or > 23) + { + DebugGuard.IsTrue(false, "Invalid bits_per_sample"); + + return false; + } + } + else if (this.bitsPerSample > 31) + { + DebugGuard.IsTrue(false, "Invalid bits_per_sample"); + + return false; + } - public bool Visit(JxlVisitor visitor) => throw new NotImplementedException(); + return true; + } }