Browse Source

Add Bootstrapper

Former-commit-id: 3697a99fa9f1578be79fe7c25ab0c80621284486
Former-commit-id: dff38d2a7517949e251371504082ec4d767f257e
Former-commit-id: daa364a34287743b2bc6cf667268c7059a9aa9f4
pull/1/head
James Jackson-South 10 years ago
parent
commit
e46266737b
  1. 62
      src/ImageProcessorCore/Bootstrapper.cs
  2. 71
      src/ImageProcessorCore/Image.cs
  3. 2
      src/ImageProcessorCore/ImageExtensions.cs

62
src/ImageProcessorCore/Bootstrapper.cs

@ -0,0 +1,62 @@
// <copyright file="Bootstrapper.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessorCore
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ImageProcessorCore.Formats;
/// <summary>
/// Provides initialization code which allows extending the library.
/// </summary>
public class Bootstrapper
{
/// <summary>
/// A new instance Initializes a new instance of the <see cref="Bootstrapper"/> class.
/// with lazy initialization.
/// </summary>
private static readonly Lazy<Bootstrapper> Lazy = new Lazy<Bootstrapper>(() => new Bootstrapper());
/// <summary>
/// The default list of supported <see cref="IImageFormat"/>
/// </summary>
private readonly List<IImageFormat> imageFormats;
/// <summary>
/// Prevents a default instance of the <see cref="Bootstrapper"/> class from being created.
/// </summary>
private Bootstrapper()
{
this.imageFormats = new List<IImageFormat>(new List<IImageFormat>
{
new BmpFormat(),
new JpegFormat(),
new PngFormat(),
new GifFormat()
});
}
/// <summary>
/// Gets the current bootstrapper instance.
/// </summary>
public static Bootstrapper Instance = Lazy.Value;
/// <summary>
/// Gets the list of supported <see cref="IImageFormat"/>
/// </summary>
public IReadOnlyCollection<IImageFormat> ImageFormats => new ReadOnlyCollection<IImageFormat>(imageFormats);
/// <summary>
/// Adds a new <see cref="IImageFormat"/> to the collection of supported image formats.
/// </summary>
/// <param name="format">The new format to add.</param>
public void AddImageFormat(IImageFormat format)
{
this.imageFormats.Add(format);
}
}
}

71
src/ImageProcessorCore/Image.cs

@ -7,6 +7,7 @@ namespace ImageProcessorCore
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; 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. /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// The image data is always stored in BGRA format, where the blue, green, red, and /// The image data is always stored in RGBA format, where the red, green, blue, and
/// alpha values are simple bytes. /// alpha values are floats.
/// </remarks> /// </remarks>
[DebuggerDisplay("Image: {Width}x{Height}")] [DebuggerDisplay("Image: {Width}x{Height}")]
public class Image : ImageBase, IImage public class Image : ImageBase, IImage
@ -36,18 +37,6 @@ namespace ImageProcessorCore
/// </summary> /// </summary>
public const double DefaultVerticalResolution = 96; public const double DefaultVerticalResolution = 96;
/// <summary>
/// The default collection of <see cref="IImageFormat"/>.
/// </summary>
private static readonly Lazy<List<IImageFormat>> DefaultFormats =
new Lazy<List<IImageFormat>>(() => new List<IImageFormat>
{
new BmpFormat(),
new JpegFormat(),
new PngFormat(),
new GifFormat()
});
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Image"/> class. /// Initializes a new instance of the <see cref="Image"/> class.
/// </summary> /// </summary>
@ -55,7 +44,7 @@ namespace ImageProcessorCore
{ {
this.HorizontalResolution = DefaultHorizontalResolution; this.HorizontalResolution = DefaultHorizontalResolution;
this.VerticalResolution = DefaultVerticalResolution; this.VerticalResolution = DefaultVerticalResolution;
this.CurrentImageFormat = DefaultFormats.Value.First(f => f.GetType() == typeof(PngFormat)); this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
} }
/// <summary> /// <summary>
@ -69,7 +58,7 @@ namespace ImageProcessorCore
{ {
this.HorizontalResolution = DefaultHorizontalResolution; this.HorizontalResolution = DefaultHorizontalResolution;
this.VerticalResolution = DefaultVerticalResolution; this.VerticalResolution = DefaultVerticalResolution;
this.CurrentImageFormat = DefaultFormats.Value.First(f => f.GetType() == typeof(PngFormat)); this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
} }
/// <summary> /// <summary>
@ -92,6 +81,7 @@ namespace ImageProcessorCore
this.RepeatCount = other.RepeatCount; this.RepeatCount = other.RepeatCount;
this.HorizontalResolution = other.HorizontalResolution; this.HorizontalResolution = other.HorizontalResolution;
this.VerticalResolution = other.VerticalResolution; this.VerticalResolution = other.VerticalResolution;
this.Formats = other.Formats;
this.CurrentImageFormat = other.CurrentImageFormat; this.CurrentImageFormat = other.CurrentImageFormat;
} }
@ -112,7 +102,7 @@ namespace ImageProcessorCore
// Most likely a gif // Most likely a gif
// TODO: Should this be aproperty on ImageFrame? // 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));
} }
/// <summary> /// <summary>
@ -125,7 +115,7 @@ namespace ImageProcessorCore
public Image(Stream stream) public Image(Stream stream)
{ {
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
this.Load(stream, Formats); this.Load(stream, Bootstrapper.Instance.ImageFormats.ToList());
} }
/// <summary> /// <summary>
@ -141,13 +131,13 @@ namespace ImageProcessorCore
public Image(Stream stream, params IImageFormat[] formats) public Image(Stream stream, params IImageFormat[] formats)
{ {
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
this.Load(stream, formats); this.Load(stream, formats.ToList());
} }
/// <summary> /// <summary>
/// Gets a list of supported image formats. /// Gets a list of supported image formats.
/// </summary> /// </summary>
public static IList<IImageFormat> Formats => DefaultFormats.Value; public IReadOnlyCollection<IImageFormat> Formats { get; internal set; } = Bootstrapper.Instance.ImageFormats;
/// <inheritdoc/> /// <inheritdoc/>
public double HorizontalResolution { get; set; } public double HorizontalResolution { get; set; }
@ -258,24 +248,24 @@ namespace ImageProcessorCore
this.Frames.Clear(); this.Frames.Clear();
} }
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
/// <summary> /// <summary>
/// Loads the image from the given stream. /// Loads the image from the given stream.
/// </summary> /// </summary>
/// <param name="stream"> /// <param name="stream">The stream containing image information.</param>
/// The stream containing image information. /// <param name="formats">The collection of <see cref="IImageFormat"/>.</param>
/// </param>
/// <param name="formats">
/// The collection of <see cref="IImageFormat"/>.
/// </param>
/// <exception cref="NotSupportedException"> /// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable. /// Thrown if the stream is not readable nor seekable.
/// </exception> /// </exception>
private void Load(Stream stream, IList<IImageFormat> formats) private void Load(Stream stream, IList<IImageFormat> formats)
{ {
if (!formats.Any()) { return; }
this.Formats = new ReadOnlyCollection<IImageFormat>(formats);
if (!stream.CanRead) if (!stream.CanRead)
{ {
throw new NotSupportedException("Cannot read from the stream."); throw new NotSupportedException("Cannot read from the stream.");
@ -286,24 +276,21 @@ namespace ImageProcessorCore
throw new NotSupportedException("The stream does not support seeking."); 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); byte[] header = new byte[maxHeaderSize];
if (maxHeaderSize > 0)
{
byte[] header = new byte[maxHeaderSize];
stream.Position = 0; stream.Position = 0;
stream.Read(header, 0, maxHeaderSize); stream.Read(header, 0, maxHeaderSize);
stream.Position = 0; stream.Position = 0;
IImageFormat format = formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header)); IImageFormat format = formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header));
if (format != null) if (format != null)
{ {
format.Decoder.Decode(this, stream); format.Decoder.Decode(this, stream);
this.CurrentImageFormat = format; this.CurrentImageFormat = format;
return; return;
}
} }
} }

2
src/ImageProcessorCore/ImageExtensions.cs

@ -144,8 +144,10 @@ namespace ImageProcessorCore
: new Image : new Image
{ {
// Several properties require copying // Several properties require copying
// TODO: Check why we need to set these?
HorizontalResolution = source.HorizontalResolution, HorizontalResolution = source.HorizontalResolution,
VerticalResolution = source.VerticalResolution, VerticalResolution = source.VerticalResolution,
Formats = source.Formats,
CurrentImageFormat = source.CurrentImageFormat, CurrentImageFormat = source.CurrentImageFormat,
RepeatCount = source.RepeatCount RepeatCount = source.RepeatCount
}; };

Loading…
Cancel
Save