Browse Source

Complete HEVC Range Extensions profile matrix

pull/2633/head
James Jackson-South 4 days ago
parent
commit
9d7348efd6
  1. 44
      src/ImageSharp/Formats/Heif/Hevc/HevcCodingTreeState.cs
  2. 8
      src/ImageSharp/Formats/Heif/Hevc/HevcPictureDecoder.Deblocking.cs
  3. 5
      src/ImageSharp/Formats/Heif/Hevc/HevcPictureDecoder.Prediction.cs
  4. 3
      src/ImageSharp/Formats/Heif/Hevc/HevcPictureDecoder.Traversal.cs
  5. 215
      tests/ImageSharp.Tests/Formats/Heif/Hevc/HevcPictureDecoderTests.cs
  6. 24
      tests/ImageSharp.Tests/TestImages.cs
  7. 3
      tests/Images/Input/Heif/Hevc/Conformance/ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2_frame0.bit
  8. 3
      tests/Images/Input/Heif/Hevc/Conformance/Bitdepth_A_RExt_Sony_1_frame0.bit
  9. 3
      tests/Images/Input/Heif/Hevc/Conformance/Bitdepth_B_RExt_Sony_1_frame0.bit
  10. 3
      tests/Images/Input/Heif/Hevc/Conformance/CCP_10bit_RExt_QCOM_frame0.bit
  11. 3
      tests/Images/Input/Heif/Hevc/Conformance/CCP_12bit_RExt_QCOM_frame0.bit
  12. 3
      tests/Images/Input/Heif/Hevc/Conformance/CCP_8bit_RExt_QCOM_frame0.bit
  13. 3
      tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit
  14. 3
      tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1_extended.bit
  15. 3
      tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit
  16. 3
      tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit
  17. 3
      tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit
  18. 3
      tests/Images/Input/Heif/Hevc/Conformance/IPCM_A_RExt_NEC_2_frame0.bit
  19. 3
      tests/Images/Input/Heif/Hevc/Conformance/IPCM_B_RExt_NEC_frame0.bit
  20. 3
      tests/Images/Input/Heif/Hevc/Conformance/Main_422_10_A_RExt_Sony_2_frame0.bit
  21. 3
      tests/Images/Input/Heif/Hevc/Conformance/Main_422_10_B_RExt_Sony_2_frame0.bit
  22. 3
      tests/Images/Input/Heif/Hevc/Conformance/PERSIST_RPARAM_A_RExt_Sony_3_frame0.bit
  23. 35
      tests/Images/Input/Heif/Hevc/Conformance/README.md
  24. 3
      tests/Images/Input/Heif/Hevc/Conformance/TSCTX_10bit_I_RExt_SHARP_1_frame0.bit
  25. 3
      tests/Images/Input/Heif/Hevc/Conformance/TSCTX_12bit_I_RExt_SHARP_1_frame0.bit
  26. 3
      tests/Images/Input/Heif/Hevc/Conformance/TSCTX_8bit_I_RExt_SHARP_1_frame0.bit
  27. 3
      tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_10Bit422Test_HIGH_TP_444_10BIT_RExt_Apple_2_frame0.bit
  28. 3
      tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit
  29. 3
      tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_AND_CABAC_EXT_PREC_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit
  30. 3
      tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit
  31. 3
      tests/Images/Input/Heif/Hevc/Conformance/WPP_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit

44
src/ImageSharp/Formats/Heif/Hevc/HevcCodingTreeState.cs

@ -30,16 +30,6 @@ internal sealed class HevcCodingTreeState : IDisposable
/// </summary>
private readonly Buffer2D<sbyte> quantizationParameters;
/// <summary>
/// The combined picture, slice, and coding-unit Cb quantization offsets at minimum-coding-block resolution.
/// </summary>
private readonly Buffer2D<sbyte> chromaBlueQuantizationOffsets;
/// <summary>
/// The combined picture, slice, and coding-unit Cr quantization offsets at minimum-coding-block resolution.
/// </summary>
private readonly Buffer2D<sbyte> chromaRedQuantizationOffsets;
/// <summary>
/// The packed bypass and PCM flags at minimum-coding-block resolution.
/// </summary>
@ -63,8 +53,6 @@ internal sealed class HevcCodingTreeState : IDisposable
Buffer2D<byte>? depths = null;
Buffer2D<sbyte>? quantizationParameters = null;
Buffer2D<sbyte>? chromaBlueQuantizationOffsets = null;
Buffer2D<sbyte>? chromaRedQuantizationOffsets = null;
Buffer2D<byte>? flags = null;
try
{
@ -76,29 +64,17 @@ internal sealed class HevcCodingTreeState : IDisposable
this.WidthInMinCodingBlocks,
this.HeightInMinCodingBlocks);
chromaBlueQuantizationOffsets = configuration.MemoryAllocator.Allocate2D<sbyte>(
this.WidthInMinCodingBlocks,
this.HeightInMinCodingBlocks);
chromaRedQuantizationOffsets = configuration.MemoryAllocator.Allocate2D<sbyte>(
this.WidthInMinCodingBlocks,
this.HeightInMinCodingBlocks);
flags = configuration.MemoryAllocator.Allocate2D<byte>(
this.WidthInMinCodingBlocks,
this.HeightInMinCodingBlocks);
this.depths = depths;
this.quantizationParameters = quantizationParameters;
this.chromaBlueQuantizationOffsets = chromaBlueQuantizationOffsets;
this.chromaRedQuantizationOffsets = chromaRedQuantizationOffsets;
this.flags = flags;
}
catch
{
flags?.Dispose();
chromaRedQuantizationOffsets?.Dispose();
chromaBlueQuantizationOffsets?.Dispose();
quantizationParameters?.Dispose();
depths?.Dispose();
throw;
@ -155,8 +131,6 @@ internal sealed class HevcCodingTreeState : IDisposable
/// <param name="log2Size">The base-two logarithm of the square coding-unit size.</param>
/// <param name="depth">The coding-tree depth.</param>
/// <param name="quantizationParameter">The effective luma quantization parameter.</param>
/// <param name="chromaBlueQuantizationOffset">The combined Cb quantization-parameter offset.</param>
/// <param name="chromaRedQuantizationOffset">The combined Cr quantization-parameter offset.</param>
/// <param name="transquantBypass">A value indicating whether transform and quantization are bypassed.</param>
/// <param name="pcm">A value indicating whether the coding unit contains pulse-code-modulated samples.</param>
public void SetCodingUnit(
@ -165,8 +139,6 @@ internal sealed class HevcCodingTreeState : IDisposable
int log2Size,
int depth,
int quantizationParameter,
int chromaBlueQuantizationOffset,
int chromaRedQuantizationOffset,
bool transquantBypass,
bool pcm)
{
@ -183,8 +155,6 @@ internal sealed class HevcCodingTreeState : IDisposable
{
this.depths.DangerousGetRowSpan(row)[unitX..endX].Fill((byte)depth);
this.quantizationParameters.DangerousGetRowSpan(row)[unitX..endX].Fill((sbyte)quantizationParameter);
this.chromaBlueQuantizationOffsets.DangerousGetRowSpan(row)[unitX..endX].Fill((sbyte)chromaBlueQuantizationOffset);
this.chromaRedQuantizationOffsets.DangerousGetRowSpan(row)[unitX..endX].Fill((sbyte)chromaRedQuantizationOffset);
this.flags.DangerousGetRowSpan(row)[unitX..endX].Fill(packedFlags);
}
}
@ -207,18 +177,6 @@ internal sealed class HevcCodingTreeState : IDisposable
public int GetQuantizationParameter(int x, int y)
=> this.quantizationParameters.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2];
/// <summary>
/// Gets the combined chroma quantization-parameter offset at a luma sample coordinate.
/// </summary>
/// <param name="plane">The Cb or Cr reconstruction plane.</param>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns>The selected picture, slice, and coding-unit offset.</returns>
public int GetChromaQuantizationOffset(HevcPlane plane, int x, int y)
=> plane == HevcPlane.Cb
? this.chromaBlueQuantizationOffsets.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2]
: this.chromaRedQuantizationOffsets.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2];
/// <summary>
/// Gets a value indicating whether the coding unit at a luma sample coordinate bypasses transform and quantization.
/// </summary>
@ -246,8 +204,6 @@ internal sealed class HevcCodingTreeState : IDisposable
{
this.depths.Dispose();
this.quantizationParameters.Dispose();
this.chromaBlueQuantizationOffsets.Dispose();
this.chromaRedQuantizationOffsets.Dispose();
this.flags.Dispose();
}

8
src/ImageSharp/Formats/Heif/Hevc/HevcPictureDecoder.Deblocking.cs

@ -246,7 +246,13 @@ internal sealed partial class HevcPictureDecoder
int quantizationParameterP = codingTreeState.GetQuantizationParameter(pX, pY);
int quantizationParameterQ = codingTreeState.GetQuantizationParameter(qX, qY);
int averageQuantizationParameter = (quantizationParameterP + quantizationParameterQ + 1) >> 1;
int componentOffset = codingTreeState.GetChromaQuantizationOffset(plane, qX, qY);
// Chroma deblocking uses only the picture-level component offset. Slice offsets and the RExt
// coding-unit adjustment affect inverse quantization, but H.265 excludes both from tc derivation.
int componentOffset = plane == HevcPlane.Cb
? this.pictureParameterSet.ChromaCbQuantizationParameterOffset
: this.pictureParameterSet.ChromaCrQuantizationParameterOffset;
int chromaQuantizationParameter = HevcQuantizationParameters.GetChromaQuantizationParameter(
averageQuantizationParameter,
componentOffset,

5
src/ImageSharp/Formats/Heif/Hevc/HevcPictureDecoder.Prediction.cs

@ -215,12 +215,15 @@ internal sealed partial class HevcPictureDecoder
int bitDepth,
int regionId)
{
// PCM samples can use fewer bits than the reconstructed component. H.265 places those bits at the
// most-significant end of the component range, so the raw code value must be restored before filtering.
int bitDepthShift = this.Picture.GetBitDepth(plane) - bitDepth;
for (int row = 0; row < height; row++)
{
Span<ushort> destination = this.Picture.GetRowSpan(plane, y + row).Slice(x, width);
for (int column = 0; column < width; column++)
{
destination[column] = reader.ReadPcmSample(bitDepth);
destination[column] = (ushort)(reader.ReadPcmSample(bitDepth) << bitDepthShift);
}
}

3
src/ImageSharp/Formats/Heif/Hevc/HevcPictureDecoder.Traversal.cs

@ -351,15 +351,12 @@ internal sealed partial class HevcPictureDecoder
default);
}
HevcQuantizationParameters quantizationParameters = this.CreateQuantizationParameters();
this.codingTreeStates[colorPlaneIndex].SetCodingUnit(
x,
y,
log2Size,
depth,
this.currentQuantizationParameter,
quantizationParameters.CbOffset,
quantizationParameters.CrOffset,
transquantBypass,
pcm);

215
tests/ImageSharp.Tests/Formats/Heif/Hevc/HevcPictureDecoderTests.cs

@ -137,6 +137,68 @@ public class HevcPictureDecoderTests
EntryPoints = 16,
}
/// <summary>
/// Identifies Range Extensions syntax that an official independently decoded picture must exercise.
/// </summary>
[Flags]
public enum RangeExtensionTools
{
/// <summary>
/// No additional tool assertion is required beyond the profile, precision, chroma layout, and plane hashes.
/// </summary>
None = 0,
/// <summary>
/// Cross-component residual prediction is enabled.
/// </summary>
CrossComponentPrediction = 1,
/// <summary>
/// Luma and chroma use different sample precisions.
/// </summary>
UnequalBitDepth = 2,
/// <summary>
/// Persistent Golomb-Rice adaptation is enabled.
/// </summary>
PersistentRice = 4,
/// <summary>
/// Extended-precision transform processing is enabled.
/// </summary>
ExtendedPrecision = 8,
/// <summary>
/// Pulse-code-modulated coding units are enabled.
/// </summary>
Pcm = 16,
/// <summary>
/// Transform-skip-specific coefficient contexts are enabled.
/// </summary>
TransformSkipContext = 32,
/// <summary>
/// Tile entry points are enabled.
/// </summary>
Tiles = 64,
/// <summary>
/// Wavefront row entry points are enabled.
/// </summary>
Wavefront = 128,
/// <summary>
/// CABAC bypass bins are byte-aligned.
/// </summary>
CabacBypassAlignment = 256,
/// <summary>
/// A coding-unit chroma quantization-offset list is enabled.
/// </summary>
ChromaQuantizationAdjustment = 512,
}
/// <summary>
/// Verifies the first independently coded picture from official ITU RExt conformance streams against its
/// published decoded-picture hashes.
@ -168,7 +230,7 @@ public class HevcPictureDecoderTests
{
byte[] annexB = TestFile.Create(path).Bytes;
byte[] expectedYuv = TestFile.Create($"{path[..^4]}_frame0.yuv").Bytes;
ConvertAnnexBStillPicture(annexB, bitDepth, chromaFormat, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, bitDepth, bitDepth, chromaFormat, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcSliceSegmentHeader sliceHeader = bitstream.SliceSegments[0];
@ -206,6 +268,127 @@ public class HevcPictureDecoderTests
}
}
/// <summary>
/// Verifies the remaining supported Range Extensions profiles and independently coded tools against normative
/// decoded-picture hashes or first pictures from published reference output.
/// </summary>
/// <param name="path">The provenance-preserving extracted Annex B picture.</param>
/// <param name="bitDepthLuma">The signaled luma precision.</param>
/// <param name="bitDepthChroma">The signaled chroma precision.</param>
/// <param name="chromaFormat">The signaled HEVC chroma-format identifier.</param>
/// <param name="profileIdc">The signaled HEVC profile identifier.</param>
/// <param name="requiredTools">The Range Extensions syntax that the retained picture must enable.</param>
/// <param name="lumaDigest">The normative luma-plane MD5 digest.</param>
/// <param name="chromaBlueDigest">The normative blue-difference-plane MD5 digest.</param>
/// <param name="chromaRedDigest">The normative red-difference-plane MD5 digest.</param>
[Theory]
[InlineData(TestImages.Heif.RangeExtensionChromaAngle422, 10, 10, 2, 4, RangeExtensionTools.None, "90085930ec5de68c8e0c95ed59ec0ce4", "a2053b886e4d2b26569472c4e65865ca", "82fc61a1450dc6df0b87d1e17c4d66db")]
[InlineData(TestImages.Heif.RangeExtensionCrossComponent8Bit444, 8, 8, 3, 4, RangeExtensionTools.CrossComponentPrediction, "ab4619c33dc1f67d332ec1945acab23f", "2cc70454f33f32f97c7ecf244d858398", "c54605014b2e9133d66867bf572c3ac6")]
[InlineData(TestImages.Heif.RangeExtensionCrossComponent10Bit444, 10, 10, 3, 4, RangeExtensionTools.CrossComponentPrediction, "daa07e34beaa525d416211025b9ee73d", "7ca36368377b0c02cdf53767ea43c36a", "d2a777f65e1fe6c2e638ae0d4f8ad884")]
[InlineData(TestImages.Heif.RangeExtensionCrossComponent12Bit444, 12, 12, 3, 4, RangeExtensionTools.CrossComponentPrediction, "7bed50ae49c39dd30e1085e7578d3555", "d2a06b27ddfba5fd2f14463f5d88e10d", "1a06a414d88ec6a7819a464021b1e935")]
[InlineData(TestImages.Heif.RangeExtensionLuma12Chroma8, 12, 8, 3, 4, RangeExtensionTools.UnequalBitDepth, "c8a92f6c83830232615157130460aa52", "1a88d067a709f8d4ee66e608edcf1454", "7582e448a0ca0ec91d84e86264048c58")]
[InlineData(TestImages.Heif.RangeExtensionLuma8Chroma12, 8, 12, 3, 4, RangeExtensionTools.UnequalBitDepth, "0f0b9d9ae27e541854f985d2b4f1cb8c", "a1834614ecd2d873cf748af0d182fccd", "cc733d65275087e6ad480f98150139e5")]
[InlineData(TestImages.Heif.ExtendedPrecision8Bit444, 8, 8, 3, 4, RangeExtensionTools.ExtendedPrecision, "abef53fa20dab9ab755b51b6eafac2a8", "eb3fb765be767658b515ce4260a011e9", "e9f741b608b8c2c8efa4607c5fee6664")]
[InlineData(TestImages.Heif.ExtendedPrecision10Bit444, 10, 10, 3, 4, RangeExtensionTools.ExtendedPrecision, "0a6955b11ede15c22279186dcef5f75e", "3de15052d5e92ffc8cc98db58ed3db5c", "bfe0b418ca96bafc86953d9e0065315b")]
[InlineData(TestImages.Heif.ExtendedPrecision12Bit444, 12, 12, 3, 4, RangeExtensionTools.ExtendedPrecision, "c8664d56d8391b236a8347397eb97a08", "08cd345d8798ac2714b2939462ac45e2", "5424bce4562f298e983302da697db849")]
[InlineData(TestImages.Heif.HighThroughputExtendedPrecision8Bit444, 8, 8, 3, 5, RangeExtensionTools.ExtendedPrecision, "ca77f9c29a2d25266d33d77bea0edc66", "473d1bd93cfebffa04f99cfe7e37eb0d", "8ab614af0526c77685ade3c9bbde2510")]
[InlineData(TestImages.Heif.HighThroughputExtendedPrecision10Bit444, 10, 10, 3, 5, RangeExtensionTools.ExtendedPrecision, "635507721877b619dc04593abafcfb1d", "d486efd70d9d3cbc3bcd2110abab6e87", "2b9966cd21c5b1fba41e3c793a40ebcb")]
[InlineData(TestImages.Heif.HighThroughputExtendedPrecision12Bit444, 12, 12, 3, 5, RangeExtensionTools.ExtendedPrecision, "cf547552a75b5e7b819937b82abf7985", "f2b863051a7c8f9af29bddd18401f291", "39a89074bc70d212dfe082ce544a43a0")]
[InlineData(TestImages.Heif.RangeExtensionPcm10Bit422, 10, 10, 2, 4, RangeExtensionTools.Pcm, "32248d41f772b2f69ae921d59b19f878", "678aec54e4b2af3578d06eefd8d6d097", "072613ebc1393dc2a5c17f882d1476f1")]
[InlineData(TestImages.Heif.RangeExtensionPcm12Bit444, 12, 12, 3, 4, RangeExtensionTools.Pcm, "0d91f6c4b691e47f48cf039b6c948d50", "5578d8774855b2a52f26cffda0edf10c", "e7860063b7b05ff55cf8ad981d08ee0f")]
[InlineData(TestImages.Heif.PersistentRice12Bit444, 12, 12, 3, 4, RangeExtensionTools.PersistentRice, "ddea37dedd9b541aaf371351d73e821b", "eb611e94654b76eb14fbcf20295a33ec", "b1655845f49114550fd26ab722ccc335")]
[InlineData(TestImages.Heif.TransformSkipContext8Bit444, 8, 8, 3, 4, RangeExtensionTools.TransformSkipContext, "c148a3f5610b0ec1369b702fc1383445", "82b10517c01f4fe5ca0aa19f5f8f2a0a", "29a841e63b5bf84fd9f8734dcc5df4e7")]
[InlineData(TestImages.Heif.TransformSkipContext10Bit444, 10, 10, 3, 4, RangeExtensionTools.TransformSkipContext, "006f3314efb25b15adc1c734fe7845b0", "99fa977f7603eeaa4981d9ac08b5aec1", "16aa20a082b534aec5e91bc9924060d3")]
[InlineData(TestImages.Heif.TransformSkipContext12Bit444, 12, 12, 3, 4, RangeExtensionTools.TransformSkipContext, "f26cffd119796bcbd2c4730eac6cc0c7", "e12a6a3faccadc8cf77952a7ef443c27", "f96fff6246848c9bd6808d65d1f3337d")]
[InlineData(TestImages.Heif.Main42210A, 10, 10, 2, 4, RangeExtensionTools.ChromaQuantizationAdjustment, "41746faffb59051c7b9002d7c79dc05d", "5180c8020b597bc66d0c1ec3a35656f6", "44140b531120e0737afc57fb25d16207")]
[InlineData(TestImages.Heif.Main42210B, 10, 10, 2, 4, RangeExtensionTools.ChromaQuantizationAdjustment, "845e930817261106c8edb352a1cdc9d6", "ca1e0aa4fd8ea6ba6ebacb3997bc32d1", "4377426b33fee59375d9dedd3b1eee9b")]
[InlineData(TestImages.Heif.HighThroughput10Bit422TilesWavefront, 10, 10, 2, 5, RangeExtensionTools.Tiles | RangeExtensionTools.Wavefront, "efd80653065c89989303827c56eca1ad", "7966084cebcd537109bf49084de31ced", "8030bdf42331b9a1033d0c62ce3ea452")]
[InlineData(TestImages.Heif.HighThroughput8Bit420TilesWavefront, 8, 8, 1, 5, RangeExtensionTools.Tiles | RangeExtensionTools.Wavefront, "6a99581bc96d002befb1bc6ef1c610aa", "79c51aa1ea347d81edcd7a2128e14060", "103dcfa2c88f4d98a24044a0e283cf87")]
[InlineData(TestImages.Heif.HighThroughput8Bit420Wavefront, 8, 8, 1, 5, RangeExtensionTools.Wavefront, "6b7404a197543d0adb7a2711b04273c2", "2f0e9ce1af96ff80ad2c5028d0109685", "a5d0b489441120fe235b7110f4fcaa45")]
[InlineData(TestImages.Heif.HighThroughput8Bit420CabacBypassAlignment, 8, 8, 1, 5, RangeExtensionTools.Tiles | RangeExtensionTools.Wavefront | RangeExtensionTools.CabacBypassAlignment, "6a783152cea8c612766d2173f2a30c5b", "9329df9e4ad589dfc24ac64acc9db1ea", "b01428a538cd555d61a9d3e950faf1cd")]
[InlineData(TestImages.Heif.HighThroughput8Bit420ExtendedPrecision, 8, 8, 1, 5, RangeExtensionTools.Tiles | RangeExtensionTools.Wavefront | RangeExtensionTools.ExtendedPrecision, "2e49cc92405a262f3b0065b764c96c7c", "f2f7073c45814147362ae156eadaaaa9", "b002b9b7a0da39301d112666ce4435d9")]
public void DecodeOfficialRangeExtensionProfilePictureMatchesDecodedPictureHash(
string path,
int bitDepthLuma,
int bitDepthChroma,
byte chromaFormat,
byte profileIdc,
RangeExtensionTools requiredTools,
string lumaDigest,
string chromaBlueDigest,
string chromaRedDigest)
{
byte[] annexB = TestFile.Create(path).Bytes;
ConvertAnnexBStillPicture(annexB, bitDepthLuma, bitDepthChroma, chromaFormat, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcPictureParameterSet pictureParameterSet = bitstream.SliceSegments[0].PictureParameterSet;
HevcSequenceParameterSet sequenceParameterSet = pictureParameterSet.SequenceParameterSet;
using HevcPictureDecoder decoder = new(Configuration.Default, pictureParameterSet);
decoder.Decode(bitstream);
Assert.Equal(profileIdc, sequenceParameterSet.ProfileTierLevel.ProfileIdc);
Assert.Equal(bitDepthLuma, decoder.Picture.BitDepthLuma);
Assert.Equal(bitDepthChroma, decoder.Picture.BitDepthChroma);
Assert.Equal(chromaFormat, decoder.Picture.ChromaFormat);
if ((requiredTools & RangeExtensionTools.CrossComponentPrediction) != 0)
{
Assert.True(pictureParameterSet.CrossComponentPredictionEnabled);
}
if ((requiredTools & RangeExtensionTools.UnequalBitDepth) != 0)
{
Assert.NotEqual(decoder.Picture.BitDepthLuma, decoder.Picture.BitDepthChroma);
}
if ((requiredTools & RangeExtensionTools.PersistentRice) != 0)
{
Assert.True(sequenceParameterSet.PersistentRiceAdaptationEnabled);
}
if ((requiredTools & RangeExtensionTools.ExtendedPrecision) != 0)
{
Assert.True(sequenceParameterSet.ExtendedPrecisionProcessingEnabled);
}
if ((requiredTools & RangeExtensionTools.Pcm) != 0)
{
Assert.True(sequenceParameterSet.PcmEnabled);
}
if ((requiredTools & RangeExtensionTools.TransformSkipContext) != 0)
{
Assert.True(pictureParameterSet.TransformSkipEnabled);
Assert.True(sequenceParameterSet.TransformSkipContextEnabled);
}
if ((requiredTools & RangeExtensionTools.Tiles) != 0)
{
Assert.True(pictureParameterSet.TilesEnabled);
}
if ((requiredTools & RangeExtensionTools.Wavefront) != 0)
{
Assert.True(pictureParameterSet.EntropyCodingSynchronizationEnabled);
}
if ((requiredTools & RangeExtensionTools.CabacBypassAlignment) != 0)
{
Assert.True(sequenceParameterSet.CabacBypassAlignmentEnabled);
}
if ((requiredTools & RangeExtensionTools.ChromaQuantizationAdjustment) != 0)
{
Assert.NotEmpty(pictureParameterSet.ChromaQuantizationParameterOffsetsCb);
Assert.NotEmpty(pictureParameterSet.ChromaQuantizationParameterOffsetsCr);
}
Assert.Equal(lumaDigest, GetPlaneDigest(decoder.Picture, HevcPlane.Y));
Assert.Equal(chromaBlueDigest, GetPlaneDigest(decoder.Picture, HevcPlane.Cb));
Assert.Equal(chromaRedDigest, GetPlaneDigest(decoder.Picture, HevcPlane.Cr));
}
/// <summary>
/// Verifies the official Main Still Picture stream containing every luma and chroma intra mode at every
/// conformance block size against its published native planar output.
@ -215,7 +398,7 @@ public class HevcPictureDecoderTests
{
byte[] annexB = TestFile.Create(TestImages.Heif.IntraPredictionB).Bytes;
byte[] expectedYuv = TestFile.Create(TestImages.Heif.IntraPredictionBReference).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcPictureParameterSet pictureParameterSet = bitstream.SliceSegments[0].PictureParameterSet;
@ -252,7 +435,7 @@ public class HevcPictureDecoderTests
public void DecodeOfficialConstrainedIntraPictureMatchesPublishedDigest()
{
byte[] annexB = TestFile.Create(TestImages.Heif.ConstrainedIntraPredictionA).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcPictureParameterSet pictureParameterSet = bitstream.SliceSegments[0].PictureParameterSet;
@ -296,7 +479,7 @@ public class HevcPictureDecoderTests
string chromaRedDigest)
{
byte[] annexB = TestFile.Create(path).Bytes;
ConvertAnnexBStillPicture(annexB, bitDepth, chromaFormat, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, bitDepth, bitDepth, chromaFormat, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcPictureParameterSet pictureParameterSet = bitstream.SliceSegments[0].PictureParameterSet;
@ -374,7 +557,7 @@ public class HevcPictureDecoderTests
public void DecodeOfficialLoopFilterPictureWithConstrainedAllocatorMatchesPinnedHmDigest()
{
byte[] annexB = TestFile.Create(TestImages.Heif.SampleAdaptiveOffsetA).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration codecConfiguration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, codecConfiguration);
TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 2_048 };
@ -468,7 +651,7 @@ public class HevcPictureDecoderTests
string chromaRedDigest)
{
byte[] annexB = TestFile.Create(path).Bytes;
ConvertAnnexBStillPicture(annexB, bitDepth, chromaFormat, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, bitDepth, bitDepth, chromaFormat, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcSliceSegmentHeader sliceHeader = bitstream.SliceSegments[0];
@ -520,7 +703,7 @@ public class HevcPictureDecoderTests
string chromaRedDigest)
{
byte[] annexB = TestFile.Create(path).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcSequenceParameterSet sequenceParameterSet = bitstream.SliceSegments[0].PictureParameterSet.SequenceParameterSet;
@ -578,7 +761,7 @@ public class HevcPictureDecoderTests
string chromaRedDigest)
{
byte[] annexB = TestFile.Create(path).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration configuration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, configuration);
HevcPictureParameterSet pictureParameterSet = bitstream.SliceSegments[0].PictureParameterSet;
@ -642,7 +825,7 @@ public class HevcPictureDecoderTests
string chromaRedDigest)
{
byte[] annexB = TestFile.Create(path).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration codecConfiguration = new(configurationData);
HevcImageItemBitstream bitstream = new(itemData, codecConfiguration);
TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 4_096 };
@ -781,7 +964,7 @@ public class HevcPictureDecoderTests
public void DecodeRejectsNonDisplayAndConflictingSupplementalMetadata()
{
byte[] annexB = TestFile.Create(TestImages.Heif.IntraPredictionB).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration codecConfiguration = new(configurationData);
HeifItem item = new(Heif4CharCode.Hvc1, 1) { HevcCodecConfiguration = codecConfiguration };
HevcHeifItemDecoder<Rgba32> itemDecoder = new();
@ -1061,7 +1244,7 @@ public class HevcPictureDecoderTests
// intrinsics, so the remote process cannot obtain the test's cancellation token.
CancellationToken cancellationToken = CancellationToken.None;
byte[] annexB = TestFile.Create(TestImages.Heif.IntraPredictionB).Bytes;
ConvertAnnexBStillPicture(annexB, 8, 1, out byte[] configurationData, out byte[] itemData);
ConvertAnnexBStillPicture(annexB, 8, 8, 1, out byte[] configurationData, out byte[] itemData);
HevcCodecConfiguration codecConfiguration = new(configurationData);
HeifItem item = new(Heif4CharCode.Hvc1, 1) { HevcCodecConfiguration = codecConfiguration };
byte[] supplementalItemData = PrependPrefixSeiNalUnit(itemData, SupplementalMetadataRbsp);
@ -1287,13 +1470,15 @@ public class HevcPictureDecoderTests
/// production decoder.
/// </summary>
/// <param name="annexB">The complete official conformance stream.</param>
/// <param name="bitDepth">The stream's published component precision.</param>
/// <param name="bitDepthLuma">The stream's published luma precision.</param>
/// <param name="bitDepthChroma">The stream's published chroma precision.</param>
/// <param name="chromaFormat">The stream's published chroma-format identifier.</param>
/// <param name="configurationData">The generated item-local HEVC decoder configuration.</param>
/// <param name="itemData">The generated length-delimited payload containing only the first picture.</param>
private static void ConvertAnnexBStillPicture(
ReadOnlySpan<byte> annexB,
int bitDepth,
int bitDepthLuma,
int bitDepthChroma,
byte chromaFormat,
out byte[] configurationData,
out byte[] itemData)
@ -1377,8 +1562,8 @@ public class HevcPictureDecoderTests
configurationData[13] = 0xF0; // reserved and min_spatial_segmentation_idc = 0
configurationData[15] = 0xFC; // reserved and parallelismType = 0
configurationData[16] = (byte)(0xFC | chromaFormat); // reserved and chromaFormat
configurationData[17] = (byte)(0xF8 | (bitDepth - 8)); // reserved and bitDepthLumaMinus8
configurationData[18] = (byte)(0xF8 | (chromaFormat == 0 ? 0 : bitDepth - 8)); // reserved and bitDepthChromaMinus8
configurationData[17] = (byte)(0xF8 | (bitDepthLuma - 8)); // reserved and bitDepthLumaMinus8
configurationData[18] = (byte)(0xF8 | (chromaFormat == 0 ? 0 : bitDepthChroma - 8)); // reserved and bitDepthChromaMinus8
int maxSubLayers = ((spsRbspPrefix[0] >> 1) & 7) + 1;
int temporalIdNesting = spsRbspPrefix[0] & 1;

24
tests/ImageSharp.Tests/TestImages.cs

@ -1304,6 +1304,30 @@ public static class TestImages
public const string General12Bit420 = "Heif/Hevc/Conformance/GENERAL_12b_420_RExt_Sony_1.bit";
public const string General12Bit422 = "Heif/Hevc/Conformance/GENERAL_12b_422_RExt_Sony_1.bit";
public const string General12Bit444 = "Heif/Hevc/Conformance/GENERAL_12b_444_RExt_Sony_2.bit";
public const string RangeExtensionChromaAngle422 = "Heif/Hevc/Conformance/ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2_frame0.bit";
public const string RangeExtensionCrossComponent8Bit444 = "Heif/Hevc/Conformance/CCP_8bit_RExt_QCOM_frame0.bit";
public const string RangeExtensionCrossComponent10Bit444 = "Heif/Hevc/Conformance/CCP_10bit_RExt_QCOM_frame0.bit";
public const string RangeExtensionCrossComponent12Bit444 = "Heif/Hevc/Conformance/CCP_12bit_RExt_QCOM_frame0.bit";
public const string RangeExtensionLuma12Chroma8 = "Heif/Hevc/Conformance/Bitdepth_A_RExt_Sony_1_frame0.bit";
public const string RangeExtensionLuma8Chroma12 = "Heif/Hevc/Conformance/Bitdepth_B_RExt_Sony_1_frame0.bit";
public const string ExtendedPrecision8Bit444 = "Heif/Hevc/Conformance/EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit";
public const string ExtendedPrecision10Bit444 = "Heif/Hevc/Conformance/EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit";
public const string HighThroughputExtendedPrecision8Bit444 = "Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit";
public const string HighThroughputExtendedPrecision10Bit444 = "Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit";
public const string HighThroughputExtendedPrecision12Bit444 = "Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1_extended.bit";
public const string RangeExtensionPcm10Bit422 = "Heif/Hevc/Conformance/IPCM_A_RExt_NEC_2_frame0.bit";
public const string RangeExtensionPcm12Bit444 = "Heif/Hevc/Conformance/IPCM_B_RExt_NEC_frame0.bit";
public const string PersistentRice12Bit444 = "Heif/Hevc/Conformance/PERSIST_RPARAM_A_RExt_Sony_3_frame0.bit";
public const string TransformSkipContext8Bit444 = "Heif/Hevc/Conformance/TSCTX_8bit_I_RExt_SHARP_1_frame0.bit";
public const string TransformSkipContext10Bit444 = "Heif/Hevc/Conformance/TSCTX_10bit_I_RExt_SHARP_1_frame0.bit";
public const string TransformSkipContext12Bit444 = "Heif/Hevc/Conformance/TSCTX_12bit_I_RExt_SHARP_1_frame0.bit";
public const string Main42210A = "Heif/Hevc/Conformance/Main_422_10_A_RExt_Sony_2_frame0.bit";
public const string Main42210B = "Heif/Hevc/Conformance/Main_422_10_B_RExt_Sony_2_frame0.bit";
public const string HighThroughput10Bit422TilesWavefront = "Heif/Hevc/Conformance/WPP_AND_TILE_10Bit422Test_HIGH_TP_444_10BIT_RExt_Apple_2_frame0.bit";
public const string HighThroughput8Bit420TilesWavefront = "Heif/Hevc/Conformance/WPP_AND_TILE_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit";
public const string HighThroughput8Bit420Wavefront = "Heif/Hevc/Conformance/WPP_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit";
public const string HighThroughput8Bit420CabacBypassAlignment = "Heif/Hevc/Conformance/WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit";
public const string HighThroughput8Bit420ExtendedPrecision = "Heif/Hevc/Conformance/WPP_AND_TILE_AND_CABAC_EXT_PREC_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit";
public const string IntraPredictionB = "Heif/Hevc/Conformance/IPRED_B_Nokia_3.bit";
public const string IntraPredictionBReference = "Heif/Hevc/Conformance/IPRED_B_Nokia_3.yuv";
public const string ConstrainedIntraPredictionA = "Heif/Hevc/Conformance/CIP_A_Panasonic_3.bit";

3
tests/Images/Input/Heif/Hevc/Conformance/ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56924b6d5c19e5147649973d13a5ddd83af402fd3dca41b2698d03515b4bb2d7
size 77368

3
tests/Images/Input/Heif/Hevc/Conformance/Bitdepth_A_RExt_Sony_1_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:19206fe90232d5cc99cadd70a663a303ec0a27f64539bbf155012461e8c14b8d
size 26723

3
tests/Images/Input/Heif/Hevc/Conformance/Bitdepth_B_RExt_Sony_1_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0e8bb3d6ad34078bd5319aebc52c4f64a3999cf6fb529808dc7e9a3d51a69c4b
size 26751

3
tests/Images/Input/Heif/Hevc/Conformance/CCP_10bit_RExt_QCOM_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e92952c1da523290592c98b766656964299bac330a357851980f71331b920ee4
size 44331

3
tests/Images/Input/Heif/Hevc/Conformance/CCP_12bit_RExt_QCOM_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:33c20dd58a4ae2e16e412bb00ec8def0d071ab6959a8821ea9410405c732ea4e
size 365428

3
tests/Images/Input/Heif/Hevc/Conformance/CCP_8bit_RExt_QCOM_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2bb969c41f2eb6664ba29bcbd71a094c76add86df6a2c6c49e90d1f3265952f2
size 28905

3
tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3572e1c350bd60ba6b0edd71bae1388ccd4d57a1c18c7d62439fa1661e33980c
size 149305

3
tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1_extended.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:15026126bbaa266f5551077bf1a29018ef11d5aa274ae3aadfd282184c1837b0
size 206758

3
tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5584b06fbf9affc87d3f1bffa56ecfadb892a80ed6468401a2acf46622444d66
size 93552

3
tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28f0fa43f8c9a5c80c2158b087ed030d8e3e8deac6819239ba84890302a8f30a
size 148045

3
tests/Images/Input/Heif/Hevc/Conformance/EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:abace12c9947acaaf91bf8e4cb8bf50cd5ff5b2a7ab5a14d9ee25fe2cdf6b746
size 92709

3
tests/Images/Input/Heif/Hevc/Conformance/IPCM_A_RExt_NEC_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:26ae7aefa4ded2ccdc917b99b5ecf2352bd9c7100ce0cfd9a9bdc918c5d242b6
size 4273

3
tests/Images/Input/Heif/Hevc/Conformance/IPCM_B_RExt_NEC_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:39f97b25079ce5f12340cce43c9dbd5821c5e23f44da58dd6f1942e135bc93b5
size 4973

3
tests/Images/Input/Heif/Hevc/Conformance/Main_422_10_A_RExt_Sony_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d6dd0506e85bfd17cfd8d676107927c2860d38d1e8b7e5486647279e6b33876
size 632639

3
tests/Images/Input/Heif/Hevc/Conformance/Main_422_10_B_RExt_Sony_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:951acc9c846dcb9f8ccbdc0b6971a947144baed2d9021ae4be77bcce106bbe21
size 1113811

3
tests/Images/Input/Heif/Hevc/Conformance/PERSIST_RPARAM_A_RExt_Sony_3_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b6a86ff4122512fda96ec6c4c7a143079eee5371760433c05428749140036cec
size 329271

35
tests/Images/Input/Heif/Hevc/Conformance/README.md

@ -6,7 +6,7 @@ The `.bit` files are the original Annex B conformance streams. The Samsung archi
`HevcPictureDecoderTests.DecodeOfficialRangeExtensionsPictureMatchesPublishedDigest` limits each stream to its first independently coded picture, adapts that picture to the bounded `hvc1` item contract, compares every reconstructed sample with `_frame0.yuv`, and verifies the published decoded-picture MD5 value for every present plane.
The retained matrix covers the ImageSharp 8, 10, and 12-bit still-image precision boundary across monochrome, 4:2:0, 4:2:2, and 4:4:4. Tool-specific H.265.1 streams remain necessary before every exposed Range Extensions tool can be marked complete.
The retained matrix covers the ImageSharp 8, 10, and 12-bit still-image precision boundary across monochrome, 4:2:0, 4:2:2, and 4:4:4. The tool-specific matrix below completes independently coded coverage for the exposed Range Extensions profiles and tools. Explicit residual DPCM remains with dependent-picture inter decoding because the normative syntax requires an inter prediction unit.
The Main-profile traversal matrix comes from the official `RQT_A_HHI_4` through `RQT_E_HHI_4`, `STRUCT_A_Samsung_7`, `STRUCT_B_Samsung_7`, and `TUSIZE_A_Samsung_1` archives. Their published descriptions target residual-quadtree intra hierarchy depths zero through four, coding-tree and minimum-coding-unit structure, and a 64x64 coding-tree block with 32x32 minimum coding units and 16x16 minimum luma transforms, respectively.
@ -31,6 +31,39 @@ The residual-reconstruction fixtures come from the official HEVC v1 and Range Ex
- `GENERAL_12b_444_RExt_Sony_2_idr7.bit` is the seventh independently coded picture extracted with its active VPS, SPS, and PPS from the already retained official GENERAL stream. It has SHA-256 `981D97F0ADC228F2E3A739D7A68161F84CD60309745397D5CF24D2F81C009DBC` and contains 39 coding-unit chroma-QP adjustment decisions across 8-, 16-, and 32-sample chroma transforms.
- `LS_A_Orange_2.bit` has SHA-256 `14251238F005A4576437429A327B34D216B346AAAC2A7A05C132A3430174B11B` and published MD5 `9118d01cf6b3671038d6f99342c0895e`. The official lossless description states that every coding unit uses transform, quantization, and filtering bypass; the retained first picture exercises the bypass-flag path and its decoded-picture hash reports OK.
The remaining Range Extensions fixtures come from the official H.265.1 RExt attachment. Each retained file contains the active VPS, SPS, and PPS followed by exactly one independently coded picture. For the extended-precision streams, the retained picture is the second concatenated one-picture sequence because that sequence enables extended-precision processing. `HevcPictureDecoderTests.DecodeOfficialRangeExtensionProfilePictureMatchesDecodedPictureHash` checks profile identifier, luma and chroma precision, chroma layout, required tool flags, and every native-plane MD5 through the production still-item decoder.
The expected plane hashes come directly from each selected picture's decoded-picture-hash SEI message when present. The CCP 8/10/12-bit, IPCM A/B, and Main 4:2:2 10 B streams omit that per-picture message. Their first reference pictures were extracted only after FFmpeg 9.0.1 reproduced the archives' published complete-output MD5 values `54231c6f121ca65d8b94a747b9504b8b`, `363f55fc6097a3bb7525392b87a6498a`, `f3e914fccdb820eac85f46642ea0e168`, `8d4eb18812338f9f475035b8da27e74a`, `eea32e6e1f88b7782515e53f8122be7d`, and `fd163bcbdc24792a23781ee7aace74eb`, respectively.
The SHA-256 columns below identify the downloaded archive, its original Annex B payload, and the retained bounded picture:
| Retained picture | Archive SHA-256 | Original payload SHA-256 | Retained SHA-256 |
| --- | --- | --- | --- |
| `ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2_frame0.bit` | `8C915B0554265CCD6FB1347B41788006DF9E7C66349FDEAA142D953340B12997` | `54B72F9B2F5BD7C25049A63FD4289AB19735AF5B30C2105DEDD7AA5AE90A72E8` | `56924B6D5C19E5147649973D13A5DDD83AF402FD3DCA41B2698D03515B4BB2D7` |
| `Bitdepth_A_RExt_Sony_1_frame0.bit` | `34967E2047D59B0F3E96E7501712A056C01F369501D812B170C717CE1D417368` | `0519F266D11FAD0A25878F29D5DAC153BA00629AACEF34ECD78F5F5AD0FB2174` | `19206FE90232D5CC99CADD70A663A303EC0A27F64539BBF155012461E8C14B8D` |
| `Bitdepth_B_RExt_Sony_1_frame0.bit` | `6F5F16377E9287CED1AD06A9493249ED1D61E393D779B06E777A92E14B6C6EB6` | `C8B03A11E8453E430E41BC499F686BE9E75CEF269F80CCAB85C971D048A91EA8` | `0E8BB3D6AD34078BD5319AEBC52C4F64A3999CF6FB529808DC7E9A3D51A69C4B` |
| `CCP_8bit_RExt_QCOM_frame0.bit` | `E5A0216C23F3816107441366B7743160BD0E6A39CE15B14A9FE1A3FFEA38BF88` | `C5E0D9B5E0062C2F4BFB1EC9E8A6465FB715E3AF498306D7D0E4BEC0BC9BAE5C` | `2BB969C41F2EB6664BA29BCBD71A094C76ADD86DF6A2C6C49E90D1F3265952F2` |
| `CCP_10bit_RExt_QCOM_frame0.bit` | `190AB9B4A9AADEE32ECFB639223156A3DEE721DBBA064C28574E176CE07FF032` | `6E40E49BA5BEF61D951C4088B0234DB20E1F264804C59A007B9F32A117A45603` | `E92952C1DA523290592C98B766656964299BAC330A357851980F71331B920EE4` |
| `CCP_12bit_RExt_QCOM_frame0.bit` | `E54417A143D59BA112D90355BE88E535761A22EC44C88BDA5C4913ED0B3CE7F3` | `17FD17F2449B4C44D4AFDADDAC9FE1A61B572E1BD4BF1FBDAC609E108A7F2BD3` | `33C20DD58A4AE2E16E412BB00EC8DEF0D071AB6959A8821EA9410405C732EA4E` |
| `EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit` | `7EBC6DB0E9BFBCEEEF1F168843E824CDD2B3A672C9574ECEEA9ADA8F41A37A37` | `52DEF2115F3FF5D2B4E1BCDD702B893DF280B83CD6D0DDED940735E6899556A8` | `ABACE12C9947ACAAF91BF8E4CB8BF50CD5FF5B2A7AB5A14D9EE25FE2CDF6B746` |
| `EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit` | `1120A6B1CC6D1E8AF5CF2D9980A5D4AC2C8C83217E570900D5C45BC6CD92403A` | `8760ABA893522FE302C14C8472677FED3C3A29B241918A49067F12107F6B5FDE` | `28F0FA43F8C9A5C80C2158B087ED030D8E3E8DEAC6819239BA84890302A8F30A` |
| `EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1_extended.bit` | `B7D3993DC6AA87E86D09C245665FB13F6F970E14DFE75AB25F7EE689C3BB78A0` | `07C7A14717FFFB5828D9B3472D1DB1DE554ACB9A126D34CA4E73EF1ED6F68734` | `5584B06FBF9AFFC87D3F1BFFA56ECFADB892A80ED6468401A2ACF46622444D66` |
| `EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1_extended.bit` | `445D8EF653C1C37495B62C6AFBE11006218131540289CDE5B35DFAFBA4ACF975` | `5FE487203641FDC5920C2FBC85F1A0E329A01462E18862850B42890F90F148AE` | `3572E1C350BD60BA6B0EDD71BAE1388CCD4D57A1C18C7D62439FA1661E33980C` |
| `EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1_extended.bit` | `78DF34AC5602D59A67730E231CA86A6F1E41D4B9E6967C6FBB31AFD276B2D4F8` | `BEBB8D008469343017680082D847309A0122F3133B9A8296D5BEA8F402D3F445` | `15026126BBAA266F5551077BF1A29018EF11D5AA274AE3AADFD282184C1837B0` |
| `IPCM_A_RExt_NEC_2_frame0.bit` | `CC78DF0AA70ED8536B002B48EA7FEACF72AB703BBA7E5286C290D02D1EB51308` | `26AE7AEFA4DED2CCDC917B99B5ECF2352BD9C7100CE0CFD9A9BDC918C5D242B6` | `26AE7AEFA4DED2CCDC917B99B5ECF2352BD9C7100CE0CFD9A9BDC918C5D242B6` |
| `IPCM_B_RExt_NEC_frame0.bit` | `B248E35A32F76F3384DDFB3EA7727B7D088AE977B3C649E152CCA06149F546CE` | `39F97B25079CE5F12340CCE43C9DBD5821C5E23F44DA58DD6F1942E135BC93B5` | `39F97B25079CE5F12340CCE43C9DBD5821C5E23F44DA58DD6F1942E135BC93B5` |
| `Main_422_10_A_RExt_Sony_2_frame0.bit` | `7618CCC9C836EEC9A981910F4E0E46DC36936D620755857005CF6F85BBD5CC84` | `4004FE9C86D10F36ACC6E111B8E6A473351CEECEB6B0649F1D3EFB442D27A231` | `5D6DD0506E85BFD17CFD8D676107927C2860D38D1E8B7E5486647279E6B33876` |
| `Main_422_10_B_RExt_Sony_2_frame0.bit` | `9A8CB40F0AC87635ADA427EFE80DEAAD7FE45C8ABD2E72BEF258D5EC0914C086` | `951ACC9C846DCB9F8CCBDC0B6971A947144BAED2D9021AE4BE77BCCE106BBE21` | `951ACC9C846DCB9F8CCBDC0B6971A947144BAED2D9021AE4BE77BCCE106BBE21` |
| `PERSIST_RPARAM_A_RExt_Sony_3_frame0.bit` | `8237DFE09F09E9AD390C04A30FA57D66F26AB75B9DA90C6B482BA1330DCDBEBB` | `5E1A69D29278E3E4CBD7695C7D3C229AC63C1E5E2B7AF3B1C8F8062586EA1468` | `B6A86FF4122512FDA96EC6C4C7A143079EEE5371760433C05428749140036CEC` |
| `TSCTX_8bit_I_RExt_SHARP_1_frame0.bit` | `E15D63CF239A2F4297EA6EE1E404CB02F19862929270448D0668BD01A5A3D352` | `FCB7B066FF751FE3BA72C0583D289C73B61BE3DB59691B4423ED10B9F00A5F25` | `2849C0B451F6DF2945903B5274E59C87D30E439744FAC6B5E9ECB7014EF23488` |
| `TSCTX_10bit_I_RExt_SHARP_1_frame0.bit` | `813F1951C6EB2C1F469098A05D72FBB23BE0FD1C9D15FCB93C54DA74C0FE9169` | `4B62369D263F475DD560D9F129760100C3EE429F14A515DA23D5A7A622B9368A` | `C27C76EA271243EF36D372F86551012E9E2380D92DEAED84F0E2218108810696` |
| `TSCTX_12bit_I_RExt_SHARP_1_frame0.bit` | `96CC6851668F4968EB439FC4E4823E73394415C4D26B9032AB5EC401E753F0FC` | `7A9608103F06AA750F0A07ABE42693F87B77E38EE7BBF2E47D1D0AF9A1CD958D` | `A5A766D2CEB72DEFF1006107A5A5E65290434F2CCA9EBAAA1696E9EF19898067` |
| `WPP_AND_TILE_10Bit422Test_HIGH_TP_444_10BIT_RExt_Apple_2_frame0.bit` | `C813326651E42576644264EA0F82D03DD79081F6E3163C1C0F283EE6AC03F4C2` | `25DBD378D19E10B020F413213A3CA183FF4C5132500DDECF84D7D9D22218F301` | `DA432C41E52F4DB66B8D2878D8A14A95A9320F4252851EC3242DD3800034377F` |
| `WPP_AND_TILE_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit` | `E0703E36A275DB2715D2051C72F0B4FC392C3CBA9421C069FD58EE037823C8DD` | `00075C57F3C1E17619904B60C5352C52814EAFF495012DF453763FE7A5DCB9F2` | `B5EAC077AA30EE4D228F5D89DA9EFD1588BF046B8F521D55C4E53A9455B99217` |
| `WPP_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit` | `FDFD79B04A4FAEC48E7536E4FFCF692B84B2C5945253A9E8EDFA382816B27335` | `2B7110F868BFB62DA8282A0A6300408D7ABAD70A5A940A6A0BA1FBC69536F870` | `741854FDF832F4BD144FB9F68E49119FE4094C5305EEC00472129F00C1690261` |
| `WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit` | `A852B1501950E9CE50827FD7E65043511115FFC6ACA0E5E68A1B6B25932172B9` | `BDC2868A887A56A58AAEF4046F4341525C320616834189C9E2D2F582E08340C7` | `25FD77A0BB9E41A7AD145CBBAB044F981508C506FD25B8F8F6155EB71EC082C2` |
| `WPP_AND_TILE_AND_CABAC_EXT_PREC_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit` | `4D8135BD94FE6EEFFD58E162999241F6068CCCB67C377C18A18C25B33EF34A1D` | `BE5BE06A8DD2C873E8B386B4E4EAB2F45713277F1D6F2E6BDE5C96E6D7426AF4` | `A6DAE7D643DCB2918465D82347877E6BB70F8BE30C3F9D90C9515DC4DF55A468` |
The loop-filter fixtures are the unchanged Annex B payloads from the official HEVC v1 and Range Extensions archives. `HevcPictureDecoderTests.DecodeOfficialLoopFilterPictureMatchesPinnedHmDigest` retains each first independently coded picture, verifies its signaled precision and chroma layout, and compares every native plane with output from the pinned HIGH_BITDEPTH HM decoder. The feature-runner companion repeats the same production decoder path through every available SIMD tier and the scalar fallback.
- `DBLK_A_SONY_3.bit` is the 8-bit 4:2:0 deblocking stream. The archive SHA-256 is `CE18CD42375359B9FF293D12A95793CC6B56EB75D899AD012C68E25DFA54DFBF`, and the bitstream SHA-256 is `D61A13E04A1678816C0F16CF7A47F5BB918DE95ECF1B6FAB305E2390C3DD7DE9`. Pinned HM reproduces the published complete-output MD5 `42486a48ea12d5ab6cd98ed2e2807cfe`; the retained first picture has Y, Cb, and Cr MD5 values `3ea2c2ef1f973345111480e7658908b3`, `0390b32143b1a832a385f78229e7e574`, and `8388f3a8af827da46f1fb52941ec00ad`.

3
tests/Images/Input/Heif/Hevc/Conformance/TSCTX_10bit_I_RExt_SHARP_1_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c27c76ea271243ef36d372f86551012e9e2380d92deaed84f0e2218108810696
size 165113

3
tests/Images/Input/Heif/Hevc/Conformance/TSCTX_12bit_I_RExt_SHARP_1_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a5a766d2ceb72deff1006107a5a5e65290434f2cca9ebaaa1696e9ef19898067
size 382534

3
tests/Images/Input/Heif/Hevc/Conformance/TSCTX_8bit_I_RExt_SHARP_1_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2849c0b451f6df2945903b5274e59c87d30e439744fac6b5e9ecb7014ef23488
size 165586

3
tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_10Bit422Test_HIGH_TP_444_10BIT_RExt_Apple_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:da432c41e52f4db66b8d2878d8a14a95a9320f4252851ec3242dd3800034377f
size 37152

3
tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:25fd77a0bb9e41a7ad145cbbab044f981508c506fd25b8f8f6155eb71ec082c2
size 42150

3
tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_AND_CABAC_EXT_PREC_1_HIGH_TP_444_14BIT_RExt_Apple_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a6dae7d643dcb2918465d82347877e6bb70f8be30c3f9d90c9515dc4df55a468
size 41800

3
tests/Images/Input/Heif/Hevc/Conformance/WPP_AND_TILE_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b5eac077aa30ee4d228f5d89da9efd1588bf046b8f521d55c4e53a9455b99217
size 41776

3
tests/Images/Input/Heif/Hevc/Conformance/WPP_HIGH_TP_444_8BIT_RExt_Apple_2_frame0.bit

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:741854fdf832f4bd144fb9f68e49119fe4094c5305eec00472129f00c1690261
size 41569
Loading…
Cancel
Save