diff --git a/src/ImageSharp/Bootstrapper.cs b/src/ImageSharp/Bootstrapper.cs
index a73205a76..a30d206b0 100644
--- a/src/ImageSharp/Bootstrapper.cs
+++ b/src/ImageSharp/Bootstrapper.cs
@@ -38,6 +38,11 @@ namespace ImageSharp
///
private readonly object syncRoot = new object();
+ ///
+ /// The maximum header size of all formats.
+ ///
+ private int maxHeaderSize;
+
///
/// Prevents a default instance of the class from being created.
///
@@ -50,6 +55,7 @@ namespace ImageSharp
new PngFormat(),
new GifFormat()
};
+ this.SetMaxHeaderSize();
this.parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
}
@@ -63,6 +69,11 @@ namespace ImageSharp
///
public static ParallelOptions ParallelOptions => Instance.parallelOptions;
+ ///
+ /// Gets the maximum header size of all formats.
+ ///
+ internal static int MaxHeaderSize => Instance.maxHeaderSize;
+
///
/// Adds a new to the collection of supported image formats.
///
@@ -86,6 +97,8 @@ namespace ImageSharp
this.GuardDuplicate(format);
this.imageFormats.Add(format);
+
+ this.SetMaxHeaderSize();
}
}
@@ -114,5 +127,10 @@ namespace ImageSharp
}
}
}
+
+ private void SetMaxHeaderSize()
+ {
+ this.maxHeaderSize = imageFormats.Max(x => x.HeaderSize);
+ }
}
}
diff --git a/src/ImageSharp/Image/Image.cs b/src/ImageSharp/Image/Image.cs
index 93e247b32..6dfd1c6db 100644
--- a/src/ImageSharp/Image/Image.cs
+++ b/src/ImageSharp/Image/Image.cs
@@ -15,6 +15,7 @@ namespace ImageSharp
using System.Threading.Tasks;
using Formats;
+ using System.Buffers;
///
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
@@ -399,25 +400,34 @@ namespace ImageSharp
///
private bool Decode(Stream stream)
{
- int maxHeaderSize = Bootstrapper.ImageFormats.Max(x => x.HeaderSize);
- if (maxHeaderSize > 0)
+ int maxHeaderSize = Bootstrapper.MaxHeaderSize;
+ if (maxHeaderSize <= 0)
{
- byte[] header = new byte[maxHeaderSize];
+ return false;
+ }
- stream.Position = 0;
+ IImageFormat format = null;
+ byte[] header = ArrayPool.Shared.Rent(maxHeaderSize);
+ try
+ {
+ long startPosition = stream.Position;
stream.Read(header, 0, maxHeaderSize);
stream.Position = 0;
+ format = Bootstrapper.ImageFormats.FirstOrDefault(x => x.IsSupportedFileFormat(header));
+ }
+ finally
+ {
+ ArrayPool.Shared.Return(header);
+ }
- IImageFormat format = Bootstrapper.ImageFormats.FirstOrDefault(x => x.IsSupportedFileFormat(header));
- if (format != null)
- {
- format.Decoder.Decode(this, stream);
- this.CurrentImageFormat = format;
- return true;
- }
+ if (format == null)
+ {
+ return false;
}
- return false;
+ format.Decoder.Decode(this, stream);
+ this.CurrentImageFormat = format;
+ return true;
}
}
}