mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
17 changed files with 726 additions and 474 deletions
Binary file not shown.
@ -0,0 +1,117 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
// ReSharper disable InconsistentNaming
|
||||
|
namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides information about the Adobe marker segment.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>See the included 5116.DCT.pdf file in the source for more information.</remarks>
|
||||
|
internal struct AdobeMarker : IEquatable<AdobeMarker> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the length of an adobe marker segment.
|
||||
|
/// </summary>
|
||||
|
public const int Length = 12; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="AdobeMarker"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="dctEncodeVersion">The DCT encode version</param>
|
||||
|
/// <param name="app14Flags0">The horizontal downsampling hint used for DCT encoding</param>
|
||||
|
/// <param name="app14Flags1">The vertical downsampling hint used for DCT encoding</param>
|
||||
|
/// <param name="colorTransform">The color transform model used</param>
|
||||
|
private AdobeMarker(short dctEncodeVersion, short app14Flags0, short app14Flags1, byte colorTransform) |
||||
|
{ |
||||
|
this.DCTEncodeVersion = dctEncodeVersion; |
||||
|
this.APP14Flags0 = app14Flags0; |
||||
|
this.APP14Flags1 = app14Flags1; |
||||
|
this.ColorTransform = colorTransform; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the DCT Encode Version
|
||||
|
/// </summary>
|
||||
|
public short DCTEncodeVersion { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the horizontal downsampling hint used for DCT encoding
|
||||
|
/// 0x0 : (none - Chop)
|
||||
|
/// Bit 15 : Encoded with Blend=1 downsampling
|
||||
|
/// </summary>
|
||||
|
public short APP14Flags0 { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the vertical downsampling hint used for DCT encoding
|
||||
|
/// 0x0 : (none - Chop)
|
||||
|
/// Bit 15 : Encoded with Blend=1 downsampling
|
||||
|
/// </summary>
|
||||
|
public short APP14Flags1 { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the colorspace transform model used
|
||||
|
/// 00 : Unknown (RGB or CMYK)
|
||||
|
/// 01 : YCbCr
|
||||
|
/// 02 : YCCK
|
||||
|
/// </summary>
|
||||
|
public byte ColorTransform { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the specified byte array representation of an Adobe marker to its <see cref="AdobeMarker"/> equivalent and
|
||||
|
/// returns a value that indicates whether the conversion succeeded.
|
||||
|
/// </summary>
|
||||
|
/// <param name="bytes">The byte array containing metadata to parse</param>
|
||||
|
/// <param name="marker">The marker to return.</param>
|
||||
|
public static bool TryParse(byte[] bytes, out AdobeMarker marker) |
||||
|
{ |
||||
|
if (ProfileResolver.IsProfile(bytes, ProfileResolver.AdobeMarker)) |
||||
|
{ |
||||
|
short dctEncodeVersion = (short)((bytes[5] << 8) | bytes[6]); |
||||
|
short app14Flags0 = (short)((bytes[7] << 8) | bytes[8]); |
||||
|
short app14Flags1 = (short)((bytes[9] << 8) | bytes[10]); |
||||
|
byte colorTransform = bytes[11]; |
||||
|
|
||||
|
marker = new AdobeMarker(dctEncodeVersion, app14Flags0, app14Flags1, colorTransform); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
marker = default(AdobeMarker); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public bool Equals(AdobeMarker other) |
||||
|
{ |
||||
|
return this.DCTEncodeVersion == other.DCTEncodeVersion |
||||
|
&& this.APP14Flags0 == other.APP14Flags0 |
||||
|
&& this.APP14Flags1 == other.APP14Flags1 |
||||
|
&& this.ColorTransform == other.ColorTransform; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (ReferenceEquals(null, obj)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return obj is AdobeMarker && this.Equals((AdobeMarker)obj); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
return HashHelpers.Combine( |
||||
|
this.DCTEncodeVersion.GetHashCode(), |
||||
|
HashHelpers.Combine( |
||||
|
this.APP14Flags0.GetHashCode(), |
||||
|
HashHelpers.Combine( |
||||
|
this.APP14Flags1.GetHashCode(), |
||||
|
this.ColorTransform.GetHashCode()))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,127 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides information about the JFIF marker segment
|
||||
|
/// TODO: Thumbnail?
|
||||
|
/// </summary>
|
||||
|
internal struct JFifMarker : IEquatable<JFifMarker> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the length of an JFIF marker segment.
|
||||
|
/// </summary>
|
||||
|
public const int Length = 13; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="JFifMarker"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="majorVersion">The major version</param>
|
||||
|
/// <param name="minorVersion">The minor version</param>
|
||||
|
/// <param name="densityUnits">The units for the density values</param>
|
||||
|
/// <param name="xDensity">The horizontal pixel density</param>
|
||||
|
/// <param name="yDensity">The veritcal pixel density</param>
|
||||
|
private JFifMarker(byte majorVersion, byte minorVersion, byte densityUnits, short xDensity, short yDensity) |
||||
|
{ |
||||
|
Guard.MustBeGreaterThan(xDensity, 0, nameof(xDensity)); |
||||
|
Guard.MustBeGreaterThan(yDensity, 0, nameof(yDensity)); |
||||
|
|
||||
|
this.MajorVersion = majorVersion; |
||||
|
this.MinorVersion = minorVersion; |
||||
|
this.DensityUnits = densityUnits; |
||||
|
this.XDensity = xDensity; |
||||
|
this.YDensity = yDensity; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the major version
|
||||
|
/// </summary>
|
||||
|
public byte MajorVersion { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the minor version
|
||||
|
/// </summary>
|
||||
|
public byte MinorVersion { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the units for the following pixel density fields
|
||||
|
/// 00 : No units; width:height pixel aspect ratio = Ydensity:Xdensity
|
||||
|
/// 01 : Pixels per inch (2.54 cm)
|
||||
|
/// 02 : Pixels per centimeter
|
||||
|
/// </summary>
|
||||
|
public byte DensityUnits { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the horizontal pixel density. Must not be zero.
|
||||
|
/// </summary>
|
||||
|
public short XDensity { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the vertical pixel density. Must not be zero.
|
||||
|
/// </summary>
|
||||
|
public short YDensity { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the specified byte array representation of an JFIF marker to its <see cref="JFifMarker"/> equivalent and
|
||||
|
/// returns a value that indicates whether the conversion succeeded.
|
||||
|
/// </summary>
|
||||
|
/// <param name="bytes">The byte array containing metadata to parse</param>
|
||||
|
/// <param name="marker">The marker to return.</param>
|
||||
|
public static bool TryParse(byte[] bytes, out JFifMarker marker) |
||||
|
{ |
||||
|
if (ProfileResolver.IsProfile(bytes, ProfileResolver.JFifMarker)) |
||||
|
{ |
||||
|
byte majorVersion = bytes[5]; |
||||
|
byte minorVersion = bytes[6]; |
||||
|
byte densityUnits = bytes[7]; |
||||
|
short xDensity = (short)((bytes[8] << 8) | bytes[9]); |
||||
|
short yDensity = (short)((bytes[10] << 8) | bytes[11]); |
||||
|
|
||||
|
if (xDensity > 0 && yDensity > 0) |
||||
|
{ |
||||
|
marker = new JFifMarker(majorVersion, minorVersion, densityUnits, xDensity, yDensity); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
marker = default(JFifMarker); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public bool Equals(JFifMarker other) |
||||
|
{ |
||||
|
return this.MajorVersion == other.MajorVersion |
||||
|
&& this.MinorVersion == other.MinorVersion |
||||
|
&& this.DensityUnits == other.DensityUnits |
||||
|
&& this.XDensity == other.XDensity |
||||
|
&& this.YDensity == other.YDensity; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (ReferenceEquals(null, obj)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return obj is JFifMarker && this.Equals((JFifMarker)obj); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
return HashHelpers.Combine( |
||||
|
this.MajorVersion.GetHashCode(), |
||||
|
HashHelpers.Combine( |
||||
|
this.MinorVersion.GetHashCode(), |
||||
|
HashHelpers.Combine( |
||||
|
this.DensityUnits.GetHashCode(), |
||||
|
HashHelpers.Combine(this.XDensity, this.YDensity)))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides methods for identifying metadata and color profiles within jpeg images.
|
||||
|
/// </summary>
|
||||
|
internal static class ProfileResolver |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Describes the EXIF specific markers
|
||||
|
/// </summary>
|
||||
|
public static readonly byte[] JFifMarker = ToAsciiBytes("JFIF\0"); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Describes the EXIF specific markers
|
||||
|
/// </summary>
|
||||
|
public static readonly byte[] IccMarker = ToAsciiBytes("ICC_PROFILE\0"); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Describes the ICC specific markers
|
||||
|
/// </summary>
|
||||
|
public static readonly byte[] ExifMarker = ToAsciiBytes("Exif\0\0"); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Describes Adobe specific markers <see href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#Adobe"/>
|
||||
|
/// </summary>
|
||||
|
public static readonly byte[] AdobeMarker = ToAsciiBytes("Adobe"); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a value indicating whether the passed bytes are a match to the profile identifer
|
||||
|
/// </summary>
|
||||
|
/// <param name="bytesToCheck">The bytes to check</param>
|
||||
|
/// <param name="profileIdentifier">The profile identifier</param>
|
||||
|
/// <returns>The <see cref="bool"/></returns>
|
||||
|
public static bool IsProfile(Span<byte> bytesToCheck, Span<byte> profileIdentifier) |
||||
|
{ |
||||
|
return bytesToCheck.Length >= profileIdentifier.Length |
||||
|
&& bytesToCheck.Slice(0, profileIdentifier.Length).SequenceEqual(profileIdentifier); |
||||
|
} |
||||
|
|
||||
|
// No Encoding.ASCII nor Linq.Select on NetStandard 1.1
|
||||
|
private static byte[] ToAsciiBytes(string str) |
||||
|
{ |
||||
|
int length = str.Length; |
||||
|
byte[] bytes = new byte[length]; |
||||
|
char[] chars = str.ToCharArray(); |
||||
|
for (int i = 0; i < length; i++) |
||||
|
{ |
||||
|
bytes[i] = (byte)chars[i]; |
||||
|
} |
||||
|
|
||||
|
return bytes; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,72 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
// ReSharper disable InconsistentNaming
|
|
||||
namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides information about the Adobe marker segment
|
|
||||
/// </summary>
|
|
||||
internal struct PdfJsAdobe : IEquatable<PdfJsAdobe> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The DCT Encode Version
|
|
||||
/// </summary>
|
|
||||
public short DCTEncodeVersion; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 0x0 : (none)
|
|
||||
/// Bit 15 : Encoded with Blend=1 downsampling
|
|
||||
/// </summary>
|
|
||||
public short APP14Flags0; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 0x0 : (none)
|
|
||||
/// </summary>
|
|
||||
public short APP14Flags1; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Determines the colorspace transform
|
|
||||
/// 00 : Unknown (RGB or CMYK)
|
|
||||
/// 01 : YCbCr
|
|
||||
/// 02 : YCCK
|
|
||||
/// </summary>
|
|
||||
public byte ColorTransform; |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public bool Equals(PdfJsAdobe other) |
|
||||
{ |
|
||||
return this.DCTEncodeVersion == other.DCTEncodeVersion |
|
||||
&& this.APP14Flags0 == other.APP14Flags0 |
|
||||
&& this.APP14Flags1 == other.APP14Flags1 |
|
||||
&& this.ColorTransform == other.ColorTransform; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
if (ReferenceEquals(null, obj)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return obj is PdfJsAdobe && this.Equals((PdfJsAdobe)obj); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
unchecked |
|
||||
{ |
|
||||
// TODO: Merge and use HashCodeHelpers
|
|
||||
int hashCode = this.DCTEncodeVersion.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.APP14Flags0.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.APP14Flags1.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.ColorTransform.GetHashCode(); |
|
||||
return hashCode; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,77 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides information about the JFIF marker segment
|
|
||||
/// TODO: Thumbnail?
|
|
||||
/// </summary>
|
|
||||
internal struct PdfJsJFif : IEquatable<PdfJsJFif> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The major version
|
|
||||
/// </summary>
|
|
||||
public byte MajorVersion; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The minor version
|
|
||||
/// </summary>
|
|
||||
public byte MinorVersion; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Units for the following pixel density fields
|
|
||||
/// 00 : No units; width:height pixel aspect ratio = Ydensity:Xdensity
|
|
||||
/// 01 : Pixels per inch (2.54 cm)
|
|
||||
/// 02 : Pixels per centimeter
|
|
||||
/// </summary>
|
|
||||
public byte DensityUnits; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Horizontal pixel density. Must not be zero.
|
|
||||
/// </summary>
|
|
||||
public short XDensity; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Vertical pixel density. Must not be zero.
|
|
||||
/// </summary>
|
|
||||
public short YDensity; |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public bool Equals(PdfJsJFif other) |
|
||||
{ |
|
||||
return this.MajorVersion == other.MajorVersion |
|
||||
&& this.MinorVersion == other.MinorVersion |
|
||||
&& this.DensityUnits == other.DensityUnits |
|
||||
&& this.XDensity == other.XDensity |
|
||||
&& this.YDensity == other.YDensity; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
if (ReferenceEquals(null, obj)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return obj is PdfJsJFif && this.Equals((PdfJsJFif)obj); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
unchecked |
|
||||
{ |
|
||||
int hashCode = this.MajorVersion.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.MinorVersion.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.DensityUnits.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.XDensity.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.YDensity.GetHashCode(); |
|
||||
return hashCode; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,82 @@ |
|||||
|
// 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.Common.Decoder; |
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
public class AdobeMarkerTests |
||||
|
{ |
||||
|
// Taken from actual test image
|
||||
|
private readonly byte[] bytes = { 0x41, 0x64, 0x6F, 0x62, 0x65, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x2 }; |
||||
|
|
||||
|
// Altered components
|
||||
|
private readonly byte[] bytes2 = { 0x41, 0x64, 0x6F, 0x62, 0x65, 0x0, 0x64, 0x0, 0x0, 0x1, 0x1, 0x1 }; |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerLengthIsCorrect() |
||||
|
{ |
||||
|
Assert.Equal(12, AdobeMarker.Length); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerReturnsCorrectParsedValue() |
||||
|
{ |
||||
|
bool isAdobe = AdobeMarker.TryParse(this.bytes, out var marker); |
||||
|
|
||||
|
Assert.True(isAdobe); |
||||
|
Assert.Equal(100, marker.DCTEncodeVersion); |
||||
|
Assert.Equal(0, marker.APP14Flags0); |
||||
|
Assert.Equal(0, marker.APP14Flags1); |
||||
|
Assert.Equal(OrigJpegConstants.Adobe.ColorTransformYcck, marker.ColorTransform); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerIgnoresIncorrectValue() |
||||
|
{ |
||||
|
bool isAdobe = AdobeMarker.TryParse(new byte[] { 0, 0, 0, 0 }, out var marker); |
||||
|
|
||||
|
Assert.False(isAdobe); |
||||
|
Assert.Equal(default(AdobeMarker), marker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerEqualityIsCorrect() |
||||
|
{ |
||||
|
AdobeMarker.TryParse(this.bytes, out var marker); |
||||
|
AdobeMarker.TryParse(this.bytes, out var marker2); |
||||
|
|
||||
|
Assert.True(marker.Equals(marker2)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerInEqualityIsCorrect() |
||||
|
{ |
||||
|
AdobeMarker.TryParse(this.bytes, out var marker); |
||||
|
AdobeMarker.TryParse(this.bytes2, out var marker2); |
||||
|
|
||||
|
Assert.False(marker.Equals(marker2)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerHashCodeIsReplicable() |
||||
|
{ |
||||
|
AdobeMarker.TryParse(this.bytes, out var marker); |
||||
|
AdobeMarker.TryParse(this.bytes, out var marker2); |
||||
|
|
||||
|
Assert.True(marker.GetHashCode().Equals(marker2.GetHashCode())); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerHashCodeIsUnique() |
||||
|
{ |
||||
|
AdobeMarker.TryParse(this.bytes, out var marker); |
||||
|
AdobeMarker.TryParse(this.bytes2, out var marker2); |
||||
|
|
||||
|
Assert.False(marker.GetHashCode().Equals(marker2.GetHashCode())); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,95 @@ |
|||||
|
// 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.Common.Decoder; |
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
public class JFifMarkerTests |
||||
|
{ |
||||
|
// Taken from actual test image
|
||||
|
private readonly byte[] bytes = { 0x4A, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x1, 0x0, 0x60, 0x0, 0x60, 0x0 }; |
||||
|
|
||||
|
// Altered components
|
||||
|
private readonly byte[] bytes2 = { 0x4A, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x1, 0x0, 0x48, 0x0, 0x48, 0x0 }; |
||||
|
|
||||
|
// Incorrect density values. Zero is invalid.
|
||||
|
private readonly byte[] bytes3 = { 0x4A, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0 }; |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerLengthIsCorrect() |
||||
|
{ |
||||
|
Assert.Equal(13, JFifMarker.Length); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerReturnsCorrectParsedValue() |
||||
|
{ |
||||
|
bool isJFif = JFifMarker.TryParse(this.bytes, out var marker); |
||||
|
|
||||
|
Assert.True(isJFif); |
||||
|
Assert.Equal(1, marker.MajorVersion); |
||||
|
Assert.Equal(1, marker.MinorVersion); |
||||
|
Assert.Equal(1, marker.DensityUnits); |
||||
|
Assert.Equal(96, marker.XDensity); |
||||
|
Assert.Equal(96, marker.YDensity); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerIgnoresIncorrectValue() |
||||
|
{ |
||||
|
bool isJFif = JFifMarker.TryParse(new byte[] { 0, 0, 0, 0 }, out var marker); |
||||
|
|
||||
|
Assert.False(isJFif); |
||||
|
Assert.Equal(default(JFifMarker), marker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerIgnoresCorrectHeaderButInvalidDensities() |
||||
|
{ |
||||
|
bool isJFif = JFifMarker.TryParse(this.bytes3, out var marker); |
||||
|
|
||||
|
Assert.False(isJFif); |
||||
|
Assert.Equal(default(JFifMarker), marker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerEqualityIsCorrect() |
||||
|
{ |
||||
|
JFifMarker.TryParse(this.bytes, out var marker); |
||||
|
JFifMarker.TryParse(this.bytes, out var marker2); |
||||
|
|
||||
|
Assert.True(marker.Equals(marker2)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerInEqualityIsCorrect() |
||||
|
{ |
||||
|
JFifMarker.TryParse(this.bytes, out var marker); |
||||
|
JFifMarker.TryParse(this.bytes2, out var marker2); |
||||
|
|
||||
|
Assert.False(marker.Equals(marker2)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerHashCodeIsReplicable() |
||||
|
{ |
||||
|
JFifMarker.TryParse(this.bytes, out var marker); |
||||
|
JFifMarker.TryParse(this.bytes, out var marker2); |
||||
|
|
||||
|
Assert.True(marker.GetHashCode().Equals(marker2.GetHashCode())); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MarkerHashCodeIsUnique() |
||||
|
{ |
||||
|
JFifMarker.TryParse(this.bytes, out var marker); |
||||
|
JFifMarker.TryParse(this.bytes2, out var marker2); |
||||
|
|
||||
|
Assert.False(marker.GetHashCode().Equals(marker2.GetHashCode())); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Formats.Jpg |
||||
|
{ |
||||
|
using System.Text; |
||||
|
|
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
public class ProfileResolverTests |
||||
|
{ |
||||
|
private static readonly byte[] JFifMarker = Encoding.ASCII.GetBytes("JFIF\0"); |
||||
|
private static readonly byte[] ExifMarker = Encoding.ASCII.GetBytes("Exif\0\0"); |
||||
|
private static readonly byte[] IccMarker = Encoding.ASCII.GetBytes("ICC_PROFILE\0"); |
||||
|
private static readonly byte[] AdobeMarker = Encoding.ASCII.GetBytes("Adobe"); |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverHasCorrectJFifMarker() |
||||
|
{ |
||||
|
Assert.Equal(JFifMarker, ProfileResolver.JFifMarker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverHasCorrectExifMarker() |
||||
|
{ |
||||
|
Assert.Equal(ExifMarker, ProfileResolver.ExifMarker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverHasCorrectIccMarker() |
||||
|
{ |
||||
|
Assert.Equal(IccMarker, ProfileResolver.IccMarker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverHasCorrectAdobeMarker() |
||||
|
{ |
||||
|
Assert.Equal(AdobeMarker, ProfileResolver.AdobeMarker); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverCanResolveJFifMarker() |
||||
|
{ |
||||
|
Assert.True(ProfileResolver.IsProfile(JFifMarker, ProfileResolver.JFifMarker)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverCanResolveExifMarker() |
||||
|
{ |
||||
|
Assert.True(ProfileResolver.IsProfile(ExifMarker, ProfileResolver.ExifMarker)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverCanResolveIccMarker() |
||||
|
{ |
||||
|
Assert.True(ProfileResolver.IsProfile(IccMarker, ProfileResolver.IccMarker)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverCanResolveAdobeMarker() |
||||
|
{ |
||||
|
Assert.True(ProfileResolver.IsProfile(AdobeMarker, ProfileResolver.AdobeMarker)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverCorrectlyReportsNonMarker() |
||||
|
{ |
||||
|
Assert.False(ProfileResolver.IsProfile(IccMarker, ProfileResolver.AdobeMarker)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ProfileResolverCanHandleIncorrectLength() |
||||
|
{ |
||||
|
Assert.False(ProfileResolver.IsProfile(AdobeMarker, ProfileResolver.IccMarker)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue