Browse Source

Merge pull request #1146 from SixLabors/js/identify-overloads

Add overloads. Fix #1144
pull/1152/head
James Jackson-South 6 years ago
committed by GitHub
parent
commit
5ffdc47e34
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 125
      src/ImageSharp/Image.FromBytes.cs
  2. 99
      src/ImageSharp/Image.FromFile.cs
  3. 68
      src/ImageSharp/Image.FromStream.cs
  4. 99
      tests/ImageSharp.Tests/Image/ImageTests.Identify.cs
  5. 11
      tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs

125
src/ImageSharp/Image.FromBytes.cs

@ -26,14 +26,55 @@ namespace SixLabors.ImageSharp
/// <summary>
/// By reading the header on the provided byte array this calculates the images format.
/// </summary>
/// <param name="config">The configuration.</param>
/// <param name="configuration">The configuration.</param>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration config, byte[] data)
public static IImageFormat DetectFormat(Configuration configuration, byte[] data)
{
using (var stream = new MemoryStream(data))
Guard.NotNull(configuration, nameof(configuration));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return DetectFormat(configuration, stream);
}
}
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(byte[] data) => Identify(data, out IImageFormat _);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(byte[] data, out IImageFormat format) => Identify(Configuration.Default, data, out format);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
public static IImageInfo Identify(Configuration configuration, byte[] data, out IImageFormat format)
{
Guard.NotNull(configuration, nameof(configuration));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return DetectFormat(config, stream);
return Identify(configuration, stream, out format);
}
}
@ -68,33 +109,33 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte array.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte array containing encoded image data.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration config, byte[] data)
public static Image<TPixel> Load<TPixel>(Configuration configuration, byte[] data)
where TPixel : unmanaged, IPixel<TPixel>
{
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(config, stream);
return Load<TPixel>(configuration, stream);
}
}
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte array.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte array containing encoded image data.</param>
/// <param name="format">The <see cref="IImageFormat"/> of the decoded image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration config, byte[] data, out IImageFormat format)
public static Image<TPixel> Load<TPixel>(Configuration configuration, byte[] data, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(config, stream, out format);
return Load<TPixel>(configuration, stream, out format);
}
}
@ -117,17 +158,17 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte array.
/// </summary>
/// <param name="config">The Configuration.</param>
/// <param name="configuration">The Configuration.</param>
/// <param name="data">The byte array containing encoded image data.</param>
/// <param name="decoder">The decoder.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration config, byte[] data, IImageDecoder decoder)
public static Image<TPixel> Load<TPixel>(Configuration configuration, byte[] data, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
{
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(config, stream, decoder);
return Load<TPixel>(configuration, stream, decoder);
}
}
@ -144,18 +185,18 @@ namespace SixLabors.ImageSharp
/// <summary>
/// By reading the header on the provided byte array this calculates the images format.
/// </summary>
/// <param name="config">The configuration.</param>
/// <param name="configuration">The configuration.</param>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration config, ReadOnlySpan<byte> data)
public static IImageFormat DetectFormat(Configuration configuration, ReadOnlySpan<byte> data)
{
int maxHeaderSize = config.MaxHeaderSize;
int maxHeaderSize = configuration.MaxHeaderSize;
if (maxHeaderSize <= 0)
{
return null;
}
foreach (IImageFormatDetector detector in config.ImageFormatsManager.FormatDetectors)
foreach (IImageFormatDetector detector in configuration.ImageFormatsManager.FormatDetectors)
{
IImageFormat f = detector.DetectFormat(data);
@ -203,18 +244,18 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte span.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing encoded image data.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static unsafe Image<TPixel> Load<TPixel>(Configuration config, ReadOnlySpan<byte> data)
public static unsafe Image<TPixel> Load<TPixel>(Configuration configuration, ReadOnlySpan<byte> data)
where TPixel : unmanaged, IPixel<TPixel>
{
fixed (byte* ptr = &data.GetPinnableReference())
{
using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
{
return Load<TPixel>(config, stream);
return Load<TPixel>(configuration, stream);
}
}
}
@ -222,13 +263,13 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte span.
/// </summary>
/// <param name="config">The Configuration.</param>
/// <param name="configuration">The Configuration.</param>
/// <param name="data">The byte span containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static unsafe Image<TPixel> Load<TPixel>(
Configuration config,
Configuration configuration,
ReadOnlySpan<byte> data,
IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
@ -237,7 +278,7 @@ namespace SixLabors.ImageSharp
{
using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
{
return Load<TPixel>(config, stream, decoder);
return Load<TPixel>(configuration, stream, decoder);
}
}
}
@ -245,13 +286,13 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte span.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing image data.</param>
/// <param name="format">The <see cref="IImageFormat"/> of the decoded image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static unsafe Image<TPixel> Load<TPixel>(
Configuration config,
Configuration configuration,
ReadOnlySpan<byte> data,
out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
@ -260,7 +301,7 @@ namespace SixLabors.ImageSharp
{
using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
{
return Load<TPixel>(config, stream, out format);
return Load<TPixel>(configuration, stream, out format);
}
}
}
@ -285,38 +326,38 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing encoded image data.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration config, byte[] data) => Load(config, data, out _);
public static Image Load(Configuration configuration, byte[] data) => Load(configuration, data, out _);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration config, byte[] data, IImageDecoder decoder)
public static Image Load(Configuration configuration, byte[] data, IImageDecoder decoder)
{
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load(config, stream, decoder);
return Load(configuration, stream, decoder);
}
}
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration config, byte[] data, out IImageFormat format)
public static Image Load(Configuration configuration, byte[] data, out IImageFormat format)
{
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load(config, stream, out format);
return Load(configuration, stream, out format);
}
}
@ -348,20 +389,20 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Decodes a new instance of <see cref="Image"/> from the given encoded byte span.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing image data.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration config, ReadOnlySpan<byte> data) => Load(config, data, out _);
public static Image Load(Configuration configuration, ReadOnlySpan<byte> data) => Load(configuration, data, out _);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte span.
/// </summary>
/// <param name="config">The Configuration.</param>
/// <param name="configuration">The Configuration.</param>
/// <param name="data">The byte span containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static unsafe Image Load(
Configuration config,
Configuration configuration,
ReadOnlySpan<byte> data,
IImageDecoder decoder)
{
@ -369,7 +410,7 @@ namespace SixLabors.ImageSharp
{
using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
{
return Load(config, stream, decoder);
return Load(configuration, stream, decoder);
}
}
}
@ -377,12 +418,12 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte span.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing image data.</param>
/// <param name="format">The <see cref="IImageFormat"/> of the decoded image.</param>>
/// <returns>The <see cref="Image"/>.</returns>
public static unsafe Image Load(
Configuration config,
Configuration configuration,
ReadOnlySpan<byte> data,
out IImageFormat format)
{
@ -390,7 +431,7 @@ namespace SixLabors.ImageSharp
{
using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
{
return Load(config, stream, out format);
return Load(configuration, stream, out format);
}
}
}

99
src/ImageSharp/Image.FromFile.cs

@ -26,15 +26,55 @@ namespace SixLabors.ImageSharp
/// <summary>
/// By reading the header on the provided file this calculates the images mime type.
/// </summary>
/// <param name="config">The configuration.</param>
/// <param name="configuration">The configuration.</param>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration config, string filePath)
public static IImageFormat DetectFormat(Configuration configuration, string filePath)
{
config = config ?? Configuration.Default;
using (Stream file = config.FileSystem.OpenRead(filePath))
Guard.NotNull(configuration, nameof(configuration));
using (Stream file = configuration.FileSystem.OpenRead(filePath))
{
return DetectFormat(config, file);
return DetectFormat(configuration, file);
}
}
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(string filePath) => Identify(filePath, out IImageFormat _);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(string filePath, out IImageFormat format) => Identify(Configuration.Default, filePath, out format);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
public static IImageInfo Identify(Configuration configuration, string filePath, out IImageFormat format)
{
Guard.NotNull(configuration, nameof(configuration));
using (Stream file = configuration.FileSystem.OpenRead(filePath))
{
return Identify(configuration, file, out format);
}
}
@ -62,29 +102,30 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Create a new instance of the <see cref="Image"/> class from the given file.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration 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 <see cref="Image"/>.</returns>
public static Image Load(Configuration config, string path) => Load(config, path, out _);
public static Image Load(Configuration configuration, string path) => Load(configuration, path, out _);
/// <summary>
/// Create a new instance of the <see cref="Image"/> class from the given file.
/// </summary>
/// <param name="config">The Configuration.</param>
/// <param name="configuration">The Configuration.</param>
/// <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 <see cref="Image"/>.</returns>
public static Image Load(Configuration config, string path, IImageDecoder decoder)
public static Image Load(Configuration configuration, string path, IImageDecoder decoder)
{
using (Stream stream = config.FileSystem.OpenRead(path))
Guard.NotNull(configuration, nameof(configuration));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load(config, stream, decoder);
return Load(configuration, stream, decoder);
}
}
@ -133,26 +174,27 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration config, string path)
public static Image<TPixel> Load<TPixel>(Configuration configuration, string path)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Stream stream = config.FileSystem.OpenRead(path))
Guard.NotNull(configuration, nameof(configuration));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load<TPixel>(config, stream);
return Load<TPixel>(configuration, stream);
}
}
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="NotSupportedException">
@ -160,12 +202,13 @@ namespace SixLabors.ImageSharp
/// </exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration config, string path, out IImageFormat format)
public static Image<TPixel> Load<TPixel>(Configuration configuration, string path, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Stream stream = config.FileSystem.OpenRead(path))
Guard.NotNull(configuration, nameof(configuration));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load<TPixel>(config, stream, out format);
return Load<TPixel>(configuration, stream, out format);
}
}
@ -173,18 +216,19 @@ namespace SixLabors.ImageSharp
/// Create a new instance of the <see cref="Image"/> class from the given file.
/// The pixel type is selected by the decoder.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image Load(Configuration config, string path, out IImageFormat format)
public static Image Load(Configuration configuration, string path, out IImageFormat format)
{
using (Stream stream = config.FileSystem.OpenRead(path))
Guard.NotNull(configuration, nameof(configuration));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load(config, stream, out format);
return Load(configuration, stream, out format);
}
}
@ -207,7 +251,7 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
/// </summary>
/// <param name="config">The Configuration.</param>
/// <param name="configuration">The Configuration.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">
@ -215,12 +259,13 @@ namespace SixLabors.ImageSharp
/// </exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration config, string path, IImageDecoder decoder)
public static Image<TPixel> Load<TPixel>(Configuration configuration, string path, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Stream stream = config.FileSystem.OpenRead(path))
Guard.NotNull(configuration, nameof(configuration));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load<TPixel>(config, stream, decoder);
return Load<TPixel>(configuration, stream, decoder);
}
}
}

68
src/ImageSharp/Image.FromStream.cs

@ -26,15 +26,15 @@ namespace SixLabors.ImageSharp
/// <summary>
/// By reading the header on the provided stream this calculates the images format type.
/// </summary>
/// <param name="config">The configuration.</param>
/// <param name="configuration">The configuration.</param>
/// <param name="stream">The image stream to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>The format type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration config, Stream stream)
=> WithSeekableStream(config, stream, s => InternalDetectFormat(s, config));
public static IImageFormat DetectFormat(Configuration configuration, Stream stream)
=> WithSeekableStream(configuration, stream, s => InternalDetectFormat(s, configuration));
/// <summary>
/// By reading the header on the provided stream this reads the raw image information.
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="stream">The image stream to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp
public static IImageInfo Identify(Stream stream) => Identify(stream, out IImageFormat _);
/// <summary>
/// By reading the header on the provided stream this reads the raw image information.
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="stream">The image stream to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
@ -57,16 +57,16 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="config">The configuration.</param>
/// <param name="configuration">The configuration.</param>
/// <param name="stream">The image stream to read the information from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
public static IImageInfo Identify(Configuration config, Stream stream, out IImageFormat format)
public static IImageInfo Identify(Configuration configuration, Stream stream, out IImageFormat format)
{
(IImageInfo info, IImageFormat format) data = WithSeekableStream(config, stream, s => InternalIdentity(s, config ?? Configuration.Default));
(IImageInfo info, IImageFormat format) data = WithSeekableStream(configuration, stream, s => InternalIdentity(s, configuration ?? Configuration.Default));
format = data.format;
return data.info;
@ -108,24 +108,24 @@ namespace SixLabors.ImageSharp
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
/// The pixel format is selected by the decoder.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <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.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <returns>A new <see cref="Image"/>.</returns>>
public static Image Load(Configuration config, Stream stream, IImageDecoder decoder) =>
WithSeekableStream(config, stream, s => decoder.Decode(config, s));
public static Image Load(Configuration configuration, Stream stream, IImageDecoder decoder) =>
WithSeekableStream(configuration, stream, s => decoder.Decode(configuration, s));
/// <summary>
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="stream">The stream containing image information.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <returns>A new <see cref="Image"/>.</returns>>
public static Image Load(Configuration config, Stream stream) => Load(config, stream, out _);
public static Image Load(Configuration configuration, Stream stream) => Load(configuration, stream, out _);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
@ -137,7 +137,7 @@ namespace SixLabors.ImageSharp
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
=> Load<TPixel>(null, stream);
=> Load<TPixel>(Configuration.Default, stream);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
@ -150,7 +150,7 @@ namespace SixLabors.ImageSharp
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Stream stream, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
=> Load<TPixel>(null, stream, out format);
=> Load<TPixel>(Configuration.Default, stream, out format);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
@ -168,45 +168,45 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
/// </summary>
/// <param name="config">The Configuration.</param>
/// <param name="configuration">The Configuration.</param>
/// <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.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, IImageDecoder decoder)
public static Image<TPixel> Load<TPixel>(Configuration configuration, Stream stream, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
=> WithSeekableStream(config, stream, s => decoder.Decode<TPixel>(config, s));
=> WithSeekableStream(configuration, stream, s => decoder.Decode<TPixel>(configuration, s));
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="stream">The stream containing image information.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream)
public static Image<TPixel> Load<TPixel>(Configuration configuration, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
=> Load<TPixel>(config, stream, out IImageFormat _);
=> Load<TPixel>(configuration, stream, out IImageFormat _);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, out IImageFormat format)
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, Stream stream, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
config = config ?? Configuration.Default;
(Image<TPixel> img, IImageFormat format) data = WithSeekableStream(config, stream, s => Decode<TPixel>(s, config));
Guard.NotNull(configuration, nameof(configuration));
(Image<TPixel> img, IImageFormat format) data = WithSeekableStream(configuration, stream, s => Decode<TPixel>(s, configuration));
format = data.format;
@ -218,7 +218,7 @@ namespace SixLabors.ImageSharp
var sb = new StringBuilder();
sb.AppendLine("Image cannot be loaded. Available decoders:");
foreach (KeyValuePair<IImageFormat, IImageDecoder> val in config.ImageFormatsManager.ImageDecoders)
foreach (KeyValuePair<IImageFormat, IImageDecoder> val in configuration.ImageFormatsManager.ImageDecoders)
{
sb.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
}
@ -230,16 +230,16 @@ namespace SixLabors.ImageSharp
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
/// The pixel format is selected by the decoder.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="configuration">The configuration options.</param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image Load(Configuration config, Stream stream, out IImageFormat format)
public static Image Load(Configuration configuration, Stream stream, out IImageFormat format)
{
config = config ?? Configuration.Default;
(Image img, IImageFormat format) data = WithSeekableStream(config, stream, s => Decode(s, config));
Guard.NotNull(configuration, nameof(configuration));
(Image img, IImageFormat format) data = WithSeekableStream(configuration, stream, s => Decode(s, configuration));
format = data.format;
@ -251,7 +251,7 @@ namespace SixLabors.ImageSharp
var sb = new StringBuilder();
sb.AppendLine("Image cannot be loaded. Available decoders:");
foreach (KeyValuePair<IImageFormat, IImageDecoder> val in config.ImageFormatsManager.ImageDecoders)
foreach (KeyValuePair<IImageFormat, IImageDecoder> val in configuration.ImageFormatsManager.ImageDecoders)
{
sb.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
}
@ -259,7 +259,7 @@ namespace SixLabors.ImageSharp
throw new UnknownImageFormatException(sb.ToString());
}
private static T WithSeekableStream<T>(Configuration config, Stream stream, Func<Stream, T> action)
private static T WithSeekableStream<T>(Configuration configuration, Stream stream, Func<Stream, T> action)
{
if (!stream.CanRead)
{
@ -268,7 +268,7 @@ namespace SixLabors.ImageSharp
if (stream.CanSeek)
{
if (config.ReadOrigin == ReadOrigin.Begin)
if (configuration.ReadOrigin == ReadOrigin.Begin)
{
stream.Position = 0;
}

99
tests/ImageSharp.Tests/Image/ImageTests.Identify.cs

@ -0,0 +1,99 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.IO;
using SixLabors.ImageSharp.Formats;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests
{
public partial class ImageTests
{
/// <summary>
/// Tests the <see cref="Image"/> class.
/// </summary>
public class Identify : ImageLoadTestBase
{
private static readonly string ActualImagePath = TestFile.GetInputFileFullPath(TestImages.Bmp.F);
private byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes;
private byte[] ByteArray => this.DataStream.ToArray();
private IImageInfo LocalImageInfo => this.localImageInfoMock.Object;
private IImageFormat LocalImageFormat => this.localImageFormatMock.Object;
private static readonly IImageFormat ExpectedGlobalFormat =
Configuration.Default.ImageFormatsManager.FindFormatByFileExtension("bmp");
[Fact]
public void FromBytes_GlobalConfiguration()
{
IImageInfo info = Image.Identify(this.ActualImageBytes, out IImageFormat type);
Assert.NotNull(info);
Assert.Equal(ExpectedGlobalFormat, type);
}
[Fact]
public void FromBytes_CustomConfiguration()
{
IImageInfo info = Image.Identify(this.LocalConfiguration, this.ByteArray, out IImageFormat type);
Assert.Equal(this.LocalImageInfo, info);
Assert.Equal(this.LocalImageFormat, type);
}
[Fact]
public void FromFileSystemPath_GlobalConfiguration()
{
IImageInfo info = Image.Identify(ActualImagePath, out IImageFormat type);
Assert.NotNull(info);
Assert.Equal(ExpectedGlobalFormat, type);
}
[Fact]
public void FromFileSystemPath_CustomConfiguration()
{
IImageInfo info = Image.Identify(this.LocalConfiguration, this.MockFilePath, out IImageFormat type);
Assert.Equal(this.LocalImageInfo, info);
Assert.Equal(this.LocalImageFormat, type);
}
[Fact]
public void FromStream_GlobalConfiguration()
{
using (var stream = new MemoryStream(this.ActualImageBytes))
{
IImageInfo info = Image.Identify(stream, out IImageFormat type);
Assert.NotNull(info);
Assert.Equal(ExpectedGlobalFormat, type);
}
}
[Fact]
public void FromStream_CustomConfiguration()
{
IImageInfo info = Image.Identify(this.LocalConfiguration, this.DataStream, out IImageFormat type);
Assert.Equal(this.LocalImageInfo, info);
Assert.Equal(this.LocalImageFormat, type);
}
[Fact]
public void WhenNoMatchingFormatFound_ReturnsNull()
{
IImageInfo info = Image.Identify(new Configuration(), this.DataStream, out IImageFormat type);
Assert.Null(info);
Assert.Null(type);
}
}
}
}

11
tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs

@ -26,6 +26,8 @@ namespace SixLabors.ImageSharp.Tests
protected Mock<IImageFormat> localImageFormatMock;
protected Mock<IImageInfo> localImageInfoMock;
protected readonly string MockFilePath = Guid.NewGuid().ToString();
internal readonly Mock<IFileSystem> LocalFileSystemMock = new Mock<IFileSystem>();
@ -53,9 +55,12 @@ namespace SixLabors.ImageSharp.Tests
this.localStreamReturnImageRgba32 = new Image<Rgba32>(1, 1);
this.localStreamReturnImageAgnostic = new Image<Bgra4444>(1, 1);
this.localImageInfoMock = new Mock<IImageInfo>();
this.localImageFormatMock = new Mock<IImageFormat>();
this.localDecoder = new Mock<IImageDecoder>();
var detector = new Mock<IImageInfoDetector>();
detector.Setup(x => x.Identify(It.IsAny<Configuration>(), It.IsAny<Stream>())).Returns(this.localImageInfoMock.Object);
this.localDecoder = detector.As<IImageDecoder>();
this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
this.localDecoder.Setup(x => x.Decode<Rgba32>(It.IsAny<Configuration>(), It.IsAny<Stream>()))
@ -80,9 +85,7 @@ namespace SixLabors.ImageSharp.Tests
})
.Returns(this.localStreamReturnImageAgnostic);
this.LocalConfiguration = new Configuration
{
};
this.LocalConfiguration = new Configuration();
this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector);
this.LocalConfiguration.ImageFormatsManager.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object);

Loading…
Cancel
Save