|
|
@ -124,6 +124,13 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
this.ignoreMetadata = options.IgnoreMetadata; |
|
|
this.ignoreMetadata = options.IgnoreMetadata; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal PngDecoderCore(Configuration configuration, bool ignoreMetadata) |
|
|
|
|
|
{ |
|
|
|
|
|
this.Configuration = configuration ?? Configuration.Default; |
|
|
|
|
|
this.memoryAllocator = this.Configuration.MemoryAllocator; |
|
|
|
|
|
this.ignoreMetadata = ignoreMetadata; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
/// <inheritdoc/>
|
|
|
public Configuration Configuration { get; } |
|
|
public Configuration Configuration { get; } |
|
|
|
|
|
|
|
|
@ -168,12 +175,12 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
|
|
|
|
|
|
break; |
|
|
break; |
|
|
case PngChunkType.Palette: |
|
|
case PngChunkType.Palette: |
|
|
var pal = new byte[chunk.Length]; |
|
|
byte[] pal = new byte[chunk.Length]; |
|
|
chunk.Data.GetSpan().CopyTo(pal); |
|
|
chunk.Data.GetSpan().CopyTo(pal); |
|
|
this.palette = pal; |
|
|
this.palette = pal; |
|
|
break; |
|
|
break; |
|
|
case PngChunkType.Transparency: |
|
|
case PngChunkType.Transparency: |
|
|
var alpha = new byte[chunk.Length]; |
|
|
byte[] alpha = new byte[chunk.Length]; |
|
|
chunk.Data.GetSpan().CopyTo(alpha); |
|
|
chunk.Data.GetSpan().CopyTo(alpha); |
|
|
this.paletteAlpha = alpha; |
|
|
this.paletteAlpha = alpha; |
|
|
this.AssignTransparentMarkers(alpha, pngMetadata); |
|
|
this.AssignTransparentMarkers(alpha, pngMetadata); |
|
|
@ -190,7 +197,7 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
case PngChunkType.Exif: |
|
|
case PngChunkType.Exif: |
|
|
if (!this.ignoreMetadata) |
|
|
if (!this.ignoreMetadata) |
|
|
{ |
|
|
{ |
|
|
var exifData = new byte[chunk.Length]; |
|
|
byte[] exifData = new byte[chunk.Length]; |
|
|
chunk.Data.GetSpan().CopyTo(exifData); |
|
|
chunk.Data.GetSpan().CopyTo(exifData); |
|
|
metadata.ExifProfile = new ExifProfile(exifData); |
|
|
metadata.ExifProfile = new ExifProfile(exifData); |
|
|
} |
|
|
} |
|
|
@ -263,7 +270,7 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
case PngChunkType.Exif: |
|
|
case PngChunkType.Exif: |
|
|
if (!this.ignoreMetadata) |
|
|
if (!this.ignoreMetadata) |
|
|
{ |
|
|
{ |
|
|
var exifData = new byte[chunk.Length]; |
|
|
byte[] exifData = new byte[chunk.Length]; |
|
|
chunk.Data.GetSpan().CopyTo(exifData); |
|
|
chunk.Data.GetSpan().CopyTo(exifData); |
|
|
metadata.ExifProfile = new ExifProfile(exifData); |
|
|
metadata.ExifProfile = new ExifProfile(exifData); |
|
|
} |
|
|
} |
|
|
@ -364,11 +371,10 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
/// <param name="pngMetadata">The metadata to read to.</param>
|
|
|
/// <param name="pngMetadata">The metadata to read to.</param>
|
|
|
/// <param name="data">The data containing physical data.</param>
|
|
|
/// <param name="data">The data containing physical data.</param>
|
|
|
private void ReadGammaChunk(PngMetadata pngMetadata, ReadOnlySpan<byte> data) |
|
|
private void ReadGammaChunk(PngMetadata pngMetadata, ReadOnlySpan<byte> data) |
|
|
{ |
|
|
|
|
|
// The value is encoded as a 4-byte unsigned integer, representing gamma times 100000.
|
|
|
// The value is encoded as a 4-byte unsigned integer, representing gamma times 100000.
|
|
|
// For example, a gamma of 1/2.2 would be stored as 45455.
|
|
|
// For example, a gamma of 1/2.2 would be stored as 45455.
|
|
|
pngMetadata.Gamma = BinaryPrimitives.ReadUInt32BigEndian(data) / 100_000F; |
|
|
=> pngMetadata.Gamma = BinaryPrimitives.ReadUInt32BigEndian(data) / 100_000F; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Initializes the image and various buffers needed for processing
|
|
|
/// Initializes the image and various buffers needed for processing
|
|
|
@ -477,19 +483,17 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
private void ReadScanlines<TPixel>(PngChunk chunk, ImageFrame<TPixel> image, PngMetadata pngMetadata) |
|
|
private void ReadScanlines<TPixel>(PngChunk chunk, ImageFrame<TPixel> image, PngMetadata pngMetadata) |
|
|
where TPixel : unmanaged, IPixel<TPixel> |
|
|
where TPixel : unmanaged, IPixel<TPixel> |
|
|
{ |
|
|
{ |
|
|
using (var deframeStream = new ZlibInflateStream(this.currentStream, this.ReadNextDataChunk)) |
|
|
using var deframeStream = new ZlibInflateStream(this.currentStream, this.ReadNextDataChunk); |
|
|
{ |
|
|
deframeStream.AllocateNewBytes(chunk.Length, true); |
|
|
deframeStream.AllocateNewBytes(chunk.Length, true); |
|
|
DeflateStream dataStream = deframeStream.CompressedStream; |
|
|
DeflateStream dataStream = deframeStream.CompressedStream; |
|
|
|
|
|
|
|
|
|
|
|
if (this.header.InterlaceMethod == PngInterlaceMode.Adam7) |
|
|
if (this.header.InterlaceMethod == PngInterlaceMode.Adam7) |
|
|
{ |
|
|
{ |
|
|
this.DecodeInterlacedPixelData(dataStream, image, pngMetadata); |
|
|
this.DecodeInterlacedPixelData(dataStream, image, pngMetadata); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
this.DecodePixelData(dataStream, image, pngMetadata); |
|
|
this.DecodePixelData(dataStream, image, pngMetadata); |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|