diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index afa63dacb..b0e414c2f 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; @@ -47,6 +47,8 @@ namespace SixLabors.ImageSharp #if !NETSTANDARD1_1 this.FileSystem = configuration.FileSystem; #endif + + this.ReadOrigin = configuration.ReadOrigin; } /// @@ -78,6 +80,11 @@ namespace SixLabors.ImageSharp /// Gets the currently registered s. /// public IEnumerable ImageFormats => this.ImageFormatsManager.ImageFormats; + + /// + /// Gets or sets the position in a stream to use for reading when using a seekable stream as an image data source. + /// + public ReadOrigin ReadOrigin { get; set; } = ReadOrigin.Current; /// /// Gets or sets the that is currently in use. @@ -234,4 +241,4 @@ namespace SixLabors.ImageSharp new BmpConfigurationModule()); } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Image/Image.FromBytes.cs b/src/ImageSharp/Image/Image.FromBytes.cs index 9da9c5e43..44c53d776 100644 --- a/src/ImageSharp/Image/Image.FromBytes.cs +++ b/src/ImageSharp/Image/Image.FromBytes.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp /// The format or null if none found. public static IImageFormat DetectFormat(byte[] data) { - return DetectFormat(null, data); + return DetectFormat(Configuration.Default, data); } /// @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp /// /// The byte array containing image data. /// A new . - public static Image Load(byte[] data) => Load(null, data); + public static Image Load(byte[] data) => Load(Configuration.Default, data); /// /// Create a new instance of the class from the given byte array. @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp /// The byte array containing image data. /// The mime type of the decoded image. /// A new . - public static Image Load(byte[] data, out IImageFormat format) => Load(null, data, out format); + 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. @@ -93,9 +93,7 @@ namespace SixLabors.ImageSharp /// A new . public static Image Load(byte[] data) where TPixel : struct, IPixel - { - return Load(null, data); - } + => Load(Configuration.Default, data); /// /// Create a new instance of the class from the given byte array. @@ -106,9 +104,7 @@ namespace SixLabors.ImageSharp /// A new . public static Image Load(byte[] data, out IImageFormat format) where TPixel : struct, IPixel - { - return Load(null, data, out format); - } + => Load(Configuration.Default, data, out format); /// /// Create a new instance of the class from the given byte array. diff --git a/src/ImageSharp/Image/Image.FromFile.cs b/src/ImageSharp/Image/Image.FromFile.cs index 0474a6d47..ad8f3426f 100644 --- a/src/ImageSharp/Image/Image.FromFile.cs +++ b/src/ImageSharp/Image/Image.FromFile.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp /// The mime type or null if none found. public static IImageFormat DetectFormat(string filePath) { - return DetectFormat(null, filePath); + return DetectFormat(Configuration.Default, filePath); } /// @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp public static Image Load(string path) where TPixel : struct, IPixel { - return Load(null, path); + return Load(Configuration.Default, path); } /// @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp public static Image Load(string path, out IImageFormat format) where TPixel : struct, IPixel { - return Load(null, path, out format); + return Load(Configuration.Default, path, out format); } /// @@ -150,7 +150,6 @@ namespace SixLabors.ImageSharp public static Image Load(Configuration config, string path) where TPixel : struct, IPixel { - config = config ?? Configuration.Default; using (Stream stream = config.FileSystem.OpenRead(path)) { return Load(config, stream); @@ -171,7 +170,6 @@ namespace SixLabors.ImageSharp public static Image Load(Configuration config, string path, out IImageFormat format) where TPixel : struct, IPixel { - config = config ?? Configuration.Default; using (Stream stream = config.FileSystem.OpenRead(path)) { return Load(config, stream, out format); @@ -191,7 +189,7 @@ namespace SixLabors.ImageSharp public static Image Load(string path, IImageDecoder decoder) where TPixel : struct, IPixel { - return Load(null, path, decoder); + return Load(Configuration.Default, path, decoder); } /// @@ -208,7 +206,6 @@ namespace SixLabors.ImageSharp public static Image Load(Configuration config, string path, IImageDecoder decoder) where TPixel : struct, IPixel { - config = config ?? Configuration.Default; using (Stream stream = config.FileSystem.OpenRead(path)) { return Load(config, stream, decoder); diff --git a/src/ImageSharp/Image/Image.FromStream.cs b/src/ImageSharp/Image/Image.FromStream.cs index 62668dd02..4e294260a 100644 --- a/src/ImageSharp/Image/Image.FromStream.cs +++ b/src/ImageSharp/Image/Image.FromStream.cs @@ -19,62 +19,48 @@ namespace SixLabors.ImageSharp /// By reading the header on the provided stream this calculates the images mime type. /// /// The image stream to read the header from. + /// Thrown if the stream is not readable. /// The mime type or null if none found. - public static IImageFormat DetectFormat(Stream stream) - { - return DetectFormat(null, stream); - } + public static IImageFormat DetectFormat(Stream stream) => DetectFormat(Configuration.Default, stream); /// /// By reading the header on the provided stream this calculates the images mime type. /// /// The configuration. /// The image stream to read the header from. + /// Thrown if the stream is not readable. /// The mime type or null if none found. public static IImageFormat DetectFormat(Configuration config, Stream stream) - { - return WithSeekableStream(stream, s => InternalDetectFormat(s, config ?? Configuration.Default)); - } + => WithSeekableStream(config, stream, s => InternalDetectFormat(s, config)); /// /// By reading the header on the provided stream this reads the raw image information. /// /// The image stream to read the header from. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// /// The or null if suitable info detector not found. /// - public static IImageInfo Identify(Stream stream) - { - return Identify(null, stream); - } + public static IImageInfo Identify(Stream stream) => Identify(Configuration.Default, stream); /// /// Reads the raw image information from the specified stream without fully decoding it. /// /// The configuration. /// The image stream to read the information from. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// /// The or null if suitable info detector is not found. /// public static IImageInfo Identify(Configuration config, Stream stream) - { - return WithSeekableStream(stream, s => InternalIdentity(s, config ?? Configuration.Default)); - } + => WithSeekableStream(config, stream, s => InternalIdentity(s, config ?? Configuration.Default)); /// /// Create a new instance of the class from the given stream. /// /// The stream containing image information. /// the mime type of the decoded image. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// A new .> public static Image Load(Stream stream, out IImageFormat format) => Load(stream, out format); @@ -82,9 +68,7 @@ namespace SixLabors.ImageSharp /// Create a new instance of the class from the given stream. /// /// The stream containing image information. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// A new .> public static Image Load(Stream stream) => Load(stream); @@ -93,9 +77,7 @@ namespace SixLabors.ImageSharp /// /// The stream containing image information. /// The decoder. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// A new .> public static Image Load(Stream stream, IImageDecoder decoder) => Load(stream, decoder); @@ -104,9 +86,7 @@ namespace SixLabors.ImageSharp /// /// The config for the decoder. /// The stream containing image information. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// A new .> public static Image Load(Configuration config, Stream stream) => Load(config, stream); @@ -116,58 +96,45 @@ namespace SixLabors.ImageSharp /// The config for the decoder. /// The stream containing image information. /// the mime type of the decoded image. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// A new .> - public static Image Load(Configuration config, Stream stream, out IImageFormat format) => Load(config, stream, out format); + public static Image Load(Configuration config, Stream stream, out IImageFormat format) + => Load(config, stream, out format); /// /// Create a new instance of the class from the given stream. /// /// The stream containing image information. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// The pixel format. /// A new .> public static Image Load(Stream stream) where TPixel : struct, IPixel - { - return Load(null, stream); - } + => Load(null, stream); /// /// Create a new instance of the class from the given stream. /// /// The stream containing image information. /// the mime type of the decoded image. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// The pixel format. /// A new .> public static Image Load(Stream stream, out IImageFormat format) where TPixel : struct, IPixel - { - return Load(null, stream, out format); - } + => Load(null, stream, out format); /// /// Create a new instance of the class from the given stream. /// /// The stream containing image information. /// The decoder. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// The pixel format. /// A new .> public static Image Load(Stream stream, IImageDecoder decoder) where TPixel : struct, IPixel - { - return WithSeekableStream(stream, s => decoder.Decode(Configuration.Default, s)); - } + => WithSeekableStream(Configuration.Default, stream, s => decoder.Decode(Configuration.Default, s)); /// /// Create a new instance of the class from the given stream. @@ -175,32 +142,24 @@ namespace SixLabors.ImageSharp /// The Configuration. /// The stream containing image information. /// The decoder. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// The pixel format. /// A new .> public static Image Load(Configuration config, Stream stream, IImageDecoder decoder) where TPixel : struct, IPixel - { - return WithSeekableStream(stream, s => decoder.Decode(config, s)); - } + => WithSeekableStream(config, stream, s => decoder.Decode(config, s)); /// /// Create a new instance of the class from the given stream. /// /// The configuration options. /// The stream containing image information. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// The pixel format. /// A new .> public static Image Load(Configuration config, Stream stream) where TPixel : struct, IPixel - { - return Load(config, stream, out var _); - } + => Load(config, stream, out IImageFormat _); /// /// Create a new instance of the class from the given stream. @@ -208,16 +167,14 @@ namespace SixLabors.ImageSharp /// The configuration options. /// The stream containing image information. /// the mime type of the decoded image. - /// - /// Thrown if the stream is not readable nor seekable. - /// + /// Thrown if the stream is not readable. /// The pixel format. /// A new .> public static Image Load(Configuration config, Stream stream, out IImageFormat format) - where TPixel : struct, IPixel + where TPixel : struct, IPixel { config = config ?? Configuration.Default; - (Image img, IImageFormat format) data = WithSeekableStream(stream, s => Decode(s, config)); + (Image img, IImageFormat format) data = WithSeekableStream(config, stream, s => Decode(s, config)); format = data.format; @@ -237,7 +194,7 @@ namespace SixLabors.ImageSharp throw new NotSupportedException(stringBuilder.ToString()); } - private static T WithSeekableStream(Stream stream, Func action) + private static T WithSeekableStream(Configuration config, Stream stream, Func action) { if (!stream.CanRead) { @@ -246,6 +203,11 @@ namespace SixLabors.ImageSharp if (stream.CanSeek) { + if (config.ReadOrigin == ReadOrigin.Begin) + { + stream.Position = 0; + } + return action(stream); } diff --git a/src/ImageSharp/Image/ReadOrigin.cs b/src/ImageSharp/Image/ReadOrigin.cs new file mode 100644 index 000000000..f17bc82f1 --- /dev/null +++ b/src/ImageSharp/Image/ReadOrigin.cs @@ -0,0 +1,21 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp +{ + /// + /// Specifies the position in a stream to use for reading. + /// + public enum ReadOrigin + { + /// + /// Specifies the beginning of a stream. + /// + Begin, + + /// + /// Specifies the current position within a stream. + /// + Current + } +} diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 18d4abdd1..06f02fcf1 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -59,6 +59,15 @@ namespace SixLabors.ImageSharp.Tests Assert.True(Configuration.Default.ParallelOptions != null); } + /// + /// Test that the default configuration read origin options is set to begin. + /// + [Fact] + public void TestDefultConfigurationReadOriginIsCurrent() + { + Assert.True(Configuration.Default.ReadOrigin == ReadOrigin.Current); + } + /// /// Test that the default configuration parallel options max degrees of parallelism matches the /// environment processor count. @@ -83,7 +92,7 @@ namespace SixLabors.ImageSharp.Tests { Assert.Throws(() => { - this.DefaultConfiguration.SetEncoder(null, new Mock().Object); + this.DefaultConfiguration.SetEncoder(null, new Mock().Object); }); Assert.Throws(() => {