diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/SubsampleRatio.cs b/src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs
similarity index 74%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/SubsampleRatio.cs
rename to src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs
index 86fde5e72..3b3f302a4 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/SubsampleRatio.cs
+++ b/src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs
@@ -1,54 +1,18 @@
using System.Collections.Generic;
using System.Linq;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
- ///
- /// Provides enumeration of the various available subsample ratios.
- /// https://en.wikipedia.org/wiki/Chroma_subsampling
- ///
- internal enum SubsampleRatio
- {
- Undefined,
-
- ///
- /// 4:4:4
- ///
- Ratio444,
-
- ///
- /// 4:2:2
- ///
- Ratio422,
-
- ///
- /// 4:2:0
- ///
- Ratio420,
-
- ///
- /// 4:4:0
- ///
- Ratio440,
-
- ///
- /// 4:1:1
- ///
- Ratio411,
-
- ///
- /// 4:1:0
- ///
- Ratio410,
- }
+ using System;
///
- /// Various utilities for
+ /// Various utilities for and .
///
- internal static class Subsampling
+ internal static class ComponentUtils
{
+ public static Size SizeInBlocks(this IJpegComponent component) => new Size(component.WidthInBlocks, component.HeightInBlocks);
+
public static SubsampleRatio GetSubsampleRatio(int horizontalRatio, int verticalRatio)
{
switch ((horizontalRatio << 4) | verticalRatio)
@@ -113,5 +77,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
return new Size(width, height);
}
}
+
+ public static bool IsChromaComponent(this IJpegComponent component) =>
+ component.Index > 0 && component.Index < 3;
+
+ 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/Common/IJpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs
index 5a5b95e30..07dba0bdb 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs
@@ -2,6 +2,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
internal interface IJpegComponent
{
+ ///
+ /// Gets the component's position in the components array.
+ ///
+ int Index { get; }
+
///
/// Gets the number of blocks per line
///
diff --git a/src/ImageSharp/Formats/Jpeg/Common/SubsampleRatio.cs b/src/ImageSharp/Formats/Jpeg/Common/SubsampleRatio.cs
new file mode 100644
index 000000000..f6f5fbd68
--- /dev/null
+++ b/src/ImageSharp/Formats/Jpeg/Common/SubsampleRatio.cs
@@ -0,0 +1,41 @@
+namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+{
+ ///
+ /// Provides enumeration of the various available subsample ratios.
+ /// https://en.wikipedia.org/wiki/Chroma_subsampling
+ ///
+ internal enum SubsampleRatio
+ {
+ Undefined,
+
+ ///
+ /// 4:4:4
+ ///
+ Ratio444,
+
+ ///
+ /// 4:2:2
+ ///
+ Ratio422,
+
+ ///
+ /// 4:2:0
+ ///
+ Ratio420,
+
+ ///
+ /// 4:4:0
+ ///
+ Ratio440,
+
+ ///
+ /// 4:1:1
+ ///
+ Ratio411,
+
+ ///
+ /// 4:1:0
+ ///
+ Ratio410,
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs
index e416bbc19..035a7ddd8 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs
@@ -25,9 +25,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
public byte Identifier { get; }
- ///
- /// Gets the component's position in
- ///
+ ///
public int Index { get; }
///
@@ -44,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Gets the storing the "raw" frequency-domain decoded blocks.
/// We need to apply IDCT, dequantiazition and unzigging to transform them into color-space blocks.
- /// This is done by .
+ /// This is done by .
/// When us true, we are touching these blocks multiple times - each time we process a Scan.
///
public Buffer2D SpectralBlocks { get; private set; }
@@ -224,20 +222,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.VerticalSamplingFactor = v;
}
- public Size CalculateJpegChannelSize(SubsampleRatio ratio)
- {
- Size size = new Size(this.WidthInBlocks, this.HeightInBlocks) * 8;
-
- if (this.Index > 0 && this.Index < 3) // Chroma component:
- {
- return ratio.CalculateChrominanceSize(size.Width, size.Height);
- }
- else
- {
- return size;
- }
- }
-
public void Dispose()
{
this.SpectralBlocks.Dispose();
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs
index 0fd2b5a61..b724ecb1e 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs
@@ -5,9 +5,11 @@ using System;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;
using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F;
+using SixLabors.ImageSharp.Formats.Jpeg.Common;
+using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
-{
+{
///
/// Represents an area of a Jpeg subimage (channel)
///
@@ -36,6 +38,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
}
+ public OrigJpegPixelArea(Size size)
+ : this(Buffer2D.CreateClean(size))
+ {
+ }
+
///
/// Gets the pixels buffer.
///
@@ -76,6 +83,12 @@ 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/Components/Decoder/YCbCrImage.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/YCbCrImage.cs
index 7260784ff..72a25ecd7 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/YCbCrImage.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/YCbCrImage.cs
@@ -7,6 +7,8 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
///
/// Represents an image made up of three color components (luminance, blue chroma, red chroma)
///
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
index 6fb367edc..b8eea6f37 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
@@ -17,6 +17,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
using System.Linq;
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
+ using SixLabors.Primitives;
+
///
/// Performs the jpeg decoding operation.
///
@@ -112,7 +115,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
///
- /// Gets the ratio.
+ /// Gets the ratio.
///
public SubsampleRatio SubsampleRatio { get; private set; }
@@ -775,29 +778,23 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
///
- /// Makes the image from the buffer.
+ /// Initializes the image channels.
///
private void InitJpegImageChannels()
{
if (this.ComponentCount == 1)
{
- var buffer = Buffer2D.CreateClean(8 * this.MCUCountX, 8 * this.MCUCountY);
- this.grayImage = new OrigJpegPixelArea(buffer);
+ this.grayImage = OrigJpegPixelArea.CreateForComponent(this.Components[0]);
}
else
{
- int h0 = this.Components[0].HorizontalSamplingFactor;
- int v0 = this.Components[0].VerticalSamplingFactor;
+ Size size = this.Components[0].CalculateJpegChannelSize();
- this.ycbcrImage = new YCbCrImage(8 * h0 * this.MCUCountX, 8 * v0 * this.MCUCountY, this.SubsampleRatio);
+ this.ycbcrImage = new YCbCrImage(size.Width, size.Height, this.SubsampleRatio);
if (this.ComponentCount == 4)
{
- int h3 = this.Components[3].HorizontalSamplingFactor;
- int v3 = this.Components[3].VerticalSamplingFactor;
-
- var buffer = Buffer2D.CreateClean(8 * h3 * this.MCUCountX, 8 * v3 * this.MCUCountY);
- this.blackImage = new OrigJpegPixelArea(buffer);
+ this.blackImage = OrigJpegPixelArea.CreateForComponent(this.Components[3]);
}
}
}
@@ -1198,7 +1195,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.Components[i].InitializeBlocks(this);
}
- this.SubsampleRatio = Subsampling.GetSubsampleRatio(this.Components);
+ this.SubsampleRatio = ComponentUtils.GetSubsampleRatio(this.Components);
}
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
index 8f424143a..2363d9600 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
@@ -16,13 +16,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{
#pragma warning disable SA1401 // Fields should be private
- public PdfJsFrameComponent(PdfJsFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationIdentifier)
+ public PdfJsFrameComponent(PdfJsFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationIdentifier, int index)
{
this.Frame = frame;
this.Id = id;
this.HorizontalSamplingFactor = horizontalFactor;
this.VerticalSamplingFactor = verticalFactor;
this.QuantizationIdentifier = quantizationIdentifier;
+ this.Index = index;
}
///
@@ -35,14 +36,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
///
public int Pred { get; set; }
- ///
- /// Gets the horizontal sampling factor.
- ///
+ ///
public int HorizontalSamplingFactor { get; }
- ///
- /// Gets the vertical sampling factor.
- ///
+ ///
public int VerticalSamplingFactor { get; }
///
@@ -55,6 +52,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
///
public Buffer BlockData { get; private set; }
+ ///
+ public int Index { get; }
+
///
/// Gets the number of blocks per line
///
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs
index 56814843a..e705073fa 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs
@@ -676,7 +676,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
maxV = v;
}
- var component = new PdfJsFrameComponent(this.Frame, this.temp[index], h, v, this.temp[index + 2]);
+ var component = new PdfJsFrameComponent(this.Frame, this.temp[index], h, v, this.temp[index + 2], i);
this.Frame.Components[i] = component;
this.Frame.ComponentIds[i] = component.Id;
diff --git a/src/ImageSharp/Memory/Buffer2D.cs b/src/ImageSharp/Memory/Buffer2D.cs
index d86eb5b26..8c7b104cf 100644
--- a/src/ImageSharp/Memory/Buffer2D.cs
+++ b/src/ImageSharp/Memory/Buffer2D.cs
@@ -5,6 +5,8 @@ using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Memory
{
+ using SixLabors.Primitives;
+
///
/// Represents a buffer of value type objects
/// interpreted as a 2D region of x elements.
@@ -71,5 +73,12 @@ namespace SixLabors.ImageSharp.Memory
buffer.Clear();
return buffer;
}
+
+ ///
+ /// Creates a clean instance of initializing it's elements with 'default(T)'.
+ ///
+ /// The size of the buffer
+ /// The instance
+ public static Buffer2D CreateClean(Size size) => CreateClean(size.Width, size.Height);
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
index edf3162d2..3f643344b 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using Xunit;
using Xunit.Abstractions;
- public class Block8x8FTests : JpegUtilityTestFixture
+ public class Block8x8FTests : JpegFixture
{
#if BENCHMARKING
public const int Times = 1000000;
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
index 8c1d5fb90..d1a128b53 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
@@ -7,7 +7,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using Xunit;
using Xunit.Abstractions;
- public class Block8x8Tests : JpegUtilityTestFixture
+ public class Block8x8Tests : JpegFixture
{
public Block8x8Tests(ITestOutputHelper output)
: base(output)
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs
new file mode 100644
index 000000000..a2e349d8a
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs
@@ -0,0 +1,124 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+// ReSharper disable InconsistentNaming
+namespace SixLabors.ImageSharp.Tests.Formats.Jpg
+{
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
+ using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
+ using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder;
+ using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
+ using SixLabors.Primitives;
+
+ using Xunit;
+ using Xunit.Abstractions;
+
+ public class ComponentUtilsTests
+ {
+ public ComponentUtilsTests(ITestOutputHelper output)
+ {
+ this.Output = output;
+ }
+
+ private ITestOutputHelper Output { get; }
+
+ [Theory]
+ [InlineData(SubsampleRatio.Ratio410, 4, 2)]
+ [InlineData(SubsampleRatio.Ratio411, 4, 1)]
+ [InlineData(SubsampleRatio.Ratio420, 2, 2)]
+ [InlineData(SubsampleRatio.Ratio422, 2, 1)]
+ [InlineData(SubsampleRatio.Ratio440, 1, 2)]
+ [InlineData(SubsampleRatio.Ratio444, 1, 1)]
+ internal void CalculateChrominanceSize(
+ SubsampleRatio ratio,
+ int expectedDivX,
+ int expectedDivY)
+ {
+ //this.Output.WriteLine($"RATIO: {ratio}");
+ Size size = ratio.CalculateChrominanceSize(400, 400);
+ //this.Output.WriteLine($"Ch Size: {size}");
+
+ Assert.Equal(new Size(400 / expectedDivX, 400 / expectedDivY), size);
+ }
+
+ [Theory]
+ [InlineData(SubsampleRatio.Ratio410, 4)]
+ [InlineData(SubsampleRatio.Ratio411, 4)]
+ [InlineData(SubsampleRatio.Ratio420, 2)]
+ [InlineData(SubsampleRatio.Ratio422, 2)]
+ [InlineData(SubsampleRatio.Ratio440, 1)]
+ [InlineData(SubsampleRatio.Ratio444, 1)]
+ internal void Create(SubsampleRatio ratio, int expectedCStrideDiv)
+ {
+ this.Output.WriteLine($"RATIO: {ratio}");
+
+ YCbCrImage img = new YCbCrImage(400, 400, ratio);
+
+ //this.PrintChannel("Y", img.YChannel);
+ //this.PrintChannel("Cb", img.CbChannel);
+ //this.PrintChannel("Cr", img.CrChannel);
+
+ Assert.Equal(400, img.YChannel.Width);
+ Assert.Equal(img.CbChannel.Width, 400 / expectedCStrideDiv);
+ Assert.Equal(img.CrChannel.Width, 400 / expectedCStrideDiv);
+ }
+
+ private void PrintChannel(string name, OrigJpegPixelArea channel)
+ {
+ this.Output.WriteLine($"{name}: Stride={channel.Stride}");
+ }
+
+ [Fact]
+ public void CalculateJpegChannelSize_Grayscale()
+ {
+ using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(TestImages.Jpeg.Baseline.Jpeg400))
+ {
+ Assert.Equal(1, decoder.ComponentCount);
+ Size expected = decoder.Components[0].SizeInBlocks() * 8;
+ Size actual = decoder.Components[0].CalculateJpegChannelSize(decoder.SubsampleRatio);
+
+ Assert.Equal(expected, actual);
+ }
+ }
+
+ [Theory]
+ [InlineData(TestImages.Jpeg.Baseline.Calliphora, 1)]
+ [InlineData(TestImages.Jpeg.Baseline.Jpeg444, 1)]
+ [InlineData(TestImages.Jpeg.Baseline.Jpeg420, 2)]
+ public void CalculateJpegChannelSize_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 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(ySize, s0);
+ Assert.Equal(cSize, s1);
+ Assert.Equal(cSize, s2);
+ }
+ }
+
+ [Theory]
+ [InlineData(TestImages.Jpeg.Baseline.Ycck)]
+ [InlineData(TestImages.Jpeg.Baseline.Cmyk)]
+ public void CalculateJpegChannelSize_4Chan(string imageFile)
+ {
+ using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(imageFile))
+ {
+ Size expected = decoder.Components[0].SizeInBlocks() * 8;
+
+ foreach (OrigComponent component in decoder.Components)
+ {
+ Size actual = component.CalculateJpegChannelSize(decoder.SubsampleRatio);
+ Assert.Equal(expected, actual);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
index bf0563b67..ee6f5305f 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
@@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public static class DCTTests
{
- public class FastFloatingPoint : JpegUtilityTestFixture
+ public class FastFloatingPoint : JpegFixture
{
public FastFloatingPoint(ITestOutputHelper output)
: base(output)
@@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[Fact]
public void iDCT2D8x4_LeftPart()
{
- float[] sourceArray = JpegUtilityTestFixture.Create8x8FloatData();
+ float[] sourceArray = JpegFixture.Create8x8FloatData();
float[] expectedDestArray = new float[64];
ReferenceImplementations.LLM_FloatingPoint_DCT.iDCT2D8x4_32f(sourceArray, expectedDestArray);
@@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[Fact]
public void iDCT2D8x4_RightPart()
{
- float[] sourceArray = JpegUtilityTestFixture.Create8x8FloatData();
+ float[] sourceArray = JpegFixture.Create8x8FloatData();
float[] expectedDestArray = new float[64];
ReferenceImplementations.LLM_FloatingPoint_DCT.iDCT2D8x4_32f(sourceArray.AsSpan().Slice(4), expectedDestArray.AsSpan().Slice(4));
@@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(3)]
public void LLM_TransformIDCT_CompareToNonOptimized(int seed)
{
- float[] sourceArray = JpegUtilityTestFixture.Create8x8RoundedRandomFloatData(-1000, 1000, seed);
+ float[] sourceArray = JpegFixture.Create8x8RoundedRandomFloatData(-1000, 1000, seed);
var source = Block8x8F.Load(sourceArray);
@@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(3)]
public void LLM_TransformIDCT_CompareToAccurate(int seed)
{
- float[] sourceArray = JpegUtilityTestFixture.Create8x8RoundedRandomFloatData(-1000, 1000, seed);
+ float[] sourceArray = JpegFixture.Create8x8RoundedRandomFloatData(-1000, 1000, seed);
var source = Block8x8F.Load(sourceArray);
@@ -114,7 +114,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2)]
public void FDCT8x4_LeftPart(int seed)
{
- Span src = JpegUtilityTestFixture.Create8x8RoundedRandomFloatData(-200, 200, seed);
+ Span src = JpegFixture.Create8x8RoundedRandomFloatData(-200, 200, seed);
Block8x8F srcBlock = new Block8x8F();
srcBlock.LoadFrom(src);
@@ -136,7 +136,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2)]
public void FDCT8x4_RightPart(int seed)
{
- Span src = JpegUtilityTestFixture.Create8x8RoundedRandomFloatData(-200, 200, seed);
+ Span src = JpegFixture.Create8x8RoundedRandomFloatData(-200, 200, seed);
Block8x8F srcBlock = new Block8x8F();
srcBlock.LoadFrom(src);
@@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2)]
public void TransformFDCT(int seed)
{
- Span src = JpegUtilityTestFixture.Create8x8RoundedRandomFloatData(-200, 200, seed);
+ Span src = JpegFixture.Create8x8RoundedRandomFloatData(-200, 200, seed);
Block8x8F srcBlock = new Block8x8F();
srcBlock.LoadFrom(src);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
index 15be5b771..6dd1da351 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
@@ -65,12 +65,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[Fact(Skip = "Doesn't really matter")]
public void ParseStream_BasicPropertiesAreCorrect1_Orig()
{
- byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes;
- using (var ms = new MemoryStream(bytes))
+ using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(TestImages.Jpeg.Progressive.Progress))
{
- var decoder = new OrigJpegDecoderCore(Configuration.Default, new JpegDecoder());
- decoder.ParseStream(ms);
-
VerifyJpeg.Components3(decoder.Components, 43, 61, 22, 31, 22, 31);
}
}
@@ -95,7 +91,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void DecodeBaselineJpeg_PdfJs(TestImageProvider provider)
where TPixel : struct, IPixel
{
-
using (Image image = provider.GetImage(PdfJsJpegDecoder))
{
image.DebugSave(provider);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs
index b716146e8..6b9e98d66 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs
@@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public partial class ReferenceImplementationsTests
{
- public class AccurateDCT : JpegUtilityTestFixture
+ public class AccurateDCT : JpegFixture
{
public AccurateDCT(ITestOutputHelper output)
: base(output)
@@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2)]
public void ForwardThenInverse(int seed)
{
- float[] data = JpegUtilityTestFixture.Create8x8RandomFloatData(-1000, 1000, seed);
+ float[] data = JpegFixture.Create8x8RandomFloatData(-1000, 1000, seed);
var b0 = default(Block8x8F);
b0.LoadFrom(data);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
index 1babb4f14..7ff2a3923 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public partial class ReferenceImplementationsTests
{
- public class FastFloatingPointDCT : JpegUtilityTestFixture
+ public class FastFloatingPointDCT : JpegFixture
{
public FastFloatingPointDCT(ITestOutputHelper output)
: base(output)
@@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2, 0)]
public void LLM_ForwardThenInverse(int seed, int startAt)
{
- int[] data = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed);
+ int[] data = JpegFixture.Create8x8RandomIntData(-1000, 1000, seed);
float[] original = data.ConvertAllToFloat();
float[] src = data.ConvertAllToFloat();
float[] dest = new float[64];
@@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2, 200)]
public void LLM_IDCT_IsEquivalentTo_AccurateImplementation(int seed, int range)
{
- float[] sourceArray = JpegUtilityTestFixture.Create8x8RoundedRandomFloatData(-1000, 1000, seed);
+ float[] sourceArray = JpegFixture.Create8x8RoundedRandomFloatData(-1000, 1000, seed);
var source = Block8x8F.Load(sourceArray);
@@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2)]
public void LLM_FDCT_IsEquivalentTo_AccurateImplementation(int seed)
{
- float[] floatData = JpegUtilityTestFixture.Create8x8RandomFloatData(-1000, 1000);
+ float[] floatData = JpegFixture.Create8x8RandomFloatData(-1000, 1000);
Block8x8F source = default(Block8x8F);
source.LoadFrom(floatData);
@@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2, 200)]
public void GT_IDCT_IsEquivalentTo_AccurateImplementation(int seed, int range)
{
- int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-range, range, seed);
+ int[] intData = JpegFixture.Create8x8RandomIntData(-range, range, seed);
float[] floatSrc = intData.ConvertAllToFloat();
ReferenceImplementations.AccurateDCT.TransformIDCTInplace(intData);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs
index e9e0503ed..f384a76c4 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public partial class ReferenceImplementationsTests
{
- public class StandardIntegerDCT : JpegUtilityTestFixture
+ public class StandardIntegerDCT : JpegFixture
{
public StandardIntegerDCT(ITestOutputHelper output)
: base(output)
@@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[InlineData(2, 0)]
public void ForwardThenInverse(int seed, int startAt)
{
- Span original = JpegUtilityTestFixture.Create8x8RandomIntData(-200, 200, seed);
+ Span original = JpegFixture.Create8x8RandomIntData(-200, 200, seed);
Span block = original.AddScalarToAllValues(128);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
index 8b97f1208..26ec454f9 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
@@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
- public partial class ReferenceImplementationsTests : JpegUtilityTestFixture
+ public partial class ReferenceImplementationsTests : JpegFixture
{
public ReferenceImplementationsTests(ITestOutputHelper output)
: base(output)
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SubsampleRatioTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SubsampleRatioTests.cs
deleted file mode 100644
index 6e30e6f80..000000000
--- a/tests/ImageSharp.Tests/Formats/Jpg/SubsampleRatioTests.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-namespace SixLabors.ImageSharp.Tests.Formats.Jpg
-{
- using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder;
- using SixLabors.Primitives;
-
- using Xunit;
- using Xunit.Abstractions;
-
- public class SubsampleRatioTests
- {
- public SubsampleRatioTests(ITestOutputHelper output)
- {
- this.Output = output;
- }
-
- private ITestOutputHelper Output { get; }
-
- [Theory]
- [InlineData(SubsampleRatio.Ratio410, 4, 2)]
- [InlineData(SubsampleRatio.Ratio411, 4, 1)]
- [InlineData(SubsampleRatio.Ratio420, 2, 2)]
- [InlineData(SubsampleRatio.Ratio422, 2, 1)]
- [InlineData(SubsampleRatio.Ratio440, 1, 2)]
- [InlineData(SubsampleRatio.Ratio444, 1, 1)]
- internal void CalculateChrominanceSize(
- SubsampleRatio ratio,
- int expectedDivX,
- int expectedDivY)
- {
- //this.Output.WriteLine($"RATIO: {ratio}");
- Size size = ratio.CalculateChrominanceSize(400, 400);
- //this.Output.WriteLine($"Ch Size: {size}");
-
- Assert.Equal(new Size(400 / expectedDivX, 400 / expectedDivY), size);
- }
-
- [Theory]
- [InlineData(SubsampleRatio.Ratio410, 4)]
- [InlineData(SubsampleRatio.Ratio411, 4)]
- [InlineData(SubsampleRatio.Ratio420, 2)]
- [InlineData(SubsampleRatio.Ratio422, 2)]
- [InlineData(SubsampleRatio.Ratio440, 1)]
- [InlineData(SubsampleRatio.Ratio444, 1)]
- internal void Create(SubsampleRatio ratio, int expectedCStrideDiv)
- {
- this.Output.WriteLine($"RATIO: {ratio}");
-
- YCbCrImage img = new YCbCrImage(400, 400, ratio);
-
- //this.PrintChannel("Y", img.YChannel);
- //this.PrintChannel("Cb", img.CbChannel);
- //this.PrintChannel("Cr", img.CrChannel);
-
- Assert.Equal(400, img.YChannel.Width);
- Assert.Equal(img.CbChannel.Width, 400 / expectedCStrideDiv);
- Assert.Equal(img.CrChannel.Width, 400 / expectedCStrideDiv);
- }
-
- private void PrintChannel(string name, OrigJpegPixelArea channel)
- {
- this.Output.WriteLine($"{name}: Stride={channel.Stride}");
- }
- }
-}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
similarity index 88%
rename from tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs
rename to tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
index 1ecfeacef..ab5d072a4 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
@@ -9,16 +9,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
{
using System;
using System.Diagnostics;
+ using System.IO;
using System.Text;
+ using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Common;
+ using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
using Xunit;
using Xunit.Abstractions;
- public class JpegUtilityTestFixture : MeasureFixture
+ public class JpegFixture : MeasureFixture
{
- public JpegUtilityTestFixture(ITestOutputHelper output) : base(output)
+ public JpegFixture(ITestOutputHelper output) : base(output)
{
}
@@ -166,5 +169,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
this.Output.WriteLine("TOTAL DIFF: "+totalDifference);
Assert.False(failed);
}
+
+ internal static OrigJpegDecoderCore ParseStream(string testFileName)
+ {
+ byte[] bytes = TestFile.Create(testFileName).Bytes;
+ using (var ms = new MemoryStream(bytes))
+ {
+ var decoder = new OrigJpegDecoderCore(Configuration.Default, new JpegDecoder());
+ decoder.ParseStream(ms);
+ return decoder;
+ }
+ }
}
}
\ No newline at end of file