diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs index 83dddd2fe..3c7349b19 100644 --- a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs +++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs @@ -7,8 +7,15 @@ internal class ObuColorConfig { public bool IsColorDescriptionPresent { get; set; } - public int ChannelCount { get; set; } - + /// + /// Gets or sets the number of color channels in this image. + /// + public int PlaneCount { get; set; } + + /// + /// Gets or sets a value indicating whether the image has a single greyscale plane, will have + /// color planes otherwise. + /// public bool IsMonochrome { get; set; } public ObuColorPrimaries ColorPrimaries { get; set; } diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs index d5e4ae4cc..fc3b19d31 100644 --- a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs +++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs @@ -465,7 +465,7 @@ internal class ObuReader colorConfig.IsMonochrome = reader.ReadBoolean(); } - colorConfig.ChannelCount = colorConfig.IsMonochrome ? 1 : 3; + colorConfig.PlaneCount = colorConfig.IsMonochrome ? 1 : Av1Constants.MaxPlanes; colorConfig.IsColorDescriptionPresent = reader.ReadBoolean(); colorConfig.ColorPrimaries = ObuColorPrimaries.Unspecified; colorConfig.TransferCharacteristics = ObuTransferCharacteristics.Unspecified; @@ -1191,7 +1191,7 @@ internal class ObuReader /// private void ReadFrameHeader(ref Av1BitStreamReader reader, ObuHeader header, bool trailingBit) { - int planeCount = this.SequenceHeader!.ColorConfig.IsMonochrome ? 1 : 3; + int planeCount = this.SequenceHeader!.ColorConfig.PlaneCount; int startBitPosition = reader.BitPosition; this.ReadUncompressedFrameHeader(ref reader, header, planeCount); if (trailingBit) diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs index 4a154da0e..1b704309d 100644 --- a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs +++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs @@ -112,6 +112,7 @@ internal class ObuWriter writer.WriteBoolean(colorConfig.IsMonochrome); } + colorConfig.PlaneCount = colorConfig.IsMonochrome ? 1 : Av1Constants.MaxPlanes; writer.WriteBoolean(false); // colorConfig.IsColorDescriptionPresent if (colorConfig.IsMonochrome) { diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs index ee82adced..111deae1f 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs @@ -50,7 +50,7 @@ internal class Av1ParseAboveNeighbor4x4Context public void Clear(ObuSequenceHeader sequenceHeader, int modeInfoColumnStart, int modeInfoColumnEnd) { - int planeCount = sequenceHeader.ColorConfig.ChannelCount; + int planeCount = sequenceHeader.ColorConfig.PlaneCount; int width = modeInfoColumnEnd - modeInfoColumnStart; Array.Fill(this.AboveTransformWidth, Av1TransformSize.Size64x64.GetWidth(), 0, width); Array.Fill(this.AbovePartitionWidth, 0, 0, width); diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs index 7ce7beb62..8e034f6e9 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs @@ -50,7 +50,7 @@ internal class Av1ParseLeftNeighbor4x4Context public void Clear(ObuSequenceHeader sequenceHeader) { int blockCount = sequenceHeader.SuperblockModeInfoSize; - int planeCount = sequenceHeader.ColorConfig.ChannelCount; + int planeCount = sequenceHeader.ColorConfig.PlaneCount; int neighbor4x4Count = sequenceHeader.SuperblockModeInfoSize; Array.Fill(this.LeftTransformHeight, Av1TransformSize.Size64x64.GetHeight(), 0, blockCount); Array.Fill(this.LeftPartitionHeight, 0, 0, blockCount); diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs index 66484a06a..5cb054682 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs @@ -52,7 +52,7 @@ internal class Av1TileDecoder : IAv1TileDecoder // reallocate_parse_context_memory // Hard code number of threads to 1 for now. - int planesCount = sequenceHeader.ColorConfig.IsMonochrome ? 1 : Av1Constants.MaxPlanes; + int planesCount = sequenceHeader.ColorConfig.PlaneCount; int superblockColumnCount = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, sequenceHeader.SuperblockSizeLog2) >> sequenceHeader.SuperblockSizeLog2; int modeInfoWideColumnCount = superblockColumnCount * sequenceHeader.SuperblockModeInfoSize; @@ -84,7 +84,7 @@ internal class Av1TileDecoder : IAv1TileDecoder int modeInfoRowEnd = this.FrameInfo.TilesInfo.TileRowStartModeInfo[tileRowIndex + 1]; this.aboveNeighborContext.Clear(this.SequenceHeader, modeInfoColumnStart, modeInfoColumnEnd); this.ClearLoopFilterDelta(); - int planesCount = this.SequenceHeader.ColorConfig.ChannelCount; + int planesCount = this.SequenceHeader.ColorConfig.PlaneCount; // Default initialization of Wiener and SGR Filter. this.referenceSgrXqd = new int[planesCount][]; @@ -138,7 +138,7 @@ internal class Av1TileDecoder : IAv1TileDecoder private void ReadLoopRestoration(Point modeInfoLocation, Av1BlockSize superBlockSize) { - int planesCount = this.SequenceHeader.ColorConfig.ChannelCount; + int planesCount = this.SequenceHeader.ColorConfig.PlaneCount; for (int plane = 0; plane < planesCount; plane++) { if (this.FrameInfo.LoopRestorationParameters[plane].Type != ObuRestorationType.None) @@ -290,7 +290,7 @@ internal class Av1TileDecoder : IAv1TileDecoder int columnIndex = modeInfoLocation.X; int block4x4Width = blockSize.Get4x4WideCount(); int block4x4Height = blockSize.Get4x4HighCount(); - int planesCount = this.SequenceHeader.ColorConfig.ChannelCount; + int planesCount = this.SequenceHeader.ColorConfig.PlaneCount; Point superblockLocation = superblockInfo.Position * this.SequenceHeader.SuperblockModeInfoSize; Point locationInSuperblock = new Point(modeInfoLocation.X - superblockLocation.X, modeInfoLocation.Y - superblockLocation.Y); Av1BlockModeInfo blockModeInfo = new(planesCount, blockSize, locationInSuperblock); @@ -341,7 +341,7 @@ internal class Av1TileDecoder : IAv1TileDecoder private void ResetSkipContext(Av1PartitionInfo partitionInfo) { - int planesCount = this.SequenceHeader.ColorConfig.IsMonochrome ? 1 : 3; + int planesCount = this.SequenceHeader.ColorConfig.PlaneCount; for (int i = 0; i < planesCount; i++) { bool subX = i > 0 && this.SequenceHeader.ColorConfig.SubSamplingX; @@ -368,7 +368,7 @@ internal class Av1TileDecoder : IAv1TileDecoder int modeUnitBlocksHigh = maxUnitSize.GetHeight() >> 2; modeUnitBlocksWide = Math.Min(maxBlocksWide, modeUnitBlocksWide); modeUnitBlocksHigh = Math.Min(maxBlocksHigh, modeUnitBlocksHigh); - int planeCount = this.SequenceHeader.ColorConfig.ChannelCount; + int planeCount = this.SequenceHeader.ColorConfig.PlaneCount; bool isLossless = this.FrameInfo.LosslessArray[partitionInfo.ModeInfo.SegmentId]; bool isLosslessBlock = isLossless && (blockSize >= Av1BlockSize.Block64x64) && (blockSize <= Av1BlockSize.Block128x128); int subSampling = (this.SequenceHeader.ColorConfig.SubSamplingX ? 1 : 0) + (this.SequenceHeader.ColorConfig.SubSamplingY ? 1 : 0); @@ -1734,7 +1734,7 @@ internal class Av1TileDecoder : IAv1TileDecoder int frameLoopFilterCount = 1; if (this.FrameInfo.DeltaLoopFilterParameters.IsMulti) { - frameLoopFilterCount = this.SequenceHeader.ColorConfig.ChannelCount > 1 ? Av1Constants.FrameLoopFilterCount : Av1Constants.FrameLoopFilterCount - 2; + frameLoopFilterCount = this.SequenceHeader.ColorConfig.PlaneCount > 1 ? Av1Constants.FrameLoopFilterCount : Av1Constants.FrameLoopFilterCount - 2; } Span currentDeltaLoopFilter = partitionInfo.SuperblockInfo.SuperblockDeltaLoopFilter;