|
|
|
@ -16,6 +16,7 @@ using SixLabors.ImageSharp.Formats.Png.Filters; |
|
|
|
using SixLabors.ImageSharp.IO; |
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
using SixLabors.ImageSharp.Metadata; |
|
|
|
using SixLabors.ImageSharp.Metadata.Profiles.CICP; |
|
|
|
using SixLabors.ImageSharp.Metadata.Profiles.Exif; |
|
|
|
using SixLabors.ImageSharp.Metadata.Profiles.Icc; |
|
|
|
using SixLabors.ImageSharp.Metadata.Profiles.Xmp; |
|
|
|
@ -183,6 +184,9 @@ internal sealed class PngDecoderCore : IImageDecoderInternals |
|
|
|
case PngChunkType.Gamma: |
|
|
|
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); |
|
|
|
break; |
|
|
|
case PngChunkType.Cicp: |
|
|
|
ReadCicpChunk(metadata, chunk.Data.GetSpan()); |
|
|
|
break; |
|
|
|
case PngChunkType.FrameControl: |
|
|
|
frameCount++; |
|
|
|
if (frameCount == this.maxFrames) |
|
|
|
@ -352,6 +356,15 @@ internal sealed class PngDecoderCore : IImageDecoderInternals |
|
|
|
|
|
|
|
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); |
|
|
|
break; |
|
|
|
case PngChunkType.Cicp: |
|
|
|
if (this.colorMetadataOnly) |
|
|
|
{ |
|
|
|
this.SkipChunkDataAndCrc(chunk); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
ReadCicpChunk(metadata, chunk.Data.GetSpan()); |
|
|
|
break; |
|
|
|
case PngChunkType.FrameControl: |
|
|
|
++frameCount; |
|
|
|
if (frameCount == this.maxFrames) |
|
|
|
@ -1392,6 +1405,26 @@ internal sealed class PngDecoderCore : IImageDecoderInternals |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Reads the CICP color profile chunk.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="metadata">The metadata.</param>
|
|
|
|
/// <param name="data">The bytes containing the profile.</param>
|
|
|
|
private static void ReadCicpChunk(ImageMetadata metadata, ReadOnlySpan<byte> data) |
|
|
|
{ |
|
|
|
if (data.Length < 4) |
|
|
|
{ |
|
|
|
// Ignore invalid cICP chunks.
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
byte colorPrimaries = data[0]; |
|
|
|
byte transferFunction = data[1]; |
|
|
|
byte matrixCoefficients = data[2]; |
|
|
|
bool? fullRange = data[3] == 1 ? true : data[3] == 0 ? false : null; |
|
|
|
metadata.CicpProfile = new CicpProfile(colorPrimaries, transferFunction, matrixCoefficients, fullRange); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Reads exif data encoded into a text chunk with the name "raw profile type exif".
|
|
|
|
/// This method was used by ImageMagick, exiftool, exiv2, digiKam, etc, before the
|
|
|
|
|