diff --git a/src/ImageProcessorCore/Bootstrapper.cs b/src/ImageProcessorCore/Bootstrapper.cs
new file mode 100644
index 000000000..3f1e5c1fe
--- /dev/null
+++ b/src/ImageProcessorCore/Bootstrapper.cs
@@ -0,0 +1,62 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessorCore
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using ImageProcessorCore.Formats;
+
+ ///
+ /// Provides initialization code which allows extending the library.
+ ///
+ public class Bootstrapper
+ {
+ ///
+ /// A new instance Initializes a new instance of the class.
+ /// with lazy initialization.
+ ///
+ private static readonly Lazy Lazy = new Lazy(() => new Bootstrapper());
+
+ ///
+ /// The default list of supported
+ ///
+ private readonly List imageFormats;
+
+ ///
+ /// Prevents a default instance of the class from being created.
+ ///
+ private Bootstrapper()
+ {
+ this.imageFormats = new List(new List
+ {
+ new BmpFormat(),
+ new JpegFormat(),
+ new PngFormat(),
+ new GifFormat()
+ });
+ }
+
+ ///
+ /// Gets the current bootstrapper instance.
+ ///
+ public static Bootstrapper Instance = Lazy.Value;
+
+ ///
+ /// Gets the list of supported
+ ///
+ public IReadOnlyCollection ImageFormats => new ReadOnlyCollection(imageFormats);
+
+ ///
+ /// Adds a new to the collection of supported image formats.
+ ///
+ /// The new format to add.
+ public void AddImageFormat(IImageFormat format)
+ {
+ this.imageFormats.Add(format);
+ }
+ }
+}
diff --git a/src/ImageProcessorCore/Image.cs b/src/ImageProcessorCore/Image.cs
index e772ad2c0..acef0c4d3 100644
--- a/src/ImageProcessorCore/Image.cs
+++ b/src/ImageProcessorCore/Image.cs
@@ -7,6 +7,7 @@ namespace ImageProcessorCore
{
using System;
using System.Collections.Generic;
+ using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -18,8 +19,8 @@ namespace ImageProcessorCore
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
///
///
- /// The image data is always stored in BGRA format, where the blue, green, red, and
- /// alpha values are simple bytes.
+ /// The image data is always stored in RGBA format, where the red, green, blue, and
+ /// alpha values are floats.
///
[DebuggerDisplay("Image: {Width}x{Height}")]
public class Image : ImageBase, IImage
@@ -36,18 +37,6 @@ namespace ImageProcessorCore
///
public const double DefaultVerticalResolution = 96;
- ///
- /// The default collection of .
- ///
- private static readonly Lazy> DefaultFormats =
- new Lazy>(() => new List
- {
- new BmpFormat(),
- new JpegFormat(),
- new PngFormat(),
- new GifFormat()
- });
-
///
/// Initializes a new instance of the class.
///
@@ -55,7 +44,7 @@ namespace ImageProcessorCore
{
this.HorizontalResolution = DefaultHorizontalResolution;
this.VerticalResolution = DefaultVerticalResolution;
- this.CurrentImageFormat = DefaultFormats.Value.First(f => f.GetType() == typeof(PngFormat));
+ this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
}
///
@@ -69,7 +58,7 @@ namespace ImageProcessorCore
{
this.HorizontalResolution = DefaultHorizontalResolution;
this.VerticalResolution = DefaultVerticalResolution;
- this.CurrentImageFormat = DefaultFormats.Value.First(f => f.GetType() == typeof(PngFormat));
+ this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
}
///
@@ -92,6 +81,7 @@ namespace ImageProcessorCore
this.RepeatCount = other.RepeatCount;
this.HorizontalResolution = other.HorizontalResolution;
this.VerticalResolution = other.VerticalResolution;
+ this.Formats = other.Formats;
this.CurrentImageFormat = other.CurrentImageFormat;
}
@@ -112,7 +102,7 @@ namespace ImageProcessorCore
// Most likely a gif
// TODO: Should this be aproperty on ImageFrame?
- this.CurrentImageFormat = DefaultFormats.Value.First(f => f.GetType() == typeof(GifFormat));
+ this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(GifFormat));
}
///
@@ -125,7 +115,7 @@ namespace ImageProcessorCore
public Image(Stream stream)
{
Guard.NotNull(stream, nameof(stream));
- this.Load(stream, Formats);
+ this.Load(stream, Bootstrapper.Instance.ImageFormats.ToList());
}
///
@@ -141,13 +131,13 @@ namespace ImageProcessorCore
public Image(Stream stream, params IImageFormat[] formats)
{
Guard.NotNull(stream, nameof(stream));
- this.Load(stream, formats);
+ this.Load(stream, formats.ToList());
}
///
/// Gets a list of supported image formats.
///
- public static IList Formats => DefaultFormats.Value;
+ public IReadOnlyCollection Formats { get; internal set; } = Bootstrapper.Instance.ImageFormats;
///
public double HorizontalResolution { get; set; }
@@ -258,24 +248,24 @@ namespace ImageProcessorCore
this.Frames.Clear();
}
}
-
+
base.Dispose(disposing);
}
///
/// Loads the image from the given stream.
///
- ///
- /// The stream containing image information.
- ///
- ///
- /// The collection of .
- ///
+ /// The stream containing image information.
+ /// The collection of .
///
/// Thrown if the stream is not readable nor seekable.
///
private void Load(Stream stream, IList formats)
{
+ if (!formats.Any()) { return; }
+
+ this.Formats = new ReadOnlyCollection(formats);
+
if (!stream.CanRead)
{
throw new NotSupportedException("Cannot read from the stream.");
@@ -286,24 +276,21 @@ namespace ImageProcessorCore
throw new NotSupportedException("The stream does not support seeking.");
}
- if (formats.Count > 0)
+ int maxHeaderSize = formats.Max(x => x.Decoder.HeaderSize);
+ if (maxHeaderSize > 0)
{
- int maxHeaderSize = formats.Max(x => x.Decoder.HeaderSize);
- if (maxHeaderSize > 0)
- {
- byte[] header = new byte[maxHeaderSize];
+ byte[] header = new byte[maxHeaderSize];
- stream.Position = 0;
- stream.Read(header, 0, maxHeaderSize);
- stream.Position = 0;
+ stream.Position = 0;
+ stream.Read(header, 0, maxHeaderSize);
+ stream.Position = 0;
- IImageFormat format = formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header));
- if (format != null)
- {
- format.Decoder.Decode(this, stream);
- this.CurrentImageFormat = format;
- return;
- }
+ IImageFormat format = formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header));
+ if (format != null)
+ {
+ format.Decoder.Decode(this, stream);
+ this.CurrentImageFormat = format;
+ return;
}
}
diff --git a/src/ImageProcessorCore/ImageExtensions.cs b/src/ImageProcessorCore/ImageExtensions.cs
index aa10a2b08..0e9603b51 100644
--- a/src/ImageProcessorCore/ImageExtensions.cs
+++ b/src/ImageProcessorCore/ImageExtensions.cs
@@ -144,8 +144,10 @@ namespace ImageProcessorCore
: new Image
{
// Several properties require copying
+ // TODO: Check why we need to set these?
HorizontalResolution = source.HorizontalResolution,
VerticalResolution = source.VerticalResolution,
+ Formats = source.Formats,
CurrentImageFormat = source.CurrentImageFormat,
RepeatCount = source.RepeatCount
};