diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs deleted file mode 100644 index 26a063524..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers; -using System.Numerics; -using System.Threading; -using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.PixelFormats; -using JpegColorConverter = SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters.JpegColorConverter; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder -{ - /// - /// Encapsulates the execution od post-processing algorithms to be applied on a to produce a valid :
- /// (1) Dequantization
- /// (2) IDCT
- /// (3) Color conversion form one of the -s into a buffer of RGBA values
- /// (4) Packing pixels from the buffer.
- /// These operations are executed in steps. - /// image rows are converted in one step, - /// which means that size of the allocated memory is limited (does not depend on ). - ///
- internal class JpegImagePostProcessor : IDisposable - { - private readonly Configuration configuration; - - /// - /// The number of block rows to be processed in one Step. - /// - private readonly int blockRowsPerStep; - - /// - /// The number of image pixel rows to be processed in one step. - /// - private readonly int pixelRowsPerStep; - - /// - /// Temporal buffer to store a row of colors. - /// - private readonly IMemoryOwner rgbaBuffer; - - /// - /// The corresponding to the current determined by . - /// - private readonly JpegColorConverter colorConverter; - - /// - /// Initializes a new instance of the class. - /// - /// The to configure internal operations. - /// The representing the uncompressed spectral Jpeg data - public JpegImagePostProcessor(Configuration configuration, IRawJpegData rawJpeg) - { - this.configuration = configuration; - this.RawJpeg = rawJpeg; - IJpegComponent c0 = rawJpeg.Components[0]; - - this.blockRowsPerStep = c0.SamplingFactors.Height; - this.pixelRowsPerStep = this.blockRowsPerStep * 8; - - this.NumberOfPostProcessorSteps = c0.SizeInBlocks.Height / this.blockRowsPerStep; - - var postProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, this.pixelRowsPerStep); - MemoryAllocator memoryAllocator = configuration.MemoryAllocator; - this.ComponentProcessors = new JpegComponentPostProcessor[rawJpeg.Components.Length]; - for (int i = 0; i < rawJpeg.Components.Length; i++) - { - this.ComponentProcessors[i] = new JpegComponentPostProcessor(memoryAllocator, this.RawJpeg, postProcessorBufferSize, rawJpeg.Components[i]); - } - - this.rgbaBuffer = memoryAllocator.Allocate(rawJpeg.ImageSizeInPixels.Width); - this.colorConverter = JpegColorConverter.GetConverter(rawJpeg.ColorSpace, rawJpeg.Precision); - } - - /// - /// Gets the instances. - /// - public JpegComponentPostProcessor[] ComponentProcessors { get; } - - /// - /// Gets the to be processed. - /// - public IRawJpegData RawJpeg { get; } - - /// - /// Gets the total number of post processor steps deduced from the height of the image and . - /// - public int NumberOfPostProcessorSteps { get; } - - /// - /// Gets the value of the counter that grows by each step by . - /// - public int PixelRowCounter { get; private set; } - - /// - public void Dispose() - { - foreach (JpegComponentPostProcessor cpp in this.ComponentProcessors) - { - cpp.Dispose(); - } - - this.rgbaBuffer.Dispose(); - } - - /// - /// Process all pixels into 'destination'. The image dimensions should match . - /// - /// The pixel type - /// The destination image - /// The token to request cancellation. - public void PostProcess(ImageFrame destination, CancellationToken cancellationToken) - where TPixel : unmanaged, IPixel - { - this.PixelRowCounter = 0; - - if (this.RawJpeg.ImageSizeInPixels != destination.Size()) - { - throw new ArgumentException("Input image is not of the size of the processed one!"); - } - - while (this.PixelRowCounter < this.RawJpeg.ImageSizeInPixels.Height) - { - cancellationToken.ThrowIfCancellationRequested(); - this.DoPostProcessorStep(destination); - } - } - - /// - /// Execute one step processing pixel rows into 'destination'. - /// Convert and copy row of colors into 'destination' starting at row . - /// - /// The pixel type - /// The destination image - public void DoPostProcessorStep(ImageFrame destination) - where TPixel : unmanaged, IPixel - { - int maxY = Math.Min(destination.Height, this.PixelRowCounter + this.pixelRowsPerStep); - - var buffers = new Buffer2D[this.ComponentProcessors.Length]; - for (int i = 0; i < this.ComponentProcessors.Length; i++) - { - this.ComponentProcessors[i].CopyBlocksToColorBuffer(); - buffers[i] = this.ComponentProcessors[i].ColorBuffer; - } - - for (int yy = this.PixelRowCounter; yy < maxY; yy++) - { - int y = yy - this.PixelRowCounter; - - var values = new JpegColorConverter.ComponentValues(buffers, y); - this.colorConverter.ConvertToRgba(values, this.rgbaBuffer.GetSpan()); - - Span destRow = destination.GetPixelRowSpan(yy); - - // TODO: Investigate if slicing is actually necessary - PixelOperations.Instance.FromVector4Destructive(this.configuration, this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); - } - - this.PixelRowCounter += this.pixelRowsPerStep; - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index c7a5bc42c..c4f8a1281 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -1112,32 +1112,5 @@ namespace SixLabors.ImageSharp.Formats.Jpeg stream.Read(this.markerBuffer, 0, 2); return BinaryPrimitives.ReadUInt16BigEndian(this.markerBuffer); } - - /// - /// Post processes the pixels into the destination image. - /// - /// The pixel format. - /// The . - private Image PostProcessIntoImage(CancellationToken cancellationToken) - where TPixel : unmanaged, IPixel - { - if (this.ImageWidth == 0 || this.ImageHeight == 0) - { - JpegThrowHelper.ThrowInvalidImageDimensions(this.ImageWidth, this.ImageHeight); - } - - var image = Image.CreateUninitialized( - this.Configuration, - this.ImageWidth, - this.ImageHeight, - this.Metadata); - - using (var postProcessor = new JpegImagePostProcessor(this.Configuration, this)) - { - postProcessor.PostProcess(image.Frames.RootFrame, cancellationToken); - } - - return image; - } } }