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.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.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[DebuggerDisplay("Image: {Width}x{Height}")]
public class Image : ImageBase, IImage
@ -36,18 +37,6 @@ namespace ImageProcessorCore
/// </summary>
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>
/// Initializes a new instance of the <see cref="Image"/> class.
/// </summary>
@ -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));
}
/// <summary>
@ -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));
}
/// <summary>
@ -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));
}
/// <summary>
@ -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());
}
/// <summary>
@ -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());
}
/// <summary>
/// Gets a list of supported image formats.
/// </summary>
public static IList<IImageFormat> Formats => DefaultFormats.Value;
public IReadOnlyCollection<IImageFormat> Formats { get; internal set; } = Bootstrapper.Instance.ImageFormats;
/// <inheritdoc/>
public double HorizontalResolution { get; set; }
@ -258,24 +248,24 @@ namespace ImageProcessorCore
this.Frames.Clear();
}
}
base.Dispose(disposing);
}
/// <summary>
/// Loads the image from the given stream.
/// </summary>
/// <param name="stream">
/// The stream containing image information.
/// </param>
/// <param name="formats">
/// The collection of <see cref="IImageFormat"/>.
/// </param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="formats">The collection of <see cref="IImageFormat"/>.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
private void Load(Stream stream, IList<IImageFormat> formats)
{
if (!formats.Any()) { return; }
this.Formats = new ReadOnlyCollection<IImageFormat>(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;
}
}

2
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
};

Loading…
Cancel
Save