diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs index bbdd3220f..b3cdbf0a0 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs @@ -139,12 +139,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder public void Encode444(Image pixels, ref Block8x8F luminanceQuantTable, ref Block8x8F chrominanceQuantTable, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - // Calculate reciprocal quantization tables for FDCT method - for (int i = 0; i < Block8x8F.Size; i++) - { - luminanceQuantTable[i] = FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i] / luminanceQuantTable[i]; - chrominanceQuantTable[i] = FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i] / chrominanceQuantTable[i]; - } + FastFloatingPointDCT.AdjustToFDCT(ref luminanceQuantTable); + FastFloatingPointDCT.AdjustToFDCT(ref chrominanceQuantTable); this.huffmanTables = HuffmanLut.TheHuffmanLut; @@ -206,12 +202,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder public void Encode420(Image pixels, ref Block8x8F luminanceQuantTable, ref Block8x8F chrominanceQuantTable, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - // Calculate reciprocal quantization tables for FDCT method - for (int i = 0; i < Block8x8F.Size; i++) - { - luminanceQuantTable[i] = FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i] / luminanceQuantTable[i]; - chrominanceQuantTable[i] = FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i] / chrominanceQuantTable[i]; - } + FastFloatingPointDCT.AdjustToFDCT(ref luminanceQuantTable); + FastFloatingPointDCT.AdjustToFDCT(ref chrominanceQuantTable); this.huffmanTables = HuffmanLut.TheHuffmanLut; @@ -279,11 +271,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder public void EncodeGrayscale(Image pixels, ref Block8x8F luminanceQuantTable, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - // Calculate reciprocal quantization tables for FDCT method - for (int i = 0; i < Block8x8F.Size; i++) - { - luminanceQuantTable[i] = FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i] / luminanceQuantTable[i]; - } + FastFloatingPointDCT.AdjustToFDCT(ref luminanceQuantTable); this.huffmanTables = HuffmanLut.TheHuffmanLut; @@ -325,16 +313,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// /// The pixel format. /// The pixel accessor providing access to the image pixels. - /// Luminance quantization table provided by the callee. + /// Quantization table provided by the callee. /// The token to monitor for cancellation. - public void EncodeRgb(Image pixels, ref Block8x8F luminanceQuantTable, CancellationToken cancellationToken) + public void EncodeRgb(Image pixels, ref Block8x8F quantTable, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - // Calculate reciprocal quantization tables for FDCT method - for (int i = 0; i < Block8x8F.Size; i++) - { - luminanceQuantTable[i] = FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i] / luminanceQuantTable[i]; - } + FastFloatingPointDCT.AdjustToFDCT(ref quantTable); this.huffmanTables = HuffmanLut.TheHuffmanLut; @@ -360,19 +344,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder QuantIndex.Luminance, prevDCR, ref pixelConverter.R, - ref luminanceQuantTable); + ref quantTable); prevDCG = this.WriteBlock( QuantIndex.Luminance, prevDCG, ref pixelConverter.G, - ref luminanceQuantTable); + ref quantTable); prevDCB = this.WriteBlock( QuantIndex.Luminance, prevDCB, ref pixelConverter.B, - ref luminanceQuantTable); + ref quantTable); if (this.IsStreamFlushNeeded) { diff --git a/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs b/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs index 43f6b7a1f..dc88255c5 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs @@ -62,10 +62,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 /// - /// Values are also scaled by 8 so DCT code won't do unnecessary division. + /// Values are also scaled by 8 so DCT code won't do extra division/multiplication. /// /// - public static readonly float[] DctReciprocalAdjustmentCoefficients = new float[] + private static readonly float[] DctReciprocalAdjustmentCoefficients = new float[] { 0.125f, 0.09011998f, 0.09567086f, 0.10630376f, 0.125f, 0.15909483f, 0.23096988f, 0.45306373f, 0.09011998f, 0.064972885f, 0.068974845f, 0.07664074f, 0.09011998f, 0.11470097f, 0.16652f, 0.32664075f, @@ -77,6 +77,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 0.45306373f, 0.32664075f, 0.34675997f, 0.38529903f, 0.45306373f, 0.5766407f, 0.8371526f, 1.642134f, }; + /// + /// Adjusts given quantization table to be complient with FDCT implementation. + /// + /// + /// See docs for explanation. + /// + /// Quantization table to adjust. + public static void AdjustToFDCT(ref Block8x8F quantizationtable) + { + for (int i = 0; i < Block8x8F.Size; i++) + { + quantizationtable[i] = DctReciprocalAdjustmentCoefficients[i] / quantizationtable[i]; + } + } + /// /// Apply 2D floating point FDCT inplace. ///