Browse Source

replaced some of the PixelArea usages in bmp decoder

pull/475/head
Anton Firszov 8 years ago
parent
commit
ba5e80f6ee
  1. 25
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 3
      src/ImageSharp/Formats/Bmp/BmpEncoder.cs
  3. 27
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  4. 12
      src/ImageSharp/Memory/BufferExtensions.cs
  5. 18
      src/ImageSharp/Memory/MemoryManagerExtensions.cs
  6. 2
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

25
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -69,7 +69,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
private BmpInfoHeader infoHeader;
private Configuration configuration;
private readonly Configuration configuration;
private readonly MemoryManager memoryManager;
/// <summary>
/// Initializes a new instance of the <see cref="BmpDecoderCore"/> class.
@ -79,6 +81,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public BmpDecoderCore(Configuration configuration, IBmpDecoderOptions options)
{
this.configuration = configuration;
this.memoryManager = configuration.MemoryManager;
}
/// <summary>
@ -432,16 +435,28 @@ namespace SixLabors.ImageSharp.Formats.Bmp
where TPixel : struct, IPixel<TPixel>
{
int padding = CalculatePadding(width, 3);
using (var row = new PixelArea<TPixel>(width, ComponentOrder.Zyx, padding))
using (IManagedByteBuffer row = this.memoryManager.AllocatePaddedPixelRowBuffer(width, 3, padding))
{
for (int y = 0; y < height; y++)
{
row.Read(this.currentStream);
this.currentStream.Read(row);
int newY = Invert(y, height, inverted);
pixels.CopyFrom(row, newY);
Span<TPixel> pixelSpan = pixels.GetRowSpan(newY);
PixelOperations<TPixel>.Instance.PackFromBgr24Bytes(row.Span, pixelSpan, width);
}
}
//using (var row = new PixelArea<TPixel>(width, ComponentOrder.Zyx, padding))
//{
// for (int y = 0; y < height; y++)
// {
// row.Read(this.currentStream);
// int newY = Invert(y, height, inverted);
// pixels.CopyFrom(row, newY);
// }
//}
}
/// <summary>

3
src/ImageSharp/Formats/Bmp/BmpEncoder.cs

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Bmp
@ -23,7 +24,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : struct, IPixel<TPixel>
{
var encoder = new BmpEncoderCore(this);
var encoder = new BmpEncoderCore(this, image.GetMemoryManager());
encoder.Encode(image, stream);
}
}

27
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -8,6 +8,8 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Bmp
{
using SixLabors.ImageSharp.Memory;
/// <summary>
/// Image encoder for writing an image to a stream as a Windows bitmap.
/// </summary>
@ -21,14 +23,18 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <summary>
/// Gets or sets the number of bits per pixel.
/// </summary>
private BmpBitsPerPixel bitsPerPixel;
private readonly BmpBitsPerPixel bitsPerPixel;
private readonly MemoryManager memoryManager;
/// <summary>
/// Initializes a new instance of the <see cref="BmpEncoderCore"/> class.
/// </summary>
/// <param name="options">The encoder options</param>
public BmpEncoderCore(IBmpEncoderOptions options)
/// <param name="memoryManager">The memory manager</param>
public BmpEncoderCore(IBmpEncoderOptions options, MemoryManager memoryManager)
{
this.memoryManager = memoryManager;
this.bitsPerPixel = options.BitsPerPixel;
}
@ -173,14 +179,25 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private void Write24Bit<TPixel>(EndianBinaryWriter writer, PixelAccessor<TPixel> pixels)
where TPixel : struct, IPixel<TPixel>
{
using (PixelArea<TPixel> row = new PixelArea<TPixel>(pixels.Width, ComponentOrder.Zyx, this.padding))
using (IManagedByteBuffer row =
this.memoryManager.AllocatePaddedPixelRowBuffer(pixels.Width, 3, this.padding))
{
for (int y = pixels.Height - 1; y >= 0; y--)
{
pixels.CopyTo(row, y);
writer.Write(row.Bytes, 0, row.Length);
Span<TPixel> pixelSpan = pixels.GetRowSpan(y);
PixelOperations<TPixel>.Instance.ToBgr24Bytes(pixelSpan, row.Span, pixelSpan.Length);
writer.Write(row.Array, 0, row.Length());
}
}
//using (PixelArea<TPixel> row = new PixelArea<TPixel>(pixels.Width, ComponentOrder.Zyx, this.padding))
//{
// for (int y = pixels.Height - 1; y >= 0; y--)
// {
// pixels.CopyTo(row, y);
// writer.Write(row.Bytes, 0, row.Length);
// }
//}
}
}
}

12
src/ImageSharp/Memory/BufferExtensions.cs

@ -6,6 +6,8 @@ using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Memory
{
using System.IO;
internal static class BufferExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -53,5 +55,15 @@ namespace SixLabors.ImageSharp.Memory
public static ref T DangerousGetPinnableReference<T>(this IBuffer<T> buffer)
where T : struct =>
ref buffer.Span.DangerousGetPinnableReference();
public static void Read(this Stream stream, IManagedByteBuffer buffer)
{
stream.Read(buffer.Array, 0, buffer.Length());
}
public static void Write(this Stream stream, IManagedByteBuffer buffer)
{
stream.Write(buffer.Array, 0, buffer.Length());
}
}
}

18
src/ImageSharp/Memory/MemoryManagerExtensions.cs

@ -51,5 +51,23 @@
public static Buffer2D<T> AllocateClean2D<T>(this MemoryManager memoryManager, int width, int height)
where T : struct =>
Allocate2D<T>(memoryManager, width, height, true);
/// <summary>
/// Allocates padded buffers for BMP encoder/decoder. (Replacing old PixelRow/PixelArea)
/// </summary>
/// <param name="memoryManager">The <see cref="MemoryManager"/></param>
/// <param name="width">Pixel count in the row</param>
/// <param name="pixelSizeInBytes">The pixel size in bytes, eg. 3 for RGB</param>
/// <param name="paddingInBytes">The padding</param>
/// <returns>A <see cref="IManagedByteBuffer"/></returns>
public static IManagedByteBuffer AllocatePaddedPixelRowBuffer(
this MemoryManager memoryManager,
int width,
int pixelSizeInBytes,
int paddingInBytes)
{
int length = (width * pixelSizeInBytes) + paddingInBytes;
return memoryManager.AllocateManagedByteBuffer(length);
}
}
}

2
tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Tests
public class BmpEncoderTests : FileTestBase
{
private const PixelTypes PixelTypesToTest = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Rgb24;
public static readonly TheoryData<BmpBitsPerPixel> BitsPerPixel =
new TheoryData<BmpBitsPerPixel>
{

Loading…
Cancel
Save