diff --git a/samples/ChangeDefaultEncoderOptions/Program.cs b/samples/ChangeDefaultEncoderOptions/Program.cs
index 5ba6f52b5..b085e468a 100644
--- a/samples/ChangeDefaultEncoderOptions/Program.cs
+++ b/samples/ChangeDefaultEncoderOptions/Program.cs
@@ -1,5 +1,6 @@
using System;
using ImageSharp;
+using ImageSharp.Formats;
namespace ChangeDefaultEncoderOptions
{
@@ -14,22 +15,6 @@ namespace ChangeDefaultEncoderOptions
Quality = 90,
IgnoreMetadata = true
});
-
- // now lets say we don't want animated gifs, lets skip decoding the alternative frames
- Configuration.Default.SetMimeTypeDecoder("image/gif", new ImageSharp.Formats.GifDecoder()
- {
- IgnoreFrames = true,
- IgnoreMetadata = true
- });
-
- // and just to be douple sure we don't want animations lets disable them on encode too.
- Configuration.Default.SetMimeTypeEncoder("image/gif", new ImageSharp.Formats.GifEncoder()
- {
- IgnoreFrames = true,
- IgnoreMetadata = true
- });
-
-
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
index e1dc489f4..66af2fa75 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs
@@ -26,7 +26,7 @@ namespace ImageSharp.Formats
/// Formats will be supported in a later releases. We advise always
/// to use only 24 Bit Windows bitmaps.
///
- public class BmpDecoder : IImageDecoder
+ public class BmpDecoder : IImageDecoder, IBmpDecoderOptions
{
///
public Image Decode(Configuration configuration, Stream stream)
@@ -35,7 +35,7 @@ namespace ImageSharp.Formats
{
Guard.NotNull(stream, "stream");
- return new BmpDecoderCore(configuration).Decode(stream);
+ return new BmpDecoderCore(configuration, this).Decode(stream);
}
}
}
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index 997a77d6c..817d00f7e 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
@@ -52,7 +52,8 @@ namespace ImageSharp.Formats
/// Initializes a new instance of the class.
///
/// The configuration.
- public BmpDecoderCore(Configuration configuration)
+ /// The options
+ public BmpDecoderCore(Configuration configuration, IBmpDecoderOptions options)
{
this.configuration = configuration;
}
diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoder.cs b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs
index f47bedb81..b0064a508 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoder.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs
@@ -15,7 +15,7 @@ namespace ImageSharp.Formats
/// Image encoder for writing an image to a stream as a Windows bitmap.
///
/// The encoder can currently only write 24-bit rgb images to streams.
- public class BmpEncoder : IImageEncoder
+ public class BmpEncoder : IImageEncoder, IBmpEncoderOptions
{
///
/// Gets or sets the number of bits per pixel.
@@ -26,8 +26,7 @@ namespace ImageSharp.Formats
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
{
- BmpEncoderCore encoder = new BmpEncoderCore();
- encoder.BitsPerPixel = this.BitsPerPixel;
+ var encoder = new BmpEncoderCore(this);
encoder.Encode(image, stream);
}
}
diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
index daff65cbc..e41c29501 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
@@ -23,16 +23,18 @@ namespace ImageSharp.Formats
private int padding;
///
- /// Initializes a new instance of the class.
+ /// Gets or sets the number of bits per pixel.
///
- public BmpEncoderCore()
- {
- }
+ private BmpBitsPerPixel bitsPerPixel;
///
- /// Gets or sets the number of bits per pixel.
+ /// Initializes a new instance of the class.
///
- public BmpBitsPerPixel BitsPerPixel { get; internal set; } = BmpBitsPerPixel.Pixel24;
+ /// The encoder options
+ public BmpEncoderCore(IBmpEncoderOptions options)
+ {
+ this.bitsPerPixel = options.BitsPerPixel;
+ }
///
/// Encodes the image to the specified stream from the .
@@ -47,9 +49,9 @@ namespace ImageSharp.Formats
Guard.NotNull(stream, nameof(stream));
// Cast to int will get the bytes per pixel
- short bpp = (short)(8 * (int)this.BitsPerPixel);
+ short bpp = (short)(8 * (int)this.bitsPerPixel);
int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);
- this.padding = bytesPerLine - (image.Width * (int)this.BitsPerPixel);
+ this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel);
// Do not use IDisposable pattern here as we want to preserve the stream.
EndianBinaryWriter writer = new EndianBinaryWriter(Endianness.LittleEndian, stream);
@@ -134,7 +136,7 @@ namespace ImageSharp.Formats
{
using (PixelAccessor pixels = image.Lock())
{
- switch (this.BitsPerPixel)
+ switch (this.bitsPerPixel)
{
case BmpBitsPerPixel.Pixel32:
this.Write32Bit(writer, pixels);
diff --git a/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs b/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs
new file mode 100644
index 000000000..9285b9cf7
--- /dev/null
+++ b/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs
@@ -0,0 +1,21 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Image decoder options for decoding Windows bitmap streams.
+ ///
+ internal interface IBmpDecoderOptions
+ {
+ // added this for consistancy so we can add stuff as required, no options currently availible
+ }
+}
diff --git a/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs b/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs
new file mode 100644
index 000000000..dd17043fa
--- /dev/null
+++ b/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs
@@ -0,0 +1,25 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Configuration options for use during bmp encoding
+ ///
+ /// The encoder can currently only write 24-bit rgb images to streams.
+ internal interface IBmpEncoderOptions
+ {
+ ///
+ /// Gets the number of bits per pixel.
+ ///
+ BmpBitsPerPixel BitsPerPixel { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs
index caf39c2e1..e026cc29b 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoder.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoder.cs
@@ -14,18 +14,13 @@ namespace ImageSharp.Formats
///
/// Decoder for generating an image out of a gif encoded stream.
///
- public class GifDecoder : IImageDecoder
+ public class GifDecoder : IImageDecoder, IGifDecoderOptions
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
///
public bool IgnoreMetadata { get; set; } = false;
- ///
- /// Gets or sets a value indicating whether the additional frames should be ignored when the image is being decoded.
- ///
- public bool IgnoreFrames { get; set; } = false;
-
///
/// Gets or sets the encoding that should be used when reading comments.
///
@@ -35,9 +30,7 @@ namespace ImageSharp.Formats
public Image Decode(Configuration configuration, Stream stream)
where TPixel : struct, IPixel
{
- var decoder = new GifDecoderCore(this.TextEncoding, configuration);
- decoder.IgnoreMetadata = this.IgnoreMetadata;
- decoder.IgnoreFrames = this.IgnoreFrames;
+ var decoder = new GifDecoderCore(configuration, this);
return decoder.Decode(stream);
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index ad34009b6..bbecf32dd 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
@@ -78,11 +78,12 @@ namespace ImageSharp.Formats
///
/// Initializes a new instance of the class.
///
- /// The decoder encoding.
/// The configuration.
- public GifDecoderCore(Encoding encoding, Configuration configuration)
+ /// The decoder options.
+ public GifDecoderCore(Configuration configuration, IGifDecoderOptions options)
{
- this.TextEncoding = encoding ?? GifConstants.DefaultEncoding;
+ this.TextEncoding = options.TextEncoding ?? GifConstants.DefaultEncoding;
+ this.IgnoreMetadata = options.IgnoreMetadata;
this.configuration = configuration ?? Configuration.Default;
}
@@ -96,11 +97,6 @@ namespace ImageSharp.Formats
///
public Encoding TextEncoding { get; private set; }
- ///
- /// Gets or sets a value indicating whether the additional frames should be ignored when the image is being decoded.
- ///
- public bool IgnoreFrames { get; internal set; }
-
///
/// Decodes the stream to the image.
///
@@ -362,13 +358,6 @@ namespace ImageSharp.Formats
/// The
private unsafe void ReadFrameColors(byte[] indices, byte[] colorTable, int colorTableLength, GifImageDescriptor descriptor)
{
- if (this.IgnoreFrames && this.image != null)
- {
- // we already have our images skip this
- // TODO move this higher up the stack to prevent some of the data loading higher up.
- return;
- }
-
int imageWidth = this.logicalScreenDescriptor.Width;
int imageHeight = this.logicalScreenDescriptor.Height;
diff --git a/src/ImageSharp/Formats/Gif/GifEncoder.cs b/src/ImageSharp/Formats/Gif/GifEncoder.cs
index ee78c3266..b725f1260 100644
--- a/src/ImageSharp/Formats/Gif/GifEncoder.cs
+++ b/src/ImageSharp/Formats/Gif/GifEncoder.cs
@@ -15,18 +15,13 @@ namespace ImageSharp.Formats
///
/// Image encoder for writing image data to a stream in gif format.
///
- public class GifEncoder : IImageEncoder
+ public class GifEncoder : IImageEncoder, IGifEncoderOptions
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being encoded.
///
public bool IgnoreMetadata { get; set; } = false;
- ///
- /// Gets or sets a value indicating whether the additional frames should be ignored when the image is being encoded.
- ///
- public bool IgnoreFrames { get; set; } = false;
-
///
/// Gets or sets the encoding that should be used when writing comments.
///
@@ -51,12 +46,7 @@ namespace ImageSharp.Formats
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
{
- GifEncoderCore encoder = new GifEncoderCore(this.TextEncoding);
- encoder.Quantizer = this.Quantizer;
- encoder.Threshold = this.Threshold;
- encoder.PaletteSize = this.PaletteSize;
- encoder.IgnoreMetadata = this.IgnoreMetadata;
- encoder.IgnoreFrames = this.IgnoreFrames;
+ GifEncoderCore encoder = new GifEncoderCore(this);
encoder.Encode(image, stream);
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
index 3191aafc9..81b3cfba4 100644
--- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
@@ -35,44 +35,44 @@ namespace ImageSharp.Formats
///
private bool hasFrames;
- ///
- /// Initializes a new instance of the class.
- ///
- /// The encoding for the encoder.
- public GifEncoderCore(Encoding encoding)
- {
- this.TextEncoding = encoding ?? GifConstants.DefaultEncoding;
- }
-
///
/// Gets the TextEncoding
///
- public Encoding TextEncoding { get; private set; }
+ private Encoding textEncoding;
///
/// Gets or sets the quantizer for reducing the color count.
///
- public IQuantizer Quantizer { get; set; }
+ private IQuantizer quantizer;
///
/// Gets or sets the threshold.
///
- public byte Threshold { get; internal set; }
+ private byte threshold;
///
/// Gets or sets the size of the color palette to use.
///
- public int PaletteSize { get; internal set; }
+ private int paletteSize;
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
///
- public bool IgnoreMetadata { get; internal set; }
+ private bool ignoreMetadata;
///
- /// Gets or sets a value indicating whether the additional frames should be ignored when the image is being encoded.
+ /// Initializes a new instance of the class.
///
- public bool IgnoreFrames { get; internal set; }
+ /// The options for the encoder.
+ public GifEncoderCore(IGifEncoderOptions options)
+ {
+ this.textEncoding = options.TextEncoding ?? GifConstants.DefaultEncoding;
+
+ this.quantizer = options.Quantizer;
+ this.threshold = options.Threshold;
+ this.paletteSize = options.PaletteSize;
+ this.ignoreMetadata = options.IgnoreMetadata;
+ }
///
/// Encodes the image to the specified stream from the .
@@ -86,22 +86,22 @@ namespace ImageSharp.Formats
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
- this.Quantizer = this.Quantizer ?? new OctreeQuantizer();
+ this.quantizer = this.quantizer ?? new OctreeQuantizer();
// Do not use IDisposable pattern here as we want to preserve the stream.
var writer = new EndianBinaryWriter(Endianness.LittleEndian, stream);
// Ensure that pallete size can be set but has a fallback.
- int paletteSize = this.PaletteSize;
+ int paletteSize = this.paletteSize;
paletteSize = paletteSize > 0 ? paletteSize.Clamp(1, 256) : 256;
// Get the number of bits.
this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(paletteSize);
- this.hasFrames = !this.IgnoreFrames && image.Frames.Any();
+ this.hasFrames = image.Frames.Any();
// Dithering when animating gifs is a bad idea as we introduce pixel tearing across frames.
- var ditheredQuantizer = (IQuantizer)this.Quantizer;
+ var ditheredQuantizer = (IQuantizer)this.quantizer;
ditheredQuantizer.Dither = !this.hasFrames;
// Quantize the image returning a palette.
@@ -260,7 +260,7 @@ namespace ImageSharp.Formats
private void WriteComments(Image image, EndianBinaryWriter writer)
where TPixel : struct, IPixel
{
- if (this.IgnoreMetadata)
+ if (this.ignoreMetadata)
{
return;
}
@@ -271,7 +271,7 @@ namespace ImageSharp.Formats
return;
}
- byte[] comments = this.TextEncoding.GetBytes(property.Value);
+ byte[] comments = this.textEncoding.GetBytes(property.Value);
int count = Math.Min(comments.Length, 255);
diff --git a/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs b/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs
new file mode 100644
index 000000000..caaa8932b
--- /dev/null
+++ b/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs
@@ -0,0 +1,29 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Text;
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Decoder for generating an image out of a gif encoded stream.
+ ///
+ internal interface IGifDecoderOptions
+ {
+ ///
+ /// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
+ ///
+ bool IgnoreMetadata { get; }
+
+ ///
+ /// Gets the encoding that should be used when reading comments.
+ ///
+ Encoding TextEncoding { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Gif/IGifEncoderOptions.cs b/src/ImageSharp/Formats/Gif/IGifEncoderOptions.cs
new file mode 100644
index 000000000..c38ec7e45
--- /dev/null
+++ b/src/ImageSharp/Formats/Gif/IGifEncoderOptions.cs
@@ -0,0 +1,45 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Text;
+ using ImageSharp.PixelFormats;
+ using ImageSharp.Quantizers;
+
+ ///
+ /// The configuration options used for encoding gifs
+ ///
+ internal interface IGifEncoderOptions
+ {
+ ///
+ /// Gets a value indicating whether the metadata should be ignored when the image is being encoded.
+ ///
+ bool IgnoreMetadata { get; }
+
+ ///
+ /// Gets the encoding that should be used when writing comments.
+ ///
+ Encoding TextEncoding { get; }
+
+ ///
+ /// Gets the size of the color palette to use. For gifs the value ranges from 1 to 256. Leave as zero for default size.
+ ///
+ int PaletteSize { get; }
+
+ ///
+ /// Gets the transparency threshold.
+ ///
+ byte Threshold { get; }
+
+ ///
+ /// Gets the quantizer for reducing the color count.
+ ///
+ IQuantizer Quantizer { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Jpeg/IJpegDecoderOptions.cs b/src/ImageSharp/Formats/Jpeg/IJpegDecoderOptions.cs
new file mode 100644
index 000000000..6830e2e4a
--- /dev/null
+++ b/src/ImageSharp/Formats/Jpeg/IJpegDecoderOptions.cs
@@ -0,0 +1,24 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Image decoder for generating an image out of a jpg stream.
+ ///
+ internal interface IJpegDecoderOptions
+ {
+ ///
+ /// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
+ ///
+ bool IgnoreMetadata { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs b/src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs
new file mode 100644
index 000000000..947c98ee2
--- /dev/null
+++ b/src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs
@@ -0,0 +1,37 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Encoder for writing the data image to a stream in jpeg format.
+ ///
+ internal interface IJpegEncoderOptions
+ {
+ ///
+ /// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
+ ///
+ bool IgnoreMetadata { get; }
+
+ ///
+ /// Gets the quality, that will be used to encode the image. Quality
+ /// index must be between 0 and 100 (compression from max to min).
+ ///
+ /// The quality of the jpg image from 0 to 100.
+ int Quality { get; }
+
+ ///
+ /// Gets the subsample ration, that will be used to encode the image.
+ ///
+ /// The subsample ratio of the jpg image.
+ JpegSubsample? Subsample { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
index b809908e9..0dc186697 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
@@ -14,7 +14,7 @@ namespace ImageSharp.Formats
///
/// Image decoder for generating an image out of a jpg stream.
///
- public class JpegDecoder : IImageDecoder
+ public class JpegDecoder : IImageDecoder, IJpegDecoderOptions
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
@@ -27,9 +27,8 @@ namespace ImageSharp.Formats
{
Guard.NotNull(stream, "stream");
- using (JpegDecoderCore decoder = new JpegDecoderCore(configuration))
+ using (JpegDecoderCore decoder = new JpegDecoderCore(configuration, this))
{
- decoder.IgnoreMetadata = this.IgnoreMetadata;
return decoder.Decode(stream);
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index f6456620e..1ce78a8b1 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -99,8 +99,10 @@ namespace ImageSharp.Formats
/// Initializes a new instance of the class.
///
/// The configuration.
- public JpegDecoderCore(Configuration configuration)
+ /// The options.
+ public JpegDecoderCore(Configuration configuration, IJpegDecoderOptions options)
{
+ this.IgnoreMetadata = options.IgnoreMetadata;
this.configuration = configuration ?? Configuration.Default;
this.HuffmanTrees = HuffmanTree.CreateHuffmanTrees();
this.QuantizationTables = new Block8x8F[MaxTq + 1];
@@ -184,9 +186,9 @@ namespace ImageSharp.Formats
public int TotalMCUCount => this.MCUCountX * this.MCUCountY;
///
- /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
+ /// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
///
- public bool IgnoreMetadata { get; internal set; }
+ public bool IgnoreMetadata { get; private set; }
///
/// Decodes the image from the specified and sets
diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
index d0be9eaf8..350856471 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
@@ -14,7 +14,7 @@ namespace ImageSharp.Formats
///
/// Encoder for writing the data image to a stream in jpeg format.
///
- public class JpegEncoder : IImageEncoder
+ public class JpegEncoder : IImageEncoder, IJpegEncoderOptions
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
@@ -43,19 +43,7 @@ namespace ImageSharp.Formats
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
{
- JpegEncoderCore encoder = new JpegEncoderCore();
-
- var quality = this.Quality;
- if (quality == 0)
- {
- quality = 75;
- }
-
- encoder.Quality = quality;
- encoder.Subsample = this.Subsample ?? (quality >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420);
-
- encoder.IgnoreMetadata = this.IgnoreMetadata;
-
+ var encoder = new JpegEncoderCore(this);
encoder.Encode(image, stream);
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
index 168e47311..2d67f6735 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
@@ -149,29 +149,40 @@ namespace ImageSharp.Formats
///
private Stream outputStream;
- ///
- /// Initializes a new instance of the class.
- ///
- public JpegEncoderCore()
- {
- }
-
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
///
- public bool IgnoreMetadata { get; internal set; } = false;
+ private bool ignoreMetadata = false;
///
/// Gets or sets the quality, that will be used to encode the image. Quality
/// index must be between 0 and 100 (compression from max to min).
///
/// The quality of the jpg image from 0 to 100.
- public int Quality { get; internal set; }
+ private int quality = 0;
///
/// Gets or sets the subsampling method to use.
///
- public JpegSubsample? Subsample { get; internal set; }
+ private JpegSubsample? subsample;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The options
+ public JpegEncoderCore(IJpegEncoderOptions options)
+ {
+ int quality = options.Quality;
+ if (quality == 0)
+ {
+ quality = 75;
+ }
+
+ this.quality = quality;
+ this.subsample = options.Subsample ?? (quality >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420);
+
+ this.ignoreMetadata = options.IgnoreMetadata;
+ }
///
/// Encode writes the image to the jpeg baseline format with the given options.
@@ -193,11 +204,11 @@ namespace ImageSharp.Formats
this.outputStream = stream;
- int quality = this.Quality.Clamp(1, 100);
+ int quality = this.quality.Clamp(1, 100);
// Convert from a quality rating to a scaling factor.
int scale;
- if (this.Quality < 50)
+ if (this.quality < 50)
{
scale = 5000 / quality;
}
@@ -785,7 +796,7 @@ namespace ImageSharp.Formats
private void WriteProfiles(Image image)
where TPixel : struct, IPixel
{
- if (this.IgnoreMetadata)
+ if (this.ignoreMetadata)
{
return;
}
@@ -807,7 +818,7 @@ namespace ImageSharp.Formats
byte[] subsamples = { 0x22, 0x11, 0x11 };
byte[] chroma = { 0x00, 0x01, 0x01 };
- switch (this.Subsample)
+ switch (this.subsample)
{
case JpegSubsample.Ratio444:
subsamples = new byte[] { 0x11, 0x11, 0x11 };
@@ -863,7 +874,7 @@ namespace ImageSharp.Formats
// TODO: We should allow grayscale writing.
this.outputStream.Write(SosHeaderYCbCr, 0, SosHeaderYCbCr.Length);
- switch (this.Subsample)
+ switch (this.subsample)
{
case JpegSubsample.Ratio444:
this.Encode444(pixels);
diff --git a/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs b/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs
new file mode 100644
index 000000000..de163ba7e
--- /dev/null
+++ b/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs
@@ -0,0 +1,29 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Text;
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// The optioas for decoding png images
+ ///
+ internal interface IPngDecoderOptions
+ {
+ ///
+ /// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
+ ///
+ bool IgnoreMetadata { get; }
+
+ ///
+ /// Gets the encoding that should be used when reading text chunks.
+ ///
+ Encoding TextEncoding { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs b/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
new file mode 100644
index 000000000..8f0a4cd82
--- /dev/null
+++ b/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
@@ -0,0 +1,64 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats
+{
+ using System.Collections.Generic;
+ using System.IO;
+
+ using ImageSharp.PixelFormats;
+ using ImageSharp.Quantizers;
+
+ ///
+ /// The options availible for manipulating the encoder pipeline
+ ///
+ internal interface IPngEncoderOptions
+ {
+ ///
+ /// Gets a value indicating whether the metadata should be ignored when the image is being encoded.
+ ///
+ bool IgnoreMetadata { get; }
+
+ ///
+ /// Gets the size of the color palette to use. Set to zero to leav png encoding to use pixel data.
+ ///
+ int PaletteSize { get; }
+
+ ///
+ /// Gets the png color type
+ ///
+ PngColorType PngColorType { get; }
+
+ ///
+ /// Gets the compression level 1-9.
+ /// Defaults to 6.
+ ///
+ int CompressionLevel { get; }
+
+ ///
+ /// Gets the gamma value, that will be written
+ /// the the stream, when the property
+ /// is set to true. The default value is 2.2F.
+ ///
+ /// The gamma value of the image.
+ float Gamma { get; }
+
+ ///
+ /// Gets quantizer for reducing the color count.
+ ///
+ IQuantizer Quantizer { get; }
+
+ ///
+ /// Gets the transparency threshold.
+ ///
+ byte Threshold { get; }
+
+ ///
+ /// Gets a value indicating whether this instance should write
+ /// gamma information to the stream. The default value is false.
+ ///
+ bool WriteGamma { get; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs
index c9fab8e3f..2e177bc21 100644
--- a/src/ImageSharp/Formats/Png/PngDecoder.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoder.cs
@@ -31,7 +31,7 @@ namespace ImageSharp.Formats
///
///
///
- public class PngDecoder : IImageDecoder
+ public class PngDecoder : IImageDecoder, IPngDecoderOptions
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
@@ -53,8 +53,7 @@ namespace ImageSharp.Formats
public Image Decode(Configuration configuration, Stream stream)
where TPixel : struct, IPixel
{
- var decoder = new PngDecoderCore(configuration, this.TextEncoding);
- decoder.IgnoreMetadata = this.IgnoreMetadata;
+ var decoder = new PngDecoderCore(configuration, this);
return decoder.Decode(stream);
}
}
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index b1b98eca5..aef588f25 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -155,25 +155,26 @@ namespace ImageSharp.Formats
private PngColorType pngColorType;
///
- /// Initializes a new instance of the class.
+ /// Gets the encoding to use
///
- /// The configuration.
- /// The text encoding.
- public PngDecoderCore(Configuration configuration, Encoding encoding)
- {
- this.configuration = configuration ?? Configuration.Default;
- this.TextEncoding = encoding ?? PngConstants.DefaultEncoding;
- }
+ private Encoding textEncoding;
///
- /// Gets the encoding to use
+ /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
///
- public Encoding TextEncoding { get; private set; }
+ private bool ignoreMetadata;
///
- /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
+ /// Initializes a new instance of the class.
///
- public bool IgnoreMetadata { get; internal set; }
+ /// The configuration.
+ /// The decoder options.
+ public PngDecoderCore(Configuration configuration, IPngDecoderOptions options)
+ {
+ this.configuration = configuration ?? Configuration.Default;
+ this.textEncoding = options.TextEncoding ?? PngConstants.DefaultEncoding;
+ this.ignoreMetadata = options.IgnoreMetadata;
+ }
///
/// Decodes the stream to the image.
@@ -900,7 +901,7 @@ namespace ImageSharp.Formats
/// The maximum length to read.
private void ReadTextChunk(ImageMetaData metadata, byte[] data, int length)
{
- if (this.IgnoreMetadata)
+ if (this.ignoreMetadata)
{
return;
}
@@ -916,8 +917,8 @@ namespace ImageSharp.Formats
}
}
- string name = this.TextEncoding.GetString(data, 0, zeroIndex);
- string value = this.TextEncoding.GetString(data, zeroIndex + 1, length - zeroIndex - 1);
+ string name = this.textEncoding.GetString(data, 0, zeroIndex);
+ string value = this.textEncoding.GetString(data, zeroIndex + 1, length - zeroIndex - 1);
metadata.Properties.Add(new ImageProperty(name, value));
}
diff --git a/src/ImageSharp/Formats/Png/PngEncoder.cs b/src/ImageSharp/Formats/Png/PngEncoder.cs
index 8d5b09d0c..f0d332fc4 100644
--- a/src/ImageSharp/Formats/Png/PngEncoder.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoder.cs
@@ -14,7 +14,7 @@ namespace ImageSharp.Formats
///
/// Image encoder for writing image data to a stream in png format.
///
- public class PngEncoder : IImageEncoder
+ public class PngEncoder : IImageEncoder, IPngEncoderOptions
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being encoded.
@@ -70,18 +70,8 @@ namespace ImageSharp.Formats
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
{
- using (var encoder = new PngEncoderCore())
+ using (var encoder = new PngEncoderCore(this))
{
- encoder.IgnoreMetadata = this.IgnoreMetadata;
-
- encoder.PaletteSize = this.PaletteSize > 0 ? this.PaletteSize.Clamp(1, int.MaxValue) : int.MaxValue;
- encoder.PngColorType = this.PngColorType;
- encoder.CompressionLevel = this.CompressionLevel;
- encoder.Gamma = this.Gamma;
- encoder.Quantizer = this.Quantizer;
- encoder.Threshold = this.Threshold;
- encoder.WriteGamma = this.WriteGamma;
-
encoder.Encode(image, stream);
}
}
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index c0cd0ffaf..cfbd0c449 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -118,52 +118,51 @@ namespace ImageSharp.Formats
///
private IQuantizer quantizer;
- ///
- /// Initializes a new instance of the class.
- ///
- public PngEncoderCore()
- {
- }
-
///
/// Gets or sets a value indicating whether to ignore metadata
///
- public bool IgnoreMetadata { get; internal set; }
-
- ///
- /// Gets or sets the Quality value
- ///
- public int PaletteSize { get; internal set; }
+ private bool ignoreMetadata;
///
/// Gets or sets the Quality value
///
- public PngColorType PngColorType { get; internal set; }
+ private int paletteSize;
///
/// Gets or sets the CompressionLevel value
///
- public int CompressionLevel { get; internal set; }
+ private int compressionLevel;
///
/// Gets or sets the Gamma value
///
- public float Gamma { get; internal set; }
+ private float gamma;
///
- /// Gets or sets the Quantizer value
+ /// Gets or sets the Threshold value
///
- public IQuantizer Quantizer { get; internal set; }
+ private byte threshold;
///
- /// Gets or sets the Threshold value
+ /// Gets or sets a value indicating whether to Write Gamma
///
- public byte Threshold { get; internal set; }
+ private bool writeGamma;
///
- /// Gets or sets a value indicating whether to Write Gamma
+ /// Initializes a new instance of the class.
///
- public bool WriteGamma { get; internal set; }
+ /// The options for influancing the encoder
+ public PngEncoderCore(IPngEncoderOptions options)
+ {
+ this.ignoreMetadata = options.IgnoreMetadata;
+ this.paletteSize = options.PaletteSize > 0 ? options.PaletteSize.Clamp(1, int.MaxValue) : int.MaxValue;
+ this.pngColorType = options.PngColorType;
+ this.compressionLevel = options.CompressionLevel;
+ this.gamma = options.Gamma;
+ this.quantizer = options.Quantizer;
+ this.threshold = options.Threshold;
+ this.writeGamma = options.WriteGamma;
+ }
///
/// Encodes the image to the specified stream from the .
@@ -192,23 +191,20 @@ namespace ImageSharp.Formats
stream.Write(this.chunkDataBuffer, 0, 8);
- this.pngColorType = this.PngColorType;
- this.quantizer = this.Quantizer;
-
// Set correct color type if the color count is 256 or less.
- if (this.PaletteSize <= 256)
+ if (this.paletteSize <= 256)
{
this.pngColorType = PngColorType.Palette;
}
- if (this.pngColorType == PngColorType.Palette && this.PaletteSize > 256)
+ if (this.pngColorType == PngColorType.Palette && this.paletteSize > 256)
{
- this.PaletteSize = 256;
+ this.paletteSize = 256;
}
// Set correct bit depth.
- this.bitDepth = this.PaletteSize <= 256
- ? (byte)ImageMaths.GetBitsNeededForColorDepth(this.PaletteSize).Clamp(1, 8)
+ this.bitDepth = this.paletteSize <= 256
+ ? (byte)ImageMaths.GetBitsNeededForColorDepth(this.paletteSize).Clamp(1, 8)
: (byte)8;
// Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk
@@ -538,7 +534,7 @@ namespace ImageSharp.Formats
private QuantizedImage WritePaletteChunk(Stream stream, PngHeader header, ImageBase image)
where TPixel : struct, IPixel
{
- if (this.PaletteSize > 256)
+ if (this.paletteSize > 256)
{
return null;
}
@@ -549,7 +545,7 @@ namespace ImageSharp.Formats
}
// Quantize the image returning a palette. This boxing is icky.
- QuantizedImage quantized = ((IQuantizer)this.quantizer).Quantize(image, this.PaletteSize);
+ QuantizedImage quantized = ((IQuantizer)this.quantizer).Quantize(image, this.paletteSize);
// Grab the palette and write it to the stream.
TPixel[] palette = quantized.Palette;
@@ -576,7 +572,7 @@ namespace ImageSharp.Formats
colorTable[offset + 1] = bytes[1];
colorTable[offset + 2] = bytes[2];
- if (alpha > this.Threshold)
+ if (alpha > this.threshold)
{
alpha = 255;
}
@@ -634,9 +630,9 @@ namespace ImageSharp.Formats
/// The containing image data.
private void WriteGammaChunk(Stream stream)
{
- if (this.WriteGamma)
+ if (this.writeGamma)
{
- int gammaValue = (int)(this.Gamma * 100000F);
+ int gammaValue = (int)(this.gamma * 100000F);
byte[] size = BitConverter.GetBytes(gammaValue);
@@ -679,7 +675,7 @@ namespace ImageSharp.Formats
try
{
memoryStream = new MemoryStream();
- using (var deflateStream = new ZlibDeflateStream(memoryStream, this.CompressionLevel))
+ using (var deflateStream = new ZlibDeflateStream(memoryStream, this.compressionLevel))
{
for (int y = 0; y < this.height; y++)
{
diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
index cc7935fbf..06bfd8990 100644
--- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
@@ -18,19 +18,6 @@ namespace ImageSharp.Tests
public static readonly string[] TestFiles = { TestImages.Gif.Giphy, TestImages.Gif.Rings, TestImages.Gif.Trans };
- [Fact]
- public void SkipDecodingFrames()
- {
- var file = TestFile.GetPath(TestImages.Gif.Giphy);
-
- using (Image image = Image.Load(file, new GifDecoder() { IgnoreFrames = true }))
- using (Image imageWithFrames = Image.Load(file, new GifDecoder() { IgnoreFrames = false }))
- {
- Assert.NotEmpty(imageWithFrames.Frames);
- Assert.Empty(image.Frames);
- }
- }
-
[Theory]
[WithFileCollection(nameof(TestFiles), PixelTypes)]
public void DecodeAndReSave(TestImageProvider imageProvider)
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
index ab4850ecf..9401d098d 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
@@ -90,7 +90,7 @@ namespace ImageSharp.Tests
image.Save(ms, new JpegEncoder());
ms.Seek(0, SeekOrigin.Begin);
- using (JpegDecoderCore decoder = new JpegDecoderCore(null))
+ using (JpegDecoderCore decoder = new JpegDecoderCore(null, new JpegDecoder()))
{
Image mirror = decoder.Decode(ms);