diff --git a/HEIF_IMPLEMENTATION_PLAN.md b/HEIF_IMPLEMENTATION_PLAN.md index acd6725d3..fd4a67160 100644 --- a/HEIF_IMPLEMENTATION_PLAN.md +++ b/HEIF_IMPLEMENTATION_PLAN.md @@ -132,7 +132,8 @@ Immediate checkpoint: **remaining — close the Phase 3 AV1 still-image decode e - [x] Verify the official libaom all-intra, CDF-update, and temporal motion-field sequences through exact native output, selected syntax coverage, normal/scalar dispatch, constrained tracked allocation, and the family-owned JPEG-style predictor operator architecture. - [ ] **Current:** continue inventorying and removing every remaining valid AV1 still-image unsupported branch, adding exact independent compression-tool fixtures to the profile-matrix regression gate. - [x] Add the missing official ten-bit sequence evidence from libaom's pinned test-data manifest. All ten active-film-grain YUV420 frames and all ten monochrome frames match the pinned generic libaom native Y4M samples exactly under normal and scalar `FeatureTestRunner` dispatch, and both complete sequences pass through a 2 KiB constrained tracked allocator with balanced exactly-once returns. The three new focused cases and all 20 official-sequence regression cases pass without failures or skips, the scoped Release test-project analyzer build completes with zero errors and 1,011 repository warnings, Roslynk reports zero compiler errors, and `git diff --check` is clean. The existing production decoder required no correction. Commit `deefeba2340932909aa3e27516d965a294cf6faa` records the checkpoint. - - [x] Add official minimum- and maximum-quantizer dependent-frame evidence for the eight- and ten-bit libaom matrices. The four retained streams and pinned generic-libaom Y4M references pass exact native comparison under normal and scalar `FeatureTestRunner` dispatch, and the combined sequences pass through a 2,560-byte row-aligned constrained tracked allocator with balanced exactly-once returns. All three new focused cases and all 23 official-sequence regression cases pass without failures or skips, the scoped Release test-project analyzer build completes with zero errors and 1,011 repository warnings, Roslynk reports zero compiler errors, and `git diff --check` is clean. The existing production decoder required no correction. + - [x] Add official minimum- and maximum-quantizer dependent-frame evidence for the eight- and ten-bit libaom matrices. The four retained streams and pinned generic-libaom Y4M references pass exact native comparison under normal and scalar `FeatureTestRunner` dispatch, and the combined sequences pass through a 2,560-byte row-aligned constrained tracked allocator with balanced exactly-once returns. All three new focused cases and all 23 official-sequence regression cases pass without failures or skips, the scoped Release test-project analyzer build completes with zero errors and 1,011 repository warnings, Roslynk reports zero compiler errors, and `git diff --check` is clean. The existing production decoder required no correction. Commit `68cbe2fb9483215db36977a06a2dcac04e2d90bc` records the checkpoint. + - [x] Add exact official frame-size evidence at all four corners of libaom's 196-to-226-pixel matrix. Both frames from each retained stream match the pinned generic-libaom native Y4M samples under normal and scalar `FeatureTestRunner` dispatch, and all four sequences pass through a 1 KiB constrained tracked allocator with balanced exactly-once returns. Both new focused cases and all 25 official-sequence regression cases pass without failures or skips, the scoped Release test-project analyzer build completes with zero errors and 1,011 repository warnings, Roslynk reports zero compiler errors, and `git diff --check` is clean. The existing production decoder required no correction. - [ ] Complete the remaining HEVC still-image profile and Range Extensions matrix with exact independent native-plane and presentation evidence. - [ ] Close shared decoded presentation, ICC, alpha, grid, transform, metadata, and animated AV1/HEVC decode gates. - [ ] Implement and independently verify real AV1/AVIF still encoding. diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ReconstructionConformanceTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ReconstructionConformanceTests.cs index 8c9cae50b..ca8ea5a38 100644 --- a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ReconstructionConformanceTests.cs +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ReconstructionConformanceTests.cs @@ -276,6 +276,21 @@ public class Av1ReconstructionConformanceTests /// private const int OfficialQuantizerFixtureFrameCount = 2; + /// + /// The minimum dimension retained from the official libaom frame-size matrix. + /// + private const int OfficialFrameSizeFixtureMinimumDimension = 196; + + /// + /// The maximum dimension retained from the official libaom frame-size matrix. + /// + private const int OfficialFrameSizeFixtureMaximumDimension = 226; + + /// + /// The number of frames in each official libaom frame-size sequence. + /// + private const int OfficialFrameSizeFixtureFrameCount = 2; + /// /// The coverage bit representing tile-local adaptive CDF updates. /// @@ -1761,6 +1776,81 @@ public class Av1ReconstructionConformanceTests "60:1"); } + /// + /// Verifies all four corners of the official frame-size matrix against exact pinned-libaom native output. + /// + [Fact] + public void DecodeOfficialFrameSizeCornerSequencesMatchPinnedLibaomReferences() + => FeatureTestRunner.RunWithHwIntrinsicsFeature( + ValidateOfficialFrameSizeCornerFixtures, + ReconstructionConfigurations); + + /// + /// Decodes all four retained frame-size corners. + /// + private static void ValidateOfficialFrameSizeCornerFixtures() + => ValidateOfficialFrameSizeCornerFixturesWithConfiguration(Configuration.Default); + + /// + /// Verifies all four frame-size corners through constrained tracked allocation. + /// + [Fact] + [ValidateDisposedMemoryAllocations] + public void DecodeOfficialFrameSizeCornerSequencesWithConstrainedAllocator() + { + TestMemoryAllocator allocator = new() { BufferCapacityInBytes = 1_024 }; + allocator.EnableNonThreadSafeLogging(); + Configuration configuration = Configuration.Default.Clone(); + configuration.MemoryAllocator = allocator; + + ValidateOfficialFrameSizeCornerFixturesWithConfiguration(configuration); + + Assert.Equal(allocator.AllocationLog.Count, allocator.ReturnLog.Count); + Assert.All( + allocator.AllocationLog, + allocation => Assert.Single( + allocator.ReturnLog, + returned => returned.AllocationId == allocation.AllocationId)); + } + + /// + /// Decodes every retained official frame-size fixture and compares every native sample. + /// + private static void ValidateOfficialFrameSizeCornerFixturesWithConfiguration(Configuration configuration) + { + ValidateOfficialCompactSequence( + configuration, + TestImages.Heif.Av1OfficialMinimumFrameSizeSequence, + TestImages.Heif.Av1OfficialMinimumFrameSizeSequenceNativeReference, + OfficialFrameSizeFixtureFrameCount, + OfficialFrameSizeFixtureMinimumDimension, + OfficialFrameSizeFixtureMinimumDimension); + + ValidateOfficialCompactSequence( + configuration, + TestImages.Heif.Av1OfficialMinimumWidthMaximumHeightSequence, + TestImages.Heif.Av1OfficialMinimumWidthMaximumHeightSequenceNativeReference, + OfficialFrameSizeFixtureFrameCount, + OfficialFrameSizeFixtureMinimumDimension, + OfficialFrameSizeFixtureMaximumDimension); + + ValidateOfficialCompactSequence( + configuration, + TestImages.Heif.Av1OfficialMaximumWidthMinimumHeightSequence, + TestImages.Heif.Av1OfficialMaximumWidthMinimumHeightSequenceNativeReference, + OfficialFrameSizeFixtureFrameCount, + OfficialFrameSizeFixtureMaximumDimension, + OfficialFrameSizeFixtureMinimumDimension); + + ValidateOfficialCompactSequence( + configuration, + TestImages.Heif.Av1OfficialMaximumFrameSizeSequence, + TestImages.Heif.Av1OfficialMaximumFrameSizeSequenceNativeReference, + OfficialFrameSizeFixtureFrameCount, + OfficialFrameSizeFixtureMaximumDimension, + OfficialFrameSizeFixtureMaximumDimension); + } + /// /// Decodes one compact official IVF sequence, compares every native sample, and returns its active frame-state /// coverage mask. diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 508283c51..297fc0921 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -1398,6 +1398,14 @@ public static class TestImages public const string Av1OfficialTenBitMinimumQuantizerSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b10-00-quantizer-00-libaom.y4m"; public const string Av1OfficialTenBitMaximumQuantizerSequence = "Heif/Av1/Conformance/libaom-av1-1-b10-00-quantizer-63.ivf"; public const string Av1OfficialTenBitMaximumQuantizerSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b10-00-quantizer-63-libaom.y4m"; + public const string Av1OfficialMinimumFrameSizeSequence = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196.ivf"; + public const string Av1OfficialMinimumFrameSizeSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196-libaom.y4m"; + public const string Av1OfficialMinimumWidthMaximumHeightSequence = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226.ivf"; + public const string Av1OfficialMinimumWidthMaximumHeightSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226-libaom.y4m"; + public const string Av1OfficialMaximumWidthMinimumHeightSequence = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196.ivf"; + public const string Av1OfficialMaximumWidthMinimumHeightSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196-libaom.y4m"; + public const string Av1OfficialMaximumFrameSizeSequence = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226.ivf"; + public const string Av1OfficialMaximumFrameSizeSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226-libaom.y4m"; public const string Av1OfficialCdfUpdateSequence = "Heif/Av1/Conformance/libaom-av1-1-b8-04-cdfupdate.ivf"; public const string Av1OfficialCdfUpdateSequenceNativeReference = "Heif/Av1/Conformance/libaom-av1-1-b8-04-cdfupdate-libaom.y4m"; public const string Av1OfficialMotionVectorSequence = "Heif/Av1/Conformance/libaom-av1-1-b8-05-mv.ivf"; diff --git a/tests/Images/Input/Heif/Av1/Conformance/README.md b/tests/Images/Input/Heif/Av1/Conformance/README.md index 7974864c9..401661026 100644 --- a/tests/Images/Input/Heif/Av1/Conformance/README.md +++ b/tests/Images/Input/Heif/Av1/Conformance/README.md @@ -37,6 +37,7 @@ The reference builds use `AOM_TARGET_CPU=generic` and disable libyuv. Native rec | `*-lossless-*` | Lossless quantization, reversible transforms, and exact presentation | | `*-film-grain-*` | Full and restricted range, monochrome, identity matrix, 8/10/12-bit synthesis, overlap, and odd frame dimensions | | `libaom-av1-1-b8-00-quantizer-*`, `libaom-av1-1-b10-00-quantizer-*` | Official minimum- and maximum-quantizer dependent-frame reconstruction | +| `libaom-av1-1-b8-01-size-*` | Official frame-size matrix corner reconstruction | | `libaom-av1-1-b10-23`, `libaom-av1-1-b10-24` | Official ten-bit dependent-frame film grain and monochrome sequence reconstruction | | `libavif-progressive-draw-points-8b` | A real two-layer color item whose final frame uses single-reference inter reconstruction, plus its progressive auxiliary alpha item | | `libavif-webp-logo-average-compound` | A 19-frame YUV444 image sequence whose retained references reach equal-weight compound inter reconstruction | @@ -69,6 +70,12 @@ The retained `quantizer-00` and `quantizer-63` streams are the minimum- and maxi The native references were generated with the pinned generic `aomdec --threads=1` build. Their SHA-256 values are `D499028E0606DB70CD56A72F151E04F36C09F300A448CCCD8430DD920D3589C5`, `4CC9892B3EE3399B293E31014B9F566C21E0C7A4765FC5F444528769C33E6D67`, `78373C28F401EB95D3E563D146622ED6C714ED96661E5E57C539CE71D7BED599`, and `A9DF86F671B8CF01EFC130660556412D4EBAF31A81D6F26FBDAEB0A7E839D8EA`. Each reference's two raw-frame MD5 values also match the corresponding official `.ivf.md5` file exactly. The tests compare every native sample under normal and scalar `FeatureTestRunner` dispatch and run all four sequences through a 2,560-byte row-aligned constrained tracked allocator. +## Official frame-size corner fixtures + +The retained 196x196, 196x226, 226x196, and 226x226 streams are the four corners of libaom's official eight-bit frame-size matrix. Their SHA-1 values are `9F386D19C87DBFD6AC84A06D2393DD88863AC003`, `5525F7E312EC073F480ED5A2BE5BDC4F0CE51A09`, `1A57B913443B267F4A31A6925C39F5B58022F550`, and `40DD208EB525CD90D7C0674CF787097FB909AFAE`, exactly matching `test/test-data.sha1` at pinned libaom commit `03087864cf4bea6abb0d28f95cf7843511413d8f`. Their SHA-256 values, in the same order, are `ECACF9C2065EEC1A02248395412BE5E03ED7E3FEDFD6653622E09E73D1CAC747`, `2A2ECDDE60546FA8280039228B4BE541825EFAEE30F53EE50B91B11F2952BDA7`, `999522FBF3FCD9F8CC8DAC865BEF874B7BF655A4DAD93C397F50A7A1EC2C9027`, and `B5D9A30F24E33F8FA6A655961645650542DC2545FB7D557E2D55A043DAC69F50`. + +The native references were generated with the pinned generic `aomdec --threads=1` build. Their SHA-256 values are `4479030861DD9D6AB9B00FA8CF77A34712BCECA06C31131927D3E7E9BF5DDA70`, `817FF76E70946763C000E19FCCD9F0258CF9358201B6771AA68FB8C84490D26F`, `F4A70BA358E8B4ED558B589BFE56354C9552469FDABD01B3F4D5754334B0CBD9`, and `44FC32FB1D24CE4A33830B67D927F038E0E1379C6B480C598F018382EC78E9CE`. Each reference's two raw-frame MD5 values also match the corresponding official `.ivf.md5` file exactly. The tests compare every native sample under normal and scalar `FeatureTestRunner` dispatch and run all four sequences through a 1 KiB constrained tracked allocator. + ## Progressive dependent-frame fixture The `libavif-progressive-draw-points-8b.avif` fixture is the unmodified `tests/data/draw_points_idat_progressive.avif` file from the pinned libavif tree. Its SHA-256 is `077AB2AD1E46DD912A973E4F024CB1EB242A08298BE2DBF1A52A058E88C48A4A`. It was generated with: diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196-libaom.y4m b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196-libaom.y4m new file mode 100644 index 000000000..b33d9189f --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196-libaom.y4m @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4479030861dd9d6ab9b00fa8cf77a34712bceca06c31131927d3e7e9bf5dda70 +size 115298 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196.ivf b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196.ivf new file mode 100644 index 000000000..cb60d56ea --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x196.ivf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecacf9c2065eec1a02248395412be5e03ed7e3fedfd6653622e09e73d1cac747 +size 821 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226-libaom.y4m b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226-libaom.y4m new file mode 100644 index 000000000..06e4af8f6 --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226-libaom.y4m @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:817ff76e70946763c000e19fccd9f0258cf9358201b6771aa68fb8c84490d26f +size 132938 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226.ivf b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226.ivf new file mode 100644 index 000000000..048e34ffc --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-196x226.ivf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a2ecdde60546fa8280039228b4be541825efaee30f53ee50b91b11f2952bda7 +size 841 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196-libaom.y4m b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196-libaom.y4m new file mode 100644 index 000000000..4ada37141 --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196-libaom.y4m @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a70ba358e8b4ed558b589bfe56354c9552469fdabd01b3f4d5754334b0cbd9 +size 132938 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196.ivf b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196.ivf new file mode 100644 index 000000000..a5404f55a --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x196.ivf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:999522fbf3fcd9f8cc8dac865bef874b7bf655a4dad93c397f50a7a1ec2c9027 +size 1053 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226-libaom.y4m b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226-libaom.y4m new file mode 100644 index 000000000..12d380aab --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226-libaom.y4m @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44fc32fb1d24ce4a33830b67d927f038e0e1379c6b480c598f018382ec78e9ce +size 153278 diff --git a/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226.ivf b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226.ivf new file mode 100644 index 000000000..19197890b --- /dev/null +++ b/tests/Images/Input/Heif/Av1/Conformance/libaom-av1-1-b8-01-size-226x226.ivf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5d9a30f24e33f8fa6a655961645650542dc2545fb7d557e2d55a043dac69f50 +size 1079