From 5b589c001f54c471f0d48181b8bf407475a970d7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 30 Aug 2017 12:55:17 +0200 Subject: [PATCH] XmlDocs for JpegImagePostProcessor --- .../Formats/Jpeg/Common/Block8x8F.cs | 2 +- .../Jpeg/Common/Decoder/IJpegComponent.cs | 4 +- .../Common/Decoder/JpegImagePostProcessor.cs | 99 ++++++++++++++----- .../Decoder/JpegBlockPostProcessor.cs | 13 +-- 4 files changed, 85 insertions(+), 33 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs index d54246482..1c5cd4318 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs @@ -424,7 +424,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// Qt pointer /// Unzig pointer [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void QuantizeBlock(Block8x8F* blockPtr, Block8x8F* qtPtr, int* unzigPtr) + public static unsafe void DequantizeBlock(Block8x8F* blockPtr, Block8x8F* qtPtr, int* unzigPtr) { float* b = (float*)blockPtr; float* qtp = (float*)qtPtr; diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs index 89c400bb0..4109fc10e 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs @@ -38,8 +38,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder int QuantizationTableIndex { get; } /// - /// Gets the storing the "raw" frequency-domain decoded blocks. - /// We need to apply IDCT, dequantiazition and unzigging to transform them into color-space blocks. + /// Gets the storing the "raw" frequency-domain decoded + unzigged blocks. + /// We need to apply IDCT and dequantiazition to transform them into color-space blocks. /// Buffer2D SpectralBlocks { get; } } diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs index 689dd774e..ae1180a52 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs @@ -1,26 +1,48 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Numerics; -using System.Runtime.CompilerServices; -using SixLabors.ImageSharp.ColorSpaces; -using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.YCbCrColorSapce; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder { + /// + /// Encapsulates the execution 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 { + /// + /// The number of block rows to be processed in one Step. + /// public const int BlockRowsPerStep = 4; + /// + /// The number of image pixel rows to be processed in one step. + /// public const int PixelRowsPerStep = 4 * 8; + /// + /// Temporal buffer to store a row of colors. + /// private readonly Buffer rgbaBuffer; + /// + /// The corresponding to the current determined by . + /// private JpegColorConverter colorConverter; + /// + /// Initializes a new instance of the class. + /// + /// The representing the uncompressed spectral Jpeg data public JpegImagePostProcessor(IRawJpegData rawJpeg) { this.RawJpeg = rawJpeg; @@ -33,16 +55,32 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder this.colorConverter = JpegColorConverter.GetConverter(rawJpeg.ColorSpace); } + /// + /// 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 size of the temporal buffers we need to allocate into . + /// public Size PostProcessorBufferSize { get; } - public int CurrentImageRowInPixels { get; private set; } + /// + /// 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) @@ -53,43 +91,60 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder this.rgbaBuffer.Dispose(); } - public void DoPostProcessorStep(Image destination) + /// + /// Process all pixels into 'destination'. The image dimensions should match . + /// + /// The pixel type + /// The destination image + public void PostProcess(Image destination) where TPixel : struct, IPixel { - foreach (JpegComponentPostProcessor cpp in this.ComponentProcessors) + this.PixelRowCounter = 0; + + if (this.RawJpeg.ImageSizeInPixels != destination.Size()) { - cpp.CopyBlocksToColorBuffer(); + throw new ArgumentException("Input image is not of the size of the processed one!"); } - this.ConvertColors(destination); - - this.CurrentImageRowInPixels += PixelRowsPerStep; + while (this.PixelRowCounter < this.RawJpeg.ImageSizeInPixels.Height) + { + this.DoPostProcessorStep(destination); + } } - public void PostProcess(Image destination) + /// + /// Execute one step rocessing pixel rows into 'destination'. + /// + /// The pixel type + /// The destination image. + public void DoPostProcessorStep(Image destination) where TPixel : struct, IPixel { - if (this.RawJpeg.ImageSizeInPixels != destination.Size()) + foreach (JpegComponentPostProcessor cpp in this.ComponentProcessors) { - throw new ArgumentException("Input image is not of the size of the processed one!"); + cpp.CopyBlocksToColorBuffer(); } - while (this.CurrentImageRowInPixels < this.RawJpeg.ImageSizeInPixels.Height) - { - this.DoPostProcessorStep(destination); - } + this.ConvertColorsInto(destination); + + this.PixelRowCounter += PixelRowsPerStep; } - private void ConvertColors(Image destination) + /// + /// Convert and copy row of colors into 'destination' starting at row . + /// + /// The pixel type + /// The destination image + private void ConvertColorsInto(Image destination) where TPixel : struct, IPixel { - int maxY = Math.Min(destination.Height, this.CurrentImageRowInPixels + PixelRowsPerStep); + int maxY = Math.Min(destination.Height, this.PixelRowCounter + PixelRowsPerStep); Buffer2D[] buffers = this.ComponentProcessors.Select(cp => cp.ColorBuffer).ToArray(); - for (int yy = this.CurrentImageRowInPixels; yy < maxY; yy++) + for (int yy = this.PixelRowCounter; yy < maxY; yy++) { - int y = yy - this.CurrentImageRowInPixels; + int y = yy - this.PixelRowCounter; var values = new JpegColorConverter.ComponentValues(buffers, y); this.colorConverter.ConvertToRGBA(values, this.rgbaBuffer); diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockPostProcessor.cs index 739953099..29149a186 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockPostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockPostProcessor.cs @@ -1,18 +1,15 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Formats.Jpeg.Common; +using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder; using SixLabors.ImageSharp.Memory; -using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F; +using SixLabors.Primitives; namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder { - using System.Runtime.CompilerServices; - - using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder; - using SixLabors.Primitives; - /// /// Encapsulates the implementation of processing "raw" -s into Jpeg image channels. /// @@ -63,7 +60,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder Block8x8F* b = this.pointers.SourceBlock; - Block8x8F.QuantizeBlock(b, this.pointers.QuantiazationTable, this.pointers.Unzig); + Block8x8F.DequantizeBlock(b, this.pointers.QuantiazationTable, this.pointers.Unzig); FastFloatingPointDCT.TransformIDCT(ref *b, ref this.data.WorkspaceBlock1, ref this.data.WorkspaceBlock2); } @@ -77,13 +74,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder this.QuantizeAndTransform(decoder, component, ref sourceBlock); this.data.WorkspaceBlock1.NormalizeColorsInplace(); - Size divs = component.SubSamplingDivisors; // To conform better to libjpeg we actually NEED TO loose precision here. // This is because they store blocks as Int16 between all the operations. // Unfortunately, we need to emulate this to be "more accurate" :( this.data.WorkspaceBlock1.RoundInplace(); + Size divs = component.SubSamplingDivisors; this.data.WorkspaceBlock1.CopyTo(destArea, divs.Width, divs.Height); }