From fabfd5bde1e1f15b75321027f5c9fd6835e5d8d1 Mon Sep 17 00:00:00 2001 From: Tammo Hinrichs Date: Fri, 24 Nov 2023 17:53:40 +0100 Subject: [PATCH] Added a couple of tests for CicpProfile --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 6 ++ .../Profiles/CICP/CicpProfileTests.cs | 72 +++++++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/Input/Png/adamheadsHLG.png | 3 + 4 files changed, 82 insertions(+) create mode 100644 tests/ImageSharp.Tests/Metadata/Profiles/CICP/CicpProfileTests.cs create mode 100644 tests/Images/Input/Png/adamheadsHLG.png diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index a86fd17cca..4e8792c0ef 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -786,6 +786,12 @@ internal sealed class PngEncoderCore : IImageEncoderInternals, IDisposable return; } + // by spec, the matrix coefficients must be set to Identity + if (metaData.CicpProfile.MatrixCoefficients != Metadata.Profiles.CICP.CicpMatrixCoefficients.Identity) + { + throw new NotSupportedException("CICP matrix coefficients other than Identity are not supported in PNG"); + } + Span outputBytes = this.chunkDataBuffer.Span[..4]; outputBytes[0] = (byte)metaData.CicpProfile.ColorPrimaries; outputBytes[1] = (byte)metaData.CicpProfile.TransferCharacteristics; diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/CICP/CicpProfileTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/CICP/CicpProfileTests.cs new file mode 100644 index 0000000000..be215a0881 --- /dev/null +++ b/tests/ImageSharp.Tests/Metadata/Profiles/CICP/CicpProfileTests.cs @@ -0,0 +1,72 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.Metadata.Profiles.CICP; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Cicp; + +public class CicpProfileTests +{ + [Theory] + [WithFile(TestImages.Png.AdamHeadsHlg, PixelTypes.Rgba64)] + public async Task ReadCicpMetadata_FromPng_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = await provider.GetImageAsync(PngDecoder.Instance)) + { + CicpProfile actual = image.Metadata.CicpProfile ?? image.Frames.RootFrame.Metadata.CicpProfile; + CicpProfileContainsExpectedValues(actual); + } + } + + [Fact] + public void WritingPng_PreservesCicpProfile() + { + // arrange + using var image = new Image(1, 1); + var original = new CicpProfile() + { + ColorPrimaries = CicpColorPrimaries.ItuRBt2020_2, + TransferCharacteristics = CicpTransferCharacteristics.SmpteSt2084, + MatrixCoefficients = CicpMatrixCoefficients.Identity, + FullRange = true, + }; + image.Metadata.CicpProfile = original; + var encoder = new PngEncoder(); + + // act + using Image reloadedImage = WriteAndRead(image, encoder); + + // assert + CicpProfile actual = reloadedImage.Metadata.CicpProfile ?? reloadedImage.Frames.RootFrame.Metadata.CicpProfile; + Assert.NotNull(actual); + Assert.Equal(actual.ColorPrimaries, original.ColorPrimaries); + Assert.Equal(actual.TransferCharacteristics, original.TransferCharacteristics); + Assert.Equal(actual.MatrixCoefficients, original.MatrixCoefficients); + Assert.Equal(actual.FullRange, original.FullRange); + } + + private static void CicpProfileContainsExpectedValues(CicpProfile cicp) + { + Assert.NotNull(cicp); + Assert.Equal(CicpColorPrimaries.ItuRBt2020_2, cicp.ColorPrimaries); + Assert.Equal(CicpTransferCharacteristics.AribStdB67, cicp.TransferCharacteristics); + Assert.Equal(CicpMatrixCoefficients.Identity, cicp.MatrixCoefficients); + Assert.True(cicp.FullRange); + } + + private static Image WriteAndRead(Image image, IImageEncoder encoder) + { + using (var memStream = new MemoryStream()) + { + image.Save(memStream, encoder); + image.Dispose(); + + memStream.Position = 0; + return Image.Load(memStream); + } + } +} diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 6ad93adfbd..4c4882a951 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -61,6 +61,7 @@ public static class TestImages public const string TestPattern31x31 = "Png/testpattern31x31.png"; public const string TestPattern31x31HalfTransparent = "Png/testpattern31x31-halftransparent.png"; public const string XmpColorPalette = "Png/xmp-colorpalette.png"; + public const string AdamHeadsHlg = "Png/adamHeadsHLG.png"; // Animated // https://philip.html5.org/tests/apng/tests.html diff --git a/tests/Images/Input/Png/adamheadsHLG.png b/tests/Images/Input/Png/adamheadsHLG.png new file mode 100644 index 0000000000..f5d26ac50c --- /dev/null +++ b/tests/Images/Input/Png/adamheadsHLG.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c50691da3b3af21ff4f8fc30f1313bc412b84fb0a07a5bf3b8b14eae7581ade +size 201440