Browse Source

Use PixelOperations for buffer copying.

pull/2266/head
James Jackson-South 4 years ago
parent
commit
8664ff9e6c
  1. 19
      src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs
  2. 16
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegCompressionUtils.cs
  3. 9
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs
  4. 4
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/OldJpegTiffCompression.cs

19
src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs

@ -21,11 +21,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
/// <summary>
/// <see cref="Configuration"/> instance associated with current
/// decoding routine.
/// </summary>
private readonly Configuration configuration;
private JpegFrame frame; private JpegFrame frame;
@ -81,11 +76,15 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
/// <param name="targetSize">Optional target size for decoded image.</param> /// <param name="targetSize">Optional target size for decoded image.</param>
public SpectralConverter(Configuration configuration, Size? targetSize = null) public SpectralConverter(Configuration configuration, Size? targetSize = null)
{ {
this.configuration = configuration; this.Configuration = configuration;
this.targetSize = targetSize; this.targetSize = targetSize;
} }
/// <summary>
/// Gets the configuration instance associated with current decoding routine.
/// </summary>
public Configuration Configuration { get; }
/// <summary> /// <summary>
/// Gets converted pixel buffer. /// Gets converted pixel buffer.
/// </summary> /// </summary>
@ -177,7 +176,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
{ {
DebugGuard.IsTrue(this.colorConverter == null, "SpectralConverter.PrepareForDecoding() must be called once."); DebugGuard.IsTrue(this.colorConverter == null, "SpectralConverter.PrepareForDecoding() must be called once.");
MemoryAllocator allocator = this.configuration.MemoryAllocator; MemoryAllocator allocator = this.Configuration.MemoryAllocator;
// color converter from RGB to TPixel // color converter from RGB to TPixel
JpegColorConverterBase converter = this.GetColorConverter(this.frame, this.jpegData); JpegColorConverterBase converter = this.GetColorConverter(this.frame, this.jpegData);
@ -196,7 +195,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
this.pixelBuffer = allocator.Allocate2D<TPixel>( this.pixelBuffer = allocator.Allocate2D<TPixel>(
pixelSize.Width, pixelSize.Width,
pixelSize.Height, pixelSize.Height,
this.configuration.PreferContiguousImageBuffers); this.Configuration.PreferContiguousImageBuffers);
this.paddedProxyPixelRow = allocator.Allocate<TPixel>(pixelSize.Width + 3); this.paddedProxyPixelRow = allocator.Allocate<TPixel>(pixelSize.Width + 3);
// component processors from spectral to RGB // component processors from spectral to RGB
@ -225,7 +224,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
protected ComponentProcessor[] CreateComponentProcessors(JpegFrame frame, IRawJpegData jpegData, int blockPixelSize, Size processorBufferSize) protected ComponentProcessor[] CreateComponentProcessors(JpegFrame frame, IRawJpegData jpegData, int blockPixelSize, Size processorBufferSize)
{ {
MemoryAllocator allocator = this.configuration.MemoryAllocator; MemoryAllocator allocator = this.Configuration.MemoryAllocator;
var componentProcessors = new ComponentProcessor[frame.Components.Length]; var componentProcessors = new ComponentProcessor[frame.Components.Length];
for (int i = 0; i < componentProcessors.Length; i++) for (int i = 0; i < componentProcessors.Length; i++)
{ {

16
src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegCompressionUtils.cs

@ -1,7 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Runtime.InteropServices; using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -9,27 +9,25 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
internal static class JpegCompressionUtils internal static class JpegCompressionUtils
{ {
public static void CopyImageBytesToBuffer(Span<byte> buffer, Buffer2D<Rgb24> pixelBuffer) public static void CopyImageBytesToBuffer(Configuration configuration, Span<byte> buffer, Buffer2D<Rgb24> pixelBuffer)
{ {
int offset = 0; int offset = 0;
for (int y = 0; y < pixelBuffer.Height; y++) for (int y = 0; y < pixelBuffer.Height; y++)
{ {
Span<Rgb24> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); Span<Rgb24> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y);
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); PixelOperations<Rgb24>.Instance.ToRgb24Bytes(configuration, pixelRowSpan, buffer[offset..], pixelRowSpan.Length);
rgbBytes.CopyTo(buffer[offset..]); offset += Unsafe.SizeOf<Rgb24>() * pixelRowSpan.Length;
offset += rgbBytes.Length;
} }
} }
public static void CopyImageBytesToBuffer(Span<byte> buffer, Buffer2D<L8> pixelBuffer) public static void CopyImageBytesToBuffer(Configuration configuration, Span<byte> buffer, Buffer2D<L8> pixelBuffer)
{ {
int offset = 0; int offset = 0;
for (int y = 0; y < pixelBuffer.Height; y++) for (int y = 0; y < pixelBuffer.Height; y++)
{ {
Span<L8> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); Span<L8> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y);
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); PixelOperations<L8>.Instance.ToL8Bytes(configuration, pixelRowSpan, buffer[offset..], pixelRowSpan.Length);
rgbBytes.CopyTo(buffer[offset..]); offset += Unsafe.SizeOf<L8>() * pixelRowSpan.Length;
offset += rgbBytes.Length;
} }
} }
} }

9
src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Formats.Tiff.Constants;
@ -73,8 +74,8 @@ internal sealed class JpegTiffCompression : TiffBaseDecompressor
} }
else else
{ {
using Image<Rgb24> image = Image.Load<Rgb24>(stream); using Image<Rgb24> image = Image.Load<Rgb24>(this.options.GeneralOptions, stream);
JpegCompressionUtils.CopyImageBytesToBuffer(buffer, image.Frames.RootFrame.PixelBuffer); JpegCompressionUtils.CopyImageBytesToBuffer(this.options.GeneralOptions.Configuration, buffer, image.Frames.RootFrame.PixelBuffer);
} }
} }
@ -94,7 +95,7 @@ internal sealed class JpegTiffCompression : TiffBaseDecompressor
jpegDecoder.ParseStream(stream, spectralConverterGray, cancellationToken); jpegDecoder.ParseStream(stream, spectralConverterGray, cancellationToken);
using Buffer2D<L8> decompressedBuffer = spectralConverterGray.GetPixelBuffer(cancellationToken); using Buffer2D<L8> decompressedBuffer = spectralConverterGray.GetPixelBuffer(cancellationToken);
JpegCompressionUtils.CopyImageBytesToBuffer(buffer, decompressedBuffer); JpegCompressionUtils.CopyImageBytesToBuffer(spectralConverterGray.Configuration, buffer, decompressedBuffer);
break; break;
} }
@ -108,7 +109,7 @@ internal sealed class JpegTiffCompression : TiffBaseDecompressor
jpegDecoder.ParseStream(stream, spectralConverter, cancellationToken); jpegDecoder.ParseStream(stream, spectralConverter, cancellationToken);
using Buffer2D<Rgb24> decompressedBuffer = spectralConverter.GetPixelBuffer(cancellationToken); using Buffer2D<Rgb24> decompressedBuffer = spectralConverter.GetPixelBuffer(cancellationToken);
JpegCompressionUtils.CopyImageBytesToBuffer(buffer, decompressedBuffer); JpegCompressionUtils.CopyImageBytesToBuffer(spectralConverter.Configuration, buffer, decompressedBuffer);
break; break;
} }

4
src/ImageSharp/Formats/Tiff/Compression/Decompressors/OldJpegTiffCompression.cs

@ -58,7 +58,7 @@ internal sealed class OldJpegTiffCompression : TiffBaseDecompressor
jpegDecoder.ParseStream(stream, spectralConverterGray, cancellationToken); jpegDecoder.ParseStream(stream, spectralConverterGray, cancellationToken);
using Buffer2D<L8> decompressedBuffer = spectralConverterGray.GetPixelBuffer(cancellationToken); using Buffer2D<L8> decompressedBuffer = spectralConverterGray.GetPixelBuffer(cancellationToken);
JpegCompressionUtils.CopyImageBytesToBuffer(buffer, decompressedBuffer); JpegCompressionUtils.CopyImageBytesToBuffer(spectralConverterGray.Configuration, buffer, decompressedBuffer);
break; break;
} }
@ -70,7 +70,7 @@ internal sealed class OldJpegTiffCompression : TiffBaseDecompressor
jpegDecoder.ParseStream(stream, spectralConverter, cancellationToken); jpegDecoder.ParseStream(stream, spectralConverter, cancellationToken);
using Buffer2D<Rgb24> decompressedBuffer = spectralConverter.GetPixelBuffer(cancellationToken); using Buffer2D<Rgb24> decompressedBuffer = spectralConverter.GetPixelBuffer(cancellationToken);
JpegCompressionUtils.CopyImageBytesToBuffer(buffer, decompressedBuffer); JpegCompressionUtils.CopyImageBytesToBuffer(spectralConverter.Configuration, buffer, decompressedBuffer);
break; break;
} }

Loading…
Cancel
Save