Browse Source

Verify exact AV1 palette reconstruction

pull/2633/head
James Jackson-South 1 week ago
parent
commit
7d940d3326
  1. 4
      HEIF_IMPLEMENTATION_PLAN.md
  2. 193
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ReconstructionConformanceTests.cs
  3. 4
      tests/ImageSharp.Tests/TestImages.cs
  4. 6
      tests/Images/Input/Heif/Av1/Conformance/README.md
  5. 3
      tests/Images/Input/Heif/Av1/Conformance/libaom-palette-draw-points-8b-444-libaom.yuv
  6. 3
      tests/Images/Input/Heif/Av1/Conformance/libaom-palette-draw-points-8b-444.bit
  7. 3
      tests/Images/Input/Heif/Av1/Conformance/libavif-palette-draw-points-8b.avif
  8. 3
      tests/Images/Input/Heif/Av1/Conformance/libavif-palette-draw-points-8b.png

4
HEIF_IMPLEMENTATION_PLAN.md

@ -354,7 +354,7 @@ This assessment was reconciled with the source tree on 2026-08-26. Unless a resu
- Transform coefficient entropy derivation and updates now address the above contexts relative to the tile column and the left contexts relative to the current superblock row, preserve luma coordinates independently of chroma subsampling, and test every packed context entry for the libaom any-nonzero rule. Extended vertical partition updates advance the mode-information column rather than the row. The existing multi-superblock 4:4:4 AVIF fixture now completes tile parsing; independent coefficient-context vectors across tile boundaries, chroma layouts, bit depths, and edge-clipped transforms remain required.
- The reconstruction pipeline now records plane-relative transform geometry, preserves tile-local delta-Q and delta-LF predictors, derives segmentation and reference-adjusted filter levels, and runs the exact AV1 4-, 6-, 8-, and 14-tap deblocking kernels in normative vertical-then-horizontal order. Deblocking uses the same closed edge-operator architecture as the HEVC filter, with operators specialized by sample storage and orientation, `Vector128<int>` lanes representing the four rows or columns along an edge, and an allocation-free scalar fallback for disabled intrinsics. Exact native-plane comparison with pinned scalar libaom output now verifies active deblocking and complete reconstruction for real 8-bit 4:2:0, 10-bit 4:4:4, and 12-bit 4:4:4 content; genuine AVIF containers separately verify presentation and public bit-depth metadata. The pipeline then applies CDEF through one semantic filter architecture: paired AVX2 and single-block `Vector128` direction analysis, closed primary/secondary strength operators, packed 4x4/4x8/8x4/8x8 constrained filtering, byte/16-bit output operators, and an exact allocation-free scalar fallback. Decoder orchestration now owns the immutable plane snapshots and clean direction/variance maps through ImageSharp's memory allocator, widens 8-bit source rows with the same AVX2/128-bit/scalar tiers as libaom, lists each unit's non-skipped blocks in fixed inline storage, analyzes listed blocks in pairs, and writes filtered bytes or 16-bit samples directly to the frame planes. Independently encoded active-CDEF 8-bit 4:2:0 and 10/12-bit 4:4:4 streams match every visible native sample produced by pinned scalar libaom with restoration disabled. Independently encoded AVIF containers at the same three bit depths also match pinned scalar-libavif presentation exactly under normal, 256-bit, 128-bit, and scalar color-conversion dispatch. Active super-resolution derives the Appendix A bounded coded width and applies the exact 64-phase, 8-tap horizontal filter with aligned reconstruction-edge input, 8/10/12-bit clipping, and the existing cross-platform `Vector128_.MultiplyAddAdjacent` helper. Independently encoded active-super-resolution AV1 streams at 8, 10, and 12 bits match every visible native sample produced by pinned scalar libaom under normal and forced-scalar dispatch. Independently packaged AVIF containers at the same bit depths retain matching libavif profile, dimensions, chroma, and CICP properties, require active super-resolution in their actual AV1 item, and match pinned scalar-libavif presentation exactly under normal, 256-bit, 128-bit, and scalar color-conversion dispatch. Loop restoration follows super-resolution, preserves the required pre-CDEF deblocked context at internal stripes, and applies decoded Wiener or self-guided units from immutable plane snapshots. Independently encoded active-restoration streams at 8, 10, and 12 bits now match every native sample from pinned scalar libaom across AVX2, 128-bit, and scalar dispatch, with the fixture matrix proving both Wiener and self-guided unit selection. The matching AVIF containers also match pinned scalar-libavif presentation exactly, and an independent direct-window definition verifies all sixteen self-guided parameter sets at each supported bit depth across vector and scalar dispatch. Combined 8-bit 4:2:0, 10-bit 4:2:2, and 12-bit 4:4:4 streams additionally verify restoration-unit boundaries after super-resolution, including clipped chroma transform traversal at a coded-frame edge.
- The visible still-image path applies the complete self-contained film-grain parameter set after all in-loop filters. Independently encoded pinned-libaom vectors match every native sample at 8, 10, and 12 bits across monochrome, 4:2:0, 4:2:2, and 4:4:4 layouts, full and restricted ranges, identity-matrix signaling, overlap, and odd 33x11 frame extension. `FeatureTestRunner` verifies normal, AVX-disabled, and fully scalar dispatch. A full-HD-equivalent 4:2:0 benchmark reports zero allocation: 8-bit AVX2 is 2.335 ms versus 5.806 ms scalar, while 12-bit AVX2 is 3.195 ms, cross-platform 128-bit is 7.382 ms, and scalar is 8.614 ms on the measured Ryzen platform. The slower 8-bit 128-bit lookup construction is deliberately not dispatched.
- Palette mode now reads the normative luma/chroma mode and size CDFs, neighbor color caches, high-bit-depth color syntax, diagonal color-index maps, and clipped-edge padding. Reconstruction retains libaom's exact indexed-palette contract while using repeated eight-entry tables and native lane-local shuffles across runtime-selected `Vector512`, `Vector256`, and `Vector128` paths before an exact scalar fallback. `FeatureTestRunner` verifies palette sizes 2-8, transform widths 4-64, padded rows, and 8/10/12-bit samples. This path is not production-complete until its syntax and reconstruction are verified with an independently encoded palette AVIF fixture.
- Palette mode now reads the normative luma/chroma mode and size CDFs, neighbor color caches, high-bit-depth color syntax, diagonal color-index maps, and clipped-edge padding. Reconstruction retains libaom's exact indexed-palette contract while using repeated eight-entry tables and native lane-local shuffles across runtime-selected `Vector512`, `Vector256`, and `Vector128` paths before an exact scalar fallback. `FeatureTestRunner` verifies palette sizes 2-8, transform widths 4-64, padded rows, and 8/10/12-bit samples. An independently encoded 33x11 8-bit YUV 4:4:4 AVIF fixture selects both luma and chroma palettes, matches every native sample from pinned scalar libaom, and matches scalar-libavif presentation exactly across the available vector widths and scalar fallback.
- Non-reduced still-image sequence parsing now consumes decoder-model operating parameters, temporal presentation fields, and OBU-layer-applicable buffer-removal fields only to preserve AV1 bit alignment. The scheduling values are not retained, and no movie, track, timing, playback, or generic ISO BMFF surface has been introduced. Existing focused sequence-header coverage exercises only reduced-still syntax, so an independent non-reduced still AVIF vector remains required.
- Loop-restoration unit parsing records tile-local switchable/Wiener/self-guided filter selections and coefficients in frame-owned plane grids, including super-resolution-adjusted unit corners and the corrected conditional 64x64-superblock unit-size bit. The active restoration stage implements the normative unit geometry, striped deblocked boundaries, Wiener filtering, self-guided projection, and 8/10/12-bit clipping. Self-guided filtering now follows libaom's summed-area-table, coefficient-grid, alternating-row radius-two, full radius-one, and projection stages through AVX2 and cross-platform 128-bit traversals with one exact scalar fallback and caller-owned scratch. Independently encoded fixtures cover active Wiener and self-guided reconstruction and exact AVIF presentation at every supported bit depth. An independent direct-window definition covers all sixteen self-guided parameter sets, narrow and odd processing units, both vector-tail widths, padded strides, and the scalar fallback. Combined active-restoration and super-resolution fixtures cover 4:2:0, 4:2:2, and 4:4:4 at 8, 10, and 12 bits, including restoration-unit boundaries and clipped chroma transform traversal. Other normative independently decodable still-image syntax paths still contain `NotImplementedException` or equivalent unsupported branches. Tile-local palette CDF adaptation is present; the remaining still-image frame-context behavior requires a separate source audit without introducing sequence playback state.
- The frame buffer now establishes two-byte native sample storage, logical plane rows, and sample-unit block strides for 10/12-bit frames. The active intra-prediction, inverse-transform, and block-reconstruction path selects native 16-bit samples for 10/12-bit frames and has focused pipeline wiring coverage. Chroma-from-luma storage, 4:4:4/4:2:2/4:2:0 subsampling, rounded mean subtraction, U/V sharing, and 8/10/12-bit prediction now traverse AVX2 and cross-platform `Vector128` paths before an exact scalar fallback. `FeatureTestRunner` verifies every tier against independent fixed-point definitions across every supported block width; independently encoded high-bit-depth and chroma-from-luma AVIF conformance files are still required.
@ -501,7 +501,7 @@ Implement and verify in dependency order:
- [ ] Intra prediction, including every directional, smooth, Paeth, CFL, filter-intra, and palette case permitted by AV1.
- [x] Implement SIMD-first chroma-from-luma storage, 4:4:4/4:2:2/4:2:0 subsampling, rounded mean subtraction, and 8/10/12-bit prediction with exact scalar fallback and `FeatureTestRunner` parity.
- [x] Implement allocation-free SIMD-first palette reconstruction for palette sizes 2-8, transform widths 4-64, and 8/10/12-bit samples with exact scalar fallback and `FeatureTestRunner` parity.
- [ ] Verify palette mode syntax and presented reconstruction with an independently encoded palette AVIF fixture.
- [x] Verify palette mode syntax and presented reconstruction with an independently encoded palette AVIF fixture.
- [ ] Lossless and high-bit-depth reconstruction with correct clipping and intermediate precision.
- [x] Route lossless 4x4 blocks through allocation-free reversible inverse Walsh-Hadamard reconstruction for 8/10/12-bit samples, including the DC-only specialization, `Vector128` production traversal, scalar fallback, exact clipping, and `FeatureTestRunner` parity.
- [ ] Verify lossless syntax, inverse quantization, prediction, and presented reconstruction with independently encoded 8/10/12-bit AVIF fixtures.

193
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ReconstructionConformanceTests.cs

@ -25,6 +25,12 @@ public class Av1ReconstructionConformanceTests
/// </summary>
private const HwIntrinsics ReconstructionConfigurations = HwIntrinsics.AllowAll | HwIntrinsics.DisableHWIntrinsic;
/// <summary>
/// The hardware configurations covering the 256-bit, 128-bit, and scalar palette-reconstruction paths.
/// </summary>
private const HwIntrinsics PaletteConfigurations =
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic;
/// <summary>
/// The hardware configurations covering the 256-bit, 128-bit, and scalar loop-restoration paths.
/// </summary>
@ -41,6 +47,21 @@ public class Av1ReconstructionConformanceTests
/// </summary>
private const int SelfGuidedRestorationCoverage = 1 << (int)Av1RestorationFilterType.SgrProjection;
/// <summary>
/// The coverage bit representing luma palette prediction.
/// </summary>
private const int LumaPaletteCoverage = 1 << 0;
/// <summary>
/// The coverage bit representing chroma palette prediction.
/// </summary>
private const int ChromaPaletteCoverage = 1 << 1;
/// <summary>
/// The luma and chroma syntax coverage required from the independent palette fixture.
/// </summary>
private const int RequiredPaletteCoverage = LumaPaletteCoverage | ChromaPaletteCoverage;
/// <summary>
/// The hardware configurations covering the available vector widths and the scalar color-conversion fallback.
/// </summary>
@ -103,6 +124,22 @@ public class Av1ReconstructionConformanceTests
public void DecodeWithActiveCdefMatchesPinnedLibavifPresentation()
=> FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidatePresentedFixtures, PresentationConfigurations);
/// <summary>
/// Verifies decoded luma and chroma palette syntax and exact native samples against scalar libaom for an
/// independently encoded AV1 still-picture stream.
/// </summary>
[Fact]
public void DecodeWithPaletteMatchesPinnedLibaomReference()
=> FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidatePaletteNativeFixture, PaletteConfigurations);
/// <summary>
/// Verifies decoded luma and chroma palette syntax and exact presented pixels for an independently encoded AVIF
/// image across the available vector widths and the scalar fallback.
/// </summary>
[Fact]
public void DecodeWithPaletteMatchesPinnedLibavifPresentation()
=> FeatureTestRunner.RunWithHwIntrinsicsFeature(ValidatePalettePresentedFixture, PresentationConfigurations);
/// <summary>
/// Verifies active normative super-resolution, chroma-width rounding, replicated edges, and exact native samples
/// against scalar libaom for independently encoded eight-, ten-, and twelve-bit still-picture streams.
@ -242,6 +279,35 @@ public class Av1ReconstructionConformanceTests
HeifBitDepth.Bit12);
}
/// <summary>
/// Validates the active-palette presentation fixture under the hardware configuration selected by
/// <see cref="FeatureTestRunner"/>.
/// </summary>
private static void ValidatePalettePresentedFixture()
=> ValidatePresentedFixture(
TestImages.Heif.Av1Palette8BitAvif,
TestImages.Heif.Av1Palette8BitPresentationReference,
33,
11,
HeifBitDepth.Bit8,
requirePalette: true);
/// <summary>
/// Validates the active-palette native fixture under the hardware configuration selected by
/// <see cref="FeatureTestRunner"/>.
/// </summary>
private static void ValidatePaletteNativeFixture()
=> ValidateNativeFixture(
TestImages.Heif.Av1Palette8BitPayload,
TestImages.Heif.Av1Palette8BitReference,
33,
11,
Av1BitDepth.EightBit,
Av1ColorFormat.Yuv444,
requireActiveCdef: false,
requireActiveLoopFilter: false,
requirePalette: true);
/// <summary>
/// Validates every active super-resolution fixture under the hardware configuration selected by
/// <see cref="FeatureTestRunner"/>.
@ -515,6 +581,7 @@ public class Av1ReconstructionConformanceTests
/// <param name="requireRestrictedRange">Indicates whether film grain must clip every plane to its restricted range.</param>
/// <param name="requireIdentityMatrix">Indicates whether restricted chroma clipping must use the luma endpoints.</param>
/// <param name="requireActiveLoopFilter">Indicates whether the stream must signal a nonzero deblocking strength.</param>
/// <param name="requirePalette">Indicates whether the stream must select palette prediction for luma and chroma.</param>
/// <returns>A bit mask containing every selected loop-restoration filter type.</returns>
private static int ValidateNativeFixture(
string payloadPath,
@ -529,7 +596,8 @@ public class Av1ReconstructionConformanceTests
bool requireFilmGrain = false,
bool requireRestrictedRange = false,
bool requireIdentityMatrix = false,
bool requireActiveLoopFilter = true)
bool requireActiveLoopFilter = true,
bool requirePalette = false)
{
int restorationCoverage = 0;
byte[] payload = TestFile.Create(payloadPath).Bytes;
@ -624,6 +692,11 @@ public class Av1ReconstructionConformanceTests
Assert.Equal(ObuMatrixCoefficients.Identity, decoder.SequenceHeader.ColorConfig.MatrixCoefficients);
}
if (requirePalette)
{
Assert.Equal(RequiredPaletteCoverage, GetPaletteCoverage(decoder));
}
AssertNativePlanesEqual(frameBuffer, reference);
return restorationCoverage;
}
@ -765,13 +838,15 @@ public class Av1ReconstructionConformanceTests
/// <param name="height">The expected displayed height.</param>
/// <param name="metadataBitDepth">The expected public HEIF sample precision.</param>
/// <param name="requireSuperResolution">Whether the AV1 item must upscale from a narrower coded frame.</param>
/// <param name="requirePalette">Whether the AV1 item must select palette prediction for luma and chroma.</param>
private static void ValidatePresentedFixture(
string imagePath,
string referencePath,
int width,
int height,
HeifBitDepth metadataBitDepth,
bool requireSuperResolution = false)
bool requireSuperResolution = false,
bool requirePalette = false)
{
DecoderOptions options = new() { MaxFrames = 1 };
byte[] imageBytes = TestFile.Create(imagePath).Bytes;
@ -782,6 +857,11 @@ public class Av1ReconstructionConformanceTests
AssertUsesSuperResolution(imageBytes);
}
if (requirePalette)
{
AssertUsesPalette(imageBytes);
}
using Image<Rgba32> image = Image.Load<Rgba32>(options, imageBytes);
using Image<Rgba32> reference = Image.Load<Rgba32>(referenceBytes);
@ -800,32 +880,27 @@ public class Av1ReconstructionConformanceTests
/// <param name="imageBytes">The complete AVIF file.</param>
private static void AssertUsesSuperResolution(Span<byte> imageBytes)
{
int offset = 0;
while (offset < imageBytes.Length)
{
int headerLength = HeifBoxReader.ParseHeader(imageBytes[offset..], out long payloadLength, out Heif4CharCode boxType);
Assert.InRange(payloadLength, 0, int.MaxValue);
int payloadLength32 = (int)payloadLength;
Span<byte> payload = GetSoleAv1ItemPayload(imageBytes);
using Av1Decoder decoder = new(Configuration.Default);
using Av1FrameBuffer<byte> frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _);
if (boxType == Heif4CharCode.Mdat)
{
// These single-item fixtures deliberately make the complete mdat payload the AV1 item. Inspecting
// those exact bytes prevents an unscaled container from satisfying only the presentation comparison.
Span<byte> payload = imageBytes.Slice(offset + headerLength, payloadLength32);
using Av1Decoder decoder = new(Configuration.Default);
using Av1FrameBuffer<byte> frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _);
Assert.NotNull(decoder.FrameHeader);
ObuFrameSize frameSize = decoder.FrameHeader.FrameSize;
Assert.True(frameSize.FrameWidth < frameSize.SuperResolutionUpscaledWidth);
Assert.Equal(frameBuffer.Width, frameSize.SuperResolutionUpscaledWidth);
return;
}
Assert.NotNull(decoder.FrameHeader);
ObuFrameSize frameSize = decoder.FrameHeader.FrameSize;
Assert.True(frameSize.FrameWidth < frameSize.SuperResolutionUpscaledWidth);
Assert.Equal(frameBuffer.Width, frameSize.SuperResolutionUpscaledWidth);
}
offset = checked(offset + headerLength + payloadLength32);
}
/// <summary>
/// Verifies that the sole AV1 image item in an independently encoded AVIF selects luma and chroma palettes.
/// </summary>
/// <param name="imageBytes">The complete AVIF file.</param>
private static void AssertUsesPalette(Span<byte> imageBytes)
{
Span<byte> payload = GetSoleAv1ItemPayload(imageBytes);
using Av1Decoder decoder = new(Configuration.Default);
using Av1FrameBuffer<byte> frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _);
Assert.Fail("The AVIF fixture does not contain a media-data box.");
Assert.Equal(RequiredPaletteCoverage, GetPaletteCoverage(decoder));
}
/// <summary>
@ -834,6 +909,25 @@ public class Av1ReconstructionConformanceTests
/// <param name="imageBytes">The complete AVIF file.</param>
/// <returns>A bit mask containing every selected loop-restoration filter type.</returns>
private static int GetRestorationCoverageFromAvif(Span<byte> imageBytes)
{
Span<byte> payload = GetSoleAv1ItemPayload(imageBytes);
using Av1Decoder decoder = new(Configuration.Default);
using Av1FrameBuffer<byte> frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _);
Assert.NotNull(decoder.FrameHeader);
Assert.True(decoder.FrameHeader.LoopRestorationParameters.UsesLoopRestoration);
Assert.NotNull(decoder.FrameInfo);
int restorationCoverage = GetRestorationCoverage(decoder);
Assert.NotEqual(0, restorationCoverage);
return restorationCoverage;
}
/// <summary>
/// Gets the complete media-data payload from a single-item AVIF conformance fixture.
/// </summary>
/// <param name="imageBytes">The complete AVIF file.</param>
/// <returns>The sole AV1 image-item payload.</returns>
private static Span<byte> GetSoleAv1ItemPayload(Span<byte> imageBytes)
{
int offset = 0;
while (offset < imageBytes.Length)
@ -844,25 +938,48 @@ public class Av1ReconstructionConformanceTests
if (boxType == Heif4CharCode.Mdat)
{
// These single-item fixtures deliberately make the complete mdat payload the AV1 item. Decoding
// those exact bytes proves the container used for pixel comparison actually selects restoration.
Span<byte> payload = imageBytes.Slice(offset + headerLength, payloadLength32);
using Av1Decoder decoder = new(Configuration.Default);
using Av1FrameBuffer<byte> frameBuffer = decoder.DecodeFrameBuffer(payload, null, null, out _);
Assert.NotNull(decoder.FrameHeader);
Assert.True(decoder.FrameHeader.LoopRestorationParameters.UsesLoopRestoration);
Assert.NotNull(decoder.FrameInfo);
int restorationCoverage = GetRestorationCoverage(decoder);
Assert.NotEqual(0, restorationCoverage);
return restorationCoverage;
// Every conformance container passed here deliberately stores its sole AV1 item as the complete
// mdat payload, so feature assertions inspect the exact bytes used by public presentation decoding.
return imageBytes.Slice(offset + headerLength, payloadLength32);
}
offset = checked(offset + headerLength + payloadLength32);
}
Assert.Fail("The AVIF fixture does not contain a media-data box.");
return 0;
return [];
}
/// <summary>
/// Returns the luma and chroma palette classes selected by a decoded frame.
/// </summary>
/// <param name="decoder">The decoder after tile parsing and reconstruction.</param>
/// <returns>A bit mask containing the selected plane classes.</returns>
private static int GetPaletteCoverage(Av1Decoder decoder)
{
Assert.NotNull(decoder.FrameHeader);
Assert.NotNull(decoder.FrameInfo);
int modeInfoWidth = Av1Math.DivideLog2Ceiling(decoder.FrameHeader.FrameSize.FrameWidth, Av1Constants.ModeInfoSizeLog2);
int modeInfoHeight = Av1Math.DivideLog2Ceiling(decoder.FrameHeader.FrameSize.FrameHeight, Av1Constants.ModeInfoSizeLog2);
int paletteCoverage = 0;
for (int y = 0; y < modeInfoHeight; y++)
{
for (int x = 0; x < modeInfoWidth; x++)
{
Av1BlockModeInfo modeInfo = decoder.FrameInfo.GetModeInfoAt(new Point(x, y));
if (modeInfo.GetPaletteSize(Av1PlaneType.Y) != 0)
{
paletteCoverage |= LumaPaletteCoverage;
}
if (modeInfo.GetPaletteSize(Av1PlaneType.Uv) != 0)
{
paletteCoverage |= ChromaPaletteCoverage;
}
}
}
return paletteCoverage;
}
/// <summary>

4
tests/ImageSharp.Tests/TestImages.cs

@ -1365,6 +1365,10 @@ public static class TestImages
public const string Av1Cdef12BitReference = "Heif/Av1/Conformance/libaom-cdef-cosmos-12b-libaom.yuv";
public const string Av1Cdef12BitAvif = "Heif/Av1/Conformance/libavif-cdef-cosmos-12b.avif";
public const string Av1Cdef12BitPresentationReference = "Heif/Av1/Conformance/libavif-cdef-cosmos-12b.png";
public const string Av1Palette8BitPayload = "Heif/Av1/Conformance/libaom-palette-draw-points-8b-444.bit";
public const string Av1Palette8BitReference = "Heif/Av1/Conformance/libaom-palette-draw-points-8b-444-libaom.yuv";
public const string Av1Palette8BitAvif = "Heif/Av1/Conformance/libavif-palette-draw-points-8b.avif";
public const string Av1Palette8BitPresentationReference = "Heif/Av1/Conformance/libavif-palette-draw-points-8b.png";
public const string Av1SuperResolution8BitPayload = "Heif/Av1/Conformance/libaom-superres-kodim23-8b.bit";
public const string Av1SuperResolution8BitReference = "Heif/Av1/Conformance/libaom-superres-kodim23-8b-libaom.yuv";
public const string Av1SuperResolution8BitAvif = "Heif/Av1/Conformance/libavif-superres-kodim23-8b.avif";

6
tests/Images/Input/Heif/Av1/Conformance/README.md

@ -45,6 +45,12 @@ The `libaom-restoration-superres-*` streams combine active restoration with a co
The 10-bit 4:2:2 source was produced from libavif's `abc.png` with pinned generic `avifenc` using `-j 1 -s 8 -q 100 -d 10 -y 422`, then decoded to Y4M before the combined libaom encode. Its clipped rightmost 128x128 coding block crosses a second 64x64 residual region. This independently exercises the required conversion of the luma-region cursor to the subsampled chroma transform grid instead of relying only on full-width 4:4:4 blocks.
## Palette coverage
The palette fixture was encoded independently from ImageSharp using `tests/data/draw_points.png` from the pinned libavif revision. The source is a 33x11 flat-color image whose AV1 item selects both luma and chroma palette prediction. The pinned generic `avifenc` command used `-j 1 -s 0 -q 100 --ignore-alpha -y 444 --cicp 12/16/12 -a enable-palette=1 -a enable-intrabc=0 -a tune-content=screen`.
`libaom-palette-draw-points-8b-444.bit` is the exact sole AV1 item extracted from `libavif-palette-draw-points-8b.avif`. The matching native YUV reference was decoded from that payload by the pinned scalar `aomdec --rawvideo` build. The presented PNG was decoded from the complete AVIF container by the pinned scalar `avifdec -j 1 -d 8` build. The tests require both palette planes to be selected, compare every native YUV sample exactly, and compare every presented RGBA byte exactly across the available vector widths and scalar fallback. No tolerance is used.
## Film-grain coverage
The film-grain pairs were generated independently from ImageSharp. Each `.bit` file is an AV1 still-picture OBU stream, and the matching `-libaom.yuv` file is the exact visible planar output from the pinned scalar libaom decoder.

3
tests/Images/Input/Heif/Av1/Conformance/libaom-palette-draw-points-8b-444-libaom.yuv

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

3
tests/Images/Input/Heif/Av1/Conformance/libaom-palette-draw-points-8b-444.bit

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

3
tests/Images/Input/Heif/Av1/Conformance/libavif-palette-draw-points-8b.avif

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

3
tests/Images/Input/Heif/Av1/Conformance/libavif-palette-draw-points-8b.png

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