From 769d4de78cf5ecdd54181e0978e40f4cbf5a3082 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 27 Aug 2017 04:18:59 +0200 Subject: [PATCH] CalculateJpegChannelSizes() --- .../Formats/Jpeg/Common/ComponentUtils.cs | 39 ++++++++++++++++--- .../Components/Decoder/OrigJpegPixelArea.cs | 8 +--- .../Jpeg/GolangPort/OrigJpegDecoderCore.cs | 8 ++-- .../Formats/Jpg/ComponentUtilsTests.cs | 38 ++++++++++-------- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs b/src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs index 3b3f302a43..78405a313c 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs @@ -81,18 +81,45 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common public static bool IsChromaComponent(this IJpegComponent component) => component.Index > 0 && component.Index < 3; - public static Size CalculateJpegChannelSize(this IJpegComponent component, SubsampleRatio ratio = SubsampleRatio.Undefined) + public static Size[] CalculateJpegChannelSizes(IEnumerable components, SubsampleRatio ratio) { - Size size = new Size(component.WidthInBlocks, component.HeightInBlocks) * 8; + IJpegComponent[] c = components.ToArray(); + Size[] sizes = new Size[c.Length]; - if (component.IsChromaComponent()) + Size s0 = new Size(c[0].WidthInBlocks, c[0].HeightInBlocks) * 8; + sizes[0] = s0; + + if (c.Length > 1) { - return ratio.CalculateChrominanceSize(size.Width, size.Height); + Size chromaSize = ratio.CalculateChrominanceSize(s0.Width, s0.Height); + sizes[1] = chromaSize; + + if (c.Length > 2) + { + sizes[2] = chromaSize; + } } - else + + if (c.Length > 3) { - return size; + sizes[3] = s0; } + + return sizes; } + + //public static Size CalculateJpegChannelSize(this IJpegComponent component, SubsampleRatio ratio = SubsampleRatio.Undefined) + //{ + // Size size = new Size(component.WidthInBlocks, component.HeightInBlocks) * 8; + + // if (component.IsChromaComponent()) + // { + // return ratio.CalculateChrominanceSize(size.Width, size.Height); + // } + // else + // { + // return size; + // } + //} } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs index b724ecb1ea..91b9b3a101 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder : this(Buffer2D.CreateClean(size)) { } - + /// /// Gets the pixels buffer. /// @@ -83,12 +83,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder } } - public static OrigJpegPixelArea CreateForComponent(IJpegComponent component, SubsampleRatio ratio = SubsampleRatio.Undefined) - { - Size size = component.CalculateJpegChannelSize(ratio); - return new OrigJpegPixelArea(size); - } - /// /// Gets the subarea that belongs to the Block8x8 defined by block indices /// diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs index b8eea6f37c..705a571cd9 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs @@ -782,19 +782,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort /// private void InitJpegImageChannels() { + Size[] sizes = ComponentUtils.CalculateJpegChannelSizes(this.Components, this.SubsampleRatio); + if (this.ComponentCount == 1) { - this.grayImage = OrigJpegPixelArea.CreateForComponent(this.Components[0]); + this.grayImage = new OrigJpegPixelArea(sizes[0]); } else { - Size size = this.Components[0].CalculateJpegChannelSize(); + Size size = sizes[0]; this.ycbcrImage = new YCbCrImage(size.Width, size.Height, this.SubsampleRatio); if (this.ComponentCount == 4) { - this.blackImage = OrigJpegPixelArea.CreateForComponent(this.Components[3]); + this.blackImage = new OrigJpegPixelArea(sizes[3]); } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs index a2e349d8a5..b547993b5d 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs @@ -69,15 +69,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Fact] - public void CalculateJpegChannelSize_Grayscale() + public void CalculateJpegChannelSizes_Grayscale() { using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(TestImages.Jpeg.Baseline.Jpeg400)) { - Assert.Equal(1, decoder.ComponentCount); + Size[] sizes = ComponentUtils.CalculateJpegChannelSizes(decoder.Components, decoder.SubsampleRatio); + + Assert.Equal(1, sizes.Length); + Size expected = decoder.Components[0].SizeInBlocks() * 8; - Size actual = decoder.Components[0].CalculateJpegChannelSize(decoder.SubsampleRatio); - Assert.Equal(expected, actual); + Assert.Equal(expected, sizes[0]); } } @@ -85,38 +87,40 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(TestImages.Jpeg.Baseline.Calliphora, 1)] [InlineData(TestImages.Jpeg.Baseline.Jpeg444, 1)] [InlineData(TestImages.Jpeg.Baseline.Jpeg420, 2)] - public void CalculateJpegChannelSize_YCbCr( + public void CalculateJpegChannelSizes_YCbCr( string imageFile, int chromaDiv) { using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(imageFile)) { - Size ySize = decoder.Components[0].SizeInBlocks() * 8; - Size cSize = decoder.Components[1].SizeInBlocks() * 8 / chromaDiv; + Size[] s = ComponentUtils.CalculateJpegChannelSizes(decoder.Components, decoder.SubsampleRatio); - Size s0 = decoder.Components[0].CalculateJpegChannelSize(decoder.SubsampleRatio); - Size s1 = decoder.Components[1].CalculateJpegChannelSize(decoder.SubsampleRatio); - Size s2 = decoder.Components[2].CalculateJpegChannelSize(decoder.SubsampleRatio); + Assert.Equal(3, s.Length); - Assert.Equal(ySize, s0); - Assert.Equal(cSize, s1); - Assert.Equal(cSize, s2); + Size ySize = decoder.Components[0].SizeInBlocks() * 8; + Size cSize = ySize / chromaDiv; + + Assert.Equal(ySize, s[0]); + Assert.Equal(cSize, s[1]); + Assert.Equal(cSize, s[2]); } } [Theory] [InlineData(TestImages.Jpeg.Baseline.Ycck)] [InlineData(TestImages.Jpeg.Baseline.Cmyk)] - public void CalculateJpegChannelSize_4Chan(string imageFile) + public void CalculateJpegChannelSizes_4Chan(string imageFile) { using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(imageFile)) { + Size[] sizes = ComponentUtils.CalculateJpegChannelSizes(decoder.Components, decoder.SubsampleRatio); + Assert.Equal(4, sizes.Length); + Size expected = decoder.Components[0].SizeInBlocks() * 8; - foreach (OrigComponent component in decoder.Components) + foreach (Size s in sizes) { - Size actual = component.CalculateJpegChannelSize(decoder.SubsampleRatio); - Assert.Equal(expected, actual); + Assert.Equal(expected, s); } } }