Browse Source

CalculateJpegChannelSizes()

pull/322/head
Anton Firszov 9 years ago
parent
commit
769d4de78c
  1. 39
      src/ImageSharp/Formats/Jpeg/Common/ComponentUtils.cs
  2. 8
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs
  3. 8
      src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
  4. 38
      tests/ImageSharp.Tests/Formats/Jpg/ComponentUtilsTests.cs

39
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<IJpegComponent> 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;
// }
//}
}
}

8
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegPixelArea.cs

@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
: this(Buffer2D<byte>.CreateClean(size))
{
}
/// <summary>
/// Gets the pixels buffer.
/// </summary>
@ -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);
}
/// <summary>
/// Gets the subarea that belongs to the Block8x8 defined by block indices
/// </summary>

8
src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs

@ -782,19 +782,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// </summary>
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]);
}
}
}

38
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);
}
}
}

Loading…
Cancel
Save