Browse Source

Tests

pull/2177/head
Dmitry Pentin 4 years ago
parent
commit
0cc3c683cc
  1. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs
  2. 69
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  3. 69
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Internal.cs

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;

69
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -85,6 +85,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// </summary>
private byte[] xmpData;
/// <summary>
/// Whether the image has a APP14 adobe marker. This is needed to determine image encoded colorspace.
/// </summary>
private bool hasAdobeMarker;
/// <summary>
/// Contains information about the JFIF marker.
/// </summary>
@ -501,49 +506,48 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// Returns the correct colorspace based on the image component count and the jpeg frame component id's.
/// </summary>
/// <param name="componentCount">The number of components.</param>
/// <param name="adobeMarker">Parsed adobe APP14 marker.</param>
/// <returns>The <see cref="JpegColorSpace"/></returns>
private JpegColorSpace DeduceJpegColorSpace(byte componentCount)
internal static JpegColorSpace DeduceJpegColorSpace(byte componentCount, ref AdobeMarker adobeMarker)
{
if (componentCount == 1)
{
return JpegColorSpace.Grayscale;
}
if (componentCount == 3)
{
if (!this.adobe.Equals(default))
if (adobeMarker.ColorTransform == JpegConstants.Adobe.ColorTransformUnknown)
{
if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYCbCr)
{
return JpegColorSpace.YCbCr;
}
if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformUnknown)
{
return JpegColorSpace.RGB;
}
return JpegColorSpace.RGB;
}
// Fallback to YCbCr
return JpegColorSpace.YCbCr;
}
if (componentCount == 4)
{
if (!this.adobe.Equals(default))
if (adobeMarker.ColorTransform == JpegConstants.Adobe.ColorTransformYcck)
{
if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYcck)
{
return JpegColorSpace.Ycck;
}
if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformUnknown)
{
return JpegColorSpace.Cmyk;
}
return JpegColorSpace.Ycck;
}
// Fallback to CMYK
return JpegColorSpace.Cmyk;
}
JpegThrowHelper.ThrowNotSupportedComponentCount(componentCount);
return default;
}
internal static JpegColorSpace DeduceJpegColorSpace(byte componentCount)
{
if (componentCount == 1)
{
return JpegColorSpace.Grayscale;
}
if (componentCount == 3)
{
return JpegColorSpace.YCbCr;
}
if (componentCount == 4)
{
return JpegColorSpace.Cmyk;
}
@ -1013,7 +1017,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
stream.Read(this.temp, 0, MarkerLength);
remaining -= MarkerLength;
AdobeMarker.TryParse(this.temp, out this.adobe);
if (AdobeMarker.TryParse(this.temp, out this.adobe))
{
this.hasAdobeMarker = true;
}
if (remaining > 0)
{
@ -1260,7 +1267,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
index += componentBytes;
}
this.ColorSpace = this.DeduceJpegColorSpace(componentCount);
this.ColorSpace = this.hasAdobeMarker
? DeduceJpegColorSpace(componentCount, ref this.adobe)
: DeduceJpegColorSpace(componentCount);
this.Metadata.GetJpegMetadata().ColorType = this.DeduceJpegColorType();
if (!metadataOnly)

69
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Internal.cs

@ -0,0 +1,69 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
[Trait("Format", "Jpg")]
public partial class JpegDecoderTests
{
[Theory]
[InlineData(3, JpegConstants.Adobe.ColorTransformUnknown, JpegColorSpace.RGB)]
[InlineData(3, JpegConstants.Adobe.ColorTransformYCbCr, JpegColorSpace.YCbCr)]
[InlineData(4, JpegConstants.Adobe.ColorTransformUnknown, JpegColorSpace.Cmyk)]
[InlineData(4, JpegConstants.Adobe.ColorTransformYcck, JpegColorSpace.Ycck)]
internal void DeduceJpegColorSpaceAdobeMarker_ShouldReturnValidColorSpace(byte componentCount, byte adobeFlag, JpegColorSpace expectedColorSpace)
{
byte[] adobeMarkerPayload = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, adobeFlag };
ProfileResolver.AdobeMarker.CopyTo(adobeMarkerPayload);
_ = AdobeMarker.TryParse(adobeMarkerPayload, out AdobeMarker adobeMarker);
JpegColorSpace actualColorSpace = JpegDecoderCore.DeduceJpegColorSpace(componentCount, ref adobeMarker);
Assert.Equal(expectedColorSpace, actualColorSpace);
}
[Theory]
[InlineData(2)]
[InlineData(5)]
public void DeduceJpegColorSpaceAdobeMarker_ShouldThrowOnUnsupportedComponentCount(byte componentCount)
{
AdobeMarker adobeMarker = default;
Assert.Throws<NotSupportedException>(() => JpegDecoderCore.DeduceJpegColorSpace(componentCount, ref adobeMarker));
}
[Theory]
[InlineData(1, JpegColorSpace.Grayscale)]
[InlineData(3, JpegColorSpace.YCbCr)]
[InlineData(4, JpegColorSpace.Cmyk)]
internal void DeduceJpegColorSpace_ShouldReturnValidColorSpace(byte componentCount, JpegColorSpace expectedColorSpace)
{
JpegColorSpace actualColorSpace = JpegDecoderCore.DeduceJpegColorSpace(componentCount);
Assert.Equal(expectedColorSpace, actualColorSpace);
}
[Theory]
[InlineData(2)]
[InlineData(5)]
public void DeduceJpegColorSpace_ShouldThrowOnUnsupportedComponentCount(byte componentCount)
=> Assert.Throws<NotSupportedException>(() => JpegDecoderCore.DeduceJpegColorSpace(componentCount));
}
}
Loading…
Cancel
Save