From 88de0a61f13e6b85ca491a58d56012a43fba2f7a Mon Sep 17 00:00:00 2001 From: LuisAlfredo92 <92luisalfredo@protonmail.com> Date: Thu, 29 Jun 2023 20:06:38 -0600 Subject: [PATCH] Fixing encoder optimizations --- src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs | 7 +++++-- src/ImageSharp/Formats/Qoi/QoiEncoder.cs | 3 ++- src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs | 18 +++++++++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs b/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs index a9212874d9..a3f8171b3d 100644 --- a/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs +++ b/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs @@ -72,12 +72,15 @@ internal class QoiDecoderCore : IImageDecoderInternals /// 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); } diff --git a/src/ImageSharp/Formats/Qoi/QoiEncoder.cs b/src/ImageSharp/Formats/Qoi/QoiEncoder.cs index 50d9cb30f7..137cd8d706 100644 --- a/src/ImageSharp/Formats/Qoi/QoiEncoder.cs +++ b/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 /// protected override void Encode(Image image, Stream stream, CancellationToken cancellationToken) { - QoiEncoderCore encoder = new(this); + QoiEncoderCore encoder = new(this, image.GetMemoryAllocator()); encoder.Encode(image, stream, cancellationToken); } } diff --git a/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs b/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs index d1fe87ed08..dd0aab1f7c 100644 --- a/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs +++ b/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; + /// /// Initializes a new instance of the class. /// - public QoiEncoderCore(QoiEncoder encoder) => this.encoder = encoder; + public QoiEncoderCore(QoiEncoder encoder, MemoryAllocator memoryAllocator) + { + this.encoder = encoder; + this.memoryAllocator = memoryAllocator; + } /// public void Encode(Image 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(Image image, Stream stream) + private void WritePixels(Image image, Stream stream) where TPixel : unmanaged, IPixel { // Start image encoding - Rgba32[] previouslySeenPixels = new Rgba32[64]; + using IMemoryOwner previouslySeenPixelsBuffer = this.memoryAllocator.Allocate(64); + Span previouslySeenPixels = previouslySeenPixelsBuffer.GetSpan(); Rgba32 previousPixel = new(0, 0, 0, 255); Rgba32 currentRgba32 = default; Buffer2D pixels = image.Frames[0].PixelBuffer; for (int i = 0; i < pixels.Height; i++) { + Span row = pixels.DangerousGetRowSpan(i); for (int j = 0; j < pixels.Width && i < pixels.Height; j++) { // We get the RGBA value from pixels - Span row = pixels.DangerousGetRowSpan(i); TPixel currentPixel = pixels[j, i]; currentPixel.ToRgba32(ref currentRgba32);