diff --git a/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs b/src/ImageSharp/Common/Exceptions/ImageProcessingException.cs
index 3c75a6418..ccd0b71e5 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;
@@ -10,6 +10,13 @@ namespace SixLabors.ImageSharp
///
public sealed 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/Formats/Png/PngChunkType.cs b/src/ImageSharp/Formats/Png/PngChunkType.cs
index e41b49066..015f6984d 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
+ ///
+ ProprietaryApple = 0x43674249
}
}
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 272f93d10..0247dba35 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.ProprietaryApple:
+ PngThrowHelper.ThrowInvalidChunkType("Proprietary 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)
{
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/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/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs
index dde7beb3e..1478d2951 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;
@@ -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.
@@ -268,6 +286,11 @@ namespace SixLabors.ImageSharp.Processing
/// Returns the combined matrix for a given source rectangle.
///
/// The rectangle in the source image.
+ ///
+ /// 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)
{
@@ -284,9 +307,19 @@ namespace SixLabors.ImageSharp.Processing
matrix *= factory(size);
}
+ CheckDegenerate(matrix);
+
return matrix;
}
+ private static void CheckDegenerate(Matrix3x2 matrix)
+ {
+ if (TransformUtilities.IsDegenerate(matrix))
+ {
+ throw new DegenerateTransformException("Matrix is degenerate. Check input values.");
+ }
+ }
+
private AffineTransformBuilder Prepend(Func factory)
{
this.matrixFactories.Insert(0, factory);
@@ -299,4 +332,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..4d46540bc
--- /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 : Exception
+ {
+ ///
+ /// 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..b474b4371 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtilities.cs
@@ -12,6 +12,57 @@ 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 .
+ ///
+ /// 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..b7e65b4cc 100644
--- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs
+++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs
@@ -1,9 +1,10 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Numerics;
+using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
namespace SixLabors.ImageSharp.Processing
@@ -263,27 +264,51 @@ 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 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)
{
@@ -300,9 +325,19 @@ namespace SixLabors.ImageSharp.Processing
matrix *= factory(size);
}
+ CheckDegenerate(matrix);
+
return matrix;
}
+ private static void CheckDegenerate(Matrix4x4 matrix)
+ {
+ if (TransformUtilities.IsDegenerate(matrix))
+ {
+ throw new DegenerateTransformException("Matrix is degenerate. Check input values.");
+ }
+ }
+
private ProjectiveTransformBuilder Prepend(Func factory)
{
this.matrixFactories.Insert(0, factory);
@@ -315,4 +350,4 @@ namespace SixLabors.ImageSharp.Processing
return this;
}
}
-}
\ No newline at end of file
+}
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);
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);
+ }
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs
index 2e8c0de27..3a207722b 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.ProprietaryApple, GetType("CgBI"));
}
private static PngChunkType GetType(string text)
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..6eb6e93db 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("Proprietary Apple PNG detected!", ex.Message);
+ }
+
[Theory]
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)]
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");
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);
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 000000000..b145c2b8e
Binary files /dev/null and b/tests/Images/Input/Png/basn3p01.png differ
diff --git a/tests/Images/Input/Png/basn3p02.png b/tests/Images/Input/Png/basn3p02.png
new file mode 100644
index 000000000..8985b3d81
Binary files /dev/null and b/tests/Images/Input/Png/basn3p02.png differ
diff --git a/tests/Images/Input/Png/basn3p04.png b/tests/Images/Input/Png/basn3p04.png
new file mode 100644
index 000000000..0fbf9e827
Binary files /dev/null and b/tests/Images/Input/Png/basn3p04.png differ
diff --git a/tests/Images/Input/Png/basn3p08.png b/tests/Images/Input/Png/basn3p08.png
new file mode 100644
index 000000000..0ddad07e5
Binary files /dev/null and b/tests/Images/Input/Png/basn3p08.png differ
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 000000000..ad3581fbb
Binary files /dev/null and b/tests/Images/Input/Png/issues/Issue_410.png differ
diff --git a/tests/Images/Input/Png/xc1n0g08.png b/tests/Images/Input/Png/xc1n0g08.png
new file mode 100644
index 000000000..940422737
Binary files /dev/null and b/tests/Images/Input/Png/xc1n0g08.png differ
diff --git a/tests/Images/Input/Png/xc9n2c08.png b/tests/Images/Input/Png/xc9n2c08.png
new file mode 100644
index 000000000..b11c2a7b4
Binary files /dev/null and b/tests/Images/Input/Png/xc9n2c08.png differ
diff --git a/tests/Images/Input/Png/xd0n2c08.png b/tests/Images/Input/Png/xd0n2c08.png
new file mode 100644
index 000000000..2f001610a
Binary files /dev/null and b/tests/Images/Input/Png/xd0n2c08.png differ
diff --git a/tests/Images/Input/Png/xd3n2c08.png b/tests/Images/Input/Png/xd3n2c08.png
new file mode 100644
index 000000000..9e4a3ff7a
Binary files /dev/null and b/tests/Images/Input/Png/xd3n2c08.png differ
diff --git a/tests/Images/Input/Png/xdtn0g01.png b/tests/Images/Input/Png/xdtn0g01.png
new file mode 100644
index 000000000..1a81abef8
Binary files /dev/null and b/tests/Images/Input/Png/xdtn0g01.png differ