diff --git a/src/ImageSharp/Formats/Bmp/ImageExtensions.cs b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs index aa1c353db2..0c37907c22 100644 --- a/src/ImageSharp/Formats/Bmp/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs @@ -2,38 +2,35 @@ // Licensed under the Apache License, Version 2.0. using System.IO; + using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Bmp; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp { /// - /// Extension methods for the type. + /// Extension methods for the type. /// public static partial class ImageExtensions { /// /// Saves the image to the given stream with the bmp format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// Thrown if the stream is null. - public static void SaveAsBmp(this Image source, Stream stream) - where TPixel : struct, IPixel - => source.SaveAsBmp(stream, null); + public static void SaveAsBmp(this Image source, Stream stream) => source.SaveAsBmp(stream, null); /// /// Saves the image to the given stream with the bmp format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// The encoder to save the image with. /// Thrown if the stream is null. - public static void SaveAsBmp(this Image source, Stream stream, BmpEncoder encoder) - where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance)); + public static void SaveAsBmp(this Image source, Stream stream, BmpEncoder encoder) => + source.Save( + stream, + encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance)); } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index 8ddd4247e1..c7ac001ff5 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -2,38 +2,35 @@ // Licensed under the Apache License, Version 2.0. using System.IO; + using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp { /// - /// Extension methods for the type. + /// Extension methods for the type. /// public static partial class ImageExtensions { /// /// Saves the image to the given stream in the gif format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// Thrown if the stream is null. - public static void SaveAsGif(this Image source, Stream stream) - where TPixel : struct, IPixel - => source.SaveAsGif(stream, null); + public static void SaveAsGif(this Image source, Stream stream) => source.SaveAsGif(stream, null); /// /// Saves the image to the given stream in the gif format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// The options for the encoder. /// Thrown if the stream is null. - public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) - where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); + public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) => + source.Save( + stream, + encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs index cb7fc19446..7fec050b4a 100644 --- a/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs @@ -2,38 +2,35 @@ // Licensed under the Apache License, Version 2.0. using System.IO; + using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp { /// - /// Extension methods for the type. + /// Extension methods for the type. /// public static partial class ImageExtensions { /// /// Saves the image to the given stream with the jpeg format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// Thrown if the stream is null. - public static void SaveAsJpeg(this Image source, Stream stream) - where TPixel : struct, IPixel - => SaveAsJpeg(source, stream, null); + public static void SaveAsJpeg(this Image source, Stream stream) => SaveAsJpeg(source, stream, null); /// /// Saves the image to the given stream with the jpeg format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// The options for the encoder. /// Thrown if the stream is null. - public static void SaveAsJpeg(this Image source, Stream stream, JpegEncoder encoder) - where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance)); + public static void SaveAsJpeg(this Image source, Stream stream, JpegEncoder encoder) => + source.Save( + stream, + encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance)); } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Png/ImageExtensions.cs b/src/ImageSharp/Formats/Png/ImageExtensions.cs index c73ec6f57e..af56830f42 100644 --- a/src/ImageSharp/Formats/Png/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Png/ImageExtensions.cs @@ -2,39 +2,35 @@ // Licensed under the Apache License, Version 2.0. using System.IO; + using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp { /// - /// Extension methods for the type. + /// Extension methods for the type. /// public static partial class ImageExtensions { /// /// Saves the image to the given stream with the png format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// Thrown if the stream is null. - public static void SaveAsPng(this Image source, Stream stream) - where TPixel : struct, IPixel - => SaveAsPng(source, stream, null); + public static void SaveAsPng(this Image source, Stream stream) => SaveAsPng(source, stream, null); /// /// Saves the image to the given stream with the png format. /// - /// The pixel format. /// The image this method extends. /// The stream to save the image to. /// The options for the encoder. /// Thrown if the stream is null. - public static void SaveAsPng(this Image source, Stream stream, PngEncoder encoder) - where TPixel : struct, IPixel - => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance)); + public static void SaveAsPng(this Image source, Stream stream, PngEncoder encoder) => + source.Save( + stream, + encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance)); } } \ No newline at end of file diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 24a169f6e9..25dc5a1e0e 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -44,48 +44,6 @@ namespace SixLabors.ImageSharp /// A new . public static Image Load(byte[] data) => Load(Configuration.Default, data); - /// - /// Load a new instance of from the given encoded byte array. - /// - /// 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); - - /// - /// Load a new instance of from the given encoded byte array. - /// - /// The config for the decoder. - /// The byte array containing encoded image data. - /// A new . - public static Image Load(Configuration config, byte[] data) => Load(config, data); - - /// - /// Load a new instance of from the given encoded byte array. - /// - /// The config for the decoder. - /// The byte array containing image data. - /// The mime type of the decoded image. - /// A new . - public static Image Load(Configuration config, byte[] data, out IImageFormat format) => Load(config, data, out format); - - /// - /// Load a new instance of from the given encoded byte array. - /// - /// The byte array containing encoded image data. - /// The decoder. - /// A new . - public static Image Load(byte[] data, IImageDecoder decoder) => Load(data, decoder); - - /// - /// Load a new instance of from the given encoded byte array. - /// - /// The config for the decoder. - /// The byte array containing image data. - /// The decoder. - /// A new . - public static Image Load(Configuration config, byte[] data, IImageDecoder decoder) => Load(config, data, decoder); - /// /// Load a new instance of from the given encoded byte array. /// @@ -117,9 +75,9 @@ namespace SixLabors.ImageSharp public static Image Load(Configuration config, byte[] data) where TPixel : struct, IPixel { - using (var steram = new MemoryStream(data)) + using (var stream = new MemoryStream(data)) { - return Load(config, steram); + return Load(config, stream); } } @@ -211,29 +169,36 @@ namespace SixLabors.ImageSharp } /// - /// Load a new instance of from the given encoded byte span. + /// 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); + /// 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. + /// Load a new instance of from the given encoded byte array. /// - /// 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); + /// The byte span containing image data. + /// The mime type of the decoded image. + /// The pixel format. + /// A new . + public static Image Load(ReadOnlySpan data, out IImageFormat format) + where TPixel : struct, IPixel + => Load(Configuration.Default, data, out format); /// - /// Load a new instance of from the given encoded byte span. + /// Load a new instance of from the given encoded byte array. /// /// The byte span containing encoded image data. + /// The decoder. /// The pixel format. /// A new . - public static Image Load(ReadOnlySpan data) + public static Image Load(ReadOnlySpan data, IImageDecoder decoder) where TPixel : struct, IPixel - => Load(Configuration.Default, data); + => Load(Configuration.Default, data, decoder); /// /// Load a new instance of from the given encoded byte span. @@ -299,5 +264,135 @@ namespace SixLabors.ImageSharp } } } + + /// + /// Load a new instance of from the given encoded byte array. + /// + /// The byte array containing image data. + /// The detected format. + /// A new . + public static Image Load(byte[] data, out IImageFormat format) => + Load(Configuration.Default, data, out format); + + /// + /// Load a new instance of from the given encoded byte array. + /// + /// The byte array containing encoded image data. + /// The decoder. + /// A new . + public static Image Load(byte[] data, IImageDecoder decoder) => Load(Configuration.Default, data, decoder); + + /// + /// Load a new instance of from the given encoded byte array. + /// + /// The config for the decoder. + /// The byte array containing encoded image data. + /// A new . + public static Image Load(Configuration config, byte[] data) => Load(config, data, out _); + + /// + /// Load a new instance of from the given encoded byte array. + /// + /// The config for the decoder. + /// The byte array containing image data. + /// The decoder. + /// A new . + public static Image Load(Configuration config, byte[] data, IImageDecoder decoder) + { + using (var stream = new MemoryStream(data)) + { + return Load(config, stream, decoder); + } + } + + /// + /// Load a new instance of from the given encoded byte array. + /// + /// The config for the decoder. + /// The byte array containing image data. + /// The mime type of the decoded image. + /// A new . + public static Image Load(Configuration config, byte[] data, out IImageFormat format) + { + using (var stream = new MemoryStream(data)) + { + return Load(config, stream, out format); + } + } + + /// + /// 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 byte span containing image data. + /// The decoder. + /// A new . + public static Image Load(ReadOnlySpan data, IImageDecoder decoder) => + Load(Configuration.Default, data, decoder); + + /// + /// Load a new instance of from the given encoded byte array. + /// + /// The byte span containing image data. + /// The detected format. + /// A new . + public static Image Load(ReadOnlySpan data, out IImageFormat format) => + Load(Configuration.Default, data, out format); + + /// + /// Decodes a new instance of from the given encoded byte span. + /// + /// The configuration options. + /// The byte span containing image data. + /// A new . + public static unsafe Image Load(Configuration config, ReadOnlySpan data) => Load(config, data, out _); + + /// + /// Load a new instance of from the given encoded byte span. + /// + /// The Configuration. + /// The byte span containing image data. + /// The decoder. + /// A new . + public static unsafe Image Load( + Configuration config, + ReadOnlySpan data, + IImageDecoder decoder) + { + 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.> + /// A new . + public static unsafe Image Load( + Configuration config, + ReadOnlySpan data, + out IImageFormat format) + { + fixed (byte* ptr = &data.GetPinnableReference()) + { + using (var stream = new UnmanagedMemoryStream(ptr, data.Length)) + { + return Load(config, stream, out format); + } + } + } } } \ No newline at end of file diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index 61500e20d7..08ed381c5a 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is not readable nor seekable. /// /// A new . - public static Image Load(string path) => Load(path); + public static Image Load(string path) => Load(Configuration.Default, path); /// /// Create a new instance of the class from the given file. @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is not readable nor seekable. /// /// A new . - public static Image Load(string path, out IImageFormat format) => Load(path, out format); + public static Image Load(string path, out IImageFormat format) => Load(Configuration.Default, path, out format); /// /// Create a new instance of the class from the given file. @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is not readable nor seekable. /// /// A new . - public static Image Load(Configuration config, string path) => Load(config, path); + public static Image Load(Configuration config, string path) => Load(config, path, out _); /// /// Create a new instance of the class from the given file. @@ -80,7 +80,13 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is not readable nor seekable. /// /// A new . - public static Image Load(Configuration config, string path, IImageDecoder decoder) => Load(config, path, decoder); + public static Image Load(Configuration config, string path, IImageDecoder decoder) + { + using (Stream stream = config.FileSystem.OpenRead(path)) + { + return Load(config, stream, decoder); + } + } /// /// Create a new instance of the class from the given file. @@ -91,7 +97,7 @@ namespace SixLabors.ImageSharp /// Thrown if the stream is not readable nor seekable. /// /// A new . - public static Image Load(string path, IImageDecoder decoder) => Load(path, decoder); + public static Image Load(string path, IImageDecoder decoder) => Load(Configuration.Default, path, decoder); /// /// Create a new instance of the class from the given file. diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index a4a9eeec75..74b99dfb3f 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -56,39 +56,54 @@ namespace SixLabors.ImageSharp => WithSeekableStream(config, stream, s => InternalIdentity(s, config ?? Configuration.Default)); /// - /// Create a new instance of the class from the given stream. + /// Decode a new instance of the class from the given stream. + /// The pixel format is selected by the decoder. /// /// The stream containing image information. /// the mime type of the decoded image. /// Thrown if the stream is not readable. - /// A new .> - public static Image Load(Stream stream, out IImageFormat format) => Load(stream, out format); + /// A new .> + public static Image Load(Stream stream, out IImageFormat format) => Load(Configuration.Default, stream, out format); /// - /// Create a new instance of the class from the given stream. + /// Decode a new instance of the class from the given stream. + /// The pixel format is selected by the decoder. /// /// The stream containing image information. /// Thrown if the stream is not readable. - /// A new .> - public static Image Load(Stream stream) => Load(stream); + /// A new .> + public static Image Load(Stream stream) => Load(Configuration.Default, stream); /// - /// Create a new instance of the class from the given stream. + /// Decode a new instance of the class from the given stream. + /// The pixel format is selected by the decoder. /// /// The stream containing image information. /// The decoder. /// Thrown if the stream is not readable. - /// A new .> - public static Image Load(Stream stream, IImageDecoder decoder) => Load(stream, decoder); + /// A new .> + public static Image Load(Stream stream, IImageDecoder decoder) => Load(Configuration.Default, stream, decoder); /// - /// Create a new instance of the class from the given stream. + /// Decode a new instance of the class from the given stream. + /// The pixel format is selected by the decoder. + /// + /// The config for the decoder. + /// The stream containing image information. + /// The decoder. + /// Thrown if the stream is not readable. + /// A new .> + public static Image Load(Configuration config, Stream stream, IImageDecoder decoder) => + WithSeekableStream(config, stream, s => decoder.Decode(config, s)); + + /// + /// Decode a new instance of the class from the given stream. /// /// The config for the decoder. /// The stream containing image information. /// Thrown if the stream is not readable. - /// A new .> - public static Image Load(Configuration config, Stream stream) => Load(config, stream); + /// A new .> + public static Image Load(Configuration config, Stream stream) => Load(config, stream, out _); /// /// Create a new instance of the class from the given stream. @@ -183,7 +198,16 @@ namespace SixLabors.ImageSharp throw new NotSupportedException(sb.ToString()); } - private static Image Load(Configuration config, Stream stream, out IImageFormat format) + /// + /// Decode a new instance of the class from the given stream. + /// The pixel format is selected by the decoder. + /// + /// The configuration options. + /// The stream containing image information. + /// the mime type of the decoded image. + /// Thrown if the stream is not readable. + /// A new . + public static Image Load(Configuration config, Stream stream, out IImageFormat format) { config = config ?? Configuration.Default; (Image img, IImageFormat format) data = WithSeekableStream(config, stream, s => Decode(s, config)); diff --git a/tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs b/tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs index 2dcd8b3d34..b064d9c964 100644 --- a/tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests foreach (TestFile file in Files) { - using (Image image = file.CreateImage()) + using (Image image = file.CreateRgba32Image()) { image.Mutate(x => x.Fill(brush)); image.Save($"{path}/{file.FileName}"); @@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Tests foreach (TestFile file in Files) { - using (Image image = file.CreateImage()) + using (Image image = file.CreateRgba32Image()) { int imageHeight = image.Height; image.Mutate(x => x.Fill(brush, new Rectangle(0, imageHeight / 2 - imageHeight / 4, image.Width, imageHeight / 2))); diff --git a/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs b/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs index d7fb0a3d37..5660518eb4 100644 --- a/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs +++ b/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing new Vector2(50, 300) }; - using (Image brushImage = TestFile.Create(TestImages.Bmp.Car).CreateImage()) + using (Image brushImage = TestFile.Create(TestImages.Bmp.Car).CreateRgba32Image()) using (var image = new Image(500, 500)) { var brush = new ImageBrush(brushImage); diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs index 7e054734e3..df3029a7fc 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp var options = new BmpEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp var options = new BmpEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index e8fdbd8926..b2f9788ae4 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Tests foreach (TestFile file in Files) { - using (Image image = file.CreateImage()) + using (Image image = file.CreateRgba32Image()) { string filename = path + "/" + file.FileNameWithoutExtension + ".txt"; File.WriteAllText(filename, image.ToBase64String(PngFormat.Instance)); @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests foreach (TestFile file in Files) { - using (Image image = file.CreateImage()) + using (Image image = file.CreateRgba32Image()) { image.Save($"{path}/{file.FileName}"); } @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Tests foreach (TestFile file in Files) { - using (Image image = file.CreateImage()) + using (Image image = file.CreateRgba32Image()) { using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.bmp")) { diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index b13362aa3b..784f7ce703 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -165,7 +165,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif var testFile = TestFile.Create(TestImages.Gif.Rings); - using (Image image = testFile.CreateImage(options)) + using (Image image = testFile.CreateRgba32Image(options)) { Assert.Equal(1, image.Metadata.Properties.Count); Assert.Equal("Comments", image.Metadata.Properties[0].Name); @@ -183,7 +183,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif var testFile = TestFile.Create(TestImages.Gif.Rings); - using (Image image = testFile.CreateImage(options)) + using (Image image = testFile.CreateRgba32Image(options)) { Assert.Equal(0, image.Metadata.Properties.Count); } @@ -199,7 +199,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif var testFile = TestFile.Create(TestImages.Gif.Rings); - using (Image image = testFile.CreateImage(options)) + using (Image image = testFile.CreateRgba32Image(options)) { Assert.Equal(1, image.Metadata.Properties.Count); Assert.Equal("浉条卥慨灲", image.Metadata.Properties[0].Value); diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs index 5da1c3bb78..eab30944e9 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif var options = new GifEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif var testFile = TestFile.Create(TestImages.Gif.Rings); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif var testFile = TestFile.Create(TestImages.Gif.Rings); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { input.Metadata.Properties.Clear(); using (var memStream = new MemoryStream()) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs index 48acc9ea47..308cf28b35 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs @@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg // Snake.jpg has both Exif and ICC profiles defined: var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Snake); - using (Image image = testFile.CreateImage(decoder)) + using (Image image = testFile.CreateRgba32Image(decoder)) { if (ignoreMetaData) { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 618947130a..d9013b507e 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var options = new JpegEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { @@ -137,7 +137,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) using (var memStream0 = new MemoryStream()) using (var memStream1 = new MemoryStream()) { @@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) using (var memStream0 = new MemoryStream()) using (var memStream1 = new MemoryStream()) { @@ -180,7 +180,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var options = new JpegEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 0dbccd2509..70d191d74e 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -202,7 +202,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png var testFile = TestFile.Create(TestImages.Png.Blur); - using (Image image = testFile.CreateImage(options)) + using (Image image = testFile.CreateRgba32Image(options)) { Assert.Equal(1, image.Metadata.Properties.Count); Assert.Equal("Software", image.Metadata.Properties[0].Name); @@ -220,7 +220,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png var testFile = TestFile.Create(TestImages.Png.Blur); - using (Image image = testFile.CreateImage(options)) + using (Image image = testFile.CreateRgba32Image(options)) { Assert.Equal(0, image.Metadata.Properties.Count); } @@ -236,7 +236,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png var testFile = TestFile.Create(TestImages.Png.Blur); - using (Image image = testFile.CreateImage(options)) + using (Image image = testFile.CreateRgba32Image(options)) { Assert.Equal(1, image.Metadata.Properties.Count); Assert.Equal("潓瑦慷敲", image.Metadata.Properties[0].Name); diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs index 5aa69dd6af..b8178fd4f3 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png var options = new PngEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { @@ -244,7 +244,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png var options = new PngEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { @@ -268,7 +268,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png var options = new PngEncoder(); var testFile = TestFile.Create(imagePath); - using (Image input = testFile.CreateImage()) + using (Image input = testFile.CreateRgba32Image()) { PngMetadata inMeta = input.Metadata.GetFormatMetadata(PngFormat.Instance); Assert.True(inMeta.HasTrans); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index aabc3f50e5..ec6705d0ec 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -16,7 +16,9 @@ namespace SixLabors.ImageSharp.Tests { public abstract class ImageLoadTestBase : IDisposable { - protected Image returnImage; + protected Image localStreamReturnImageRgba32; + + protected Image localStreamReturnImageAgnostic; protected Mock localDecoder; @@ -48,12 +50,14 @@ namespace SixLabors.ImageSharp.Tests protected ImageLoadTestBase() { - this.returnImage = new Image(1, 1); + this.localStreamReturnImageRgba32 = new Image(1, 1); + this.localStreamReturnImageAgnostic = 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) => { @@ -63,7 +67,19 @@ namespace SixLabors.ImageSharp.Tests this.DecodedData = ms.ToArray(); } }) - .Returns(this.returnImage); + .Returns(this.localStreamReturnImageRgba32); + + 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.localStreamReturnImageAgnostic); + this.LocalConfiguration = new Configuration { @@ -85,7 +101,8 @@ namespace SixLabors.ImageSharp.Tests public void Dispose() { // clean up the global object; - this.returnImage?.Dispose(); + this.localStreamReturnImageRgba32?.Dispose(); + this.localStreamReturnImageAgnostic?.Dispose(); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs index 1a21d3d105..d6fe43897c 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests Assert.NotNull(img); - this.TestFormat.VerifyDecodeCall(this.Marker, this.TopLevelConfiguration); + this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } [Fact] diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes.cs deleted file mode 100644 index eed1a28252..0000000000 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes.cs +++ /dev/null @@ -1,120 +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.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_FromBytes_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs new file mode 100644 index 0000000000..5fe87fedca --- /dev/null +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs @@ -0,0 +1,119 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; + +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests +{ + public partial class ImageTests + { + public class Load_FromBytes_PassLocalConfiguration : 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 Configuration_Bytes_Specific(bool useSpan) + { + var 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.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Configuration_Bytes_Agnostic(bool useSpan) + { + var img = useSpan + ? Image.Load(this.TopLevelConfiguration, this.ByteSpan) + : Image.Load(this.TopLevelConfiguration, this.ByteArray); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat.SampleAgnostic(), img); + + this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Configuration_Bytes_Decoder_Specific(bool useSpan) + { + TestFormat localFormat = new TestFormat(); + + var img = useSpan ? + Image.Load(this.TopLevelConfiguration, this.ByteSpan, localFormat.Decoder) : + Image.Load(this.TopLevelConfiguration, this.ByteArray, localFormat.Decoder); + + Assert.NotNull(img); + localFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Configuration_Bytes_Decoder_Agnostic(bool useSpan) + { + TestFormat localFormat = new TestFormat(); + + var img = useSpan ? + Image.Load(this.TopLevelConfiguration, this.ByteSpan, localFormat.Decoder) : + Image.Load(this.TopLevelConfiguration, this.ByteArray, localFormat.Decoder); + + Assert.NotNull(img); + localFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Configuration_Bytes_OutFormat_Specific(bool useSpan) + { + IImageFormat format; + var img = useSpan ? + Image.Load(this.TopLevelConfiguration, this.ByteSpan, out format) : + Image.Load(this.TopLevelConfiguration, this.ByteArray, out format); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat, format); + + this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Configuration_Bytes_OutFormat_Agnostic(bool useSpan) + { + IImageFormat format; + var img = useSpan ? + Image.Load(this.TopLevelConfiguration, this.ByteSpan, out format) : + Image.Load(this.TopLevelConfiguration, this.ByteArray, out format); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat, format); + + this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs new file mode 100644 index 0000000000..23c25d9dbb --- /dev/null +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs @@ -0,0 +1,101 @@ +// 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.Formats.Bmp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Primitives; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests +{ + public partial class ImageTests + { + public class Load_FromBytes_UseGlobalConfiguration + { + private static byte[] ByteArray { get; } = TestFile.Create(TestImages.Bmp.F).Bytes; + + private static Span ByteSpan => new Span(ByteArray); + + private static void VerifyDecodedImage(Image img) + { + Assert.Equal(new Size(108, 202), img.Size()); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Bytes_Specific(bool useSpan) + { + using (var img = useSpan ? Image.Load(ByteSpan) : Image.Load(ByteArray)) + { + VerifyDecodedImage(img); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Bytes_Agnostic(bool useSpan) + { + using (var img = useSpan ? Image.Load(ByteSpan) : Image.Load(ByteArray)) + { + VerifyDecodedImage(img); + } + } + + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Bytes_Decoder_Specific(bool useSpan) + { + using (var img = useSpan ? Image.Load(ByteSpan, new BmpDecoder()) : Image.Load(ByteArray, new BmpDecoder())) + { + VerifyDecodedImage(img); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Bytes_Decoder_Agnostic(bool useSpan) + { + using (var img = useSpan ? Image.Load(ByteSpan, new BmpDecoder()) : Image.Load(ByteArray, new BmpDecoder())) + { + VerifyDecodedImage(img); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Bytes_OutFormat_Specific(bool useSpan) + { + IImageFormat format; + using (var img = useSpan ? Image.Load(ByteSpan, out format) : Image.Load(ByteArray, out format)) + { + VerifyDecodedImage(img); + Assert.IsType(format); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Bytes_OutFormat_Agnostic(bool useSpan) + { + IImageFormat format; + using (var img = useSpan ? Image.Load(ByteSpan, out format) : Image.Load(ByteArray, out format)) + { + VerifyDecodedImage(img); + Assert.IsType(format); + } + } + } + } +} \ 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 deleted file mode 100644 index 6b6acb1b80..0000000000 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream.cs +++ /dev/null @@ -1,102 +0,0 @@ -// 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/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs new file mode 100644 index 0000000000..5ca86c3cee --- /dev/null +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs @@ -0,0 +1,93 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; + +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests +{ + public partial class ImageTests + { + public class Load_FromStream_PassLocalConfiguration : ImageLoadTestBase + { + [Fact] + public void Configuration_Stream_Specific() + { + var img = Image.Load(this.TopLevelConfiguration, this.DataStream); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat.Sample(), img); + + this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Fact] + public void Configuration_Stream_Agnostic() + { + var img = Image.Load(this.TopLevelConfiguration, this.DataStream); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat.SampleAgnostic(), img); + + this.TestFormat.VerifyAgnosticDecodeCall(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.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Fact] + public void Configuration_Stream_Decoder_Specific() + { + 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)); + } + + [Fact] + public void Configuration_Stream_Decoder_Agnostic() + { + 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)); + } + + [Fact] + public void Configuration_Stream_OutFormat_Specific() + { + var img = Image.Load(this.TopLevelConfiguration, this.DataStream, out IImageFormat format); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat, format); + + this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); + } + + [Fact] + public void Configuration_Stream_OutFormat_Agnostic() + { + var img = Image.Load(this.TopLevelConfiguration, this.DataStream, out IImageFormat format); + + Assert.NotNull(img); + Assert.Equal(this.TestFormat, format); + + this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs new file mode 100644 index 0000000000..27aba42ead --- /dev/null +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs @@ -0,0 +1,95 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; + +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Bmp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Primitives; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests +{ + public partial class ImageTests + { + public class Load_FromStream_UseDefaultConfiguration + { + [Fact] + public void Stream_Specific() + { + 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 Stream_Agnostic() + { + 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 Stream_OutFormat_Specific() + { + byte[] data = TestFile.Create(TestImages.Bmp.F).Bytes; + + + using (var stream = new MemoryStream(data)) + using (var img = Image.Load(stream, out IImageFormat format)) + { + Assert.Equal(new Size(108, 202), img.Size()); + Assert.IsType(format); + } + } + + [Fact] + public void Stream_Decoder_Specific() + { + byte[] data = TestFile.Create(TestImages.Bmp.F).Bytes; + + using (var stream = new MemoryStream(data)) + using (var img = Image.Load(stream, new BmpDecoder())) + { + Assert.Equal(new Size(108, 202), img.Size()); + } + } + + [Fact] + public void Stream_Decoder_Agnostic() + { + byte[] data = TestFile.Create(TestImages.Bmp.F).Bytes; + + using (var stream = new MemoryStream(data)) + using (var img = Image.Load(stream, new BmpDecoder())) + { + Assert.Equal(new Size(108, 202), img.Size()); + } + } + + [Fact] + public void Stream_OutFormat_Agnostic() + { + byte[] data = TestFile.Create(TestImages.Bmp.F).Bytes; + + using (var stream = new MemoryStream(data)) + using (var img = Image.Load(stream, out IImageFormat format)) + { + Assert.Equal(new Size(108, 202), img.Size()); + Assert.IsType(format); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifProfileTests.cs b/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifProfileTests.cs index 9d145f3805..668e699c5f 100644 --- a/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifProfileTests.cs +++ b/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifProfileTests.cs @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData(TestImageWriteFormat.Png)] public void Constructor(TestImageWriteFormat imageFormat) { - Image image = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora).CreateImage(); + Image image = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora).CreateRgba32Image(); Assert.Null(image.Metadata.ExifProfile); @@ -126,7 +126,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData(TestImageWriteFormat.Png)] public void ReadWriteInfinity(TestImageWriteFormat imageFormat) { - Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage(); + Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image(); image.Metadata.ExifProfile.SetValue(ExifTag.ExposureBiasValue, new SignedRational(double.PositiveInfinity)); image = WriteAndReadJpeg(image); @@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.Tests { var latitude = new Rational[] { new Rational(12.3), new Rational(4.56), new Rational(789.0) }; - Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage(); + Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image(); image.Metadata.ExifProfile.SetValue(ExifTag.Software, "ImageSharp"); ExifValue value = image.Metadata.ExifProfile.GetValue(ExifTag.Software); @@ -314,7 +314,7 @@ namespace SixLabors.ImageSharp.Tests // This image contains an 802 byte EXIF profile // It has a tag with an index offset of 18,481,152 bytes (overrunning the data) - Image image = TestFile.Create(TestImages.Jpeg.Progressive.Bad.ExifUndefType).CreateImage(); + Image image = TestFile.Create(TestImages.Jpeg.Progressive.Bad.ExifUndefType).CreateRgba32Image(); Assert.NotNull(image); ExifProfile profile = image.Metadata.ExifProfile; @@ -333,7 +333,7 @@ namespace SixLabors.ImageSharp.Tests public void TestArrayValueWithUnspecifiedSize() { // This images contains array in the exif profile that has zero components. - Image image = TestFile.Create(TestImages.Jpeg.Issues.InvalidCast520).CreateImage(); + Image image = TestFile.Create(TestImages.Jpeg.Issues.InvalidCast520).CreateRgba32Image(); ExifProfile profile = image.Metadata.ExifProfile; Assert.NotNull(profile); @@ -408,7 +408,7 @@ namespace SixLabors.ImageSharp.Tests internal static ExifProfile GetExifProfile() { - Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage(); + Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image(); ExifProfile profile = image.Metadata.ExifProfile; Assert.NotNull(profile); diff --git a/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifValueTests.cs b/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifValueTests.cs index 4327cae335..8d786811cf 100644 --- a/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifValueTests.cs +++ b/tests/ImageSharp.Tests/MetaData/Profiles/Exif/ExifValueTests.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Tests private static ExifValue GetExifValue() { ExifProfile profile; - using (Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage()) + using (Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image()) { profile = image.Metadata.ExifProfile; } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs index 9c3ea90d53..0c7a760818 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void PorterDuffOutputIsCorrect(TestImageProvider provider, PixelAlphaCompositionMode mode) { var srcFile = TestFile.Create(TestImages.Png.PDSrc); - using (Image src = srcFile.CreateImage()) + using (Image src = srcFile.CreateRgba32Image()) using (Image dest = provider.GetImage()) { GraphicsOptions options = new GraphicsOptions diff --git a/tests/ImageSharp.Tests/TestFile.cs b/tests/ImageSharp.Tests/TestFile.cs index 089249e217..6ca86ced6e 100644 --- a/tests/ImageSharp.Tests/TestFile.cs +++ b/tests/ImageSharp.Tests/TestFile.cs @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.Tests /// /// The . /// - public Image CreateImage() + public Image CreateRgba32Image() { return this.Image.Clone(); } @@ -145,9 +145,9 @@ namespace SixLabors.ImageSharp.Tests /// /// The . /// - public Image CreateImage(IImageDecoder decoder) + public Image CreateRgba32Image(IImageDecoder decoder) { - return ImageSharp.Image.Load(this.Image.GetConfiguration(), this.Bytes, decoder); + return ImageSharp.Image.Load(this.Image.GetConfiguration(), this.Bytes, decoder); } } } diff --git a/tests/ImageSharp.Tests/TestFileSystem.cs b/tests/ImageSharp.Tests/TestFileSystem.cs index 21ad4d2c1a..9211e70f79 100644 --- a/tests/ImageSharp.Tests/TestFileSystem.cs +++ b/tests/ImageSharp.Tests/TestFileSystem.cs @@ -12,29 +12,24 @@ namespace SixLabors.ImageSharp.Tests /// public class TestFileSystem : ImageSharp.IO.IFileSystem { - - public static TestFileSystem Global { get; } = new TestFileSystem(); - - public static void RegisterGlobalTestFormat() - { - Configuration.Default.FileSystem = Global; - } - - Dictionary fileSystem = new Dictionary(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary fileSystem = new Dictionary(StringComparer.OrdinalIgnoreCase); public void AddFile(string path, Stream data) { - fileSystem.Add(path, data); + lock (this.fileSystem) + { + this.fileSystem.Add(path, data); + } } public Stream Create(string path) { // if we have injected a fake file use it instead - lock (fileSystem) + lock (this.fileSystem) { - if (fileSystem.ContainsKey(path)) + if (this.fileSystem.ContainsKey(path)) { - Stream stream = fileSystem[path]; + Stream stream = this.fileSystem[path]; stream.Position = 0; return stream; } @@ -43,15 +38,14 @@ namespace SixLabors.ImageSharp.Tests return File.Create(path); } - public Stream OpenRead(string path) { // if we have injected a fake file use it instead - lock (fileSystem) + lock (this.fileSystem) { - if (fileSystem.ContainsKey(path)) + if (this.fileSystem.ContainsKey(path)) { - Stream stream = fileSystem[path]; + Stream stream = this.fileSystem[path]; stream.Position = 0; return stream; } @@ -60,5 +54,4 @@ namespace SixLabors.ImageSharp.Tests return File.OpenRead(path); } } -} - +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs index 91e31b356e..23bd0a54c3 100644 --- a/tests/ImageSharp.Tests/TestFormat.cs +++ b/tests/ImageSharp.Tests/TestFormat.cs @@ -6,6 +6,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Numerics; using System.Reflection; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -18,6 +19,8 @@ namespace SixLabors.ImageSharp.Tests /// public class TestFormat : IConfigurationModule, IImageFormat { + private readonly Dictionary sampleImages = new Dictionary(); + // 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(); @@ -49,12 +52,23 @@ namespace SixLabors.ImageSharp.Tests return ms; } - Dictionary _sampleImages = new Dictionary(); + public void VerifySpecificDecodeCall(byte[] marker, Configuration config) + where TPixel : struct, IPixel + { + DecodeOperation[] discovered = this.DecodeCalls.Where(x => x.IsMatch(marker, config, typeof(TPixel))).ToArray(); - public void VerifyDecodeCall(byte[] marker, Configuration config) + 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 void VerifyAgnosticDecodeCall(byte[] marker, Configuration config) { - DecodeOperation[] discovered = this.DecodeCalls.Where(x => x.IsMatch(marker, config)).ToArray(); + DecodeOperation[] discovered = this.DecodeCalls.Where(x => x.IsMatch(marker, config, typeof(TestPixelForAgnosticDecode))).ToArray(); Assert.True(discovered.Any(), "No calls to decode on this formate with the proveded options happend"); @@ -68,17 +82,19 @@ namespace SixLabors.ImageSharp.Tests public Image Sample() where TPixel : struct, IPixel { - lock (this._sampleImages) + lock (this.sampleImages) { - if (!this._sampleImages.ContainsKey(typeof(TPixel))) + if (!this.sampleImages.ContainsKey(typeof(TPixel))) { - this._sampleImages.Add(typeof(TPixel), new Image(1, 1)); + this.sampleImages.Add(typeof(TPixel), new Image(1, 1)); } - return (Image)this._sampleImages[typeof(TPixel)]; + return (Image)this.sampleImages[typeof(TPixel)]; } } + public Image SampleAgnostic() => this.Sample(); + public string MimeType => "img/test"; public string Extension => "test_ext"; @@ -123,10 +139,12 @@ namespace SixLabors.ImageSharp.Tests public byte[] marker; internal Configuration config; - public bool IsMatch(byte[] testMarker, Configuration config) + public Type pixelType; + + public bool IsMatch(byte[] testMarker, Configuration config, Type pixelType) { - if (this.config != config) + if (this.config != config || this.pixelType != pixelType) { return false; } @@ -191,7 +209,8 @@ namespace SixLabors.ImageSharp.Tests this.testFormat.DecodeCalls.Add(new DecodeOperation { marker = marker, - config = config + config = config, + pixelType = typeof(TPixel) }); // TODO record this happend so we can verify it. @@ -200,7 +219,7 @@ namespace SixLabors.ImageSharp.Tests public bool IsSupportedFileFormat(Span header) => testFormat.IsSupportedFileFormat(header); - public Image Decode(Configuration configuration, Stream stream) => this.Decode(configuration, stream); + public Image Decode(Configuration configuration, Stream stream) => this.Decode(configuration, stream); } public class TestEncoder : ImageSharp.Formats.IImageEncoder @@ -221,5 +240,27 @@ namespace SixLabors.ImageSharp.Tests // TODO record this happend so we can verify it. } } + + + struct TestPixelForAgnosticDecode : IPixel + { + public PixelOperations CreatePixelOperations() => new PixelOperations(); + public void FromScaledVector4(Vector4 vector) { } + public Vector4 ToScaledVector4() => default; + public void FromVector4(Vector4 vector) { } + public Vector4 ToVector4() => default; + public void FromArgb32(Argb32 source) { } + public void FromBgra5551(Bgra5551 source) { } + public void FromBgr24(Bgr24 source) { } + public void FromBgra32(Bgra32 source) { } + public void FromGray8(Gray8 source) { } + public void FromGray16(Gray16 source) { } + public void FromRgb24(Rgb24 source) { } + public void FromRgba32(Rgba32 source) { } + public void ToRgba32(ref Rgba32 dest) { } + public void FromRgb48(Rgb48 source) { } + public void FromRgba64(Rgba64 source) { } + public bool Equals(TestPixelForAgnosticDecode other) => false; + } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs index 033f0866a3..15213d5d32 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs @@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests { foreach (string testFile in testFiles) { - Image image = TestFile.Create(testFile).CreateImage(decoder); + Image image = TestFile.Create(testFile).CreateRgba32Image(decoder); image.Dispose(); } },