diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs
index 44c53d776..98a39193d 100644
--- a/src/ImageSharp/Image.FromBytes.cs
+++ b/src/ImageSharp/Image.FromBytes.cs
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using System;
using System.IO;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
@@ -15,7 +16,7 @@ namespace SixLabors.ImageSharp
///
/// By reading the header on the provided byte array this calculates the images format.
///
- /// The byte array containing image data to read the header from.
+ /// The byte array containing encoded image data to read the header from.
/// The format or null if none found.
public static IImageFormat DetectFormat(byte[] data)
{
@@ -26,7 +27,7 @@ namespace SixLabors.ImageSharp
/// By reading the header on the provided byte array this calculates the images format.
///
/// The configuration.
- /// The byte array containing image data to read the header from.
+ /// The byte array containing encoded image data to read the header from.
/// The mime type or null if none found.
public static IImageFormat DetectFormat(Configuration config, byte[] data)
{
@@ -37,30 +38,30 @@ namespace SixLabors.ImageSharp
}
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The byte array containing image data.
/// A new .
public static Image Load(byte[] data) => Load(Configuration.Default, data);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// The mime type of the decoded image.
/// A new .
public static Image Load(byte[] data, out IImageFormat format) => Load(Configuration.Default, data, out format);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The config for the decoder.
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// A new .
public static Image Load(Configuration config, byte[] data) => Load(config, data);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The config for the decoder.
/// The byte array containing image data.
@@ -69,15 +70,15 @@ namespace SixLabors.ImageSharp
public static Image Load(Configuration config, byte[] data, out IImageFormat format) => Load(config, data, out format);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// The decoder.
/// A new .
public static Image Load(byte[] data, IImageDecoder decoder) => Load(data, decoder);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The config for the decoder.
/// The byte array containing image data.
@@ -86,9 +87,9 @@ namespace SixLabors.ImageSharp
public static Image Load(Configuration config, byte[] data, IImageDecoder decoder) => Load(config, data, decoder);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// The pixel format.
/// A new .
public static Image Load(byte[] data)
@@ -96,7 +97,7 @@ namespace SixLabors.ImageSharp
=> Load(Configuration.Default, data);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The byte array containing image data.
/// The mime type of the decoded image.
@@ -107,10 +108,10 @@ namespace SixLabors.ImageSharp
=> Load(Configuration.Default, data, out format);
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The configuration options.
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// The pixel format.
/// A new .
public static Image Load(Configuration config, byte[] data)
@@ -123,11 +124,11 @@ namespace SixLabors.ImageSharp
}
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The configuration options.
- /// The byte array containing image data.
- /// The mime type of the decoded image.
+ /// The byte array containing encoded image data.
+ /// The of the decoded image.
/// The pixel format.
/// A new .
public static Image Load(Configuration config, byte[] data, out IImageFormat format)
@@ -140,9 +141,9 @@ namespace SixLabors.ImageSharp
}
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// The decoder.
/// The pixel format.
/// A new .
@@ -156,10 +157,10 @@ namespace SixLabors.ImageSharp
}
///
- /// Create a new instance of the class from the given byte array.
+ /// Load a new instance of from the given encoded byte array.
///
/// The Configuration.
- /// The byte array containing image data.
+ /// The byte array containing encoded image data.
/// The decoder.
/// The pixel format.
/// A new .
@@ -171,5 +172,125 @@ namespace SixLabors.ImageSharp
return Load(config, memoryStream, decoder);
}
}
+
+#if !NETSTANDARD1_1
+
+ ///
+ /// By reading the header on the provided byte array this calculates the images format.
+ ///
+ /// The byte array containing encoded image data to read the header from.
+ /// The format or null if none found.
+ public static IImageFormat DetectFormat(ReadOnlySpan data)
+ {
+ return DetectFormat(Configuration.Default, data);
+ }
+
+ ///
+ /// By reading the header on the provided byte array this calculates the images format.
+ ///
+ /// The configuration.
+ /// The byte array containing encoded image data to read the header from.
+ /// The mime type or null if none found.
+ public static unsafe IImageFormat DetectFormat(Configuration config, ReadOnlySpan data)
+ {
+ fixed (byte* ptr = &data.GetPinnableReference())
+ {
+ using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
+ {
+ return DetectFormat(config, stream);
+ }
+ }
+ }
+
+ ///
+ /// Load a new instance of from the given encoded byte span.
+ ///
+ /// The byte span containing image data.
+ /// A new .
+ public static Image Load(ReadOnlySpan data) => Load(Configuration.Default, data);
+
+ ///
+ /// Load a new instance of from the given encoded byte span.
+ ///
+ /// The config for the decoder.
+ /// The byte span containing encoded image data.
+ /// A new .
+ public static Image Load(Configuration config, ReadOnlySpan data) => Load(config, data);
+
+ ///
+ /// Load a new instance of from the given encoded byte span.
+ ///
+ /// The byte span containing encoded image data.
+ /// The pixel format.
+ /// A new .
+ public static Image Load(ReadOnlySpan data)
+ where TPixel : struct, IPixel
+ => Load(Configuration.Default, data);
+
+ ///
+ /// Load a new instance of from the given encoded byte span.
+ ///
+ /// The configuration options.
+ /// The byte span containing encoded image data.
+ /// The pixel format.
+ /// A new .
+ public static unsafe Image Load(Configuration config, ReadOnlySpan data)
+ where TPixel : struct, IPixel
+ {
+ fixed (byte* ptr = &data.GetPinnableReference())
+ {
+ using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
+ {
+ return Load(config, stream);
+ }
+ }
+ }
+
+ ///
+ /// Load a new instance of from the given encoded byte span.
+ ///
+ /// The Configuration.
+ /// The byte span containing image data.
+ /// The decoder.
+ /// The pixel format.
+ /// A new .
+ public static unsafe Image Load(
+ Configuration config,
+ ReadOnlySpan data,
+ IImageDecoder decoder)
+ where TPixel : struct, IPixel
+ {
+ fixed (byte* ptr = &data.GetPinnableReference())
+ {
+ using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
+ {
+ return Load(config, stream, decoder);
+ }
+ }
+ }
+
+ ///
+ /// Load a new instance of from the given encoded byte span.
+ ///
+ /// The configuration options.
+ /// The byte span containing image data.
+ /// The of the decoded image.
+ /// The pixel format.
+ /// A new .
+ public static unsafe Image Load(
+ Configuration config,
+ ReadOnlySpan data,
+ out IImageFormat format)
+ where TPixel : struct, IPixel
+ {
+ fixed (byte* ptr = &data.GetPinnableReference())
+ {
+ using (var stream = new UnmanagedMemoryStream(ptr, data.Length))
+ {
+ return Load(config, stream, out format);
+ }
+ }
+ }
+#endif
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj
index b1934faa6..777c5016c 100644
--- a/src/ImageSharp/ImageSharp.csproj
+++ b/src/ImageSharp/ImageSharp.csproj
@@ -44,6 +44,9 @@
+
+
+
diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
index a6f6600f0..f10a4ce84 100644
--- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
+++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
@@ -20,12 +20,12 @@ namespace SixLabors.ImageSharp.Tests
{
public class ImageFormatManagerTests
{
- public ImageFormatManager FormatsManagerEmpty { get; private set; }
- public ImageFormatManager DefaultFormatsManager { get; private set; }
+ public ImageFormatManager FormatsManagerEmpty { get; }
+ public ImageFormatManager DefaultFormatsManager { get; }
public ImageFormatManagerTests()
{
- this.DefaultFormatsManager = Configuration.Default.ImageFormatsManager;
+ this.DefaultFormatsManager = Configuration.CreateDefaultInstance().ImageFormatsManager;
this.FormatsManagerEmpty = new ImageFormatManager();
}
diff --git a/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs b/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs
deleted file mode 100644
index 1a2275062..000000000
--- a/tests/ImageSharp.Tests/Image/ImageDiscoverMimeType.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.IO;
-using SixLabors.ImageSharp.Formats;
-using SixLabors.ImageSharp.IO;
-using Moq;
-using Xunit;
-
-namespace SixLabors.ImageSharp.Tests
-{
- ///
- /// Tests the class.
- ///
- public class DiscoverImageFormatTests
- {
- private readonly Mock fileSystem;
- private readonly string FilePath;
- private readonly IImageFormatDetector localMimeTypeDetector;
- private readonly Mock localImageFormatMock;
-
- public IImageFormat localImageFormat => this.localImageFormatMock.Object;
- public Configuration LocalConfiguration { get; private set; }
- public byte[] Marker { get; private set; }
- public MemoryStream DataStream { get; private set; }
- public byte[] DecodedData { get; private set; }
- private const string localMimeType = "image/local";
-
- public DiscoverImageFormatTests()
- {
- this.localImageFormatMock = new Mock();
-
- this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
-
- this.fileSystem = new Mock();
-
- this.LocalConfiguration = new Configuration
- {
- FileSystem = this.fileSystem.Object
- };
-
- this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector);
-
- TestFormat.RegisterGlobalTestFormat();
- this.Marker = Guid.NewGuid().ToByteArray();
- this.DataStream = TestFormat.GlobalTestFormat.CreateStream(this.Marker);
-
- this.FilePath = Guid.NewGuid().ToString();
- this.fileSystem.Setup(x => x.OpenRead(this.FilePath)).Returns(this.DataStream);
-
- TestFileSystem.RegisterGlobalTestFormat();
- TestFileSystem.Global.AddFile(this.FilePath, this.DataStream);
- }
-
- [Fact]
- public void DiscoverImageFormatByteArray()
- {
- IImageFormat type = Image.DetectFormat(this.DataStream.ToArray());
- Assert.Equal(TestFormat.GlobalTestFormat, type);
- }
-
- [Fact]
- public void DiscoverImageFormatByteArray_WithConfig()
- {
- IImageFormat type = Image.DetectFormat(this.LocalConfiguration, this.DataStream.ToArray());
- Assert.Equal(this.localImageFormat, type);
- }
-
- [Fact]
- public void DiscoverImageFormatFile()
- {
- IImageFormat type = Image.DetectFormat(this.FilePath);
- Assert.Equal(TestFormat.GlobalTestFormat, type);
- }
-
- [Fact]
- public void DiscoverImageFormatFilePath_WithConfig()
- {
- IImageFormat type = Image.DetectFormat(this.LocalConfiguration, this.FilePath);
- Assert.Equal(this.localImageFormat, type);
- }
-
- [Fact]
- public void DiscoverImageFormatStream()
- {
- IImageFormat type = Image.DetectFormat(this.DataStream);
- Assert.Equal(TestFormat.GlobalTestFormat, type);
- }
-
- [Fact]
- public void DiscoverImageFormatFileStream_WithConfig()
- {
- IImageFormat type = Image.DetectFormat(this.LocalConfiguration, this.DataStream);
- Assert.Equal(this.localImageFormat, type);
- }
-
- [Fact]
- public void DiscoverImageFormatNoDetectorsRegisterdShouldReturnNull()
- {
- IImageFormat type = Image.DetectFormat(new Configuration(), this.DataStream);
- Assert.Null(type);
- }
- }
-}
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs
new file mode 100644
index 000000000..9d709d488
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs
@@ -0,0 +1,99 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.IO;
+using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.IO;
+using Moq;
+using Xunit;
+// ReSharper disable InconsistentNaming
+
+namespace SixLabors.ImageSharp.Tests
+{
+ public partial class ImageTests
+ {
+ ///
+ /// Tests the class.
+ ///
+ public class DetectFormat : ImageLoadTestBase
+ {
+ private static readonly string ActualImagePath = TestFile.GetInputFileFullPath(TestImages.Bmp.F);
+
+ private byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes;
+
+ private ReadOnlySpan ActualImageSpan => this.ActualImageBytes.AsSpan();
+
+ private byte[] ByteArray => this.DataStream.ToArray();
+
+ private ReadOnlySpan ByteSpan => this.ByteArray.AsSpan();
+
+ private IImageFormat LocalImageFormat => this.localImageFormatMock.Object;
+
+ private static readonly IImageFormat ExpectedGlobalFormat =
+ Configuration.Default.ImageFormatsManager.FindFormatByFileExtension("bmp");
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void FromBytes_GlobalConfiguration(bool useSpan)
+ {
+ IImageFormat type = useSpan
+ ? Image.DetectFormat(this.ActualImageSpan)
+ : Image.DetectFormat(this.ActualImageBytes);
+
+ Assert.Equal(ExpectedGlobalFormat, type);
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void FromBytes_CustomConfiguration(bool useSpan)
+ {
+ IImageFormat type = useSpan
+ ? Image.DetectFormat(this.LocalConfiguration, this.ByteArray.AsSpan())
+ : Image.DetectFormat(this.LocalConfiguration, this.ByteArray);
+
+ Assert.Equal(this.LocalImageFormat, type);
+ }
+
+ [Fact]
+ public void FromFileSystemPath_GlobalConfiguration()
+ {
+ IImageFormat type = Image.DetectFormat(ActualImagePath);
+ Assert.Equal(ExpectedGlobalFormat, type);
+ }
+
+ [Fact]
+ public void FromFileSystemPath_CustomConfiguration()
+ {
+ IImageFormat type = Image.DetectFormat(this.LocalConfiguration, this.MockFilePath);
+ Assert.Equal(this.LocalImageFormat, type);
+ }
+
+ [Fact]
+ public void FromStream_GlobalConfiguration()
+ {
+ using (var stream = new MemoryStream(this.ActualImageBytes))
+ {
+ IImageFormat type = Image.DetectFormat(stream);
+ Assert.Equal(ExpectedGlobalFormat, type);
+ }
+ }
+
+ [Fact]
+ public void FromStream_CustomConfiguration()
+ {
+ IImageFormat type = Image.DetectFormat(this.LocalConfiguration, this.DataStream);
+ Assert.Equal(this.LocalImageFormat, type);
+ }
+
+ [Fact]
+ public void WhenNoMatchingFormatFound_ReturnsNull()
+ {
+ IImageFormat type = Image.DetectFormat(new Configuration(), this.DataStream);
+ Assert.Null(type);
+ }
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
new file mode 100644
index 000000000..aabc3f50e
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
@@ -0,0 +1,92 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.IO;
+
+using Moq;
+
+using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.IO;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Tests
+{
+ public partial class ImageTests
+ {
+ public abstract class ImageLoadTestBase : IDisposable
+ {
+ protected Image returnImage;
+
+ protected Mock localDecoder;
+
+ protected IImageFormatDetector localMimeTypeDetector;
+
+ protected Mock localImageFormatMock;
+
+ protected readonly string MockFilePath = Guid.NewGuid().ToString();
+
+ internal readonly Mock localFileSystemMock = new Mock();
+
+ protected readonly TestFileSystem topLevelFileSystem = new TestFileSystem();
+
+ public Configuration LocalConfiguration { get; }
+
+ public TestFormat TestFormat { get; } = new TestFormat();
+
+ ///
+ /// Gets the top-level configuration in the context of this test case.
+ /// It has registered.
+ ///
+ public Configuration TopLevelConfiguration { get; }
+
+ public byte[] Marker { get; }
+
+ public MemoryStream DataStream { get; }
+
+ public byte[] DecodedData { get; private set; }
+
+ protected ImageLoadTestBase()
+ {
+ this.returnImage = new Image(1, 1);
+
+ this.localImageFormatMock = new Mock();
+
+ this.localDecoder = new Mock();
+ this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
+ this.localDecoder.Setup(x => x.Decode(It.IsAny(), It.IsAny()))
+ .Callback((c, s) =>
+ {
+ using (var ms = new MemoryStream())
+ {
+ s.CopyTo(ms);
+ this.DecodedData = ms.ToArray();
+ }
+ })
+ .Returns(this.returnImage);
+
+ this.LocalConfiguration = new Configuration
+ {
+ };
+ this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector);
+ this.LocalConfiguration.ImageFormatsManager.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object);
+
+ this.TopLevelConfiguration = new Configuration(this.TestFormat);
+
+ this.Marker = Guid.NewGuid().ToByteArray();
+ this.DataStream = this.TestFormat.CreateStream(this.Marker);
+
+ this.localFileSystemMock.Setup(x => x.OpenRead(this.MockFilePath)).Returns(this.DataStream);
+ this.topLevelFileSystem.AddFile(this.MockFilePath, this.DataStream);
+ this.LocalConfiguration.FileSystem = this.localFileSystemMock.Object;
+ this.TopLevelConfiguration.FileSystem = this.topLevelFileSystem;
+ }
+
+ public void Dispose()
+ {
+ // clean up the global object;
+ this.returnImage?.Dispose();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.LoadPixelData.cs b/tests/ImageSharp.Tests/Image/ImageTests.LoadPixelData.cs
new file mode 100644
index 000000000..7a5fa8729
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.LoadPixelData.cs
@@ -0,0 +1,60 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using SixLabors.ImageSharp.PixelFormats;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests
+{
+ public partial class ImageTests
+ {
+ public class LoadPixelData
+ {
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void FromPixels(bool useSpan)
+ {
+ Rgba32[] data = { Rgba32.Black, Rgba32.White, Rgba32.White, Rgba32.Black, };
+
+ using (Image img = useSpan
+ ? Image.LoadPixelData(data.AsSpan(), 2, 2)
+ : Image.LoadPixelData(data, 2, 2))
+ {
+ Assert.NotNull(img);
+ Assert.Equal(Rgba32.Black, img[0, 0]);
+ Assert.Equal(Rgba32.White, img[0, 1]);
+
+ Assert.Equal(Rgba32.White, img[1, 0]);
+ Assert.Equal(Rgba32.Black, img[1, 1]);
+ }
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void FromBytes(bool useSpan)
+ {
+ byte[] data =
+ {
+ 0, 0, 0, 255, // 0,0
+ 255, 255, 255, 255, // 0,1
+ 255, 255, 255, 255, // 1,0
+ 0, 0, 0, 255, // 1,1
+ };
+ using (Image img = useSpan
+ ? Image.LoadPixelData(data.AsSpan(), 2, 2)
+ : Image.LoadPixelData(data, 2, 2))
+ {
+ Assert.NotNull(img);
+ Assert.Equal(Rgba32.Black, img[0, 0]);
+ Assert.Equal(Rgba32.White, img[0, 1]);
+
+ Assert.Equal(Rgba32.White, img[1, 0]);
+ Assert.Equal(Rgba32.Black, img[1, 1]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_BasicCases.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_BasicCases.cs
deleted file mode 100644
index e442b5654..000000000
--- a/tests/ImageSharp.Tests/Image/ImageTests.Load_BasicCases.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using SixLabors.ImageSharp.PixelFormats;
-using Xunit;
-// ReSharper disable InconsistentNaming
-
-namespace SixLabors.ImageSharp.Tests
-{
- public partial class ImageTests
- {
- public class Load_BasicCases
- {
- [Fact]
- public void ByteArray()
- {
- Assert.Throws(() =>
- {
- Image.Load((byte[])null);
- });
-
- var file = TestFile.Create(TestImages.Bmp.Car);
- using (var image = Image.Load(file.Bytes))
- {
- Assert.Equal(600, image.Width);
- Assert.Equal(450, image.Height);
- }
- }
-
- [Fact]
- public void FileSystemPath()
- {
- var file = TestFile.Create(TestImages.Bmp.Car);
- using (var image = Image.Load(file.FullPath))
- {
- Assert.Equal(600, image.Width);
- Assert.Equal(450, image.Height);
- }
- }
-
- [Fact]
- public void FileSystemPath_FileNotFound()
- {
- System.IO.FileNotFoundException ex = Assert.Throws(
- () =>
- {
- Image.Load(Guid.NewGuid().ToString());
- });
- }
-
- [Fact]
- public void FileSystemPath_NullPath()
- {
- ArgumentNullException ex = Assert.Throws(
- () =>
- {
- Image.Load((string)null);
- });
- }
- }
- }
-}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_ComplexCases.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_ComplexCases.cs
deleted file mode 100644
index 957e5c40a..000000000
--- a/tests/ImageSharp.Tests/Image/ImageTests.Load_ComplexCases.cs
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.IO;
-
-using Moq;
-
-using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Formats;
-using SixLabors.ImageSharp.IO;
-using SixLabors.ImageSharp.PixelFormats;
-
-using Xunit;
-// ReSharper disable InconsistentNaming
-
-namespace SixLabors.ImageSharp.Tests
-{
- public partial class ImageTests
- {
- ///
- /// Tests the class.
- ///
- public class Load_ComplexCases : IDisposable
- {
- private readonly Mock fileSystem;
- private readonly Image returnImage;
- private readonly Mock localDecoder;
- private readonly string FilePath;
- private readonly IImageFormatDetector localMimeTypeDetector;
- private readonly Mock localImageFormatMock;
-
- 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 Load_ComplexCases()
- {
- this.returnImage = new Image(1, 1);
-
- this.localImageFormatMock = new Mock();
-
- this.localDecoder = new Mock();
- this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
- this.localDecoder.Setup(x => x.Decode(It.IsAny(), It.IsAny()))
-
- .Callback((c, s) =>
- {
- using (var ms = new MemoryStream())
- {
- s.CopyTo(ms);
- this.DecodedData = ms.ToArray();
- }
- })
- .Returns(this.returnImage);
-
- this.fileSystem = new Mock();
-
- this.LocalConfiguration = new Configuration
- {
- FileSystem = this.fileSystem.Object
- };
- this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector);
- this.LocalConfiguration.ImageFormatsManager.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object);
-
- TestFormat.RegisterGlobalTestFormat();
- this.Marker = Guid.NewGuid().ToByteArray();
- this.DataStream = TestFormat.GlobalTestFormat.CreateStream(this.Marker);
-
- this.FilePath = Guid.NewGuid().ToString();
- this.fileSystem.Setup(x => x.OpenRead(this.FilePath)).Returns(this.DataStream);
-
- TestFileSystem.RegisterGlobalTestFormat();
- TestFileSystem.Global.AddFile(this.FilePath, this.DataStream);
- }
-
- [Fact]
- public void LoadFromStream()
- {
- var img = Image.Load(this.DataStream);
-
- Assert.NotNull(img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
- }
-
- [Fact]
- public void LoadFromNoneSeekableStream()
- {
- var stream = new NoneSeekableStream(this.DataStream);
- var img = Image.Load(stream);
-
- Assert.NotNull(img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
- }
-
- [Fact]
- public void LoadFromStreamWithType()
- {
- var img = Image.Load(this.DataStream);
-
- Assert.NotNull(img);
- Assert.Equal(TestFormat.GlobalTestFormat.Sample(), img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
- }
-
-
- [Fact]
- public void LoadFromStreamWithConfig()
- {
- Stream stream = new MemoryStream();
- var img = Image.Load(this.LocalConfiguration, stream);
-
- Assert.NotNull(img);
-
- this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, stream));
- }
-
- [Fact]
- public void LoadFromStreamWithTypeAndConfig()
- {
- Stream stream = new MemoryStream();
- var img = Image.Load(this.LocalConfiguration, stream);
-
- Assert.NotNull(img);
- Assert.Equal(this.returnImage, img);
-
- this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, stream));
- }
-
-
- [Fact]
- public void LoadFromStreamWithDecoder()
- {
- Stream stream = new MemoryStream();
- var img = Image.Load(stream, this.localDecoder.Object);
-
- Assert.NotNull(img);
- this.localDecoder.Verify(x => x.Decode(Configuration.Default, stream));
- }
-
- [Fact]
- public void LoadFromStreamWithTypeAndDecoder()
- {
- Stream stream = new MemoryStream();
- var img = Image.Load(stream, this.localDecoder.Object);
-
- Assert.NotNull(img);
- Assert.Equal(this.returnImage, img);
- this.localDecoder.Verify(x => x.Decode(Configuration.Default, stream));
- }
-
- [Fact]
- public void LoadFromBytes()
- {
- var img = Image.Load(this.DataStream.ToArray());
-
- Assert.NotNull(img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
- }
-
- [Fact]
- public void LoadFromBytesWithType()
- {
- var img = Image.Load(this.DataStream.ToArray());
-
- Assert.NotNull(img);
- Assert.Equal(TestFormat.GlobalTestFormat.Sample(), img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
-
- }
-
- [Fact]
- public void LoadFromBytesWithConfig()
- {
- var img = Image.Load(this.LocalConfiguration, this.DataStream.ToArray());
-
- Assert.NotNull(img);
-
- this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, It.IsAny()));
-
- Assert.Equal(this.DataStream.ToArray(), this.DecodedData);
- }
-
- [Fact]
- public void LoadFromBytesWithTypeAndConfig()
- {
- var img = Image.Load(this.LocalConfiguration, this.DataStream.ToArray());
-
- Assert.NotNull(img);
- Assert.Equal(this.returnImage, img);
-
- this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, It.IsAny()));
-
- Assert.Equal(this.DataStream.ToArray(), this.DecodedData);
- }
-
- [Fact]
- public void LoadFromBytesWithDecoder()
- {
- var img = Image.Load(this.DataStream.ToArray(), this.localDecoder.Object);
-
- Assert.NotNull(img);
- this.localDecoder.Verify(x => x.Decode(Configuration.Default, It.IsAny()));
- Assert.Equal(this.DataStream.ToArray(), this.DecodedData);
- }
-
- [Fact]
- public void LoadFromBytesWithTypeAndDecoder()
- {
- var img = Image.Load(this.DataStream.ToArray(), this.localDecoder.Object);
-
- Assert.NotNull(img);
- Assert.Equal(this.returnImage, img);
- this.localDecoder.Verify(x => x.Decode(Configuration.Default, It.IsAny()));
- Assert.Equal(this.DataStream.ToArray(), this.DecodedData);
- }
-
- [Fact]
- public void LoadFromFile()
- {
- var img = Image.Load(this.DataStream);
-
- Assert.NotNull(img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
- }
-
- [Fact]
- public void LoadFromFileWithType()
- {
- var img = Image.Load(this.DataStream);
-
- Assert.NotNull(img);
- Assert.Equal(TestFormat.GlobalTestFormat.Sample(), img);
-
- TestFormat.GlobalTestFormat.VerifyDecodeCall(this.Marker, Configuration.Default);
- }
-
- [Fact]
- public void LoadFromFileWithConfig()
- {
- var img = Image.Load(this.LocalConfiguration, this.FilePath);
-
- Assert.NotNull(img);
-
- this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, this.DataStream));
- }
-
- [Fact]
- public void LoadFromFileWithTypeAndConfig()
- {
- var img = Image.Load(this.LocalConfiguration, this.FilePath);
-
- Assert.NotNull(img);
- Assert.Equal(this.returnImage, img);
-
- this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, this.DataStream));
- }
-
- [Fact]
- public void LoadFromFileWithDecoder()
- {
- var img = Image.Load(this.FilePath, this.localDecoder.Object);
-
- Assert.NotNull(img);
- this.localDecoder.Verify(x => x.Decode(Configuration.Default, this.DataStream));
- }
-
- [Fact]
- public void LoadFromFileWithTypeAndDecoder()
- {
- var img = Image.Load(this.FilePath, this.localDecoder.Object);
-
- Assert.NotNull(img);
- Assert.Equal(this.returnImage, img);
- this.localDecoder.Verify(x => x.Decode(Configuration.Default, this.DataStream));
- }
-
- [Fact]
- public void LoadFromPixelData_Pixels()
- {
- var img = Image.LoadPixelData(new Rgba32[] {
- Rgba32.Black, Rgba32.White,
- Rgba32.White, Rgba32.Black,
- }, 2, 2);
-
- Assert.NotNull(img);
- Assert.Equal(Rgba32.Black, img[0, 0]);
- Assert.Equal(Rgba32.White, img[0, 1]);
-
- Assert.Equal(Rgba32.White, img[1, 0]);
- Assert.Equal(Rgba32.Black, img[1, 1]);
- }
-
- [Fact]
- public void LoadFromPixelData_Bytes()
- {
- var img = Image.LoadPixelData(new byte[] {
- 0,0,0,255, // 0,0
- 255,255,255,255, // 0,1
- 255,255,255,255, // 1,0
- 0,0,0,255, // 1,1
- }, 2, 2);
-
- Assert.NotNull(img);
- Assert.Equal(Rgba32.Black, img[0, 0]);
- Assert.Equal(Rgba32.White, img[0, 1]);
-
- Assert.Equal(Rgba32.White, img[1, 0]);
- Assert.Equal(Rgba32.Black, img[1, 1]);
- }
-
-
- [Fact]
- public void LoadsImageWithoutThrowingCrcException()
- {
- var image1Provider = TestImageProvider.File(TestImages.Png.VersioningImage1);
-
- using (Image img = image1Provider.GetImage())
- {
- Assert.Equal(166036, img.Frames.RootFrame.GetPixelSpan().Length);
- }
- }
-
- public void Dispose()
- {
- // clean up the global object;
- this.returnImage?.Dispose();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs
new file mode 100644
index 000000000..1a21d3d10
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs
@@ -0,0 +1,83 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using SixLabors.ImageSharp.PixelFormats;
+using Xunit;
+// ReSharper disable InconsistentNaming
+
+namespace SixLabors.ImageSharp.Tests
+{
+ using Moq;
+
+ using SixLabors.ImageSharp.IO;
+
+ public partial class ImageTests
+ {
+ public class Load_FileSystemPath : ImageLoadTestBase
+ {
+ [Fact]
+ public void BasicCase()
+ {
+ var img = Image.Load(this.TopLevelConfiguration, this.MockFilePath);
+
+ Assert.NotNull(img);
+
+ this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration);
+ }
+
+ [Fact]
+ public void UseLocalConfiguration()
+ {
+ var img = Image.Load(this.LocalConfiguration, this.MockFilePath);
+
+ Assert.NotNull(img);
+
+ this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, this.DataStream));
+ }
+
+ [Fact]
+ public void UseCustomDecoder()
+ {
+ var img = Image.Load(this.TopLevelConfiguration, this.MockFilePath, this.localDecoder.Object);
+
+ Assert.NotNull(img);
+ this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, this.DataStream));
+ }
+
+
+ [Fact]
+ public void UseGlobalConfigration()
+ {
+ var file = TestFile.Create(TestImages.Bmp.Car);
+ using (var image = Image.Load(file.FullPath))
+ {
+ Assert.Equal(600, image.Width);
+ Assert.Equal(450, image.Height);
+ }
+ }
+
+ [Fact]
+ public void WhenFileNotFound_Throws()
+ {
+ System.IO.FileNotFoundException ex = Assert.Throws(
+ () =>
+ {
+ Image.Load(Guid.NewGuid().ToString());
+ });
+ }
+
+ [Fact]
+ public void WhenPathIsNull_Throws()
+ {
+ ArgumentNullException ex = Assert.Throws(
+ () =>
+ {
+ Image.Load((string)null);
+ });
+ }
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes.cs
new file mode 100644
index 000000000..eed1a2825
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes.cs
@@ -0,0 +1,120 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.IO;
+
+using Moq;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+
+using Xunit;
+
+// ReSharper disable InconsistentNaming
+namespace SixLabors.ImageSharp.Tests
+{
+ public partial class ImageTests
+ {
+ public class Load_FromBytes : ImageLoadTestBase
+ {
+ private byte[] ByteArray => this.DataStream.ToArray();
+
+ private ReadOnlySpan ByteSpan => this.ByteArray.AsSpan();
+
+ private byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes;
+
+ private ReadOnlySpan ActualImageSpan => this.ActualImageBytes.AsSpan();
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void BasicCase(bool useSpan)
+ {
+ Image img = useSpan
+ ? Image.Load(this.TopLevelConfiguration, this.ByteSpan)
+ : Image.Load(this.TopLevelConfiguration, this.ByteArray);
+
+ Assert.NotNull(img);
+ Assert.Equal(this.TestFormat.Sample(), img);
+
+ this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration);
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void NonDefaultPixelType(bool useSpan)
+ {
+ Image img = useSpan
+ ? Image.Load(this.TopLevelConfiguration, this.ByteSpan)
+ : Image.Load(this.TopLevelConfiguration, this.ByteArray);
+
+ Assert.NotNull(img);
+ Assert.Equal(this.TestFormat.Sample(), img);
+
+ this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration);
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseLocalConfiguration(bool useSpan)
+ {
+ Image img = useSpan
+ ? Image.Load(this.LocalConfiguration, this.ByteSpan)
+ : Image.Load(this.LocalConfiguration, this.ByteArray);
+
+ Assert.NotNull(img);
+
+ this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, It.IsAny()));
+
+ Assert.Equal(this.DataStream.ToArray(), this.DecodedData);
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseCustomDecoder(bool useSpan)
+ {
+ Image img = useSpan
+ ? Image.Load(
+ this.TopLevelConfiguration,
+ this.ByteSpan,
+ this.localDecoder.Object)
+ : Image.Load(
+ this.TopLevelConfiguration,
+ this.ByteArray,
+ this.localDecoder.Object);
+ Assert.NotNull(img);
+ this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, It.IsAny()));
+ Assert.Equal(this.DataStream.ToArray(), this.DecodedData);
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseGlobalConfiguration(bool useSpan)
+ {
+ using (Image img =
+ useSpan ? Image.Load(this.ActualImageSpan) : Image.Load(this.ActualImageBytes))
+ {
+ Assert.Equal(new Size(108, 202), img.Size());
+ }
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseGlobalConfiguration_NonDefaultPixelType(bool useSpan)
+ {
+ using (Image img = useSpan
+ ? Image.Load(this.ActualImageSpan)
+ : Image.Load(this.ActualImageBytes))
+ {
+ Assert.Equal(new Size(108, 202), img.Size());
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream.cs
new file mode 100644
index 000000000..6b6acb1b8
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream.cs
@@ -0,0 +1,102 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.IO;
+
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.PixelFormats;
+
+using Xunit;
+// ReSharper disable InconsistentNaming
+
+namespace SixLabors.ImageSharp.Tests
+{
+ using SixLabors.Primitives;
+
+ public partial class ImageTests
+ {
+ ///
+ /// Tests the class.
+ ///
+ public class Load_FromStream : ImageLoadTestBase
+ {
+ [Fact]
+ public void BasicCase()
+ {
+ var img = Image.Load(this.TopLevelConfiguration, this.DataStream);
+
+ Assert.NotNull(img);
+ Assert.Equal(this.TestFormat.Sample(), img);
+
+ this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration);
+ }
+
+ [Fact]
+ public void UseGlobalConfiguration()
+ {
+ byte[] data = TestFile.Create(TestImages.Bmp.F).Bytes;
+
+ using (var stream = new MemoryStream(data))
+ using (var img = Image.Load(stream))
+ {
+ Assert.Equal(new Size(108, 202), img.Size());
+ }
+ }
+
+ [Fact]
+ public void NonDefaultPixelTypeImage()
+ {
+ var img = Image.Load(this.TopLevelConfiguration, this.DataStream);
+
+ Assert.NotNull(img);
+ Assert.Equal(this.TestFormat.Sample(), img);
+
+ this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration);
+ }
+
+ [Fact]
+ public void NonSeekableStream()
+ {
+ var stream = new NoneSeekableStream(this.DataStream);
+ var img = Image.Load(this.TopLevelConfiguration, stream);
+
+ Assert.NotNull(img);
+
+ this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration);
+ }
+
+ [Fact]
+ public void UseLocalConfiguration()
+ {
+ Stream stream = new MemoryStream();
+ var img = Image.Load(this.LocalConfiguration, stream);
+
+ Assert.NotNull(img);
+
+ this.localDecoder.Verify(x => x.Decode(this.LocalConfiguration, stream));
+ }
+
+ [Fact]
+ public void UseCustomDecoder()
+ {
+ Stream stream = new MemoryStream();
+ var img = Image.Load(this.TopLevelConfiguration, stream, this.localDecoder.Object);
+
+ Assert.NotNull(img);
+ this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, stream));
+ }
+
+ // TODO: This should be a png decoder test!
+ [Fact]
+ public void LoadsImageWithoutThrowingCrcException()
+ {
+ var image1Provider = TestImageProvider.File(TestImages.Png.VersioningImage1);
+
+ using (Image img = image1Provider.GetImage())
+ {
+ Assert.Equal(166036, img.Frames.RootFrame.GetPixelSpan().Length);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs
index 70e6c498a..64357a17e 100644
--- a/tests/ImageSharp.Tests/TestFormat.cs
+++ b/tests/ImageSharp.Tests/TestFormat.cs
@@ -18,13 +18,10 @@ namespace SixLabors.ImageSharp.Tests
///
public class TestFormat : IConfigurationModule, IImageFormat
{
+ // We should not change Configuration.Default in individual tests!
+ // Create new configuration instances with new Configuration(TestFormat.GlobalTestFormat) instead!
public static TestFormat GlobalTestFormat { get; } = new TestFormat();
- public static void RegisterGlobalTestFormat()
- {
- Configuration.Default.Configure(GlobalTestFormat);
- }
-
public TestFormat()
{
this.Encoder = new TestEncoder(this);
@@ -155,12 +152,12 @@ namespace SixLabors.ImageSharp.Tests
private TestFormat testFormat;
- public int HeaderSize => testFormat.HeaderSize;
+ public int HeaderSize => this.testFormat.HeaderSize;
public IImageFormat DetectFormat(ReadOnlySpan header)
{
- if (testFormat.IsSupportedFileFormat(header))
- return testFormat;
+ if (this.testFormat.IsSupportedFileFormat(header))
+ return this.testFormat;
return null;
}