From 9eaeecfae9769094a6636861f064ee9f2932c6f6 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Wed, 22 Apr 2020 12:17:33 +0200 Subject: [PATCH 01/13] Add tests for setting iptc value with strict option disabled --- .../Metadata/Profiles/IPTC/IptcProfile.cs | 2 +- .../Profiles/IPTC/IptcProfileTests.cs | 36 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs index 9206e4377..f138cc650 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc public IptcProfile DeepClone() => new IptcProfile(this); /// - /// Returns all value with the specified tag. + /// Returns all values with the specified tag. /// /// The tag of the iptc value. /// The values found with the specified tag. diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/IPTC/IptcProfileTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/IPTC/IptcProfileTests.cs index d9f44cef9..3baea45d6 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/IPTC/IptcProfileTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/IPTC/IptcProfileTests.cs @@ -25,8 +25,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.IPTC } [Theory] - [MemberData("AllIptcTags")] - public void IptcProfile_SetValue_WithStrictOption_Works(IptcTag tag) + [MemberData(nameof(AllIptcTags))] + public void IptcProfile_SetValue_WithStrictEnabled_Works(IptcTag tag) { // arrange var profile = new IptcProfile(); @@ -41,6 +41,23 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.IPTC Assert.Equal(expectedLength, actual.Value.Length); } + [Theory] + [MemberData(nameof(AllIptcTags))] + public void IptcProfile_SetValue_WithStrictDisabled_Works(IptcTag tag) + { + // arrange + var profile = new IptcProfile(); + var value = new string('s', tag.MaxLength() + 1); + var expectedLength = value.Length; + + // act + profile.SetValue(tag, value, false); + + // assert + IptcValue actual = profile.GetValues(tag).First(); + Assert.Equal(expectedLength, actual.Value.Length); + } + [Theory] [InlineData(IptcTag.DigitalCreationDate)] [InlineData(IptcTag.ExpirationDate)] @@ -199,13 +216,6 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.IPTC ContainsIptcValue(iptcValues, IptcTag.Caption, expectedCaption); } - [Fact] - public void IptcProfile_SetNewValue_RespectsMaxLength() - { - // arrange - var profile = new IptcProfile(); - } - [Theory] [InlineData(IptcTag.ObjectAttribute)] [InlineData(IptcTag.SubjectReference)] @@ -292,7 +302,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.IPTC [Fact] public void IptcProfile_RemoveByTag_RemovesAllEntrys() { - // arange + // arrange var profile = new IptcProfile(); profile.SetValue(IptcTag.Byline, "test"); profile.SetValue(IptcTag.Byline, "test2"); @@ -308,7 +318,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.IPTC [Fact] public void IptcProfile_RemoveByTagAndValue_Works() { - // arange + // arrange var profile = new IptcProfile(); profile.SetValue(IptcTag.Byline, "test"); profile.SetValue(IptcTag.Byline, "test2"); @@ -322,9 +332,9 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.IPTC } [Fact] - public void IptcProfile_GetValue_RetrievesAllEntrys() + public void IptcProfile_GetValue_RetrievesAllEntries() { - // arange + // arrange var profile = new IptcProfile(); profile.SetValue(IptcTag.Byline, "test"); profile.SetValue(IptcTag.Byline, "test2"); From cbab62dac3a56224f1c7dab2d95bfc28bbfba5a3 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Apr 2020 15:21:14 +0100 Subject: [PATCH 02/13] Capture and throw degenerate matrices. --- .../Exceptions/ImageProcessingException.cs | 13 ++++-- .../Processing/AffineTransformBuilder.cs | 9 +++- .../DegenerateTransformException.cs | 42 +++++++++++++++++++ .../Transforms/TransformUtilities.cs | 29 +++++++++++++ .../Processing/ProjectiveTransformBuilder.cs | 9 +++- .../Transforms/AffineTransformBuilderTests.cs | 7 ++-- .../ProjectiveTransformBuilderTests.cs | 23 ++++++---- .../Transforms/TransformBuilderTestBase.cs | 34 +++++++++------ 8 files changed, 136 insertions(+), 30 deletions(-) create mode 100644 src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs diff --git a/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs b/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs index 3c75a6418..c254eaeb3 100644 --- a/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs +++ b/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; @@ -8,8 +8,15 @@ namespace SixLabors.ImageSharp /// /// The exception that is thrown when an error occurs when applying a process to an image. /// - public sealed class ImageProcessingException : Exception + public class ImageProcessingException : Exception { + /// + /// Initializes a new instance of the class. + /// + public ImageProcessingException() + { + } + /// /// Initializes a new instance of the class with the name of the /// parameter that causes this exception. @@ -32,4 +39,4 @@ namespace SixLabors.ImageSharp { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index dde7beb3e..51a110dfc 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; @@ -284,6 +284,11 @@ namespace SixLabors.ImageSharp.Processing matrix *= factory(size); } + if (TransformUtilities.IsNaN(matrix)) + { + throw new DegenerateTransformException("Matrix is NaN. Check input values."); + } + return matrix; } @@ -299,4 +304,4 @@ namespace SixLabors.ImageSharp.Processing return this; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs b/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs new file mode 100644 index 000000000..970a044dc --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs @@ -0,0 +1,42 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; + +namespace SixLabors.ImageSharp.Processing.Processors.Transforms +{ + /// + /// Represents an error that occurs during a transform operation. + /// + public sealed class DegenerateTransformException : ImageProcessingException + { + /// + /// Initializes a new instance of the class. + /// + public DegenerateTransformException() + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The message that describes the error. + public DegenerateTransformException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message and a reference to the inner exception that is + /// the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference ( in Visual Basic) if no inner exception is specified. + public DegenerateTransformException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs index 0760d2e3e..329d57f3d 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs @@ -12,6 +12,35 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal static class TransformUtilities { + /// + /// Returns a value that indicates whether the specified matrix contains any values + /// that are not a number . + /// + /// The transform matrix. + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public static bool IsNaN(Matrix3x2 matrix) + { + return float.IsNaN(matrix.M11) || float.IsNaN(matrix.M12) + || float.IsNaN(matrix.M21) || float.IsNaN(matrix.M22) + || float.IsNaN(matrix.M31) || float.IsNaN(matrix.M32); + } + + /// + /// Returns a value that indicates whether the specified matrix contains any values + /// that are not a number . + /// + /// The transform matrix. + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public static bool IsNaN(Matrix4x4 matrix) + { + return float.IsNaN(matrix.M11) || float.IsNaN(matrix.M12) || float.IsNaN(matrix.M13) || float.IsNaN(matrix.M14) + || float.IsNaN(matrix.M21) || float.IsNaN(matrix.M22) || float.IsNaN(matrix.M23) || float.IsNaN(matrix.M24) + || float.IsNaN(matrix.M31) || float.IsNaN(matrix.M32) || float.IsNaN(matrix.M33) || float.IsNaN(matrix.M34) + || float.IsNaN(matrix.M41) || float.IsNaN(matrix.M42) || float.IsNaN(matrix.M43) || float.IsNaN(matrix.M44); + } + /// /// Applies the projective transform against the given coordinates flattened into the 2D space. /// diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index ef44dc16d..caebc34a3 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; @@ -300,6 +300,11 @@ namespace SixLabors.ImageSharp.Processing matrix *= factory(size); } + if (TransformUtilities.IsNaN(matrix)) + { + throw new DegenerateTransformException("Matrix is NaN. Check input values."); + } + return matrix; } @@ -315,4 +320,4 @@ namespace SixLabors.ImageSharp.Processing return this; } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index 42017f3af..70b5be73e 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System.Numerics; @@ -8,7 +8,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { public class AffineTransformBuilderTests : TransformBuilderTestBase { - protected override AffineTransformBuilder CreateBuilder(Rectangle rectangle) => new AffineTransformBuilder(); + protected override AffineTransformBuilder CreateBuilder() + => new AffineTransformBuilder(); protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); @@ -67,4 +68,4 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms return Vector2.Transform(sourcePoint, matrix); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 309a73fb4..22388a0ac 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -1,6 +1,7 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using SixLabors.ImageSharp.Processing; @@ -8,20 +9,25 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { public class ProjectiveTransformBuilderTests : TransformBuilderTestBase { - protected override ProjectiveTransformBuilder CreateBuilder(Rectangle rectangle) => new ProjectiveTransformBuilder(); + protected override ProjectiveTransformBuilder CreateBuilder() + => new ProjectiveTransformBuilder(); - protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); + protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees) + => builder.AppendRotationDegrees(degrees); - protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees, Vector2 origin) => builder.AppendRotationDegrees(degrees, origin); + protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees, Vector2 origin) + => builder.AppendRotationDegrees(degrees, origin); - protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) + => builder.AppendRotationRadians(radians); - protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) => builder.AppendRotationRadians(radians, origin); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) + => builder.AppendRotationRadians(radians, origin); protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); protected override void AppendSkewDegrees(ProjectiveTransformBuilder builder, float degreesX, float degreesY) - => builder.AppendSkewDegrees(degreesX, degreesY); + => builder.AppendSkewDegrees(degreesX, degreesY); protected override void AppendSkewDegrees(ProjectiveTransformBuilder builder, float degreesX, float degreesY, Vector2 origin) => builder.AppendSkewDegrees(degreesX, degreesY, origin); @@ -44,7 +50,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected override void PrependSkewRadians(ProjectiveTransformBuilder builder, float radiansX, float radiansY, Vector2 origin) => builder.PrependSkewRadians(radiansX, radiansY, origin); - protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) + => builder.PrependTranslation(translate); protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) => builder.PrependRotationRadians(radians, origin); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index 21359799e..8c75cea7f 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { // These operations should be size-agnostic: var size = new Size(123, 321); - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); this.AppendScale(builder, new SizeF(scale)); this.AppendTranslation(builder, translate); @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { // Translate ans scale are size-agnostic: var size = new Size(456, 432); - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); this.AppendTranslation(builder, translate); this.AppendScale(builder, new SizeF(scale)); @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void LocationOffsetIsPrepended(int locationX, int locationY) { var rectangle = new Rectangle(locationX, locationY, 10, 10); - TBuilder builder = this.CreateBuilder(rectangle); + TBuilder builder = this.CreateBuilder(); this.AppendScale(builder, new SizeF(2, 2)); @@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms float y) { var size = new Size(width, height); - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); this.AppendRotationDegrees(builder, degrees); @@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms float y) { var size = new Size(width, height); - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); var centerPoint = new Vector2(cx, cy); this.AppendRotationDegrees(builder, degrees, centerPoint); @@ -149,7 +149,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms float y) { var size = new Size(width, height); - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); this.AppendSkewDegrees(builder, degreesX, degreesY); @@ -176,7 +176,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms float y) { var size = new Size(width, height); - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); var centerPoint = new Vector2(cx, cy); this.AppendSkewDegrees(builder, degreesX, degreesY, centerPoint); @@ -194,8 +194,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void AppendPrependOpposite() { var rectangle = new Rectangle(-1, -1, 3, 3); - TBuilder b1 = this.CreateBuilder(rectangle); - TBuilder b2 = this.CreateBuilder(rectangle); + TBuilder b1 = this.CreateBuilder(); + TBuilder b2 = this.CreateBuilder(); const float pi = (float)Math.PI; @@ -232,14 +232,24 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Assert.ThrowsAny( () => { - TBuilder builder = this.CreateBuilder(size); + TBuilder builder = this.CreateBuilder(); this.Execute(builder, new Rectangle(Point.Empty, size), Vector2.Zero); }); } - protected TBuilder CreateBuilder(Size size) => this.CreateBuilder(new Rectangle(Point.Empty, size)); + [Fact] + public void ThrowsForInvalidMatrix() + { + Assert.ThrowsAny( + () => + { + TBuilder builder = this.CreateBuilder(); + this.AppendSkewDegrees(builder, 45, 45); + this.Execute(builder, new Rectangle(0, 0, 150, 150), Vector2.Zero); + }); + } - protected abstract TBuilder CreateBuilder(Rectangle rectangle); + protected abstract TBuilder CreateBuilder(); protected abstract void AppendRotationDegrees(TBuilder builder, float degrees); From a8d2d1f8520302a9a622787a7125a826806bf741 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Apr 2020 15:25:09 +0100 Subject: [PATCH 03/13] Add exception docs. --- src/ImageSharp/Processing/AffineTransformBuilder.cs | 3 +++ src/ImageSharp/Processing/ProjectiveTransformBuilder.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 51a110dfc..c7007679f 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -268,6 +268,9 @@ namespace SixLabors.ImageSharp.Processing /// Returns the combined matrix for a given source rectangle. /// /// The rectangle in the source image. + /// + /// The resultant matrix contains one or more values equivalent to . + /// /// The . public Matrix3x2 BuildMatrix(Rectangle sourceRectangle) { diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index caebc34a3..a407074aa 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -284,6 +284,9 @@ namespace SixLabors.ImageSharp.Processing /// Returns the combined matrix for a given source rectangle. /// /// The rectangle in the source image. + /// + /// The resultant matrix contains one or more values equivalent to . + /// /// The . public Matrix4x4 BuildMatrix(Rectangle sourceRectangle) { From 562b3b9f4a905e3d19a4a502f878b51e818882a3 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Apr 2020 22:57:56 +0100 Subject: [PATCH 04/13] Check determinant and update error message. --- src/ImageSharp/Processing/AffineTransformBuilder.cs | 4 ++-- src/ImageSharp/Processing/ProjectiveTransformBuilder.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index c7007679f..d793c67a2 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -287,9 +287,9 @@ namespace SixLabors.ImageSharp.Processing matrix *= factory(size); } - if (TransformUtilities.IsNaN(matrix)) + if (TransformUtilities.IsNaN(matrix) || matrix.GetDeterminant() == 0) { - throw new DegenerateTransformException("Matrix is NaN. Check input values."); + throw new DegenerateTransformException("Matrix is degenerate. Check input values."); } return matrix; diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index a407074aa..0535eaeb1 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -303,9 +303,9 @@ namespace SixLabors.ImageSharp.Processing matrix *= factory(size); } - if (TransformUtilities.IsNaN(matrix)) + if (TransformUtilities.IsNaN(matrix) || matrix.GetDeterminant() == 0) { - throw new DegenerateTransformException("Matrix is NaN. Check input values."); + throw new DegenerateTransformException("Matrix is degenerate. Check input values."); } return matrix; From ff28048fa397cfb192c4aad2c168e7f776f0c657 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Apr 2020 23:55:26 +0100 Subject: [PATCH 05/13] Remove inheritance --- src/ImageSharp/Common/Exceptions/ImageProcessingException.cs | 2 +- .../Processors/Transforms/DegenerateTransformException.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs b/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs index c254eaeb3..ccd0b71e5 100644 --- a/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs +++ b/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp /// /// The exception that is thrown when an error occurs when applying a process to an image. /// - public class ImageProcessingException : Exception + public sealed class ImageProcessingException : Exception { /// /// Initializes a new instance of the class. diff --git a/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs b/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs index 970a044dc..4d46540bc 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/DegenerateTransformException.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Represents an error that occurs during a transform operation. /// - public sealed class DegenerateTransformException : ImageProcessingException + public sealed class DegenerateTransformException : Exception { /// /// Initializes a new instance of the class. From f21af373213efc6263fb5eb2301eae1384411e20 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Apr 2020 23:56:26 +0100 Subject: [PATCH 06/13] Add determinant check and update check location/message --- .../Processing/AffineTransformBuilder.cs | 37 ++++++++++++++--- .../Transforms/TransformUtilities.cs | 22 ++++++++++ .../Processing/ProjectiveTransformBuilder.cs | 41 +++++++++++++++---- 3 files changed, 87 insertions(+), 13 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index d793c67a2..1478d2951 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -247,15 +247,33 @@ namespace SixLabors.ImageSharp.Processing /// Prepends a raw matrix. /// /// The matrix to prepend. + /// + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. + /// /// The . - public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) => this.Prepend(_ => matrix); + public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) + { + CheckDegenerate(matrix); + return this.Prepend(_ => matrix); + } /// /// Appends a raw matrix. /// /// The matrix to append. + /// + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. + /// /// The . - public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) => this.Append(_ => matrix); + public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) + { + CheckDegenerate(matrix); + return this.Append(_ => matrix); + } /// /// Returns the combined matrix for a given source size. @@ -269,7 +287,9 @@ namespace SixLabors.ImageSharp.Processing /// /// The rectangle in the source image. /// - /// The resultant matrix contains one or more values equivalent to . + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. /// /// The . public Matrix3x2 BuildMatrix(Rectangle sourceRectangle) @@ -287,12 +307,17 @@ namespace SixLabors.ImageSharp.Processing matrix *= factory(size); } - if (TransformUtilities.IsNaN(matrix) || matrix.GetDeterminant() == 0) + CheckDegenerate(matrix); + + return matrix; + } + + private static void CheckDegenerate(Matrix3x2 matrix) + { + if (TransformUtilities.IsDegenerate(matrix)) { throw new DegenerateTransformException("Matrix is degenerate. Check input values."); } - - return matrix; } private AffineTransformBuilder Prepend(Func factory) diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs index 329d57f3d..b474b4371 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs @@ -12,6 +12,28 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal static class TransformUtilities { + /// + /// Returns a value that indicates whether the specified matrix is degenerate + /// containing one or more values equivalent to or a + /// zero determinant and therefore cannot be used for linear transforms. + /// + /// The transform matrix. + public static bool IsDegenerate(Matrix3x2 matrix) + => IsNaN(matrix) || IsZero(matrix.GetDeterminant()); + + /// + /// Returns a value that indicates whether the specified matrix is degenerate + /// containing one or more values equivalent to or a + /// zero determinant and therefore cannot be used for linear transforms. + /// + /// The transform matrix. + public static bool IsDegenerate(Matrix4x4 matrix) + => IsNaN(matrix) || IsZero(matrix.GetDeterminant()); + + [MethodImpl(InliningOptions.ShortMethod)] + private static bool IsZero(float a) + => a > -Constants.EpsilonSquared && a < Constants.EpsilonSquared; + /// /// Returns a value that indicates whether the specified matrix contains any values /// that are not a number . diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 0535eaeb1..b7e65b4cc 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Numerics; +using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Processing.Processors.Transforms; namespace SixLabors.ImageSharp.Processing @@ -263,29 +264,50 @@ namespace SixLabors.ImageSharp.Processing /// Prepends a raw matrix. /// /// The matrix to prepend. + /// + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. + /// /// The . - public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) => this.Prepend(_ => matrix); + public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) + { + CheckDegenerate(matrix); + return this.Prepend(_ => matrix); + } /// /// Appends a raw matrix. /// /// The matrix to append. + /// + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. + /// /// The . - public ProjectiveTransformBuilder AppendMatrix(Matrix4x4 matrix) => this.Append(_ => matrix); + public ProjectiveTransformBuilder AppendMatrix(Matrix4x4 matrix) + { + CheckDegenerate(matrix); + return this.Append(_ => matrix); + } /// /// Returns the combined matrix for a given source size. /// /// The source image size. /// The . - public Matrix4x4 BuildMatrix(Size sourceSize) => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize)); + public Matrix4x4 BuildMatrix(Size sourceSize) + => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize)); /// /// Returns the combined matrix for a given source rectangle. /// /// The rectangle in the source image. /// - /// The resultant matrix contains one or more values equivalent to . + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. /// /// The . public Matrix4x4 BuildMatrix(Rectangle sourceRectangle) @@ -303,12 +325,17 @@ namespace SixLabors.ImageSharp.Processing matrix *= factory(size); } - if (TransformUtilities.IsNaN(matrix) || matrix.GetDeterminant() == 0) + CheckDegenerate(matrix); + + return matrix; + } + + private static void CheckDegenerate(Matrix4x4 matrix) + { + if (TransformUtilities.IsDegenerate(matrix)) { throw new DegenerateTransformException("Matrix is degenerate. Check input values."); } - - return matrix; } private ProjectiveTransformBuilder Prepend(Func factory) From 5415bde174f41e5a6b3fcf039af22a3897911a26 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 23 Apr 2020 10:01:33 +0200 Subject: [PATCH 07/13] Throw exception when malformed apple png chunk is detected (#410) --- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 272f93d10..757b08481 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -9,7 +9,7 @@ using System.IO.Compression; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using SixLabors.ImageSharp.Advanced; + using SixLabors.ImageSharp.Formats.Png.Chunks; using SixLabors.ImageSharp.Formats.Png.Filters; using SixLabors.ImageSharp.Formats.Png.Zlib; @@ -215,6 +215,9 @@ namespace SixLabors.ImageSharp.Formats.Png case PngChunkType.End: this.isEndChunkReached = true; break; + case PngChunkType.MalformedApple: + PngThrowHelper.ThrowInvalidChunkType("Malformed Apple PNG detected! This PNG file is not conform to the specification and cannot be decoded."); + break; } } finally @@ -1039,7 +1042,7 @@ namespace SixLabors.ImageSharp.Formats.Png var uncompressedBytes = new List(); - // Note: this uses the a buffer which is only 4 bytes long to read the stream, maybe allocating a larger buffer makes sense here. + // Note: this uses a buffer which is only 4 bytes long to read the stream, maybe allocating a larger buffer makes sense here. int bytesRead = inflateStream.CompressedStream.Read(this.buffer, 0, this.buffer.Length); while (bytesRead != 0) { From b394e0594e4ad50fe8835e7d46fbc4fa9cc4acd2 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 23 Apr 2020 13:05:52 +0200 Subject: [PATCH 08/13] Add additional chunk types --- src/ImageSharp/Formats/Png/PngChunkType.cs | 54 ++++++++++++++++++- .../Formats/Png/PngChunkTypeTests.cs | 27 +++++++--- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngChunkType.cs b/src/ImageSharp/Formats/Png/PngChunkType.cs index e41b49066..67e5ccf55 100644 --- a/src/ImageSharp/Formats/Png/PngChunkType.cs +++ b/src/ImageSharp/Formats/Png/PngChunkType.cs @@ -73,6 +73,58 @@ namespace SixLabors.ImageSharp.Formats.Png /// either alpha values associated with palette entries (for indexed-color images) /// or a single transparent color (for grayscale and true color images). /// - Transparency = 0x74524E53U + Transparency = 0x74524E53U, + + /// + /// The tIME chunk gives the time of the last image modification (not the time of initial image creation). + /// + Time = 0x74494d45, + + /// + /// The bKGD chunk specifies a default background colour to present the image against. + /// If there is any other preferred background, either user-specified or part of a larger page (as in a browser), + /// the bKGD chunk should be ignored. + /// + Background = 0x624b4744, + + /// + /// The iCCP chunk contains a embedded color profile. If the iCCP chunk is present, + /// the image samples conform to the colour space represented by the embedded ICC profile as defined by the International Color Consortium. + /// + EmbeddedColorProfile = 0x69434350, + + /// + /// The sBIT chunk defines the original number of significant bits (which can be less than or equal to the sample depth). + /// This allows PNG decoders to recover the original data losslessly even if the data had a sample depth not directly supported by PNG. + /// + SignificantBits = 0x73424954, + + /// + /// If the sRGB chunk is present, the image samples conform to the sRGB colour space [IEC 61966-2-1] and should be displayed + /// using the specified rendering intent defined by the International Color Consortium. + /// + StandardRgbColourSpace = 0x73524742, + + /// + /// The hIST chunk gives the approximate usage frequency of each colour in the palette. + /// + Histogram = 0x68495354, + + /// + /// The sPLT chunk contains the suggested palette. + /// + SuggestedPalette = 0x73504c54, + + /// + /// The cHRM chunk may be used to specify the 1931 CIE x,y chromaticities of the red, + /// green, and blue display primaries used in the image, and the referenced white point. + /// + Chroma = 0x6348524d, + + /// + /// Malformed chunk named CgBI produced by apple, which is not conform to the specification. + /// Related issue is here https://github.com/SixLabors/ImageSharp/issues/410 + /// + MalformedApple = 0x43674249 } } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs index 2e8c0de27..f3984ac82 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs @@ -13,15 +13,26 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [Fact] public void ChunkTypeIdsAreCorrect() { - Assert.Equal(PngChunkType.Header, GetType("IHDR")); - Assert.Equal(PngChunkType.Palette, GetType("PLTE")); - Assert.Equal(PngChunkType.Data, GetType("IDAT")); - Assert.Equal(PngChunkType.End, GetType("IEND")); + Assert.Equal(PngChunkType.Header, GetType("IHDR")); + Assert.Equal(PngChunkType.Palette, GetType("PLTE")); + Assert.Equal(PngChunkType.Data, GetType("IDAT")); + Assert.Equal(PngChunkType.End, GetType("IEND")); Assert.Equal(PngChunkType.Transparency, GetType("tRNS")); - Assert.Equal(PngChunkType.Text, GetType("tEXt")); - Assert.Equal(PngChunkType.Gamma, GetType("gAMA")); - Assert.Equal(PngChunkType.Physical, GetType("pHYs")); - Assert.Equal(PngChunkType.Exif, GetType("eXIf")); + Assert.Equal(PngChunkType.Text, GetType("tEXt")); + Assert.Equal(PngChunkType.InternationalText, GetType("iTXt")); + Assert.Equal(PngChunkType.CompressedText, GetType("zTXt")); + Assert.Equal(PngChunkType.Chroma, GetType("cHRM")); + Assert.Equal(PngChunkType.Gamma, GetType("gAMA")); + Assert.Equal(PngChunkType.Physical, GetType("pHYs")); + Assert.Equal(PngChunkType.Exif, GetType("eXIf")); + Assert.Equal(PngChunkType.Time, GetType("tIME")); + Assert.Equal(PngChunkType.Background, GetType("bKGD")); + Assert.Equal(PngChunkType.EmbeddedColorProfile, GetType("iCCP")); + Assert.Equal(PngChunkType.StandardRgbColourSpace, GetType("sRGB")); + Assert.Equal(PngChunkType.SignificantBits, GetType("sBIT")); + Assert.Equal(PngChunkType.Histogram, GetType("hIST")); + Assert.Equal(PngChunkType.SuggestedPalette, GetType("sPLT")); + Assert.Equal(PngChunkType.MalformedApple, GetType("CgBI")); } private static PngChunkType GetType(string text) From da35e847feb422f34d72948fa1d5498460cd5a00 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 23 Apr 2020 13:55:15 +0200 Subject: [PATCH 09/13] Add tests for jpg encoder preserving metadata --- .../Formats/Jpg/JpegEncoderTests.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index bb79abf54..6cbdb83fc 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -1,10 +1,14 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.Collections.Generic; using System.IO; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata; +using SixLabors.ImageSharp.Metadata.Profiles.Exif; +using SixLabors.ImageSharp.Metadata.Profiles.Icc; +using SixLabors.ImageSharp.Metadata.Profiles.Iptc; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; @@ -215,5 +219,70 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } } + + [Fact] + public void Encode_PreservesIptcProfile() + { + // arrange + using var input = new Image(1, 1); + input.Metadata.IptcProfile = new IptcProfile(); + input.Metadata.IptcProfile.SetValue(IptcTag.Byline, "unit_test"); + var encoder = new JpegEncoder(); + + // act + using var memStream = new MemoryStream(); + input.Save(memStream, encoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(memStream); + IptcProfile actual = output.Metadata.IptcProfile; + Assert.NotNull(actual); + IEnumerable values = input.Metadata.IptcProfile.Values; + Assert.Equal(values, actual.Values); + } + + [Fact] + public void Encode_PreservesExifProfile() + { + // arrange + using var input = new Image(1, 1); + input.Metadata.ExifProfile = new ExifProfile(); + input.Metadata.ExifProfile.SetValue(ExifTag.Software, "unit_test"); + var encoder = new JpegEncoder(); + + // act + using var memStream = new MemoryStream(); + input.Save(memStream, encoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(memStream); + ExifProfile actual = output.Metadata.ExifProfile; + Assert.NotNull(actual); + IReadOnlyList values = input.Metadata.ExifProfile.Values; + Assert.Equal(values, actual.Values); + } + + [Fact] + public void Encode_PreservesIccProfile() + { + // arrange + using var input = new Image(1, 1); + input.Metadata.IccProfile = new IccProfile(IccTestDataProfiles.Profile_Random_Array); + var encoder = new JpegEncoder(); + + // act + using var memStream = new MemoryStream(); + input.Save(memStream, encoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(memStream); + IccProfile actual = output.Metadata.IccProfile; + Assert.NotNull(actual); + IccProfile values = input.Metadata.IccProfile; + Assert.Equal(values.Entries, actual.Entries); + } } } From 67c4007d3d61207ca787a3f226c18f17a33d502a Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 23 Apr 2020 15:55:32 +0200 Subject: [PATCH 10/13] Additional png test cases --- src/ImageSharp/Formats/Png/PngThrowHelper.cs | 5 +- .../Formats/Png/PngDecoderTests.Chunks.cs | 15 ++ .../Formats/Png/PngDecoderTests.cs | 239 +++++++++++++----- tests/ImageSharp.Tests/TestImages.cs | 31 ++- tests/Images/Input/Png/basn3p01.png | Bin 0 -> 112 bytes tests/Images/Input/Png/basn3p02.png | Bin 0 -> 146 bytes tests/Images/Input/Png/basn3p04.png | Bin 0 -> 216 bytes tests/Images/Input/Png/basn3p08.png | Bin 0 -> 1286 bytes tests/Images/Input/Png/issues/Issue_410.png | Bin 0 -> 674 bytes tests/Images/Input/Png/xc1n0g08.png | Bin 0 -> 138 bytes tests/Images/Input/Png/xc9n2c08.png | Bin 0 -> 145 bytes tests/Images/Input/Png/xd0n2c08.png | Bin 0 -> 145 bytes tests/Images/Input/Png/xd3n2c08.png | Bin 0 -> 145 bytes tests/Images/Input/Png/xdtn0g01.png | Bin 0 -> 61 bytes 14 files changed, 220 insertions(+), 70 deletions(-) create mode 100644 tests/Images/Input/Png/basn3p01.png create mode 100644 tests/Images/Input/Png/basn3p02.png create mode 100644 tests/Images/Input/Png/basn3p04.png create mode 100644 tests/Images/Input/Png/basn3p08.png create mode 100644 tests/Images/Input/Png/issues/Issue_410.png create mode 100644 tests/Images/Input/Png/xc1n0g08.png create mode 100644 tests/Images/Input/Png/xc9n2c08.png create mode 100644 tests/Images/Input/Png/xd0n2c08.png create mode 100644 tests/Images/Input/Png/xd3n2c08.png create mode 100644 tests/Images/Input/Png/xdtn0g01.png diff --git a/src/ImageSharp/Formats/Png/PngThrowHelper.cs b/src/ImageSharp/Formats/Png/PngThrowHelper.cs index dcb643d03..b0a2571ea 100644 --- a/src/ImageSharp/Formats/Png/PngThrowHelper.cs +++ b/src/ImageSharp/Formats/Png/PngThrowHelper.cs @@ -20,11 +20,14 @@ namespace SixLabors.ImageSharp.Formats.Png [MethodImpl(InliningOptions.ColdPath)] public static void ThrowInvalidChunkType() => throw new InvalidImageContentException("Invalid PNG data."); + [MethodImpl(InliningOptions.ColdPath)] + public static void ThrowInvalidChunkType(string message) => throw new InvalidImageContentException(message); + [MethodImpl(InliningOptions.ColdPath)] public static void ThrowInvalidChunkCrc(string chunkTypeName) => throw new InvalidImageContentException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!"); [MethodImpl(InliningOptions.ColdPath)] - public static void ThrowNotSupportedColor() => new NotSupportedException("Unsupported PNG color type"); + public static void ThrowNotSupportedColor() => throw new NotSupportedException("Unsupported PNG color type"); [MethodImpl(InliningOptions.ColdPath)] public static void ThrowUnknownFilter() => throw new InvalidImageContentException("Unknown filter type."); diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs index 297512fa6..6cefff95d 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs @@ -6,6 +6,7 @@ using System.IO; using System.Text; using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.Formats.Png.Zlib; using SixLabors.ImageSharp.PixelFormats; using Xunit; @@ -78,6 +79,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } } + [Fact] + public void CalculateCrc_Works() + { + // arrange + var data = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; + var crc = new Crc32(); + + // act + crc.Update(data); + + // assert + Assert.Equal(0x88AA689F, crc.Value); + } + private static string GetChunkTypeName(uint value) { var data = new byte[4]; diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index b08025f53..c4b5d0b4b 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -4,7 +4,6 @@ using System.IO; using Microsoft.DotNet.RemoteExecutor; -using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -26,62 +25,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png public static readonly string[] CommonTestImages = { TestImages.Png.Splash, - TestImages.Png.Indexed, TestImages.Png.FilterVar, - TestImages.Png.Bad.ChunkLength1, - TestImages.Png.Bad.CorruptedChunk, TestImages.Png.VimImage1, + TestImages.Png.VimImage2, TestImages.Png.VersioningImage1, TestImages.Png.VersioningImage2, TestImages.Png.SnakeGame, - TestImages.Png.Banner7Adam7InterlaceMode, - TestImages.Png.Banner8Index, - - TestImages.Png.Bad.ChunkLength2, - TestImages.Png.VimImage2, TestImages.Png.Rgb24BppTrans, - TestImages.Png.GrayA8Bit, - TestImages.Png.Gray1BitTrans, - TestImages.Png.Bad.ZlibOverflow, - TestImages.Png.Bad.ZlibOverflow2, - TestImages.Png.Bad.ZlibZtxtBadHeader, - TestImages.Png.Bad.Issue1047_BadEndChunk - }; - - public static readonly string[] TestImages48Bpp = - { - TestImages.Png.Rgb48Bpp, - TestImages.Png.Rgb48BppInterlaced - }; - - public static readonly string[] TestImages64Bpp = - { - TestImages.Png.Rgba64Bpp, - TestImages.Png.Rgb48BppTrans - }; - - public static readonly string[] TestImagesL16Bit = - { - TestImages.Png.L16Bit, - }; - public static readonly string[] TestImagesGrayAlpha16Bit = - { - TestImages.Png.GrayAlpha16Bit, - TestImages.Png.GrayTrns16BitInterlaced + TestImages.Png.Bad.ChunkLength1, + TestImages.Png.Bad.ChunkLength2, }; - public static readonly string[] TestImagesL8BitInterlaced = - { - TestImages.Png.GrayAlpha1BitInterlaced, - TestImages.Png.GrayAlpha2BitInterlaced, - TestImages.Png.Gray4BitInterlaced, - TestImages.Png.GrayA8BitInterlaced - }; - public static readonly string[] TestImagesIssue1014 = { TestImages.Png.Issue1014_1, TestImages.Png.Issue1014_2, @@ -95,6 +53,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png TestImages.Png.Issue1177_2 }; + public static readonly string[] CorruptedTestImages = + { + TestImages.Png.Bad.CorruptedChunk, + TestImages.Png.Bad.ZlibOverflow, + TestImages.Png.Bad.ZlibOverflow2, + TestImages.Png.Bad.ZlibZtxtBadHeader, + }; + [Theory] [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32)] public void Decode(TestImageProvider provider) @@ -103,25 +69,28 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png using (Image image = provider.GetImage(PngDecoder)) { image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); + } + } - // We don't have another x-plat reference decoder that can be compared for this image. - if (provider.Utility.SourceFileOrDescription == TestImages.Png.Bad.Issue1047_BadEndChunk) - { - if (TestEnvironment.IsWindows) - { - image.CompareToOriginal(provider, ImageComparer.Exact, (IImageDecoder)SystemDrawingReferenceDecoder.Instance); - } - } - else - { - image.CompareToOriginal(provider, ImageComparer.Exact); - } + [Theory] + [WithFile(TestImages.Png.GrayA8Bit, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Gray1BitTrans, PixelTypes.Rgba32)] + public void Decode_GrayWithAlpha(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); } } [Theory] [WithFile(TestImages.Png.Interlaced, PixelTypes.Rgba32)] - public void Decode_Interlaced_ImageIsCorrect(TestImageProvider provider) + [WithFile(TestImages.Png.Banner7Adam7InterlaceMode, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Banner8Index, PixelTypes.Rgba32)] + public void Decode_Interlaced(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(PngDecoder)) @@ -132,7 +101,25 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } [Theory] - [WithFileCollection(nameof(TestImages48Bpp), PixelTypes.Rgb48)] + [WithFile(TestImages.Png.Indexed, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Banner8Index, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.PalettedTwoColor, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.PalettedFourColor, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.PalettedSixteenColor, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Paletted256Colors, PixelTypes.Rgba32)] + public void Decode_Indexed(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); + } + } + + [Theory] + [WithFile(TestImages.Png.Rgb48Bpp, PixelTypes.Rgb48)] + [WithFile(TestImages.Png.Rgb48BppInterlaced, PixelTypes.Rgb48)] public void Decode_48Bpp(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -144,7 +131,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } [Theory] - [WithFileCollection(nameof(TestImages64Bpp), PixelTypes.Rgba64)] + [WithFile(TestImages.Png.Rgba64Bpp, PixelTypes.Rgba64)] + [WithFile(TestImages.Png.Rgb48BppTrans, PixelTypes.Rgba64)] public void Decode_64Bpp(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -156,7 +144,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } [Theory] - [WithFileCollection(nameof(TestImagesL8BitInterlaced), PixelTypes.Rgba32)] + [WithFile(TestImages.Png.GrayAlpha1BitInterlaced, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.GrayAlpha2BitInterlaced, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Gray4BitInterlaced, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.GrayA8BitInterlaced, PixelTypes.Rgba32)] public void Decoder_L8bitInterlaced(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -168,7 +159,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } [Theory] - [WithFileCollection(nameof(TestImagesL16Bit), PixelTypes.Rgb48)] + [WithFile(TestImages.Png.L16Bit, PixelTypes.Rgb48)] public void Decode_L16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -180,7 +171,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } [Theory] - [WithFileCollection(nameof(TestImagesGrayAlpha16Bit), PixelTypes.Rgba64)] + [WithFile(TestImages.Png.GrayAlpha16Bit, PixelTypes.Rgba64)] + [WithFile(TestImages.Png.GrayTrns16BitInterlaced, PixelTypes.Rgba64)] public void Decode_GrayAlpha16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -193,7 +185,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [Theory] [WithFile(TestImages.Png.GrayA8BitInterlaced, PixelTypes)] - public void Decoder_CanDecodeGrey8bitWithAlpha(TestImageProvider provider) + public void Decoder_CanDecode_Grey8bitInterlaced_WithAlpha(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); + } + } + + [Theory] + [WithFileCollection(nameof(CorruptedTestImages), PixelTypes.Rgba32)] + public void Decoder_CanDecode_CorruptedImages(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(PngDecoder)) @@ -232,9 +236,63 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } } + [Theory] + [WithFile(TestImages.Png.Bad.MissingDataChunk, PixelTypes.Rgba32)] + public void Decode_MissingDataChunk_ThrowsException(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + } + }); + Assert.NotNull(ex); + Assert.Contains("PNG Image does not contain a data chunk", ex.Message); + } + + [Theory] + [WithFile(TestImages.Png.Bad.BitDepthZero, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Bad.BitDepthThree, PixelTypes.Rgba32)] + public void Decode_InvalidBitDepth_ThrowsException(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + } + }); + Assert.NotNull(ex); + Assert.Contains("Invalid or unsupported bit depth", ex.Message); + } + + [Theory] + [WithFile(TestImages.Png.Bad.ColorTypeOne, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Bad.ColorTypeNine, PixelTypes.Rgba32)] + public void Decode_InvalidColorType_ThrowsException(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + } + }); + Assert.NotNull(ex); + Assert.Contains("Invalid or unsupported color type", ex.Message); + } + + // https://github.com/SixLabors/ImageSharp/issues/1014 [Theory] [WithFileCollection(nameof(TestImagesIssue1014), PixelTypes.Rgba32)] - public void Issue1014(TestImageProvider provider) + public void Issue1014_DataSplitOverMultipleIDatChunks(TestImageProvider provider) where TPixel : unmanaged, IPixel { System.Exception ex = Record.Exception( @@ -249,9 +307,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png Assert.Null(ex); } + // https://github.com/SixLabors/ImageSharp/issues/1177 [Theory] [WithFileCollection(nameof(TestImagesIssue1177), PixelTypes.Rgba32)] - public void Issue1177(TestImageProvider provider) + public void Issue1177_CRC_Omitted(TestImageProvider provider) where TPixel : unmanaged, IPixel { System.Exception ex = Record.Exception( @@ -266,6 +325,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png Assert.Null(ex); } + // https://github.com/SixLabors/ImageSharp/issues/1127 [Theory] [WithFile(TestImages.Png.Issue1127, PixelTypes.Rgba32)] public void Issue1127(TestImageProvider provider) @@ -283,6 +343,53 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png Assert.Null(ex); } + // https://github.com/SixLabors/ImageSharp/issues/1047 + [Theory] + [WithFile(TestImages.Png.Bad.Issue1047_BadEndChunk, PixelTypes.Rgba32)] + public void Issue1047(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + + // We don't have another x-plat reference decoder that can be compared for this image. + if (TestEnvironment.IsWindows) + { + image.CompareToOriginal(provider, ImageComparer.Exact, SystemDrawingReferenceDecoder.Instance); + } + } + }); + Assert.Null(ex); + } + + // https://github.com/SixLabors/ImageSharp/issues/410 + [Theory] + [WithFile(TestImages.Png.Bad.Issue410_MalformedApplePng, PixelTypes.Rgba32)] + public void Issue410_MalformedApplePng(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + + // We don't have another x-plat reference decoder that can be compared for this image. + if (TestEnvironment.IsWindows) + { + image.CompareToOriginal(provider, ImageComparer.Exact, SystemDrawingReferenceDecoder.Instance); + } + } + }); + Assert.NotNull(ex); + Assert.Contains("Malformed Apple PNG detected!", ex.Message); + } + [Theory] [WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)] [WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 18fd84331..bec0c6624 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -65,6 +65,12 @@ namespace SixLabors.ImageSharp.Tests public const string Filter3 = "Png/filter3.png"; public const string Filter4 = "Png/filter4.png"; + // Paletted images also from http://www.schaik.com/pngsuite/pngsuite_fil_png.html + public const string PalettedTwoColor = "Png/basn3p01.png"; + public const string PalettedFourColor = "Png/basn3p02.png"; + public const string PalettedSixteenColor = "Png/basn3p04.png"; + public const string Paletted256Colors = "Png/basn3p08.png"; + // Filter changing per scanline public const string FilterVar = "Png/filterVar.png"; @@ -93,6 +99,8 @@ namespace SixLabors.ImageSharp.Tests public const string Issue1014_4 = "Png/issues/Issue_1014_4.png"; public const string Issue1014_5 = "Png/issues/Issue_1014_5.png"; public const string Issue1014_6 = "Png/issues/Issue_1014_6.png"; + + // Issue 1127: https://github.com/SixLabors/ImageSharp/issues/1127 public const string Issue1127 = "Png/issues/Issue_1127.png"; // Issue 1177: https://github.com/SixLabors/ImageSharp/issues/1177 @@ -101,14 +109,31 @@ namespace SixLabors.ImageSharp.Tests public static class Bad { - // Odd chunk lengths - public const string ChunkLength1 = "Png/chunklength1.png"; - public const string ChunkLength2 = "Png/chunklength2.png"; + public const string MissingDataChunk = "Png/xdtn0g01.png"; public const string CorruptedChunk = "Png/big-corrupted-chunk.png"; + + // Zlib errors. public const string ZlibOverflow = "Png/zlib-overflow.png"; public const string ZlibOverflow2 = "Png/zlib-overflow2.png"; public const string ZlibZtxtBadHeader = "Png/zlib-ztxt-bad-header.png"; + + // Odd chunk lengths + public const string ChunkLength1 = "Png/chunklength1.png"; + public const string ChunkLength2 = "Png/chunklength2.png"; + + // Issue 1047: https://github.com/SixLabors/ImageSharp/issues/1047 public const string Issue1047_BadEndChunk = "Png/issues/Issue_1047.png"; + + // Issue 410: https://github.com/SixLabors/ImageSharp/issues/410 + public const string Issue410_MalformedApplePng = "Png/issues/Issue_410.png"; + + // Bad bit depth. + public const string BitDepthZero = "Png/xd0n2c08.png"; + public const string BitDepthThree = "Png/xd3n2c08.png"; + + // Invalid color type. + public const string ColorTypeOne = "Png/xc1n0g08.png"; + public const string ColorTypeNine = "Png/xc9n2c08.png"; } public static readonly string[] All = diff --git a/tests/Images/Input/Png/basn3p01.png b/tests/Images/Input/Png/basn3p01.png new file mode 100644 index 0000000000000000000000000000000000000000..b145c2b8eff1f4298e540bfae5c1351d015a3592 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;SkfJR9T^zg78t&m77ygJ1^9%x zzWcAFl=eSI>XI5zMAXy8F{ENn@&k4zHj_up0tD0@h%3W?AY}Lt#0>va?X`CSX(dk=$B>FS$v@Vz>816FsF9(VN75txh7sS~8e>Vez z3y|e3}y1F=z>r=LEEca@LnZf*~BA0ROZ5~$d#4)lIa>n+tGAx#s~NCh;!h=Q?&7t5~~Lk>mL*|1x+L`Ivp6mn?kJ^kK$c6a~%|NrOteLPR)ru^*4 zh?oc>ipx)wHw!xP<||VqG2mh2yNQ1IZKr30Xr(I7PBXU z(o_;ftk^?X5O*qmM)+A^aUR*s!>r3PlcI=3mc_D63M-aHQVj83+hHDKi)~wG8A%eb zMRFVzAa0kL4aW(lxy(-(A3@r7{KRdCcI^9^ zBwSWlMY4uMp(p@%T`0C7K$rnonuoRmLY9xP#5bTx(RKJi zCYfG^*s^*-{Ro^e4Kgw{Dlmv)JpjQ5bKwF@CLI|%59=nhA>e#HJh5GNjRLr(&Jco- zL=roU($L^w70~)&xPh+uFV&-K!K0w3W-9Hy@g@HWXL3ML4|%5ULen8 zlT@|D2@;VI*iada4446_ptp_#Sul*Cx7Y6>PlSiq8TyN-q=y}cXZX&@20)p=ihIP{CfA$Z*4W@ zEr$zzJ<~t_(0G1&!T9U{_Iz>DPFy@Dgq4(i*+1}U*ZiG1m)32#<4sRFJ5!AP>yZ}L zzdq~5lB&|C6*=qgy?nj!is#SN$*Gwo6M?qJgKJtd1_tvb_xS3qJuRh&eH)f1f0J@< z)4uq(Z_li{H~+s=+3L-xjU7X)ZvEUC-CLA+t^7d7$jI)tsK~;c&XdnBOC5Txp}1)@ zusm-vWl2G`{dnN}K>pDE=;yi{rVB@Y3B-HrtGOePxNz#}j}FD`z3|nlwikX+ZZ56= zAY&lKTUG9w&2^VN89D}o5=^>%~&6ID5>`0fk%7K&zZcY&F#znJTW|E zB5&cFwM~ly35&;HdZq5*>W9rM<&V4Wr%mNt{B`@CxYpR8I;^7!?Tc=wu6t&Du2Ec< zKIiz-xXN3dttqGahAW20Qo6MzgSk7e_{!(?CKyw`*?j|NY=7wG%F`JaWZ(VOm8CUr z$$no_)1uMK%W6)nN!IrL6EB>puUj#i+1xg}<&qUPnY6#j4&NW^MpZNn{t+Cq+^l@L JEAySt{s-!kV`~5a literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Png/issues/Issue_410.png b/tests/Images/Input/Png/issues/Issue_410.png new file mode 100644 index 0000000000000000000000000000000000000000..ad3581fbba7ea9d157f10d0e68938cef35ef7465 GIT binary patch literal 674 zcmV;T0$u%yP)e@KzIrsU^ciGghC4n zI=}*>iC;y+$1TWuT&}r)NtW4}otfXx0&wKIt{X*Bl%{F=d_JGA50s{98bwj$x~>az zOV@RsQc7Pl3lUM*b$u2m4Z|?XvMgUeq^hba(=^R*pJY{4)$4~^lSM@A8>N&| zLI}|`O%t`JX_`g|A-po8l+ur!bR5U&8}mHRo2%}9-}n3Wce~wA*iaAzK|f+ik|Yru zT}nJ2k4I}O%d%{_TrQI&NxFLkK@b1{6h%?=DY4)0_uNhLJkPsE48t(yq{QKHI9Qft zb-(3#o&x~HaUAphp_I}uwcIpK(_JLXvOJX%QyP#l#$;KRyWg6oX#fDiFbu~i@!z4{ zZnvALqau`GjIq^fwGwso3nea>%SANxL)}aWA)C!+(_cT7`YDt^LM#=@zLP?sdH}!=ReJ?f8vJKaR2}S07*qo IM6N<$g7DNg_y7O^ literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Png/xc1n0g08.png b/tests/Images/Input/Png/xc1n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..940422737011509e21d5c02e879c643a83d360e6 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE2qfRFb@ByLEa{HEjtq=#3k+XOiwE)@JzX3_ zD&{1oB&aZmaGco8!^+yj&!PF_yS#lurGboy!70HB=_!jUV|dtDd-^||`uG3*kM?JU ih7v%T2UAm1SQrAH{wp+nbR!aI7=x#)pUXO@geCxzGb>{N literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Png/xc9n2c08.png b/tests/Images/Input/Png/xc9n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..b11c2a7b4049475d967a8cc76b93ef1039684a3a GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE2_&^8vlam5jgR42*3H3|~x(2l72UT^vIy z=DfXnkdwiHhsmM!&BVXki-fIRw7)F;aqgk^7G4(X1}>2wG7H{5sr9LFXk_B|YL`FM q!Y-omVL^$7@=Axs-38@~4=^@u{29mZaNZkeCWEJ|pUXO@geCyFeJ}z5 literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Png/xd3n2c08.png b/tests/Images/Input/Png/xd3n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..9e4a3ff7accf4453ddcd58318f7048b326b44ad2 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnP1SGpp+}Q-ASkfJR9T^zg78t&m77yfmc)B=- zRLpsM^&lsM0S}Wy>zj#xw-*UpyJ&w|_~YC|?Jc}4)(u=DKV%lXeNyXF;n2v$@6|4U rsD)ibc;6;z8n`u6{1- HoD!M<9fb>g literal 0 HcmV?d00001 From bc223bcd0b58a88791087f8bd14a50d60e7a770b Mon Sep 17 00:00:00 2001 From: Brian Popow <38701097+brianpopow@users.noreply.github.com> Date: Thu, 23 Apr 2020 18:20:18 +0200 Subject: [PATCH 11/13] Change CgBI chunk name to ProprietaryApple Co-Authored-By: James Jackson-South --- src/ImageSharp/Formats/Png/PngChunkType.cs | 2 +- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngChunkType.cs b/src/ImageSharp/Formats/Png/PngChunkType.cs index 67e5ccf55..015f6984d 100644 --- a/src/ImageSharp/Formats/Png/PngChunkType.cs +++ b/src/ImageSharp/Formats/Png/PngChunkType.cs @@ -125,6 +125,6 @@ namespace SixLabors.ImageSharp.Formats.Png /// Malformed chunk named CgBI produced by apple, which is not conform to the specification. /// Related issue is here https://github.com/SixLabors/ImageSharp/issues/410 /// - MalformedApple = 0x43674249 + ProprietaryApple = 0x43674249 } } diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 757b08481..0247dba35 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -215,8 +215,8 @@ namespace SixLabors.ImageSharp.Formats.Png case PngChunkType.End: this.isEndChunkReached = true; break; - case PngChunkType.MalformedApple: - PngThrowHelper.ThrowInvalidChunkType("Malformed Apple PNG detected! This PNG file is not conform to the specification and cannot be decoded."); + case PngChunkType.ProprietaryApple: + PngThrowHelper.ThrowInvalidChunkType("Proprietary Apple PNG detected! This PNG file is not conform to the specification and cannot be decoded."); break; } } From 6fb16cd44a9d20860bd1ebfcad5ba3131f1fbcbb Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 23 Apr 2020 18:30:00 +0200 Subject: [PATCH 12/13] Fix chunk type unit tests --- tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs | 2 +- tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs index f3984ac82..3a207722b 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png Assert.Equal(PngChunkType.SignificantBits, GetType("sBIT")); Assert.Equal(PngChunkType.Histogram, GetType("hIST")); Assert.Equal(PngChunkType.SuggestedPalette, GetType("sPLT")); - Assert.Equal(PngChunkType.MalformedApple, GetType("CgBI")); + Assert.Equal(PngChunkType.ProprietaryApple, GetType("CgBI")); } private static PngChunkType GetType(string text) diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index c4b5d0b4b..6eb6e93db 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -387,7 +387,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } }); Assert.NotNull(ex); - Assert.Contains("Malformed Apple PNG detected!", ex.Message); + Assert.Contains("Proprietary Apple PNG detected!", ex.Message); } [Theory] From b1afae8cdb209a67e226f61a6e8e5e5267638404 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 24 Apr 2020 12:08:49 +0200 Subject: [PATCH 13/13] Fix warning --- .../Drawing/DrawImageExtensionsTests.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageExtensionsTests.cs b/tests/ImageSharp.Tests/Drawing/DrawImageExtensionsTests.cs index 3f90412ae..0aff95d99 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageExtensionsTests.cs @@ -1,17 +1,10 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; -using System.Linq; -using Moq; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Drawing; using SixLabors.ImageSharp.Tests.Processing; -using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; @@ -19,7 +12,6 @@ namespace SixLabors.ImageSharp.Tests.Drawing { public class DrawImageExtensionsTests : BaseImageOperationsExtensionTest { - [Fact] public void DrawImage_OpacityOnly_VerifyGraphicOptionsTakenFromContext() { @@ -28,7 +20,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing this.options.ColorBlendingMode = PixelColorBlendingMode.Screen; this.operations.DrawImage(null, 0.5f); - var dip = this.Verify(); + DrawImageProcessor dip = this.Verify(); Assert.Equal(0.5, dip.Opacity); Assert.Equal(this.options.AlphaCompositionMode, dip.AlphaCompositionMode); @@ -43,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing this.options.ColorBlendingMode = PixelColorBlendingMode.Screen; this.operations.DrawImage(null, PixelColorBlendingMode.Multiply, 0.5f); - var dip = this.Verify(); + DrawImageProcessor dip = this.Verify(); Assert.Equal(0.5, dip.Opacity); Assert.Equal(this.options.AlphaCompositionMode, dip.AlphaCompositionMode); @@ -58,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing this.options.ColorBlendingMode = PixelColorBlendingMode.Screen; this.operations.DrawImage(null, Point.Empty, 0.5f); - var dip = this.Verify(); + DrawImageProcessor dip = this.Verify(); Assert.Equal(0.5, dip.Opacity); Assert.Equal(this.options.AlphaCompositionMode, dip.AlphaCompositionMode); @@ -73,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing this.options.ColorBlendingMode = PixelColorBlendingMode.Screen; this.operations.DrawImage(null, Point.Empty, PixelColorBlendingMode.Multiply, 0.5f); - var dip = this.Verify(); + DrawImageProcessor dip = this.Verify(); Assert.Equal(0.5, dip.Opacity); Assert.Equal(this.options.AlphaCompositionMode, dip.AlphaCompositionMode);