From 66b5a8df67437cb66dad2756e2a598df2aad1385 Mon Sep 17 00:00:00 2001 From: Dmitry Pentin Date: Fri, 21 May 2021 08:07:47 +0300 Subject: [PATCH] [WIP] Moved SOS writing logic to separate class --- .../Encoder/YCbCrEncoder{TPixel}.cs | 29 ++++++++++-- .../Formats/Jpeg/JpegEncoderCore.cs | 44 ++++++++++--------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrEncoder{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrEncoder{TPixel}.cs index 6c81832440..a8411e218b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrEncoder{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrEncoder{TPixel}.cs @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// The pixel accessor providing access to the image pixels. /// The token to monitor for cancellation. /// The reference to the emit buffer. - public void Encode444(Image pixels, CancellationToken cancellationToken) + private void Encode444(Image pixels, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { // TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.) @@ -209,7 +209,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// The pixel accessor providing access to the image pixels. /// The token to monitor for cancellation. /// The reference to the emit buffer. - public void Encode420(Image pixels, CancellationToken cancellationToken) + private void Encode420(Image pixels, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { // TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.) @@ -290,7 +290,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// The pixel accessor providing access to the image pixels. /// The token to monitor for cancellation. /// The reference to the emit buffer. - public void EncodeGrayscale(Image pixels, CancellationToken cancellationToken) + private void EncodeGrayscale(Image pixels, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { // TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.) @@ -331,6 +331,29 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder } } + public void WriteStartOfScan(Image image, JpegColorType? colorType, JpegSubsample? subsample, CancellationToken cancellationToken) + where TPixel : unmanaged, IPixel + { + if (colorType == JpegColorType.Luminance) + { + this.EncodeGrayscale(image, cancellationToken); + } + else + { + switch (subsample) + { + case JpegSubsample.Ratio444: + this.Encode444(image, cancellationToken); + break; + case JpegSubsample.Ratio420: + this.Encode420(image, cancellationToken); + break; + } + } + + // Pad the last byte with 1's. + this.Emit(0x7f, 7); + } /// /// Writes a block of pixel data using the given quantization table, diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs index 14cb87af3b..f1dd7f6bf1 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs @@ -203,7 +203,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg this.WriteDefineHuffmanTables(componentCount); // Write the image data. - this.WriteStartOfScan(image, componentCount, cancellationToken); + this.WriteStartOfScan(scanEncoder, image, componentCount, cancellationToken); // Write the End Of Image marker. this.buffer[0] = JpegConstants.Markers.XFF; @@ -969,7 +969,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// The pixel accessor providing access to the image pixels. /// The number of components in a pixel. /// The token to monitor for cancellation. - private void WriteStartOfScan(Image image, int componentCount, CancellationToken cancellationToken) + private void WriteStartOfScan(YCbCrEncoder scanEncoder, Image image, int componentCount, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { // TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.) @@ -1015,26 +1015,28 @@ namespace SixLabors.ImageSharp.Formats.Jpeg this.buffer[sosSize + 1] = 0x00; // Ah + Ah (Successive approximation bit position high + low) this.outputStream.Write(this.buffer, 0, sosSize + 2); - ref byte emitBufferBase = ref MemoryMarshal.GetReference(this.emitBuffer); - if (this.colorType == JpegColorType.Luminance) - { - this.EncodeGrayscale(image, cancellationToken, ref emitBufferBase); - } - else - { - switch (this.subsample) - { - case JpegSubsample.Ratio444: - this.Encode444(image, cancellationToken, ref emitBufferBase); - break; - case JpegSubsample.Ratio420: - this.Encode420(image, cancellationToken, ref emitBufferBase); - break; - } - } - // Pad the last byte with 1's. - this.Emit(0x7f, 7, ref emitBufferBase); + scanEncoder.WriteStartOfScan(image, this.colorType, this.subsample, cancellationToken); + //ref byte emitBufferBase = ref MemoryMarshal.GetReference(this.emitBuffer); + //if (this.colorType == JpegColorType.Luminance) + //{ + // scanEncoder.EncodeGrayscale(image, cancellationToken); + //} + //else + //{ + // switch (this.subsample) + // { + // case JpegSubsample.Ratio444: + // scanEncoder.Encode444(image, cancellationToken); + // break; + // case JpegSubsample.Ratio420: + // scanEncoder.Encode420(image, cancellationToken); + // break; + // } + //} + + //// Pad the last byte with 1's. + //this.Emit(0x7f, 7, ref emitBufferBase); } ///