Browse Source

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

af/merge-core
Dirk Lemstra 10 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> /// </summary>
private readonly object syncRoot = new object(); private readonly object syncRoot = new object();
/// <summary>
/// The maximum header size of all formats.
/// </summary>
private int maxHeaderSize;
/// <summary> /// <summary>
/// Prevents a default instance of the <see cref="Bootstrapper"/> class from being created. /// Prevents a default instance of the <see cref="Bootstrapper"/> class from being created.
/// </summary> /// </summary>
@ -50,6 +55,7 @@ namespace ImageSharp
new PngFormat(), new PngFormat(),
new GifFormat() new GifFormat()
}; };
this.SetMaxHeaderSize();
this.parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; this.parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
} }
@ -63,6 +69,11 @@ namespace ImageSharp
/// </summary> /// </summary>
public static ParallelOptions ParallelOptions => Instance.parallelOptions; public static ParallelOptions ParallelOptions => Instance.parallelOptions;
/// <summary>
/// Gets the maximum header size of all formats.
/// </summary>
internal static int MaxHeaderSize => Instance.maxHeaderSize;
/// <summary> /// <summary>
/// Adds a new <see cref="IImageFormat"/> to the collection of supported image formats. /// Adds a new <see cref="IImageFormat"/> to the collection of supported image formats.
/// </summary> /// </summary>
@ -86,6 +97,8 @@ namespace ImageSharp
this.GuardDuplicate(format); this.GuardDuplicate(format);
this.imageFormats.Add(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 System.Threading.Tasks;
using Formats; using Formats;
using System.Buffers;
/// <summary> /// <summary>
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes. /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
@ -399,25 +400,34 @@ namespace ImageSharp
/// </returns> /// </returns>
private bool Decode(Stream stream) private bool Decode(Stream stream)
{ {
int maxHeaderSize = Bootstrapper.ImageFormats.Max(x => x.HeaderSize); int maxHeaderSize = Bootstrapper.MaxHeaderSize;
if (maxHeaderSize > 0) 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.Read(header, 0, maxHeaderSize);
stream.Position = 0; 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)
if (format != null) {
{ return false;
format.Decoder.Decode(this, stream);
this.CurrentImageFormat = format;
return true;
}
} }
return false; format.Decoder.Decode(this, stream);
this.CurrentImageFormat = format;
return true;
} }
} }
} }

Loading…
Cancel
Save