Browse Source

Only calculate the maximum header size once and use ArrayPool to create the buffer.

af/merge-core
Dirk Lemstra 9 years ago
parent
commit
7cc97b6fca
  1. 18
      src/ImageSharp/Bootstrapper.cs
  2. 34
      src/ImageSharp/Image/Image.cs

18
src/ImageSharp/Bootstrapper.cs

@ -38,6 +38,11 @@ namespace ImageSharp
/// </summary>
private readonly object syncRoot = new object();
/// <summary>
/// The maximum header size of all formats.
/// </summary>
private int maxHeaderSize;
/// <summary>
/// Prevents a default instance of the <see cref="Bootstrapper"/> class from being created.
/// </summary>
@ -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
/// </summary>
public static ParallelOptions ParallelOptions => Instance.parallelOptions;
/// <summary>
/// Gets the maximum header size of all formats.
/// </summary>
internal static int MaxHeaderSize => Instance.maxHeaderSize;
/// <summary>
/// Adds a new <see cref="IImageFormat"/> to the collection of supported image formats.
/// </summary>
@ -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);
}
}
}

34
src/ImageSharp/Image/Image.cs

@ -15,6 +15,7 @@ namespace ImageSharp
using System.Threading.Tasks;
using Formats;
using System.Buffers;
/// <summary>
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
@ -399,25 +400,34 @@ namespace ImageSharp
/// </returns>
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<byte>.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<byte>.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;
}
}
}

Loading…
Cancel
Save