diff --git a/src/ImageSharp.Formats.Png/IPngDecoderOptions.cs b/src/ImageSharp.Formats.Png/IPngDecoderOptions.cs
new file mode 100644
index 000000000..f60f3d1cd
--- /dev/null
+++ b/src/ImageSharp.Formats.Png/IPngDecoderOptions.cs
@@ -0,0 +1,20 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System.Text;
+
+ ///
+ /// Encapsulates the png decoder options.
+ ///
+ public interface IPngDecoderOptions : IDecoderOptions
+ {
+ ///
+ /// Gets the encoding that should be used when reading text chunks.
+ ///
+ Encoding TextEncoding { get; }
+ }
+}
diff --git a/src/ImageSharp.Formats.Png/PngDecoder.cs b/src/ImageSharp.Formats.Png/PngDecoder.cs
index 9aab6673a..c731ae448 100644
--- a/src/ImageSharp.Formats.Png/PngDecoder.cs
+++ b/src/ImageSharp.Formats.Png/PngDecoder.cs
@@ -34,7 +34,9 @@ namespace ImageSharp.Formats
public void Decode(Image image, Stream stream, IDecoderOptions options)
where TColor : struct, IPixel
{
- new PngDecoderCore().Decode(image, stream);
+ IPngDecoderOptions pngOptions = PngDecoderOptions.Create(options);
+
+ new PngDecoderCore(pngOptions).Decode(image, stream);
}
}
}
diff --git a/src/ImageSharp.Formats.Png/PngDecoderCore.cs b/src/ImageSharp.Formats.Png/PngDecoderCore.cs
index 47b09d5ff..4a5ad3648 100644
--- a/src/ImageSharp.Formats.Png/PngDecoderCore.cs
+++ b/src/ImageSharp.Formats.Png/PngDecoderCore.cs
@@ -64,6 +64,11 @@ namespace ImageSharp.Formats
///
private readonly char[] chars = new char[4];
+ ///
+ /// The decoder options.
+ ///
+ private readonly IPngDecoderOptions options;
+
///
/// Reusable crc for validating chunks.
///
@@ -120,6 +125,15 @@ namespace ImageSharp.Formats
ColorTypes.Add((int)PngColorType.RgbWithAlpha, new byte[] { 8 });
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The decoder options.
+ public PngDecoderCore(IPngDecoderOptions options)
+ {
+ this.options = options ?? new PngDecoderOptions();
+ }
+
///
/// Gets or sets the png color type
///
@@ -763,6 +777,11 @@ namespace ImageSharp.Formats
private void ReadTextChunk(Image image, byte[] data, int length)
where TColor : struct, IPixel
{
+ if (this.options.IgnoreMetadata)
+ {
+ return;
+ }
+
int zeroIndex = 0;
for (int i = 0; i < length; i++)
@@ -774,8 +793,8 @@ namespace ImageSharp.Formats
}
}
- string name = Encoding.Unicode.GetString(data, 0, zeroIndex);
- string value = Encoding.Unicode.GetString(data, zeroIndex + 1, length - zeroIndex - 1);
+ string name = this.options.TextEncoding.GetString(data, 0, zeroIndex);
+ string value = this.options.TextEncoding.GetString(data, zeroIndex + 1, length - zeroIndex - 1);
image.MetaData.Properties.Add(new ImageProperty(name, value));
}
diff --git a/src/ImageSharp.Formats.Png/PngDecoderOptions.cs b/src/ImageSharp.Formats.Png/PngDecoderOptions.cs
new file mode 100644
index 000000000..07c0c2739
--- /dev/null
+++ b/src/ImageSharp.Formats.Png/PngDecoderOptions.cs
@@ -0,0 +1,62 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System.Text;
+
+ ///
+ /// Encapsulates the png decoder options.
+ ///
+ public sealed class PngDecoderOptions : DecoderOptions, IPngDecoderOptions
+ {
+ private static readonly Encoding DefaultEncoding = Encoding.GetEncoding("ASCII");
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PngDecoderOptions()
+ {
+ this.InitializeWithDefaults();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The options for the decoder.
+ private PngDecoderOptions(IDecoderOptions options)
+ : base(options)
+ {
+ this.InitializeWithDefaults();
+ }
+
+ ///
+ /// Gets or sets the encoding that should be used when reading text chunks.
+ ///
+ public Encoding TextEncoding { get; set; }
+
+ ///
+ /// Converts the options to a instance with a cast
+ /// or by creating a new instance with the specfied options.
+ ///
+ /// The options for the decoder.
+ /// The options for the png decoder.
+ internal static IPngDecoderOptions Create(IDecoderOptions options)
+ {
+ IPngDecoderOptions pngOptions = options as IPngDecoderOptions;
+ if (pngOptions != null)
+ {
+ return pngOptions;
+ }
+
+ return new PngDecoderOptions(options);
+ }
+
+ private void InitializeWithDefaults()
+ {
+ this.TextEncoding = DefaultEncoding;
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderCoreTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderCoreTests.cs
new file mode 100644
index 000000000..3ee2ea826
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderCoreTests.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Tests
+{
+ using System.Text;
+ using Xunit;
+
+ using ImageSharp.Formats;
+
+ public class PngDecoderCoreTests
+ {
+ [Fact]
+ public void Decode_IgnoreMetadataIsFalse_TextChunckIsRead()
+ {
+ var options = new PngDecoderOptions()
+ {
+ IgnoreMetadata = false
+ };
+
+ TestFile testFile = TestFile.Create(TestImages.Png.Blur);
+
+ using (Image image = new Image(testFile.FilePath, options))
+ {
+ Assert.Equal(1, image.MetaData.Properties.Count);
+ Assert.Equal("Software", image.MetaData.Properties[0].Name);
+ Assert.Equal("paint.net 4.0.6", image.MetaData.Properties[0].Value);
+ }
+ }
+
+ [Fact]
+ public void Decode_IgnoreMetadataIsTrue_TextChunksAreIgnored()
+ {
+ var options = new PngDecoderOptions()
+ {
+ IgnoreMetadata = true
+ };
+
+ TestFile testFile = TestFile.Create(TestImages.Png.Blur);
+
+ using (Image image = new Image(testFile.FilePath, options))
+ {
+ Assert.Equal(0, image.MetaData.Properties.Count);
+ }
+ }
+
+ [Fact]
+ public void Decode_TextEncodingSetToUnicode_TextIsReadWithCorrectEncoding()
+ {
+ var options = new PngDecoderOptions()
+ {
+ TextEncoding = Encoding.Unicode
+ };
+
+ TestFile testFile = TestFile.Create(TestImages.Png.Blur);
+
+ using (Image image = new Image(testFile.FilePath, options))
+ {
+ Assert.Equal(1, image.MetaData.Properties.Count);
+ Assert.Equal("潓瑦慷敲", image.MetaData.Properties[0].Name);
+ }
+ }
+ }
+}
\ No newline at end of file