mirror of https://github.com/SixLabors/ImageSharp
56 changed files with 1943 additions and 698 deletions
@ -0,0 +1,66 @@ |
|||
// <copyright file="Image.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Diagnostics; |
|||
using System.IO; |
|||
|
|||
using Formats; |
|||
|
|||
/// <summary>
|
|||
/// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha
|
|||
/// packed into a single unsigned integer value.
|
|||
/// </summary>
|
|||
public sealed partial class Image |
|||
{ |
|||
/// <summary>
|
|||
/// Create a new instance of the <see cref="Image{TColor}"/> class
|
|||
/// with the height and the width of the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="width">The width of the image in pixels.</param>
|
|||
/// <param name="height">The height of the image in pixels.</param>
|
|||
/// <param name="metadata">The images matadata to preload.</param>
|
|||
/// <param name="configuration">
|
|||
/// The configuration providing initialization code which allows extending the library.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// A new <see cref="Image{TColor}"/> unless <typeparamref name="TColor"/> is <see cref="Color"/> in which case it returns <see cref="Image" />
|
|||
/// </returns>
|
|||
internal static Image<TColor> Create<TColor>(int width, int height, ImageMetaData metadata, Configuration configuration) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
if (typeof(TColor) == typeof(Color)) |
|||
{ |
|||
return new Image(width, height, metadata, configuration) as Image<TColor>; |
|||
} |
|||
else |
|||
{ |
|||
return new Image<TColor>(width, height, metadata, configuration); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a new instance of the <see cref="Image{TColor}"/> class
|
|||
/// with the height and the width of the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="width">The width of the image in pixels.</param>
|
|||
/// <param name="height">The height of the image in pixels.</param>
|
|||
/// <param name="configuration">
|
|||
/// The configuration providing initialization code which allows extending the library.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// A new <see cref="Image{TColor}"/> unless <typeparamref name="TColor"/> is <see cref="Color"/> in which case it returns <see cref="Image" />
|
|||
/// </returns>
|
|||
internal static Image<TColor> Create<TColor>(int width, int height, Configuration configuration) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Image.Create<TColor>(width, height, null, configuration); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
// <copyright file="Image.Decode.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Buffers; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Formats; |
|||
|
|||
/// <summary>
|
|||
/// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha
|
|||
/// packed into a single unsigned integer value.
|
|||
/// </summary>
|
|||
public sealed partial class Image |
|||
{ |
|||
/// <summary>
|
|||
/// By reading the header on the provided stream this calculates the images format.
|
|||
/// </summary>
|
|||
/// <param name="stream">The image stream to read the header from.</param>
|
|||
/// <param name="config">The configuration.</param>
|
|||
/// <returns>The image format or null if none found.</returns>
|
|||
private static IImageFormat DiscoverFormat(Stream stream, Configuration config) |
|||
{ |
|||
// This is probably a candidate for making into a public API in the future!
|
|||
int maxHeaderSize = config.MaxHeaderSize; |
|||
if (maxHeaderSize <= 0) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
IImageFormat format; |
|||
byte[] header = ArrayPool<byte>.Shared.Rent(maxHeaderSize); |
|||
try |
|||
{ |
|||
long startPosition = stream.Position; |
|||
stream.Read(header, 0, maxHeaderSize); |
|||
stream.Position = startPosition; |
|||
format = config.ImageFormats.FirstOrDefault(x => x.IsSupportedFileFormat(header)); |
|||
} |
|||
finally |
|||
{ |
|||
ArrayPool<byte>.Shared.Return(header); |
|||
} |
|||
|
|||
return format; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Decodes the image stream to the current image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <param name="config">the configuration.</param>
|
|||
/// <returns>
|
|||
/// The decoded image
|
|||
/// </returns>
|
|||
private static Image<TColor> Decode<TColor>(Stream stream, IDecoderOptions options, Configuration config) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
IImageFormat format = DiscoverFormat(stream, config); |
|||
if (format == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
Image<TColor> img = format.Decoder.Decode<TColor>(config, stream, options); |
|||
img.CurrentImageFormat = format; |
|||
return img; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,212 @@ |
|||
// <copyright file="Image.FromStream.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.IO; |
|||
using Formats; |
|||
|
|||
/// <summary>
|
|||
/// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha
|
|||
/// packed into a single unsigned integer value.
|
|||
/// </summary>
|
|||
public sealed partial class Image |
|||
{ |
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(byte[] data) |
|||
{ |
|||
return Load(null, data, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(byte[] data, IDecoderOptions options) |
|||
{ |
|||
return Load(null, data, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <param name="config">The config for the decoder.</param>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Configuration config, byte[] data) |
|||
{ |
|||
return Load(config, data, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(byte[] data, IImageDecoder decoder) |
|||
{ |
|||
return Load(data, decoder, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <param name="config">The configuration options.</param>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Configuration config, byte[] data, IDecoderOptions options) |
|||
{ |
|||
using (MemoryStream ms = new MemoryStream(data)) |
|||
{ |
|||
return Load(config, ms, options); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(byte[] data, IImageDecoder decoder, IDecoderOptions options) |
|||
{ |
|||
using (MemoryStream ms = new MemoryStream(data)) |
|||
{ |
|||
return Load(ms, decoder, options); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(byte[] data) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(null, data, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(byte[] data, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(null, data, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="config">The config for the decoder.</param>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Configuration config, byte[] data) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(config, data, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(byte[] data, IImageDecoder decoder) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(data, decoder, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="config">The configuration options.</param>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Configuration config, byte[] data, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
using (MemoryStream ms = new MemoryStream(data)) |
|||
{ |
|||
return Load<TColor>(config, ms, options); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given byte array.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="data">The byte array containing image data.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(byte[] data, IImageDecoder decoder, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
using (MemoryStream ms = new MemoryStream(data)) |
|||
{ |
|||
return Load<TColor>(ms, decoder, options); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,214 @@ |
|||
// <copyright file="Image.FromStream.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
#if !NETSTANDARD1_1
|
|||
using System; |
|||
using System.IO; |
|||
using Formats; |
|||
|
|||
/// <summary>
|
|||
/// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha
|
|||
/// packed into a single unsigned integer value.
|
|||
/// </summary>
|
|||
public sealed partial class Image |
|||
{ |
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(string path) |
|||
{ |
|||
return Load(null, path, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(string path, IDecoderOptions options) |
|||
{ |
|||
return Load(null, path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <param name="config">The config for the decoder.</param>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Configuration config, string path) |
|||
{ |
|||
return Load(config, path, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(string path, IImageDecoder decoder) |
|||
{ |
|||
return Load(path, decoder, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(string path, IImageDecoder decoder, IDecoderOptions options) |
|||
{ |
|||
return new Image(Load<Color>(path, decoder, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <param name="config">The configuration options.</param>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Configuration config, string path, IDecoderOptions options) |
|||
{ |
|||
config = config ?? Configuration.Default; |
|||
using (Stream s = config.FileSystem.OpenRead(path)) |
|||
{ |
|||
return Load(config, s, options); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(string path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(null, path, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(string path, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(null, path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="config">The config for the decoder.</param>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Configuration config, string path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(config, path, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(string path, IImageDecoder decoder) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(path, decoder, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="config">The configuration options.</param>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Configuration config, string path, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
config = config ?? Configuration.Default; |
|||
using (Stream s = config.FileSystem.OpenRead(path)) |
|||
{ |
|||
return Load<TColor>(config, s, options); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given file.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="path">The file path to the image.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(string path, IImageDecoder decoder, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
Configuration config = Configuration.Default; |
|||
using (Stream s = config.FileSystem.OpenRead(path)) |
|||
{ |
|||
return Load<TColor>(s, decoder, options); |
|||
} |
|||
} |
|||
} |
|||
#endif
|
|||
} |
|||
@ -0,0 +1,246 @@ |
|||
// <copyright file="Image.FromStream.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.IO; |
|||
using System.Text; |
|||
using Formats; |
|||
|
|||
/// <summary>
|
|||
/// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha
|
|||
/// packed into a single unsigned integer value.
|
|||
/// </summary>
|
|||
public sealed partial class Image |
|||
{ |
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Stream stream) |
|||
{ |
|||
return Load(null, stream, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Stream stream, IDecoderOptions options) |
|||
{ |
|||
return Load(null, stream, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <param name="config">The config for the decoder.</param>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Configuration config, Stream stream) |
|||
{ |
|||
return Load(config, stream, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Stream stream, IImageDecoder decoder) |
|||
{ |
|||
return Load(stream, decoder, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <param name="config">The configuration options.</param>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Configuration config, Stream stream, IDecoderOptions options) |
|||
{ |
|||
Image<Color> image = Load<Color>(config, stream, options); |
|||
|
|||
return image as Image ?? new Image(image); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image Load(Stream stream, IImageDecoder decoder, IDecoderOptions options) |
|||
{ |
|||
Image<Color> image = new Image(Load<Color>(stream, decoder, options)); |
|||
|
|||
return image as Image ?? new Image(image); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Stream stream) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(null, stream, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Stream stream, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(null, stream, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="config">The config for the decoder.</param>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Configuration config, Stream stream) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(config, stream, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Stream stream, IImageDecoder decoder) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return Load<TColor>(stream, decoder, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="decoder">The decoder.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Stream stream, IImageDecoder decoder, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return WithSeekableStream(stream, s => decoder.Decode<TColor>(Configuration.Default, s, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the image from the given stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The pixel format.</typeparam>
|
|||
/// <param name="config">The configuration options.</param>
|
|||
/// <param name="stream">The stream containing image information.</param>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <exception cref="NotSupportedException">
|
|||
/// Thrown if the stream is not readable nor seekable.
|
|||
/// </exception>
|
|||
/// <returns>The image</returns>
|
|||
public static Image<TColor> Load<TColor>(Configuration config, Stream stream, IDecoderOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
config = config ?? Configuration.Default; |
|||
|
|||
Image<TColor> img = WithSeekableStream(stream, s => Decode<TColor>(stream, options, config)); |
|||
|
|||
if (img != null) |
|||
{ |
|||
return img; |
|||
} |
|||
|
|||
StringBuilder stringBuilder = new StringBuilder(); |
|||
stringBuilder.AppendLine("Image cannot be loaded. Available formats:"); |
|||
|
|||
foreach (IImageFormat format in config.ImageFormats) |
|||
{ |
|||
stringBuilder.AppendLine("-" + format); |
|||
} |
|||
|
|||
throw new NotSupportedException(stringBuilder.ToString()); |
|||
} |
|||
|
|||
private static T WithSeekableStream<T>(Stream stream, Func<Stream, T> action) |
|||
{ |
|||
if (!stream.CanRead) |
|||
{ |
|||
throw new NotSupportedException("Cannot read from the stream."); |
|||
} |
|||
|
|||
if (stream.CanSeek) |
|||
{ |
|||
return action(stream); |
|||
} |
|||
else |
|||
{ |
|||
// We want to be able to load images from things like HttpContext.Request.Body
|
|||
using (MemoryStream ms = new MemoryStream()) |
|||
{ |
|||
stream.CopyTo(ms); |
|||
ms.Position = 0; |
|||
|
|||
return action(stream); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
# ImageSharp core libraries |
|||
|
|||
## Coding conventions |
|||
|
|||
### Argument ordering |
|||
|
|||
- When passing a `Configuration` object it should be the first argument |
|||
@ -0,0 +1,520 @@ |
|||
// <copyright file="PixelAccessorTests.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using ImageSharp.Formats; |
|||
using ImageSharp.IO; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
/// <summary>
|
|||
/// Tests the <see cref="Image"/> class.
|
|||
/// </summary>
|
|||
public class ImageLoadTests : IDisposable |
|||
{ |
|||
private readonly Mock<IFileSystem> fileSystem; |
|||
private readonly IDecoderOptions decoderOptions; |
|||
private Image<Color> returnImage; |
|||
private Mock<IImageDecoder> localDecoder; |
|||
private Mock<IImageFormat> localFormat; |
|||
private readonly string FilePath; |
|||
|
|||
public Configuration LocalConfiguration { get; private set; } |
|||
public byte[] Marker { get; private set; } |
|||
public MemoryStream DataStream { get; private set; } |
|||
public byte[] DecodedData { get; private set; } |
|||
|
|||
public ImageLoadTests() |
|||
{ |
|||
this.returnImage = new Image(1, 1); |
|||
|
|||
this.localDecoder = new Mock<IImageDecoder>(); |
|||
this.localFormat = new Mock<IImageFormat>(); |
|||
this.localFormat.Setup(x => x.Decoder).Returns(this.localDecoder.Object); |
|||
this.localFormat.Setup(x => x.Encoder).Returns(new Mock<IImageEncoder>().Object); |
|||
this.localFormat.Setup(x => x.MimeType).Returns("img/test"); |
|||
this.localFormat.Setup(x => x.Extension).Returns("png"); |
|||
this.localFormat.Setup(x => x.HeaderSize).Returns(1); |
|||
this.localFormat.Setup(x => x.IsSupportedFileFormat(It.IsAny<byte[]>())).Returns(true); |
|||
this.localFormat.Setup(x => x.SupportedExtensions).Returns(new string[] { "png", "jpg" }); |
|||
|
|||
this.localDecoder.Setup(x => x.Decode<Color>(It.IsAny<Configuration>(), It.IsAny<Stream>(), It.IsAny<IDecoderOptions>())) |
|||
|
|||
.Callback<Configuration, Stream, IDecoderOptions>((c, s, o) => { |
|||
using (var ms = new MemoryStream()) |
|||
{ |
|||
s.CopyTo(ms); |
|||
this.DecodedData = ms.ToArray(); |
|||
} |
|||
}) |
|||
.Returns(this.returnImage); |
|||
|
|||
this.fileSystem = new Mock<IFileSystem>(); |
|||
|
|||
this.LocalConfiguration = new Configuration(this.localFormat.Object) |
|||
{ |
|||
FileSystem = this.fileSystem.Object |
|||
}; |
|||
TestFormat.RegisterGloablTestFormat(); |
|||
this.Marker = Guid.NewGuid().ToByteArray(); |
|||
this.DataStream = TestFormat.GlobalTestFormat.CreateStream(this.Marker); |
|||
this.decoderOptions = new Mock<IDecoderOptions>().Object; |
|||
|
|||
this.FilePath = Guid.NewGuid().ToString(); |
|||
this.fileSystem.Setup(x => x.OpenRead(this.FilePath)).Returns(this.DataStream); |
|||
|
|||
TestFileSystem.RegisterGloablTestFormat(); |
|||
TestFileSystem.Global.AddFile(this.FilePath, this.DataStream); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStream() |
|||
{ |
|||
Image img = Image.Load(this.DataStream); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, null, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithType() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat.Sample<Color>(), img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, null, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithOptions() |
|||
{ |
|||
Image img = Image.Load(this.DataStream, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, this.decoderOptions, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithTypeAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat.Sample<Color>(), img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, this.decoderOptions, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithConfig() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image img = Image.Load(this.LocalConfiguration, stream); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, stream, null)); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithTypeAndConfig() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image<Color> img = Image.Load<Color>(this.LocalConfiguration, stream); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, stream, null)); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithConfigAndOptions() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image img = Image.Load(this.LocalConfiguration, stream, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, stream, this.decoderOptions)); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithTypeAndConfigAndOptions() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image<Color> img = Image.Load<Color>(this.LocalConfiguration, stream, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, stream, this.decoderOptions)); |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithDecoder() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image img = Image.Load(stream, this.localDecoder.Object); |
|||
|
|||
Assert.NotNull(img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, stream, null)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithTypeAndDecoder() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image<Color> img = Image.Load<Color>(stream, this.localDecoder.Object); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, stream, null)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithDecoderAndOptions() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image img = Image.Load(stream, this.localDecoder.Object, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, stream, this.decoderOptions)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromStreamWithTypeAndDecoderAndOptions() |
|||
{ |
|||
Stream stream = new MemoryStream(); |
|||
Image<Color> img = Image.Load<Color>(stream, this.localDecoder.Object, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, stream, this.decoderOptions)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytes() |
|||
{ |
|||
Image img = Image.Load(this.DataStream.ToArray()); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, null, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithType() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream.ToArray()); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat.Sample<Color>(), img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, null, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithOptions() |
|||
{ |
|||
Image img = Image.Load(this.DataStream.ToArray(), this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, this.decoderOptions, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithTypeAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream.ToArray(), this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat.Sample<Color>(), img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, this.decoderOptions, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithConfig() |
|||
{ |
|||
Image img = Image.Load(this.LocalConfiguration, this.DataStream.ToArray()); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, It.IsAny<Stream>(), null)); |
|||
|
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithTypeAndConfig() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.LocalConfiguration, this.DataStream.ToArray()); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, It.IsAny<Stream>(), null)); |
|||
|
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithConfigAndOptions() |
|||
{ |
|||
Image img = Image.Load(this.LocalConfiguration, this.DataStream.ToArray(), this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, It.IsAny<Stream>(), this.decoderOptions)); |
|||
|
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithTypeAndConfigAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.LocalConfiguration, this.DataStream.ToArray(), this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, It.IsAny<Stream>(), this.decoderOptions)); |
|||
|
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithDecoder() |
|||
{ |
|||
Image img = Image.Load(this.DataStream.ToArray(), this.localDecoder.Object); |
|||
|
|||
Assert.NotNull(img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, It.IsAny<Stream>(), null)); |
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithTypeAndDecoder() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream.ToArray(), this.localDecoder.Object); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, It.IsAny<Stream>(), null)); |
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithDecoderAndOptions() |
|||
{ |
|||
Image img = Image.Load(this.DataStream.ToArray(), this.localDecoder.Object, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, It.IsAny<Stream>(), this.decoderOptions)); |
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromBytesWithTypeAndDecoderAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream.ToArray(), this.localDecoder.Object, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, It.IsAny<Stream>(), this.decoderOptions)); |
|||
Assert.Equal(this.DataStream.ToArray(), this.DecodedData); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFile() |
|||
{ |
|||
Image img = Image.Load(this.DataStream); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, null, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithType() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat.Sample<Color>(), img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, null, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithOptions() |
|||
{ |
|||
Image img = Image.Load(this.DataStream, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, this.decoderOptions, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithTypeAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.DataStream, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat.Sample<Color>(), img); |
|||
Assert.Equal(TestFormat.GlobalTestFormat, img.CurrentImageFormat); |
|||
|
|||
TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, this.decoderOptions, Configuration.Default); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithConfig() |
|||
{ |
|||
Image img = Image.Load(this.LocalConfiguration, this.FilePath); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, this.DataStream, null)); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithTypeAndConfig() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.LocalConfiguration, this.FilePath); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, this.DataStream, null)); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithConfigAndOptions() |
|||
{ |
|||
Image img = Image.Load(this.LocalConfiguration, this.FilePath, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, this.DataStream, this.decoderOptions)); |
|||
|
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithTypeAndConfigAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.LocalConfiguration, this.FilePath, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
Assert.Equal(this.localFormat.Object, img.CurrentImageFormat); |
|||
|
|||
this.localDecoder.Verify(x => x.Decode<Color>(this.LocalConfiguration, this.DataStream, this.decoderOptions)); |
|||
|
|||
} |
|||
|
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithDecoder() |
|||
{ |
|||
Image img = Image.Load(this.FilePath, this.localDecoder.Object); |
|||
|
|||
Assert.NotNull(img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, this.DataStream, null)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithTypeAndDecoder() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.FilePath, this.localDecoder.Object); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, this.DataStream, null)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithDecoderAndOptions() |
|||
{ |
|||
Image img = Image.Load(this.FilePath, this.localDecoder.Object, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, this.DataStream, this.decoderOptions)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void LoadFromFileWithTypeAndDecoderAndOptions() |
|||
{ |
|||
Image<Color> img = Image.Load<Color>(this.FilePath, this.localDecoder.Object, this.decoderOptions); |
|||
|
|||
Assert.NotNull(img); |
|||
Assert.Equal(this.returnImage, img); |
|||
this.localDecoder.Verify(x => x.Decode<Color>(Configuration.Default, this.DataStream, this.decoderOptions)); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
// clean up the global object;
|
|||
this.returnImage?.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
// <copyright file="TestFileSystem.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Collections.Concurrent; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using ImageSharp.Formats; |
|||
using Xunit; |
|||
|
|||
/// <summary>
|
|||
/// A test image file.
|
|||
/// </summary>
|
|||
public class TestFileSystem : ImageSharp.IO.IFileSystem |
|||
{ |
|||
|
|||
public static TestFileSystem Global { get; } = new TestFileSystem(); |
|||
|
|||
public static void RegisterGloablTestFormat() |
|||
{ |
|||
Configuration.Default.FileSystem = Global; |
|||
} |
|||
|
|||
Dictionary<string, Stream> fileSystem = new Dictionary<string, Stream>(StringComparer.OrdinalIgnoreCase); |
|||
|
|||
public void AddFile(string path, Stream data) |
|||
{ |
|||
fileSystem.Add(path, data); |
|||
} |
|||
|
|||
public Stream Create(string path) |
|||
{ |
|||
// if we have injected a fake file use it instead
|
|||
lock (fileSystem) |
|||
{ |
|||
if (fileSystem.ContainsKey(path)) |
|||
{ |
|||
Stream stream = fileSystem[path]; |
|||
stream.Position = 0; |
|||
return stream; |
|||
} |
|||
} |
|||
|
|||
return File.Create(path); |
|||
} |
|||
|
|||
|
|||
public Stream OpenRead(string path) |
|||
{ |
|||
// if we have injected a fake file use it instead
|
|||
lock (fileSystem) |
|||
{ |
|||
if (fileSystem.ContainsKey(path)) |
|||
{ |
|||
Stream stream = fileSystem[path]; |
|||
stream.Position = 0; |
|||
return stream; |
|||
} |
|||
} |
|||
|
|||
return File.OpenRead(path); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,185 @@ |
|||
// <copyright file="TestImage.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Collections.Concurrent; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using ImageSharp.Formats; |
|||
using Xunit; |
|||
|
|||
/// <summary>
|
|||
/// A test image file.
|
|||
/// </summary>
|
|||
public class TestFormat : ImageSharp.Formats.IImageFormat |
|||
{ |
|||
public static TestFormat GlobalTestFormat { get; } = new TestFormat(); |
|||
|
|||
public static void RegisterGloablTestFormat() |
|||
{ |
|||
Configuration.Default.AddImageFormat(GlobalTestFormat); |
|||
} |
|||
|
|||
public TestFormat() |
|||
{ |
|||
this.Encoder = new TestEncoder(this); ; |
|||
this.Decoder = new TestDecoder(this); ; |
|||
} |
|||
|
|||
public List<DecodeOperation> DecodeCalls { get; } = new List<DecodeOperation>(); |
|||
|
|||
public IImageEncoder Encoder { get; } |
|||
|
|||
public IImageDecoder Decoder { get; } |
|||
|
|||
private byte[] header = Guid.NewGuid().ToByteArray(); |
|||
|
|||
public MemoryStream CreateStream(byte[] marker = null) |
|||
{ |
|||
MemoryStream ms = new MemoryStream(); |
|||
byte[] data = this.header; |
|||
ms.Write(data, 0, data.Length); |
|||
if (marker != null) |
|||
{ |
|||
ms.Write(marker, 0, marker.Length); |
|||
} |
|||
ms.Position = 0; |
|||
return ms; |
|||
} |
|||
|
|||
Dictionary<Type, object> _sampleImages = new Dictionary<Type, object>(); |
|||
|
|||
|
|||
public void VerifyDecodeCall(byte[] marker, IDecoderOptions options, Configuration config) |
|||
{ |
|||
DecodeOperation[] discovered = this.DecodeCalls.Where(x => x.IsMatch(marker, options, config)).ToArray(); |
|||
|
|||
|
|||
Assert.True(discovered.Any(), "No calls to decode on this formate with the proveded options happend"); |
|||
|
|||
foreach (DecodeOperation d in discovered) { |
|||
this.DecodeCalls.Remove(d); |
|||
} |
|||
} |
|||
|
|||
public Image<TColor> Sample<TColor>() |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
lock (this._sampleImages) |
|||
{ |
|||
if (!this._sampleImages.ContainsKey(typeof(TColor))) |
|||
{ |
|||
this._sampleImages.Add(typeof(TColor), new Image<TColor>(1, 1)); |
|||
} |
|||
|
|||
return (Image<TColor>)this._sampleImages[typeof(TColor)]; |
|||
} |
|||
} |
|||
|
|||
public string MimeType => "img/test"; |
|||
|
|||
public string Extension => "test_ext"; |
|||
|
|||
public IEnumerable<string> SupportedExtensions => new[] { "test_ext" }; |
|||
|
|||
public int HeaderSize => this.header.Length; |
|||
|
|||
public bool IsSupportedFileFormat(byte[] header) |
|||
{ |
|||
if (header.Length < this.header.Length) |
|||
{ |
|||
return false; |
|||
} |
|||
for (int i = 0; i < this.header.Length; i++) |
|||
{ |
|||
if (header[i] != this.header[i]) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
public struct DecodeOperation |
|||
{ |
|||
public byte[] marker; |
|||
public IDecoderOptions options; |
|||
internal Configuration config; |
|||
|
|||
public bool IsMatch(byte[] testMarker, IDecoderOptions testOptions, Configuration config) |
|||
{ |
|||
if (this.options != testOptions) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (this.config != config) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (testMarker.Length != this.marker.Length) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
for (int i = 0; i < this.marker.Length; i++) |
|||
{ |
|||
if (testMarker[i] != this.marker[i]) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
public class TestDecoder : ImageSharp.Formats.IImageDecoder |
|||
{ |
|||
private TestFormat testFormat; |
|||
|
|||
public TestDecoder(TestFormat testFormat) |
|||
{ |
|||
this.testFormat = testFormat; |
|||
} |
|||
|
|||
|
|||
public Image<TColor> Decode<TColor>(Configuration config, Stream stream, IDecoderOptions options) where TColor : struct, IPixel<TColor> |
|||
|
|||
{ |
|||
var ms = new MemoryStream(); |
|||
stream.CopyTo(ms); |
|||
var marker = ms.ToArray().Skip(this.testFormat.header.Length).ToArray(); |
|||
this.testFormat.DecodeCalls.Add(new DecodeOperation |
|||
{ |
|||
marker = marker, |
|||
options = options, |
|||
config = config |
|||
}); |
|||
|
|||
// TODO record this happend so we an verify it.
|
|||
return this.testFormat.Sample<TColor>(); |
|||
} |
|||
} |
|||
|
|||
public class TestEncoder : ImageSharp.Formats.IImageEncoder |
|||
{ |
|||
private TestFormat testFormat; |
|||
|
|||
public TestEncoder(TestFormat testFormat) |
|||
{ |
|||
this.testFormat = testFormat; |
|||
} |
|||
|
|||
public void Encode<TColor>(Image<TColor> image, Stream stream, IEncoderOptions options) where TColor : struct, IPixel<TColor> |
|||
{ |
|||
// TODO record this happend so we an verify it.
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue