diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 11c4d831b0..024bd62216 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -124,31 +124,6 @@ namespace SixLabors.ImageSharp.Formats.Png
///
private PngColorType pngColorType;
- ///
- /// Represents any color in an 8 bit Rgb24 encoded png that should be transparent
- ///
- private Rgb24 rgb24Trans;
-
- ///
- /// Represents any color in a 16 bit Rgb24 encoded png that should be transparent
- ///
- private Rgb48 rgb48Trans;
-
- ///
- /// Represents any color in an 8 bit grayscale encoded png that should be transparent
- ///
- private byte luminanceTrans;
-
- ///
- /// Represents any color in a 16 bit grayscale encoded png that should be transparent
- ///
- private ushort luminance16Trans;
-
- ///
- /// Whether the image has transparency chunk and markers were decoded
- ///
- private bool hasTrans;
-
///
/// The next chunk of data to return
///
@@ -213,7 +188,7 @@ namespace SixLabors.ImageSharp.Formats.Png
using (var deframeStream = new ZlibInflateStream(this.currentStream, this.ReadNextDataChunk))
{
deframeStream.AllocateNewBytes(chunk.Length);
- this.ReadScanlines(deframeStream.CompressedStream, image.Frames.RootFrame);
+ this.ReadScanlines(deframeStream.CompressedStream, image.Frames.RootFrame, pngMetaData);
}
break;
@@ -226,7 +201,7 @@ namespace SixLabors.ImageSharp.Formats.Png
byte[] alpha = new byte[chunk.Length];
Buffer.BlockCopy(chunk.Data.Array, 0, alpha, 0, chunk.Length);
this.paletteAlpha = alpha;
- this.AssignTransparentMarkers(alpha);
+ this.AssignTransparentMarkers(alpha, pngMetaData);
break;
case PngChunkType.Text:
this.ReadTextChunk(metaData, chunk.Data.Array.AsSpan(0, chunk.Length));
@@ -331,7 +306,9 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte ReadByteLittleEndian(ReadOnlySpan buffer, int offset)
- => (byte)(((buffer[offset] & 0xFF) << 16) | (buffer[offset + 1] & 0xFF));
+ {
+ return (byte)(((buffer[offset] & 0xFF) << 16) | (buffer[offset + 1] & 0xFF));
+ }
///
/// Attempts to convert a byte array to a new array where each value in the original array is represented by the
@@ -496,16 +473,17 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The containing data.
/// The pixel data.
- private void ReadScanlines(Stream dataStream, ImageFrame image)
+ /// The png meta data
+ private void ReadScanlines(Stream dataStream, ImageFrame image, PngMetaData pngMetaData)
where TPixel : struct, IPixel
{
if (this.header.InterlaceMethod == PngInterlaceMode.Adam7)
{
- this.DecodeInterlacedPixelData(dataStream, image);
+ this.DecodeInterlacedPixelData(dataStream, image, pngMetaData);
}
else
{
- this.DecodePixelData(dataStream, image);
+ this.DecodePixelData(dataStream, image, pngMetaData);
}
}
@@ -515,7 +493,8 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The compressed pixel data stream.
/// The image to decode to.
- private void DecodePixelData(Stream compressedStream, ImageFrame image)
+ /// The png meta data
+ private void DecodePixelData(Stream compressedStream, ImageFrame image, PngMetaData pngMetaData)
where TPixel : struct, IPixel
{
while (this.currentRow < this.header.Height)
@@ -555,7 +534,7 @@ namespace SixLabors.ImageSharp.Formats.Png
throw new ImageFormatException("Unknown filter type.");
}
- this.ProcessDefilteredScanline(scanlineSpan, image);
+ this.ProcessDefilteredScanline(scanlineSpan, image, pngMetaData);
this.SwapBuffers();
this.currentRow++;
@@ -569,7 +548,8 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The compressed pixel data stream.
/// The current image.
- private void DecodeInterlacedPixelData(Stream compressedStream, ImageFrame image)
+ /// The png meta data
+ private void DecodeInterlacedPixelData(Stream compressedStream, ImageFrame image, PngMetaData pngMetaData)
where TPixel : struct, IPixel
{
while (true)
@@ -626,7 +606,7 @@ namespace SixLabors.ImageSharp.Formats.Png
}
Span rowSpan = image.GetPixelRowSpan(this.currentRow);
- this.ProcessInterlacedDefilteredScanline(this.scanline.GetSpan(), rowSpan, Adam7.FirstColumn[this.pass], Adam7.ColumnIncrement[this.pass]);
+ this.ProcessInterlacedDefilteredScanline(this.scanline.GetSpan(), rowSpan, pngMetaData, Adam7.FirstColumn[this.pass], Adam7.ColumnIncrement[this.pass]);
this.SwapBuffers();
@@ -654,7 +634,8 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The de-filtered scanline
/// The image
- private void ProcessDefilteredScanline(ReadOnlySpan defilteredScanline, ImageFrame pixels)
+ /// The png meta data
+ private void ProcessDefilteredScanline(ReadOnlySpan defilteredScanline, ImageFrame pixels, PngMetaData pngMetaData)
where TPixel : struct, IPixel
{
Span rowSpan = pixels.GetPixelRowSpan(this.currentRow);
@@ -674,9 +655,9 @@ namespace SixLabors.ImageSharp.Formats.Png
this.header,
scanlineSpan,
rowSpan,
- this.hasTrans,
- this.luminance16Trans,
- this.luminanceTrans);
+ pngMetaData.HasTrans,
+ pngMetaData.Luminance16Trans,
+ pngMetaData.LuminanceTrans);
break;
@@ -708,9 +689,9 @@ namespace SixLabors.ImageSharp.Formats.Png
rowSpan,
this.bytesPerPixel,
this.bytesPerSample,
- this.hasTrans,
- this.rgb48Trans,
- this.rgb24Trans);
+ pngMetaData.HasTrans,
+ pngMetaData.Rgb48Trans,
+ pngMetaData.Rgb24Trans);
break;
@@ -735,9 +716,10 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The de-filtered scanline
/// The current image row.
+ /// The png meta data
/// The column start index. Always 0 for none interlaced images.
/// The column increment. Always 1 for none interlaced images.
- private void ProcessInterlacedDefilteredScanline(ReadOnlySpan defilteredScanline, Span rowSpan, int pixelOffset = 0, int increment = 1)
+ private void ProcessInterlacedDefilteredScanline(ReadOnlySpan defilteredScanline, Span rowSpan, PngMetaData pngMetaData, int pixelOffset = 0, int increment = 1)
where TPixel : struct, IPixel
{
// Trim the first marker byte from the buffer
@@ -757,9 +739,9 @@ namespace SixLabors.ImageSharp.Formats.Png
rowSpan,
pixelOffset,
increment,
- this.hasTrans,
- this.luminance16Trans,
- this.luminanceTrans);
+ pngMetaData.HasTrans,
+ pngMetaData.Luminance16Trans,
+ pngMetaData.LuminanceTrans);
break;
@@ -796,9 +778,9 @@ namespace SixLabors.ImageSharp.Formats.Png
increment,
this.bytesPerPixel,
this.bytesPerSample,
- this.hasTrans,
- this.rgb48Trans,
- this.rgb24Trans);
+ pngMetaData.HasTrans,
+ pngMetaData.Rgb48Trans,
+ pngMetaData.Rgb24Trans);
break;
@@ -822,7 +804,8 @@ namespace SixLabors.ImageSharp.Formats.Png
/// Decodes and assigns marker colors that identify transparent pixels in non indexed images
///
/// The alpha tRNS array
- private void AssignTransparentMarkers(ReadOnlySpan alpha)
+ /// The png meta data
+ private void AssignTransparentMarkers(ReadOnlySpan alpha, PngMetaData pngMetaData)
{
if (this.pngColorType == PngColorType.Rgb)
{
@@ -834,16 +817,16 @@ namespace SixLabors.ImageSharp.Formats.Png
ushort gc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(2, 2));
ushort bc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(4, 2));
- this.rgb48Trans = new Rgb48(rc, gc, bc);
- this.hasTrans = true;
+ pngMetaData.Rgb48Trans = new Rgb48(rc, gc, bc);
+ pngMetaData.HasTrans = true;
return;
}
byte r = ReadByteLittleEndian(alpha, 0);
byte g = ReadByteLittleEndian(alpha, 2);
byte b = ReadByteLittleEndian(alpha, 4);
- this.rgb24Trans = new Rgb24(r, g, b);
- this.hasTrans = true;
+ pngMetaData.Rgb24Trans = new Rgb24(r, g, b);
+ pngMetaData.HasTrans = true;
}
}
else if (this.pngColorType == PngColorType.Grayscale)
@@ -852,14 +835,14 @@ namespace SixLabors.ImageSharp.Formats.Png
{
if (this.header.BitDepth == 16)
{
- this.luminance16Trans = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2));
+ pngMetaData.Luminance16Trans = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2));
}
else
{
- this.luminanceTrans = ReadByteLittleEndian(alpha, 0);
+ pngMetaData.LuminanceTrans = ReadByteLittleEndian(alpha, 0);
}
- this.hasTrans = true;
+ pngMetaData.HasTrans = true;
}
}
}
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index 7ae716aa05..411d5d69b2 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -290,6 +290,11 @@ namespace SixLabors.ImageSharp.Formats.Png
this.WritePaletteChunk(stream, quantized);
}
+ if (pngMetaData.HasTrans)
+ {
+ //Write transparency header
+ }
+
this.WritePhysicalChunk(stream, metaData);
this.WriteGammaChunk(stream);
this.WriteExifChunk(stream, metaData);
diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs
index 9c76765146..0014defbb9 100644
--- a/src/ImageSharp/Formats/Png/PngMetaData.cs
+++ b/src/ImageSharp/Formats/Png/PngMetaData.cs
@@ -1,6 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using SixLabors.ImageSharp.PixelFormats;
+
namespace SixLabors.ImageSharp.Formats.Png
{
///
@@ -42,6 +44,31 @@ namespace SixLabors.ImageSharp.Formats.Png
///
public float Gamma { get; set; }
+ ///
+ /// Gets or sets the Rgb 24 transparent color. This represents any color in an 8 bit Rgb24 encoded png that should be transparent
+ ///
+ public Rgb24 Rgb24Trans { get; set; }
+
+ ///
+ /// Gets or sets the Rgb 48 transparent color. This represents any color in a 16 bit Rgb24 encoded png that should be transparent
+ ///
+ public Rgb48 Rgb48Trans { get; set; }
+
+ ///
+ /// Gets or sets the 8 bit grayscale transparent color. This represents any color in an 8 bit grayscale encoded png that should be transparent
+ ///
+ public byte LuminanceTrans { get; set; }
+
+ ///
+ /// Gets or sets the 16 bit grayscale transparent color. This represents any color in a 16 bit grayscale encoded png that should be transparent
+ ///
+ public ushort Luminance16Trans { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the image has transparency chunk and markers were decoded
+ ///
+ public bool HasTrans { get; set; }
+
///
public IDeepCloneable DeepClone() => new PngMetaData(this);
}
diff --git a/src/ImageSharp/MetaData/ImageMetaData.cs b/src/ImageSharp/MetaData/ImageMetaData.cs
index 73549d98aa..ec9037479b 100644
--- a/src/ImageSharp/MetaData/ImageMetaData.cs
+++ b/src/ImageSharp/MetaData/ImageMetaData.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.MetaData.Profiles.Exif;
using SixLabors.ImageSharp.MetaData.Profiles.Icc;
+using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.MetaData
{