From d8e7078bb994fb197aca2d27d2468d930b9f2f54 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 23 Jun 2024 13:04:35 +0200 Subject: [PATCH] Implement reading AV1 Codec Configuration Record --- .../Formats/Heif/Av1/Av1CodecConfiguration.cs | 63 +++++++++++++++++++ .../Formats/Heif/HeifDecoderCore.cs | 6 +- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs b/src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs new file mode 100644 index 000000000..e0cef4775 --- /dev/null +++ b/src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs @@ -0,0 +1,63 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. +namespace SixLabors.ImageSharp.Formats.Heif.Av1; + +/// +/// Implementation of section 2.3.3 of AV1 Codec ISO Media File Format Binding specification v1.2.0. +/// See https://aomediacodec.github.io/av1-isobmff/v1.2.0.html#av1codecconfigurationbox-syntax. +/// +internal struct Av1CodecConfiguration +{ + public Av1CodecConfiguration(Span boxBuffer) + { + Av1BitStreamReader reader = new(boxBuffer); + + this.Marker = (byte)reader.ReadLiteral(1); + this.Version = (byte)reader.ReadLiteral(7); + this.SeqProfile = (byte)reader.ReadLiteral(3); + this.SeqLevelIdx0 = (byte)reader.ReadLiteral(5); + this.SeqTier0 = (byte)reader.ReadLiteral(1); + this.HighBitdepth = (byte)reader.ReadLiteral(1); + this.TwelveBit = reader.ReadLiteral(1) == 1; + this.MonoChrome = reader.ReadLiteral(1) == 1; + this.ChromaSubsamplingX = reader.ReadLiteral(1) == 1; + this.ChromaSubsamplingY = reader.ReadLiteral(1) == 1; + this.ChromaSamplePosition = (byte)reader.ReadLiteral(2); + + // 3 bits are reserved. + reader.ReadLiteral(3); + + this.InitialPresentationDelayPresent = reader.ReadLiteral(1) == 1; + if (this.InitialPresentationDelayPresent) + { + byte initialPresentationDelayMinusOne = (byte)reader.ReadLiteral(4); + this.InitialPresentationDelay = (byte)(initialPresentationDelayMinusOne + 1); + } + } + + public byte Marker { get; } + + public byte Version { get; } + + public byte SeqProfile { get; } + + public byte SeqLevelIdx0 { get; } + + public byte SeqTier0 { get; } + + public byte HighBitdepth { get; } + + public bool TwelveBit { get; } + + public bool MonoChrome { get; } + + public bool ChromaSubsamplingX { get; } + + public bool ChromaSubsamplingY { get; } + + public byte ChromaSamplePosition { get; } + + public bool InitialPresentationDelayPresent { get; } + + public byte InitialPresentationDelay { get; } +} diff --git a/src/ImageSharp/Formats/Heif/HeifDecoderCore.cs b/src/ImageSharp/Formats/Heif/HeifDecoderCore.cs index 7aeeac56b..bfc397bf8 100644 --- a/src/ImageSharp/Formats/Heif/HeifDecoderCore.cs +++ b/src/ImageSharp/Formats/Heif/HeifDecoderCore.cs @@ -1,11 +1,11 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System; using System.Buffers; using System.Buffers.Binary; using System.Text; using SixLabors.ImageSharp.Formats.Heif.Av1; -using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata; @@ -35,6 +35,8 @@ internal sealed class HeifDecoderCore : IImageDecoderInternals private readonly List itemLinks; + private Av1CodecConfiguration av1CodecConfiguration; + /// /// Initializes a new instance of the class. /// @@ -475,6 +477,8 @@ internal sealed class HeifDecoderCore : IImageDecoderInternals case Heif4CharCode.Iscl: case Heif4CharCode.HvcC: case Heif4CharCode.Av1C: + this.av1CodecConfiguration = new(boxBuffer); + break; case Heif4CharCode.Rloc: case Heif4CharCode.Udes: // TODO: Implement