mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
22 changed files with 693 additions and 12 deletions
@ -0,0 +1,72 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Metadata.Profiles.Cicp; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a Cicp profile as per ITU-T H.273 / ISO/IEC 23091-2_2019 providing access to color space information
|
||||
|
/// </summary>
|
||||
|
public sealed class CicpProfile : IDeepCloneable<CicpProfile> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="CicpProfile"/> class.
|
||||
|
/// </summary>
|
||||
|
public CicpProfile() |
||||
|
: this(2, 2, 2, null) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="CicpProfile"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="colorPrimaries">The color primaries as number according to ITU-T H.273 / ISO/IEC 23091-2_2019.</param>
|
||||
|
/// <param name="transferCharacteristics">The transfer characteristics as number according to ITU-T H.273 / ISO/IEC 23091-2_2019.</param>
|
||||
|
/// <param name="matrixCoefficients">The matrix coefficients as number according to ITU-T H.273 / ISO/IEC 23091-2_2019.</param>
|
||||
|
/// <param name="fullRange">The full range flag, or null if unknown.</param>
|
||||
|
public CicpProfile(byte colorPrimaries, byte transferCharacteristics, byte matrixCoefficients, bool? fullRange) |
||||
|
{ |
||||
|
this.ColorPrimaries = Enum.IsDefined(typeof(CicpColorPrimaries), colorPrimaries) ? (CicpColorPrimaries)colorPrimaries : CicpColorPrimaries.Unspecified; |
||||
|
this.TransferCharacteristics = Enum.IsDefined(typeof(CicpTransferCharacteristics), transferCharacteristics) ? (CicpTransferCharacteristics)transferCharacteristics : CicpTransferCharacteristics.Unspecified; |
||||
|
this.MatrixCoefficients = Enum.IsDefined(typeof(CicpMatrixCoefficients), matrixCoefficients) ? (CicpMatrixCoefficients)matrixCoefficients : CicpMatrixCoefficients.Unspecified; |
||||
|
this.FullRange = fullRange ?? (this.MatrixCoefficients == CicpMatrixCoefficients.Identity); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="CicpProfile"/> class
|
||||
|
/// by making a copy from another CICP profile.
|
||||
|
/// </summary>
|
||||
|
/// <param name="other">The other CICP profile, where the clone should be made from.</param>
|
||||
|
/// <exception cref="ArgumentNullException"><paramref name="other"/> is null.</exception>>
|
||||
|
private CicpProfile(CicpProfile other) |
||||
|
{ |
||||
|
Guard.NotNull(other, nameof(other)); |
||||
|
|
||||
|
this.ColorPrimaries = other.ColorPrimaries; |
||||
|
this.TransferCharacteristics = other.TransferCharacteristics; |
||||
|
this.MatrixCoefficients = other.MatrixCoefficients; |
||||
|
this.FullRange = other.FullRange; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the color primaries
|
||||
|
/// </summary>
|
||||
|
public CicpColorPrimaries ColorPrimaries { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the transfer characteristics
|
||||
|
/// </summary>
|
||||
|
public CicpTransferCharacteristics TransferCharacteristics { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the matrix coefficients
|
||||
|
/// </summary>
|
||||
|
public CicpMatrixCoefficients MatrixCoefficients { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the colors use the full numeric range
|
||||
|
/// </summary>
|
||||
|
public bool FullRange { get; set; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public CicpProfile DeepClone() => new(this); |
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Metadata.Profiles.Cicp; |
||||
|
|
||||
|
#pragma warning disable CA1707 // Underscores in enum members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Color primaries according to ITU-T H.273 / ISO/IEC 23091-2_2019 subclause 8.1
|
||||
|
/// </summary>
|
||||
|
public enum CicpColorPrimaries : byte |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.709-6
|
||||
|
/// IEC 61966-2-1 sRGB or sYCC
|
||||
|
/// IEC 61966-2-4
|
||||
|
/// SMPTE RP 177 (1993) Annex B
|
||||
|
/// </summary>
|
||||
|
ItuRBt709_6 = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Image characteristics are unknown or are determined by the application.
|
||||
|
/// </summary>
|
||||
|
Unspecified = 2, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.470-6 System M (historical)
|
||||
|
/// </summary>
|
||||
|
ItuRBt470_6M = 4, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.601-7 625
|
||||
|
/// Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM
|
||||
|
/// </summary>
|
||||
|
ItuRBt601_7_625 = 5, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.601-7 525
|
||||
|
/// Rec. ITU-R BT.1700-0 NTSC
|
||||
|
/// SMPTE ST 170 (2004)
|
||||
|
/// (functionally the same as the value 7)
|
||||
|
/// </summary>
|
||||
|
ItuRBt601_7_525 = 6, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 240 (1999)
|
||||
|
/// (functionally the same as the value 6)
|
||||
|
/// </summary>
|
||||
|
SmpteSt240 = 7, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Generic film (colour filters using Illuminant C)
|
||||
|
/// </summary>
|
||||
|
GenericFilm = 8, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.2020-2
|
||||
|
/// Rec. ITU-R BT.2100-2
|
||||
|
/// </summary>
|
||||
|
ItuRBt2020_2 = 9, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 428-1 (2019)
|
||||
|
/// (CIE 1931 XYZ as in ISO 11664-1)
|
||||
|
/// </summary>
|
||||
|
SmpteSt428_1 = 10, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE RP 431-2 (2011)
|
||||
|
/// DCI P3
|
||||
|
/// </summary>
|
||||
|
SmpteRp431_2 = 11, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 432-1 (2010)
|
||||
|
/// P3 D65 / Display P3
|
||||
|
/// </summary>
|
||||
|
SmpteEg432_1 = 12, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// EBU Tech.3213-E
|
||||
|
/// </summary>
|
||||
|
EbuTech3213E = 22, |
||||
|
} |
||||
|
|
||||
|
#pragma warning restore CA1707 // Underscores in enum members
|
||||
@ -0,0 +1,96 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Metadata.Profiles.Cicp; |
||||
|
|
||||
|
#pragma warning disable CA1707 // Underscores in enum members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Matrix coefficients according to ITU-T H.273 / ISO/IEC 23091-2_2019 subclause 8.3
|
||||
|
/// </summary>
|
||||
|
public enum CicpMatrixCoefficients : byte |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The identity matrix.
|
||||
|
/// IEC 61966-2-1 sRGB
|
||||
|
/// SMPTE ST 428-1 (2019)
|
||||
|
/// </summary>
|
||||
|
Identity = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.709-6
|
||||
|
/// IEC 61966-2-4 xvYCC709
|
||||
|
/// SMPTE RP 177 (1993) Annex B
|
||||
|
/// </summary>
|
||||
|
ItuRBt709_6 = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Image characteristics are unknown or are determined by the application.
|
||||
|
/// </summary>
|
||||
|
Unspecified = 2, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// FCC Title 47 Code of Federal Regulations 73.682 (a) (20)
|
||||
|
/// </summary>
|
||||
|
Fcc47 = 4, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.601-7 625
|
||||
|
/// Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM
|
||||
|
/// IEC 61966-2-1 sYCC
|
||||
|
/// IEC 61966-2-4 xvYCC601
|
||||
|
/// (functionally the same as the value 6)
|
||||
|
/// </summary>
|
||||
|
ItuRBt601_7_625 = 5, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.601-7 525
|
||||
|
/// Rec. ITU-R BT.1700-0 NTSC
|
||||
|
/// SMPTE ST 170 (2004)
|
||||
|
/// (functionally the same as the value 5)
|
||||
|
/// </summary>
|
||||
|
ItuRBt601_7_525 = 6, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 240 (1999)
|
||||
|
/// </summary>
|
||||
|
SmpteSt240 = 7, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// YCgCo
|
||||
|
/// </summary>
|
||||
|
YCgCo = 8, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.2020-2 (non-constant luminance)
|
||||
|
/// Rec. ITU-R BT.2100-2 Y′CbCr
|
||||
|
/// </summary>
|
||||
|
ItuRBt2020_2_Ncl = 9, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.2020-2 (constant luminance)
|
||||
|
/// </summary>
|
||||
|
ItuRBt2020_2_Cl = 10, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 2085 (2015)
|
||||
|
/// </summary>
|
||||
|
SmpteSt2085 = 11, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Chromaticity-derived non-constant luminance system
|
||||
|
/// </summary>
|
||||
|
ChromaDerivedNcl = 12, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Chromaticity-derived constant luminance system
|
||||
|
/// </summary>
|
||||
|
ChromaDerivedCl = 13, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.2100-2 ICtCp
|
||||
|
/// </summary>
|
||||
|
ICtCp = 14, |
||||
|
} |
||||
|
|
||||
|
#pragma warning restore CA1707 // Underscores in enum members
|
||||
@ -0,0 +1,109 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Metadata.Profiles.Cicp; |
||||
|
|
||||
|
#pragma warning disable CA1707 // Underscores in enum values
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Transfer characteristics according to ITU-T H.273 / ISO/IEC 23091-2_2019 subclause 8.2
|
||||
|
/// /// </summary>
|
||||
|
public enum CicpTransferCharacteristics : byte |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.709-6
|
||||
|
/// (functionally the same as the values 6, 14 and 15)
|
||||
|
/// </summary>
|
||||
|
ItuRBt709_6 = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Image characteristics are unknown or are determined by the application.
|
||||
|
/// </summary>
|
||||
|
Unspecified = 2, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Assumed display gamma 2.2
|
||||
|
/// Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM
|
||||
|
/// </summary>
|
||||
|
Gamma2_2 = 4, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Assumed display gamma 2.8
|
||||
|
/// Rec. ITU-R BT.470-6 System B, G (historical)
|
||||
|
/// </summary>
|
||||
|
Gamma2_8 = 5, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.601-7 525 or 625
|
||||
|
/// Rec. ITU-R BT.1700-0 NTSC
|
||||
|
/// SMPTE ST 170 (2004)
|
||||
|
/// (functionally the same as the values 1, 14 and 15)
|
||||
|
/// </summary>
|
||||
|
ItuRBt601_7 = 6, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 240 (1999)
|
||||
|
/// </summary>
|
||||
|
SmpteSt240 = 7, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Linear transfer characteristics
|
||||
|
/// </summary>
|
||||
|
Linear = 8, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Logarithmic transfer characteristic (100:1 range)
|
||||
|
/// </summary>
|
||||
|
Log100 = 9, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)
|
||||
|
/// </summary>
|
||||
|
Log100Sqrt = 10, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IEC 61966-2-4
|
||||
|
/// </summary>
|
||||
|
Iec61966_2_4 = 11, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.1361-0 extended colour gamut system (historical)
|
||||
|
/// </summary>
|
||||
|
ItuRBt1361_0 = 12, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IEC 61966-2-1 sRGB or sYCC / Display P3
|
||||
|
/// </summary>
|
||||
|
Iec61966_2_1 = 13, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.2020-2 (10-bit system)
|
||||
|
/// (functionally the same as the values 1, 6 and 15)
|
||||
|
/// </summary>
|
||||
|
ItuRBt2020_2_10bit = 14, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Rec. ITU-R BT.2020-2 (12-bit system)
|
||||
|
/// (functionally the same as the values 1, 6 and 14)
|
||||
|
/// /// </summary>
|
||||
|
ItuRBt2020_2_12bit = 15, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 2084 (2014) for 10-, 12-, 14- and 16-bit systems
|
||||
|
/// Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system
|
||||
|
/// </summary>
|
||||
|
SmpteSt2084 = 16, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SMPTE ST 428-1 (2019)
|
||||
|
/// </summary>
|
||||
|
SmpteSt428_1 = 17, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// ARIB STD-B67 (2015)
|
||||
|
/// Rec. ITU-R BT.2100-2 hybrid log-gamma (HLG) system
|
||||
|
/// </summary>
|
||||
|
AribStdB67 = 18, |
||||
|
} |
||||
|
|
||||
|
#pragma warning restore CA1707 // Underscores in enum members
|
||||
Binary file not shown.
@ -0,0 +1,82 @@ |
|||||
|
// 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<TPixel>(TestImageProvider<TPixel> provider) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
using Image<TPixel> 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<Rgba32>(1, 1); |
||||
|
var original = CreateCicpProfile(); |
||||
|
image.Metadata.CicpProfile = original; |
||||
|
var encoder = new PngEncoder(); |
||||
|
|
||||
|
// act
|
||||
|
using Image<Rgba32> reloadedImage = WriteAndRead(image, encoder); |
||||
|
|
||||
|
// assert
|
||||
|
CicpProfile actual = reloadedImage.Metadata.CicpProfile ?? reloadedImage.Frames.RootFrame.Metadata.CicpProfile; |
||||
|
CicpProfileIsValidAndEqual(actual, original); |
||||
|
} |
||||
|
|
||||
|
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 CicpProfile CreateCicpProfile() |
||||
|
{ |
||||
|
var profile = new CicpProfile() |
||||
|
{ |
||||
|
ColorPrimaries = CicpColorPrimaries.ItuRBt2020_2, |
||||
|
TransferCharacteristics = CicpTransferCharacteristics.SmpteSt2084, |
||||
|
MatrixCoefficients = CicpMatrixCoefficients.Identity, |
||||
|
FullRange = true, |
||||
|
}; |
||||
|
return profile; |
||||
|
} |
||||
|
|
||||
|
private static void CicpProfileIsValidAndEqual(CicpProfile actual, CicpProfile original) |
||||
|
{ |
||||
|
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 Image<Rgba32> WriteAndRead(Image<Rgba32> image, IImageEncoder encoder) |
||||
|
{ |
||||
|
using (var memStream = new MemoryStream()) |
||||
|
{ |
||||
|
image.Save(memStream, encoder); |
||||
|
image.Dispose(); |
||||
|
|
||||
|
memStream.Position = 0; |
||||
|
return Image.Load<Rgba32>(memStream); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
version https://git-lfs.github.com/spec/v1 |
||||
|
oid sha256:650a933db9c4f76fa3e6a8ed35d061a5740c613acd1026d99461eb014d8947b2 |
||||
|
size 179015 |
||||
@ -0,0 +1,3 @@ |
|||||
|
version https://git-lfs.github.com/spec/v1 |
||||
|
oid sha256:8c50691da3b3af21ff4f8fc30f1313bc412b84fb0a07a5bf3b8b14eae7581ade |
||||
|
size 201440 |
||||
Loading…
Reference in new issue