|
|
|
@ -8,7 +8,9 @@ using Xunit.Abstractions; |
|
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
|
|
|
|
namespace SixLabors.ImageSharp.Tests.Formats.Jpg |
|
|
|
{ |
|
|
|
{ |
|
|
|
using System.Text; |
|
|
|
|
|
|
|
public class ParseStreamTests |
|
|
|
{ |
|
|
|
private ITestOutputHelper Output { get; } |
|
|
|
@ -21,39 +23,68 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg |
|
|
|
[Fact] |
|
|
|
public void ComponentScalingIsCorrect_1ChannelJpeg() |
|
|
|
{ |
|
|
|
using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(TestImages.Jpeg.Baseline.Jpeg400)) |
|
|
|
using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(TestImages.Jpeg.Baseline.Jpeg400, true)) |
|
|
|
{ |
|
|
|
Assert.Equal(1, decoder.ComponentCount); |
|
|
|
Assert.Equal(1, decoder.Components.Length); |
|
|
|
|
|
|
|
Size expectedSizeInBlocks = decoder.ImageSizeInPixels.DivideRoundUp(8); |
|
|
|
|
|
|
|
Size sizeInBlocks = decoder.ImageSizeInBlocks; |
|
|
|
|
|
|
|
Size expectedSizeInBlocks = decoder.ImageSizeInPixels.GetSubSampledSize(8); |
|
|
|
|
|
|
|
Assert.Equal(expectedSizeInBlocks, sizeInBlocks); |
|
|
|
Assert.Equal(sizeInBlocks, decoder.ImageSizeInMCU); |
|
|
|
Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU); |
|
|
|
|
|
|
|
var uniform1 = new Size(1, 1); |
|
|
|
OrigComponent c0 = decoder.Components[0]; |
|
|
|
VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Jpeg444, 3, 1, 1)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Jpeg420Exif, 3, 2, 2)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Jpeg420Small, 3, 2, 2)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Ycck, 4, 1, 1)] // TODO: Find Ycck or Cmyk images with different subsampling
|
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Cmyk, 4, 1, 1)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Jpeg444)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Jpeg420Exif)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Jpeg420Small)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Testorig420)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Ycck)] |
|
|
|
[InlineData(TestImages.Jpeg.Baseline.Cmyk)] |
|
|
|
public void PrintComponentData(string imageFile) |
|
|
|
{ |
|
|
|
StringBuilder bld = new StringBuilder(); |
|
|
|
|
|
|
|
using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(imageFile, true)) |
|
|
|
{ |
|
|
|
bld.AppendLine(imageFile); |
|
|
|
bld.AppendLine($"Size:{decoder.ImageSizeInPixels} MCU:{decoder.ImageSizeInMCU}"); |
|
|
|
OrigComponent c0 = decoder.Components[0]; |
|
|
|
OrigComponent c1 = decoder.Components[1]; |
|
|
|
|
|
|
|
bld.AppendLine($"Luma: SAMP: {c0.SamplingFactors} BLOCKS: {c0.SizeInBlocks}"); |
|
|
|
bld.AppendLine($"Chroma: {c1.SamplingFactors} BLOCKS: {c1.SizeInBlocks}"); |
|
|
|
} |
|
|
|
this.Output.WriteLine(bld.ToString()); |
|
|
|
} |
|
|
|
|
|
|
|
public static readonly TheoryData<string, int, object, object> ComponentVerificationData = new TheoryData<string, int, object, object>() |
|
|
|
{ |
|
|
|
{ TestImages.Jpeg.Baseline.Jpeg444, 3, new Size(1, 1), new Size(1, 1) }, |
|
|
|
{ TestImages.Jpeg.Baseline.Jpeg420Exif, 3, new Size(2, 2), new Size(1, 1) }, |
|
|
|
{ TestImages.Jpeg.Baseline.Jpeg420Small, 3, new Size(2, 2), new Size(1, 1) }, |
|
|
|
{ TestImages.Jpeg.Baseline.Testorig420, 3, new Size(2, 2), new Size(1, 1) }, |
|
|
|
// TODO: Find Ycck or Cmyk images with different subsampling
|
|
|
|
{ TestImages.Jpeg.Baseline.Ycck, 4, new Size(1, 1), new Size(1, 1) }, |
|
|
|
{ TestImages.Jpeg.Baseline.Cmyk, 4, new Size(1, 1), new Size(1, 1) }, |
|
|
|
}; |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(ComponentVerificationData))] |
|
|
|
public void ComponentScalingIsCorrect_MultiChannelJpeg( |
|
|
|
string imageFile, |
|
|
|
int componentCount, |
|
|
|
int hDiv, |
|
|
|
int vDiv) |
|
|
|
object expectedLumaFactors, |
|
|
|
object expectedChromaFactors) |
|
|
|
{ |
|
|
|
Size divisor = new Size(hDiv, vDiv); |
|
|
|
Size fLuma = (Size)expectedLumaFactors; |
|
|
|
Size fChroma = (Size)expectedChromaFactors; |
|
|
|
|
|
|
|
using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(imageFile)) |
|
|
|
using (OrigJpegDecoderCore decoder = JpegFixture.ParseStream(imageFile, true)) |
|
|
|
{ |
|
|
|
Assert.Equal(componentCount, decoder.ComponentCount); |
|
|
|
Assert.Equal(componentCount, decoder.Components.Length); |
|
|
|
@ -63,20 +94,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg |
|
|
|
OrigComponent c2 = decoder.Components[2]; |
|
|
|
|
|
|
|
var uniform1 = new Size(1, 1); |
|
|
|
Size expectedLumaSizeInBlocks = decoder.ImageSizeInPixels.GetSubSampledSize(8); |
|
|
|
Size expectedChromaSizeInBlocks = expectedLumaSizeInBlocks.DivideBy(divisor); |
|
|
|
|
|
|
|
Size expectedLumaSamplingFactors = expectedLumaSizeInBlocks.DivideBy(decoder.ImageSizeInMCU); |
|
|
|
Size expectedChromaSamplingFactors = expectedLumaSamplingFactors.DivideBy(divisor); |
|
|
|
Size expectedLumaSizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(fLuma) ; |
|
|
|
|
|
|
|
VerifyJpeg.VerifyComponent(c0, expectedLumaSizeInBlocks, expectedLumaSamplingFactors, uniform1); |
|
|
|
VerifyJpeg.VerifyComponent(c1, expectedChromaSizeInBlocks, expectedChromaSamplingFactors, divisor); |
|
|
|
VerifyJpeg.VerifyComponent(c2, expectedChromaSizeInBlocks, expectedChromaSamplingFactors, divisor); |
|
|
|
Size divisor = fLuma.DivideBy(fChroma); |
|
|
|
|
|
|
|
Size expectedChromaSizeInBlocks = expectedLumaSizeInBlocks.DivideRoundUp(divisor); |
|
|
|
|
|
|
|
VerifyJpeg.VerifyComponent(c0, expectedLumaSizeInBlocks, fLuma, uniform1); |
|
|
|
VerifyJpeg.VerifyComponent(c1, expectedChromaSizeInBlocks, fChroma, divisor); |
|
|
|
VerifyJpeg.VerifyComponent(c2, expectedChromaSizeInBlocks, fChroma, divisor); |
|
|
|
|
|
|
|
if (componentCount == 4) |
|
|
|
{ |
|
|
|
OrigComponent c3 = decoder.Components[2]; |
|
|
|
VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, expectedLumaSamplingFactors, uniform1); |
|
|
|
VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, fLuma, uniform1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|