Browse Source

Fixing encoder optimizations

qoi
LuisAlfredo92 3 years ago
parent
commit
88de0a61f1
No known key found for this signature in database GPG Key ID: 13A8436905993B8F
  1. 7
      src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs
  2. 3
      src/ImageSharp/Formats/Qoi/QoiEncoder.cs
  3. 18
      src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs

7
src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs

@ -72,12 +72,15 @@ internal class QoiDecoderCore : IImageDecoderInternals
/// <inheritdoc />
public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{
ImageMetadata metadata = new();
this.ProcessHeader(stream);
PixelTypeInfo pixelType = new(8 * (int)this.header.Channels);
Size size = new((int)this.header.Width, (int)this.header.Height);
ImageMetadata metadata = new();
QoiMetadata qoiMetadata = metadata.GetQoiMetadata();
qoiMetadata.Channels = this.header.Channels;
qoiMetadata.ColorSpace = this.header.ColorSpace;
return new ImageInfo(pixelType, size, metadata);
}

3
src/ImageSharp/Formats/Qoi/QoiEncoder.cs

@ -2,6 +2,7 @@
// Licensed under the Six Labors Split License.
using System.Text;
using SixLabors.ImageSharp.Advanced;
namespace SixLabors.ImageSharp.Formats.Qoi;
@ -27,7 +28,7 @@ public class QoiEncoder : ImageEncoder
/// <inheritdoc />
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
QoiEncoderCore encoder = new(this);
QoiEncoderCore encoder = new(this, image.GetMemoryAllocator());
encoder.Encode(image, stream, cancellationToken);
}
}

18
src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;
@ -14,10 +15,16 @@ namespace SixLabors.ImageSharp.Formats.Qoi;
public class QoiEncoderCore : IImageEncoderInternals
{
private readonly QoiEncoder encoder;
private readonly MemoryAllocator memoryAllocator;
/// <summary>
/// Initializes a new instance of the <see cref="QoiEncoderCore"/> class.
/// </summary>
public QoiEncoderCore(QoiEncoder encoder) => this.encoder = encoder;
public QoiEncoderCore(QoiEncoder encoder, MemoryAllocator memoryAllocator)
{
this.encoder = encoder;
this.memoryAllocator = memoryAllocator;
}
/// <inheritdoc />
public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
@ -27,7 +34,7 @@ public class QoiEncoderCore : IImageEncoderInternals
Guard.NotNull(stream, nameof(stream));
this.WriteHeader(image, stream);
WritePixels(image, stream);
this.WritePixels(image, stream);
WriteEndOfStream(stream);
stream.Flush();
}
@ -50,21 +57,22 @@ public class QoiEncoderCore : IImageEncoderInternals
stream.WriteByte((byte)qoiColorSpace);
}
private static void WritePixels<TPixel>(Image<TPixel> image, Stream stream)
private void WritePixels<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
// Start image encoding
Rgba32[] previouslySeenPixels = new Rgba32[64];
using IMemoryOwner<Rgba32> previouslySeenPixelsBuffer = this.memoryAllocator.Allocate<Rgba32>(64);
Span<Rgba32> previouslySeenPixels = previouslySeenPixelsBuffer.GetSpan();
Rgba32 previousPixel = new(0, 0, 0, 255);
Rgba32 currentRgba32 = default;
Buffer2D<TPixel> pixels = image.Frames[0].PixelBuffer;
for (int i = 0; i < pixels.Height; i++)
{
Span<TPixel> row = pixels.DangerousGetRowSpan(i);
for (int j = 0; j < pixels.Width && i < pixels.Height; j++)
{
// We get the RGBA value from pixels
Span<TPixel> row = pixels.DangerousGetRowSpan(i);
TPixel currentPixel = pixels[j, i];
currentPixel.ToRgba32(ref currentRgba32);

Loading…
Cancel
Save