From a10be094f0f257988d747d49f075735371d01754 Mon Sep 17 00:00:00 2001 From: Dmitry Pentin Date: Wed, 23 Mar 2022 16:03:09 +0300 Subject: [PATCH] Resizing converter no longer depends on avx converter only --- .../Decoder/ColorConverters/JpegColorConverterAvx.cs | 5 ++++- .../ColorConverters/JpegColorConverterBase.cs | 9 +++++++++ .../ColorConverters/JpegColorConverterScalar.cs | 4 +++- .../ColorConverters/JpegColorConverterVector.cs | 6 ++++-- .../ResizingSpectralConverter{TPixel}.cs | 12 ++++++------ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs index 81c7c0764d..57002e51a8 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterAvx.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. #if SUPPORTS_RUNTIME_INTRINSICS +using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters @@ -25,7 +26,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters { } - public override bool IsAvailable => Avx.IsSupported; + public sealed override bool IsAvailable => Avx.IsSupported; + + public sealed override int ElementsPerBatch => Vector256.Count; } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs index d2fb89caf6..5134dda4e0 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs @@ -35,6 +35,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// public abstract bool IsAvailable { get; } + /// + /// Gets a value indicating how many pixels are processed in a single batch. + /// + /// + /// This generaly should be equal to register size, + /// e.g. 1 for scalar implementation, 8 for AVX implementation and so on. + /// + public abstract int ElementsPerBatch { get; } + /// /// Gets the of this converter. /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterScalar.cs index ff88ab969f..0aefd304bf 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterScalar.cs @@ -16,7 +16,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters { } - public override bool IsAvailable => true; + public sealed override bool IsAvailable => true; + + public sealed override int ElementsPerBatch => 1; } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterVector.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterVector.cs index ca482d78df..2fc76b1694 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterVector.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterVector.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters /// Even though real life data is guaranteed to be of size /// divisible by 8 newer SIMD instructions like AVX512 won't work with /// such data out of the box. These converters have fallback code - /// for 'remainder' data. + /// for remainder data. /// internal abstract class JpegColorConverterVector : JpegColorConverterBase { @@ -28,7 +28,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters public sealed override bool IsAvailable => Vector.IsHardwareAccelerated && Vector.Count % 4 == 0; - public override void ConvertToRgbInplace(in ComponentValues values) + public sealed override int ElementsPerBatch => Vector.Count; + + public sealed override void ConvertToRgbInplace(in ComponentValues values) { DebugGuard.IsTrue(this.IsAvailable, $"{this.GetType().Name} converter is not supported on current hardware."); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConversion/ResizingSpectralConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConversion/ResizingSpectralConverter{TPixel}.cs index ed191bc063..65cc6ea244 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConversion/ResizingSpectralConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConversion/ResizingSpectralConverter{TPixel}.cs @@ -91,10 +91,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder int blockPixelSize = 8 / scaleDenominator; this.pixelRowsPerStep = majorVerticalSamplingFactor * blockPixelSize; - // BUFFER SIZE MUST BE DIVISIBLE BY 8 ATM - // TODO: fix this mess + // color converter + JpegColorConverterBase converter = this.GetColorConverter(frame, jpegData); + this.colorConverter = converter; + int bufferWidth = majorBlockWidth * blockPixelSize; - int correctedBufferWidth = bufferWidth + (8 - (bufferWidth % 8)); + int batchSize = converter.ElementsPerBatch; + int correctedBufferWidth = bufferWidth + (batchSize - (bufferWidth % batchSize)); var postProcessorBufferSize = new Size(correctedBufferWidth, this.pixelRowsPerStep); this.componentProcessors = new JpegComponentPostProcessor8[frame.Components.Length]; @@ -102,9 +105,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { this.componentProcessors[i] = new JpegComponentPostProcessor8(allocator, frame, jpegData, postProcessorBufferSize, frame.Components[i]); } - - // color converter - this.colorConverter = this.GetColorConverter(frame, jpegData); } public override void ConvertStrideBaseline()