Browse Source

Use clean buffers. Fix #390

af/merge-core
James Jackson-South 8 years ago
parent
commit
eecffcce6c
  1. 34
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  2. 2
      src/ImageSharp/Formats/Gif/LzwDecoder.cs

34
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -7,6 +7,7 @@ using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives; using SixLabors.Primitives;
@ -38,7 +39,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <summary> /// <summary>
/// The global color table. /// The global color table.
/// </summary> /// </summary>
private byte[] globalColorTable; private Buffer<byte> globalColorTable;
/// <summary> /// <summary>
/// The global color table length /// The global color table length
@ -123,10 +124,10 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (this.logicalScreenDescriptor.GlobalColorTableFlag) if (this.logicalScreenDescriptor.GlobalColorTableFlag)
{ {
this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3; this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
this.globalColorTable = ArrayPool<byte>.Shared.Rent(this.globalColorTableLength); this.globalColorTable = Buffer<byte>.CreateClean(this.globalColorTableLength);
// Read the global color table from the stream // Read the global color table from the stream
stream.Read(this.globalColorTable, 0, this.globalColorTableLength); stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength);
} }
// Loop though the respective gif parts and read the data. // Loop though the respective gif parts and read the data.
@ -175,10 +176,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
} }
finally finally
{ {
if (this.globalColorTable != null) this.globalColorTable?.Dispose();
{
ArrayPool<byte>.Shared.Return(this.globalColorTable);
}
} }
return this.image; return this.image;
@ -309,19 +307,19 @@ namespace SixLabors.ImageSharp.Formats.Gif
{ {
GifImageDescriptor imageDescriptor = this.ReadImageDescriptor(); GifImageDescriptor imageDescriptor = this.ReadImageDescriptor();
byte[] localColorTable = null; Buffer<byte> localColorTable = null;
byte[] indices = null; Buffer<byte> indices = null;
try try
{ {
// Determine the color table for this frame. If there is a local one, use it otherwise use the global color table. // Determine the color table for this frame. If there is a local one, use it otherwise use the global color table.
if (imageDescriptor.LocalColorTableFlag) if (imageDescriptor.LocalColorTableFlag)
{ {
int length = imageDescriptor.LocalColorTableSize * 3; int length = imageDescriptor.LocalColorTableSize * 3;
localColorTable = ArrayPool<byte>.Shared.Rent(length); localColorTable = Buffer<byte>.CreateClean(length);
this.currentStream.Read(localColorTable, 0, length); this.currentStream.Read(localColorTable.Array, 0, length);
} }
indices = ArrayPool<byte>.Shared.Rent(imageDescriptor.Width * imageDescriptor.Height); indices = Buffer<byte>.CreateClean(imageDescriptor.Width * imageDescriptor.Height);
this.ReadFrameIndices(imageDescriptor, indices); this.ReadFrameIndices(imageDescriptor, indices);
this.ReadFrameColors(indices, localColorTable ?? this.globalColorTable, imageDescriptor); this.ReadFrameColors(indices, localColorTable ?? this.globalColorTable, imageDescriptor);
@ -331,12 +329,8 @@ namespace SixLabors.ImageSharp.Formats.Gif
} }
finally finally
{ {
if (localColorTable != null) localColorTable?.Dispose();
{ indices?.Dispose();
ArrayPool<byte>.Shared.Return(localColorTable);
}
ArrayPool<byte>.Shared.Return(indices);
} }
} }
@ -346,7 +340,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <param name="imageDescriptor">The <see cref="GifImageDescriptor"/>.</param> /// <param name="imageDescriptor">The <see cref="GifImageDescriptor"/>.</param>
/// <param name="indices">The pixel array to write to.</param> /// <param name="indices">The pixel array to write to.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ReadFrameIndices(GifImageDescriptor imageDescriptor, byte[] indices) private void ReadFrameIndices(GifImageDescriptor imageDescriptor, Span<byte> indices)
{ {
int dataSize = this.currentStream.ReadByte(); int dataSize = this.currentStream.ReadByte();
using (var lzwDecoder = new LzwDecoder(this.currentStream)) using (var lzwDecoder = new LzwDecoder(this.currentStream))
@ -361,7 +355,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <param name="indices">The indexed pixels.</param> /// <param name="indices">The indexed pixels.</param>
/// <param name="colorTable">The color table containing the available colors.</param> /// <param name="colorTable">The color table containing the available colors.</param>
/// <param name="descriptor">The <see cref="GifImageDescriptor"/></param> /// <param name="descriptor">The <see cref="GifImageDescriptor"/></param>
private void ReadFrameColors(byte[] indices, byte[] colorTable, GifImageDescriptor descriptor) private void ReadFrameColors(Span<byte> indices, Span<byte> colorTable, GifImageDescriptor descriptor)
{ {
int imageWidth = this.logicalScreenDescriptor.Width; int imageWidth = this.logicalScreenDescriptor.Width;
int imageHeight = this.logicalScreenDescriptor.Height; int imageHeight = this.logicalScreenDescriptor.Height;

2
src/ImageSharp/Formats/Gif/LzwDecoder.cs

@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <param name="height">The height of the pixel index array.</param> /// <param name="height">The height of the pixel index array.</param>
/// <param name="dataSize">Size of the data.</param> /// <param name="dataSize">Size of the data.</param>
/// <param name="pixels">The pixel array to decode to.</param> /// <param name="pixels">The pixel array to decode to.</param>
public void DecodePixels(int width, int height, int dataSize, byte[] pixels) public void DecodePixels(int width, int height, int dataSize, Span<byte> pixels)
{ {
Guard.MustBeLessThan(dataSize, int.MaxValue, nameof(dataSize)); Guard.MustBeLessThan(dataSize, int.MaxValue, nameof(dataSize));

Loading…
Cancel
Save