Browse Source

Optimization: do not initialize pixel buffer in JpegDecoder

pull/768/head
Anton Firszov 7 years ago
parent
commit
bc79b18817
  1. 10
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  2. 24
      src/ImageSharp/Image.Decode.cs
  3. 25
      tests/ImageSharp.Tests/Image/ImageTests.cs

10
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -936,12 +936,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
private Image<TPixel> PostProcessIntoImage<TPixel>()
where TPixel : struct, IPixel<TPixel>
{
var image = Image.CreateUninitialized<TPixel>(
this.configuration,
this.ImageWidth,
this.ImageHeight,
this.MetaData);
using (var postProcessor = new JpegImagePostProcessor(this.configuration, this))
{
var image = new Image<TPixel>(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData);
postProcessor.PostProcess(image.Frames.RootFrame);
return image;
}
return image;
}
}
}

24
src/ImageSharp/Image.Decode.cs

@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
@ -15,6 +16,29 @@ namespace SixLabors.ImageSharp
/// </content>
public static partial class Image
{
/// <summary>
/// Creates an <see cref="Image{TPixel}"/> instance backed by an uninitialized memory buffer.
/// This is an optimized creation method intended to be used by decoders.
/// The image might be filled with memory garbage.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="width">The width of the image</param>
/// <param name="height">The height of the image</param>
/// <param name="metadata">The <see cref="ImageMetaData"/></param>
/// <returns>The result <see cref="Image{TPixel}"/></returns>
internal static Image<TPixel> CreateUninitialized<TPixel>(
Configuration configuration,
int width,
int height,
ImageMetaData metadata)
where TPixel : struct, IPixel<TPixel>
{
Buffer2D<TPixel> uninitializedMemoryBuffer =
configuration.MemoryAllocator.Allocate2D<TPixel>(width, height);
return new Image<TPixel>(configuration, uninitializedMemoryBuffer.MemorySource, width, height, metadata);
}
/// <summary>
/// By reading the header on the provided stream this calculates the images format.
/// </summary>

25
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -2,7 +2,10 @@
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Memory;
using Xunit;
// ReSharper disable InconsistentNaming
@ -46,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests
}
[Fact]
public void Configuration_Width_Height_BackroundColor()
public void Configuration_Width_Height_BackgroundColor()
{
Configuration configuration = Configuration.Default.Clone();
Rgba32 color = Rgba32.Aquamarine;
@ -61,6 +64,26 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(configuration, image.GetConfiguration());
}
}
[Fact]
public void CreateUninitialized()
{
Configuration configuration = Configuration.Default.Clone();
byte dirtyValue = 123;
configuration.MemoryAllocator = new TestMemoryAllocator(dirtyValue);
var metadata = new ImageMetaData();
using (Image<Gray8> image = Image.CreateUninitialized<Gray8>(configuration, 21, 22, metadata))
{
Assert.Equal(21, image.Width);
Assert.Equal(22, image.Height);
Assert.Same(configuration, image.GetConfiguration());
Assert.Same(metadata, image.MetaData);
Assert.Equal(dirtyValue, image[5, 5].PackedValue);
}
}
}
}
}

Loading…
Cancel
Save