Browse Source

Revert `using` declaration changes for until we establish guidelines.

af/octree-no-pixelmap
James Jackson-South 7 years ago
parent
commit
8cd722cfc5
  1. 137
      tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs
  2. 42
      tests/ImageSharp.Tests/Common/StreamExtensionsTests.cs
  3. 192
      tests/ImageSharp.Tests/Drawing/DrawImageTests.cs
  4. 346
      tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs
  5. 113
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
  6. 14
      tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs
  7. 119
      tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs
  8. 74
      tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
  9. 162
      tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs
  10. 86
      tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs
  11. 12
      tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
  12. 48
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs
  13. 80
      tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs
  14. 88
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
  15. 34
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  16. 107
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
  17. 58
      tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs
  18. 60
      tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
  19. 20
      tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
  20. 10
      tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
  21. 46
      tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs
  22. 8
      tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs
  23. 18
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs
  24. 102
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  25. 224
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  26. 185
      tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs
  27. 44
      tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs
  28. 120
      tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs
  29. 66
      tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs
  30. 28
      tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs
  31. 60
      tests/ImageSharp.Tests/Helpers/ParallelHelperTests.cs
  32. 18
      tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs
  33. 190
      tests/ImageSharp.Tests/IO/DoubleBufferedStreamReaderTests.cs
  34. 116
      tests/ImageSharp.Tests/Image/ImageCloneTests.cs
  35. 30
      tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs
  36. 81
      tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs
  37. 12
      tests/ImageSharp.Tests/Image/ImageRotationTests.cs
  38. 8
      tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs
  39. 40
      tests/ImageSharp.Tests/Image/ImageTests.LoadPixelData.cs
  40. 40
      tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs
  41. 40
      tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs
  42. 40
      tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs
  43. 28
      tests/ImageSharp.Tests/Image/ImageTests.Save.cs
  44. 88
      tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs
  45. 56
      tests/ImageSharp.Tests/Image/ImageTests.cs
  46. 106
      tests/ImageSharp.Tests/Memory/Buffer2DTests.cs
  47. 112
      tests/ImageSharp.Tests/Memory/BufferAreaTests.cs
  48. 16
      tests/ImageSharp.Tests/Metadata/ImageMetadataTests.cs
  49. 70
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs
  50. 6
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifValueTests.cs
  51. 32
      tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs
  52. 22
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs
  53. 8
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs
  54. 114
      tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs
  55. 60
      tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryDitherTests.cs
  56. 22
      tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs
  57. 26
      tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs
  58. 40
      tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs
  59. 28
      tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs
  60. 36
      tests/ImageSharp.Tests/Processing/Processors/Transforms/PadTest.cs
  61. 407
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs
  62. 12
      tests/ImageSharp.Tests/Processing/Processors/Transforms/RotateFlipTests.cs
  63. 102
      tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs
  64. 68
      tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs
  65. 22
      tests/ImageSharp.Tests/Processing/Transforms/TransformsHelpersTest.cs
  66. 28
      tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs
  67. 10
      tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs
  68. 40
      tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs
  69. 176
      tests/ImageSharp.Tests/Quantization/WuQuantizerTests.cs
  70. 12
      tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
  71. 64
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
  72. 60
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs
  73. 48
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs
  74. 8
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs
  75. 62
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  76. 104
      tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs
  77. 32
      tests/ImageSharp.Tests/TestUtilities/Tests/MagickReferenceCodecTests.cs
  78. 78
      tests/ImageSharp.Tests/TestUtilities/Tests/SystemDrawingReferenceCodecTests.cs
  79. 60
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageExtensionsTests.cs
  80. 50
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

137
tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs

@ -20,20 +20,23 @@ namespace SixLabors.ImageSharp.Tests.Advanced
public void WhenMemoryIsOwned<TPixel>(TestImageProvider<TPixel> provider) public void WhenMemoryIsOwned<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image0 = provider.GetImage(); using (Image<TPixel> image0 = provider.GetImage())
var targetBuffer = new TPixel[image0.Width * image0.Height]; {
var targetBuffer = new TPixel[image0.Width * image0.Height];
// Act:
Memory<TPixel> memory = image0.GetPixelMemory(); // Act:
Memory<TPixel> memory = image0.GetPixelMemory();
// Assert:
Assert.Equal(image0.Width * image0.Height, memory.Length); // Assert:
memory.Span.CopyTo(targetBuffer); Assert.Equal(image0.Width * image0.Height, memory.Length);
memory.Span.CopyTo(targetBuffer);
using Image<TPixel> image1 = provider.GetImage();
using (Image<TPixel> image1 = provider.GetImage())
// We are using a copy of the original image for assertion {
image1.ComparePixelBufferTo(targetBuffer); // We are using a copy of the original image for assertion
image1.ComparePixelBufferTo(targetBuffer);
}
}
} }
[Theory] [Theory]
@ -42,23 +45,27 @@ namespace SixLabors.ImageSharp.Tests.Advanced
public void WhenMemoryIsConsumed<TPixel>(TestImageProvider<TPixel> provider) public void WhenMemoryIsConsumed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image0 = provider.GetImage(); using (Image<TPixel> image0 = provider.GetImage())
var targetBuffer = new TPixel[image0.Width * image0.Height]; {
image0.GetPixelSpan().CopyTo(targetBuffer); var targetBuffer = new TPixel[image0.Width * image0.Height];
image0.GetPixelSpan().CopyTo(targetBuffer);
var managerOfExternalMemory = new TestMemoryManager<TPixel>(targetBuffer); var managerOfExternalMemory = new TestMemoryManager<TPixel>(targetBuffer);
Memory<TPixel> externalMemory = managerOfExternalMemory.Memory; Memory<TPixel> externalMemory = managerOfExternalMemory.Memory;
using var image1 = Image.WrapMemory(externalMemory, image0.Width, image0.Height); using (var image1 = Image.WrapMemory(externalMemory, image0.Width, image0.Height))
Memory<TPixel> internalMemory = image1.GetPixelMemory(); {
Assert.Equal(targetBuffer.Length, internalMemory.Length); Memory<TPixel> internalMemory = image1.GetPixelMemory();
Assert.True(Unsafe.AreSame(ref targetBuffer[0], ref internalMemory.Span[0])); Assert.Equal(targetBuffer.Length, internalMemory.Length);
Assert.True(Unsafe.AreSame(ref targetBuffer[0], ref internalMemory.Span[0]));
image0.ComparePixelBufferTo(internalMemory.Span); image0.ComparePixelBufferTo(internalMemory.Span);
}
// Make sure externalMemory works after destruction: // Make sure externalMemory works after destruction:
image0.ComparePixelBufferTo(externalMemory.Span); image0.ComparePixelBufferTo(externalMemory.Span);
}
} }
} }
@ -68,21 +75,24 @@ namespace SixLabors.ImageSharp.Tests.Advanced
public void GetPixelRowMemory<TPixel>(TestImageProvider<TPixel> provider) public void GetPixelRowMemory<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var targetBuffer = new TPixel[image.Width * image.Height];
// Act:
for (int y = 0; y < image.Height; y++)
{ {
Memory<TPixel> rowMemory = image.GetPixelRowMemory(y); var targetBuffer = new TPixel[image.Width * image.Height];
rowMemory.Span.CopyTo(targetBuffer.AsSpan(image.Width * y));
}
// Assert: // Act:
using Image<TPixel> image1 = provider.GetImage(); for (int y = 0; y < image.Height; y++)
{
Memory<TPixel> rowMemory = image.GetPixelRowMemory(y);
rowMemory.Span.CopyTo(targetBuffer.AsSpan(image.Width * y));
}
// We are using a copy of the original image for assertion // Assert:
image1.ComparePixelBufferTo(targetBuffer); using (Image<TPixel> image1 = provider.GetImage())
{
// We are using a copy of the original image for assertion
image1.ComparePixelBufferTo(targetBuffer);
}
}
} }
[Theory] [Theory]
@ -91,21 +101,24 @@ namespace SixLabors.ImageSharp.Tests.Advanced
public void GetPixelRowSpan<TPixel>(TestImageProvider<TPixel> provider) public void GetPixelRowSpan<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var targetBuffer = new TPixel[image.Width * image.Height];
// Act:
for (int y = 0; y < image.Height; y++)
{ {
Span<TPixel> rowMemory = image.GetPixelRowSpan(y); var targetBuffer = new TPixel[image.Width * image.Height];
rowMemory.CopyTo(targetBuffer.AsSpan(image.Width * y));
}
// Assert: // Act:
using Image<TPixel> image1 = provider.GetImage(); for (int y = 0; y < image.Height; y++)
{
Span<TPixel> rowMemory = image.GetPixelRowSpan(y);
rowMemory.CopyTo(targetBuffer.AsSpan(image.Width * y));
}
// We are using a copy of the original image for assertion // Assert:
image1.ComparePixelBufferTo(targetBuffer); using (Image<TPixel> image1 = provider.GetImage())
{
// We are using a copy of the original image for assertion
image1.ComparePixelBufferTo(targetBuffer);
}
}
} }
#pragma warning disable 0618 #pragma warning disable 0618
@ -115,19 +128,21 @@ namespace SixLabors.ImageSharp.Tests.Advanced
public unsafe void DangerousGetPinnableReference_CopyToBuffer<TPixel>(TestImageProvider<TPixel> provider) public unsafe void DangerousGetPinnableReference_CopyToBuffer<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var targetBuffer = new TPixel[image.Width * image.Height];
ref byte source = ref Unsafe.As<TPixel, byte>(ref targetBuffer[0]);
ref byte dest = ref Unsafe.As<TPixel, byte>(ref image.DangerousGetPinnableReferenceToPixelBuffer());
fixed (byte* targetPtr = &source)
fixed (byte* pixelBasePtr = &dest)
{ {
uint dataSizeInBytes = (uint)(image.Width * image.Height * Unsafe.SizeOf<TPixel>()); var targetBuffer = new TPixel[image.Width * image.Height];
Unsafe.CopyBlock(targetPtr, pixelBasePtr, dataSizeInBytes);
ref byte source = ref Unsafe.As<TPixel, byte>(ref targetBuffer[0]);
ref byte dest = ref Unsafe.As<TPixel, byte>(ref image.DangerousGetPinnableReferenceToPixelBuffer());
fixed (byte* targetPtr = &source)
fixed (byte* pixelBasePtr = &dest)
{
uint dataSizeInBytes = (uint)(image.Width * image.Height * Unsafe.SizeOf<TPixel>());
Unsafe.CopyBlock(targetPtr, pixelBasePtr, dataSizeInBytes);
}
image.ComparePixelBufferTo(targetBuffer);
} }
image.ComparePixelBufferTo(targetBuffer);
} }
} }
} }

42
tests/ImageSharp.Tests/Common/StreamExtensionsTests.cs

@ -15,43 +15,51 @@ namespace SixLabors.ImageSharp.Tests.Common
[InlineData(-1)] [InlineData(-1)]
public void Skip_CountZeroOrLower_PositionNotChanged(int count) public void Skip_CountZeroOrLower_PositionNotChanged(int count)
{ {
using var memStream = new MemoryStream(5); using (var memStream = new MemoryStream(5))
memStream.Position = 4; {
memStream.Skip(count); memStream.Position = 4;
memStream.Skip(count);
Assert.Equal(4, memStream.Position); Assert.Equal(4, memStream.Position);
}
} }
[Fact] [Fact]
public void Skip_SeekableStream_SeekIsCalled() public void Skip_SeekableStream_SeekIsCalled()
{ {
using var seekableStream = new SeekableStream(4); using (var seekableStream = new SeekableStream(4))
seekableStream.Skip(4); {
seekableStream.Skip(4);
Assert.Equal(4, seekableStream.Offset); Assert.Equal(4, seekableStream.Offset);
Assert.Equal(SeekOrigin.Current, seekableStream.Loc); Assert.Equal(SeekOrigin.Current, seekableStream.Loc);
}
} }
[Fact] [Fact]
public void Skip_NonSeekableStream_BytesAreRead() public void Skip_NonSeekableStream_BytesAreRead()
{ {
using var nonSeekableStream = new NonSeekableStream(); using (var nonSeekableStream = new NonSeekableStream())
nonSeekableStream.Skip(5); {
nonSeekableStream.Skip(5);
Assert.Equal(3, nonSeekableStream.Counts.Count); Assert.Equal(3, nonSeekableStream.Counts.Count);
Assert.Equal(5, nonSeekableStream.Counts[0]); Assert.Equal(5, nonSeekableStream.Counts[0]);
Assert.Equal(3, nonSeekableStream.Counts[1]); Assert.Equal(3, nonSeekableStream.Counts[1]);
Assert.Equal(1, nonSeekableStream.Counts[2]); Assert.Equal(1, nonSeekableStream.Counts[2]);
}
} }
[Fact] [Fact]
public void Skip_EofStream_NoExceptionIsThrown() public void Skip_EofStream_NoExceptionIsThrown()
{ {
using var eofStream = new EofStream(7); using (var eofStream = new EofStream(7))
eofStream.Skip(7); {
eofStream.Skip(7);
Assert.Equal(0, eofStream.Position); Assert.Equal(0, eofStream.Position);
}
} }
private class SeekableStream : MemoryStream private class SeekableStream : MemoryStream

192
tests/ImageSharp.Tests/Drawing/DrawImageTests.cs

@ -33,22 +33,24 @@ namespace SixLabors.ImageSharp.Tests.Drawing
public void ImageBlendingMatchesSvgSpecExamples<TPixel>(TestImageProvider<TPixel> provider, PixelColorBlendingMode mode) public void ImageBlendingMatchesSvgSpecExamples<TPixel>(TestImageProvider<TPixel> provider, PixelColorBlendingMode mode)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> background = provider.GetImage(); using (Image<TPixel> background = provider.GetImage())
using var source = Image.Load<TPixel>(TestFile.Create(TestImages.Png.Ducky).Bytes); using (var source = Image.Load<TPixel>(TestFile.Create(TestImages.Png.Ducky).Bytes))
background.Mutate(x => x.DrawImage(source, mode, 1F)); {
background.DebugSave( background.Mutate(x => x.DrawImage(source, mode, 1F));
provider, background.DebugSave(
new { mode = mode }, provider,
appendPixelTypeToFileName: false, new { mode = mode },
appendSourceFileOrDescription: false); appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
var comparer = ImageComparer.TolerantPercentage(0.01F);
background.CompareToReferenceOutput( var comparer = ImageComparer.TolerantPercentage(0.01F);
comparer, background.CompareToReferenceOutput(
provider, comparer,
new { mode = mode }, provider,
appendPixelTypeToFileName: false, new { mode = mode },
appendSourceFileOrDescription: false); appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
} }
[Theory] [Theory]
@ -70,26 +72,28 @@ namespace SixLabors.ImageSharp.Tests.Drawing
float opacity) float opacity)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using var blend = Image.Load<TPixel>(TestFile.Create(brushImage).Bytes); using (var blend = Image.Load<TPixel>(TestFile.Create(brushImage).Bytes))
var size = new Size(image.Width * 3 / 4, image.Height * 3 / 4);
var position = new Point(image.Width / 8, image.Height / 8);
blend.Mutate(x => x.Resize(size.Width, size.Height, KnownResamplers.Bicubic));
image.Mutate(x => x.DrawImage(blend, position, mode, opacity));
FormattableString testInfo = $"{System.IO.Path.GetFileNameWithoutExtension(brushImage)}-{mode}-{opacity}";
var encoder = new PngEncoder();
if (provider.PixelType == PixelTypes.Rgba64)
{ {
encoder.BitDepth = PngBitDepth.Bit16; var size = new Size(image.Width * 3 / 4, image.Height * 3 / 4);
var position = new Point(image.Width / 8, image.Height / 8);
blend.Mutate(x => x.Resize(size.Width, size.Height, KnownResamplers.Bicubic));
image.Mutate(x => x.DrawImage(blend, position, mode, opacity));
FormattableString testInfo = $"{System.IO.Path.GetFileNameWithoutExtension(brushImage)}-{mode}-{opacity}";
var encoder = new PngEncoder();
if (provider.PixelType == PixelTypes.Rgba64)
{
encoder.BitDepth = PngBitDepth.Bit16;
}
image.DebugSave(provider, testInfo, encoder: encoder);
image.CompareToReferenceOutput(
ImageComparer.TolerantPercentage(0.01f),
provider,
testInfo);
} }
image.DebugSave(provider, testInfo, encoder: encoder);
image.CompareToReferenceOutput(
ImageComparer.TolerantPercentage(0.01f),
provider,
testInfo);
} }
[Theory] [Theory]
@ -99,17 +103,19 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{ {
byte[] brushData = TestFile.Create(TestImages.Png.Ducky).Bytes; byte[] brushData = TestFile.Create(TestImages.Png.Ducky).Bytes;
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image brushImage = provider.PixelType == PixelTypes.Rgba32 using (Image brushImage = provider.PixelType == PixelTypes.Rgba32
? (Image)Image.Load<Bgra32>(brushData) ? (Image)Image.Load<Bgra32>(brushData)
: Image.Load<Rgba32>(brushData); : Image.Load<Rgba32>(brushData))
image.Mutate(c => c.DrawImage(brushImage, 0.5f)); {
image.Mutate(c => c.DrawImage(brushImage, 0.5f));
image.DebugSave(provider, appendSourceFileOrDescription: false);
image.CompareToReferenceOutput( image.DebugSave(provider, appendSourceFileOrDescription: false);
ImageComparer.TolerantPercentage(0.01f), image.CompareToReferenceOutput(
provider, ImageComparer.TolerantPercentage(0.01f),
appendSourceFileOrDescription: false); provider,
appendSourceFileOrDescription: false);
}
} }
[Theory] [Theory]
@ -119,23 +125,25 @@ namespace SixLabors.ImageSharp.Tests.Drawing
[WithSolidFilledImages(100, 100, "White", PixelTypes.Rgba32, -25, -30)] [WithSolidFilledImages(100, 100, "White", PixelTypes.Rgba32, -25, -30)]
public void WorksWithDifferentLocations(TestImageProvider<Rgba32> provider, int x, int y) public void WorksWithDifferentLocations(TestImageProvider<Rgba32> provider, int x, int y)
{ {
using Image<Rgba32> background = provider.GetImage(); using (Image<Rgba32> background = provider.GetImage())
using var overlay = new Image<Rgba32>(50, 50); using (var overlay = new Image<Rgba32>(50, 50))
overlay.GetPixelSpan().Fill(Rgba32.Black); {
overlay.GetPixelSpan().Fill(Rgba32.Black);
background.Mutate(c => c.DrawImage(overlay, new Point(x, y), PixelColorBlendingMode.Normal, 1F));
background.Mutate(c => c.DrawImage(overlay, new Point(x, y), PixelColorBlendingMode.Normal, 1F));
background.DebugSave(
provider, background.DebugSave(
testOutputDetails: $"{x}_{y}", provider,
appendPixelTypeToFileName: false, testOutputDetails: $"{x}_{y}",
appendSourceFileOrDescription: false); appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
background.CompareToReferenceOutput(
provider, background.CompareToReferenceOutput(
testOutputDetails: $"{x}_{y}", provider,
appendPixelTypeToFileName: false, testOutputDetails: $"{x}_{y}",
appendSourceFileOrDescription: false); appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
} }
[Theory] [Theory]
@ -143,27 +151,29 @@ namespace SixLabors.ImageSharp.Tests.Drawing
public void DrawTransformed<TPixel>(TestImageProvider<TPixel> provider) public void DrawTransformed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using var blend = Image.Load<TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes); using (var blend = Image.Load<TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes))
AffineTransformBuilder builder = new AffineTransformBuilder() {
.AppendRotationDegrees(45F) AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendScale(new SizeF(.25F, .25F)) .AppendRotationDegrees(45F)
.AppendTranslation(new PointF(10, 10)); .AppendScale(new SizeF(.25F, .25F))
.AppendTranslation(new PointF(10, 10));
// Apply a background color so we can see the translation.
blend.Mutate(x => x.Transform(builder)); // Apply a background color so we can see the translation.
blend.Mutate(x => x.BackgroundColor(Color.HotPink)); blend.Mutate(x => x.Transform(builder));
blend.Mutate(x => x.BackgroundColor(Color.HotPink));
// Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor
var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2); // Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor
image.Mutate(x => x.DrawImage(blend, position, .75F)); var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2);
image.Mutate(x => x.DrawImage(blend, position, .75F));
image.DebugSave(provider, appendSourceFileOrDescription: false, appendPixelTypeToFileName: false);
image.CompareToReferenceOutput( image.DebugSave(provider, appendSourceFileOrDescription: false, appendPixelTypeToFileName: false);
ImageComparer.TolerantPercentage(0.002f), image.CompareToReferenceOutput(
provider, ImageComparer.TolerantPercentage(0.002f),
appendSourceFileOrDescription: false, provider,
appendPixelTypeToFileName: false); appendSourceFileOrDescription: false,
appendPixelTypeToFileName: false);
}
} }
[Theory] [Theory]
@ -173,15 +183,17 @@ namespace SixLabors.ImageSharp.Tests.Drawing
[WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32, -30, 130)] [WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32, -30, 130)]
public void NonOverlappingImageThrows(TestImageProvider<Rgba32> provider, int x, int y) public void NonOverlappingImageThrows(TestImageProvider<Rgba32> provider, int x, int y)
{ {
using Image<Rgba32> background = provider.GetImage(); using (Image<Rgba32> background = provider.GetImage())
using var overlay = new Image<Rgba32>(Configuration.Default, 10, 10, Rgba32.Black); using (var overlay = new Image<Rgba32>(Configuration.Default, 10, 10, Rgba32.Black))
ImageProcessingException ex = Assert.Throws<ImageProcessingException>(Test); {
ImageProcessingException ex = Assert.Throws<ImageProcessingException>(Test);
Assert.Contains("does not overlap", ex.ToString()); Assert.Contains("does not overlap", ex.ToString());
void Test() void Test()
{ {
background.Mutate(context => context.DrawImage(overlay, new Point(x, y), new GraphicsOptions())); background.Mutate(context => context.DrawImage(overlay, new Point(x, y), new GraphicsOptions()));
}
} }
} }
} }

346
tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs

@ -37,11 +37,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_MiscellaneousBitmaps<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_MiscellaneousBitmaps<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider);
if (TestEnvironment.IsWindows)
{ {
image.CompareToOriginal(provider); image.DebugSave(provider);
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider);
}
} }
} }
@ -50,9 +52,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBitfields<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBitfields<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -61,9 +65,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_Inverted<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_Inverted<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -72,9 +78,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_1Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_1Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new SystemDrawingReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new SystemDrawingReferenceDecoder());
}
} }
[Theory] [Theory]
@ -82,13 +90,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_4Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_4Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider);
// The Magick Reference Decoder can not decode 4-Bit bitmaps, so only execute this on windows.
if (TestEnvironment.IsWindows)
{ {
image.CompareToOriginal(provider); image.DebugSave(provider);
// The Magick Reference Decoder can not decode 4-Bit bitmaps, so only execute this on windows.
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider);
}
} }
} }
@ -97,9 +107,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_8Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_8Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -107,9 +119,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_16Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -117,9 +131,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_32Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_32Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -127,9 +143,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_32BitV4Header_Fast<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_32BitV4Header_Fast<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -139,13 +157,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_RunLengthEncoded_4Bit_WithDelta<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_RunLengthEncoded_4Bit_WithDelta<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }); using (Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }))
image.DebugSave(provider);
// The Magick Reference Decoder can not decode 4-Bit bitmaps, so only execute this on windows.
if (TestEnvironment.IsWindows)
{ {
image.CompareToOriginal(provider); image.DebugSave(provider);
// The Magick Reference Decoder can not decode 4-Bit bitmaps, so only execute this on windows.
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider);
}
} }
} }
@ -154,13 +174,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_RunLengthEncoded_4Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_RunLengthEncoded_4Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }); using (Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }))
image.DebugSave(provider);
// The Magick Reference Decoder can not decode 4-Bit bitmaps, so only execute this on windows.
if (TestEnvironment.IsWindows)
{ {
image.CompareToOriginal(provider); image.DebugSave(provider);
// The Magick Reference Decoder can not decode 4-Bit bitmaps, so only execute this on windows.
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider);
}
} }
} }
@ -172,11 +194,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_RunLengthEncoded_8Bit_WithDelta_SystemDrawingRefDecoder<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_RunLengthEncoded_8Bit_WithDelta_SystemDrawingRefDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }); using (Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }))
image.DebugSave(provider);
if (TestEnvironment.IsWindows)
{ {
image.CompareToOriginal(provider, new SystemDrawingReferenceDecoder()); image.DebugSave(provider);
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider, new SystemDrawingReferenceDecoder());
}
} }
} }
@ -186,9 +210,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_RunLengthEncoded_8Bit_WithDelta_MagickRefDecoder<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_RunLengthEncoded_8Bit_WithDelta_MagickRefDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.FirstColorOfPalette }); using (Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.FirstColorOfPalette }))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new MagickReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -197,9 +223,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_RunLengthEncoded_8Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_RunLengthEncoded_8Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.FirstColorOfPalette }); using (Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.FirstColorOfPalette }))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new MagickReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -209,11 +237,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_RunLengthEncoded_24Bit<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_RunLengthEncoded_24Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }); using (Image<TPixel> image = provider.GetImage(new BmpDecoder { RleSkippedPixelHandling = RleSkippedPixelHandling.Black }))
image.DebugSave(provider); {
image.DebugSave(provider);
// TODO: Neither System.Drawing nor MagickReferenceDecoder decode this file. // TODO: Neither System.Drawing nor MagickReferenceDecoder decode this file.
// image.CompareToOriginal(provider); // image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -221,11 +251,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeAlphaBitfields<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeAlphaBitfields<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.DebugSave(provider);
// TODO: Neither System.Drawing nor MagickReferenceDecoder decode this file. // TODO: Neither System.Drawing nor MagickReferenceDecoder decode this file.
// image.CompareToOriginal(provider); // image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -233,9 +265,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBitmap_WithAlphaChannel<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBitmap_WithAlphaChannel<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new MagickReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -243,15 +277,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBitfields_WithUnusualBitmasks<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBitfields_WithUnusualBitmasks<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.DebugSave(provider);
// Choosing large tolerance of 6.1 here, because for some reason with the MagickReferenceDecoder the alpha channel
// seems to be wrong. This bitmap has an alpha channel of two bits. In many cases this alpha channel has a value of 3, // Choosing large tolerance of 6.1 here, because for some reason with the MagickReferenceDecoder the alpha channel
// which should be remapped to 255 for RGBA32, but the magick decoder has a value of 191 set. // seems to be wrong. This bitmap has an alpha channel of two bits. In many cases this alpha channel has a value of 3,
// The total difference without the alpha channel is still: 0.0204% // which should be remapped to 255 for RGBA32, but the magick decoder has a value of 191 set.
// Exporting the image as PNG with GIMP yields to the same result as the ImageSharp implementation. // The total difference without the alpha channel is still: 0.0204%
image.CompareToOriginal(provider, ImageComparer.TolerantPercentage(6.1f), new MagickReferenceDecoder()); // Exporting the image as PNG with GIMP yields to the same result as the ImageSharp implementation.
image.CompareToOriginal(provider, ImageComparer.TolerantPercentage(6.1f), new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -260,9 +296,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBmpv2<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBmpv2<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -270,9 +308,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBmpv3<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBmpv3<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -280,9 +320,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeLessThanFullPalette<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeLessThanFullPalette<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new MagickReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -291,11 +333,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeOversizedPalette<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeOversizedPalette<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider);
if (TestEnvironment.IsWindows)
{ {
image.CompareToOriginal(provider); image.DebugSave(provider);
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider);
}
} }
} }
@ -331,9 +375,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeAdobeBmpv3<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeAdobeBmpv3<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new MagickReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -341,9 +387,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeAdobeBmpv3_WithAlpha<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeAdobeBmpv3_WithAlpha<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, new MagickReferenceDecoder()); image.DebugSave(provider);
image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -351,9 +399,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBmpv4<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBmpv4<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -362,9 +412,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecodeBmpv5<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecodeBmpv5<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -372,9 +424,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_RespectsFileHeaderOffset<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_RespectsFileHeaderOffset<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -382,9 +436,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -392,9 +448,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode4BytePerEntryPalette<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode4BytePerEntryPalette<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider); image.DebugSave(provider);
image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -413,10 +471,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void Identify_DetectsCorrectPixelType(string imagePath, int expectedPixelSize) public void Identify_DetectsCorrectPixelType(string imagePath, int expectedPixelSize)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
IImageInfo imageInfo = Image.Identify(stream); {
Assert.NotNull(imageInfo); IImageInfo imageInfo = Image.Identify(stream);
Assert.Equal(expectedPixelSize, imageInfo.PixelType?.BitsPerPixel); Assert.NotNull(imageInfo);
Assert.Equal(expectedPixelSize, imageInfo.PixelType?.BitsPerPixel);
}
} }
[Theory] [Theory]
@ -431,11 +491,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void Identify_DetectsCorrectWidthAndHeight(string imagePath, int expectedWidth, int expectedHeight) public void Identify_DetectsCorrectWidthAndHeight(string imagePath, int expectedWidth, int expectedHeight)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
IImageInfo imageInfo = Image.Identify(stream); {
Assert.NotNull(imageInfo); IImageInfo imageInfo = Image.Identify(stream);
Assert.Equal(expectedWidth, imageInfo.Width); Assert.NotNull(imageInfo);
Assert.Equal(expectedHeight, imageInfo.Height); Assert.Equal(expectedWidth, imageInfo.Width);
Assert.Equal(expectedHeight, imageInfo.Height);
}
} }
[Theory] [Theory]
@ -443,13 +505,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new BmpDecoder(); {
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream); var decoder = new BmpDecoder();
ImageMetadata meta = image.Metadata; using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
Assert.Equal(xResolution, meta.HorizontalResolution); {
Assert.Equal(yResolution, meta.VerticalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
} }
[Theory] [Theory]
@ -457,11 +523,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_Os2v2XShortHeader<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_Os2v2XShortHeader<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.DebugSave(provider);
// TODO: Neither System.Drawing or MagickReferenceDecoder can correctly decode this file. // TODO: Neither System.Drawing or MagickReferenceDecoder can correctly decode this file.
// image.CompareToOriginal(provider); // image.CompareToOriginal(provider);
}
} }
[Theory] [Theory]
@ -469,13 +537,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_Os2v2Header<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_Os2v2Header<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.DebugSave(provider);
// TODO: System.Drawing can not decode this image. MagickReferenceDecoder can decode it, // TODO: System.Drawing can not decode this image. MagickReferenceDecoder can decode it,
// but i think incorrectly. I have loaded the image with GIMP and exported as PNG. // but i think incorrectly. I have loaded the image with GIMP and exported as PNG.
// The results are the same as the image sharp implementation. // The results are the same as the image sharp implementation.
// image.CompareToOriginal(provider, new MagickReferenceDecoder()); // image.CompareToOriginal(provider, new MagickReferenceDecoder());
}
} }
[Theory] [Theory]
@ -491,11 +561,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void BmpDecoder_CanDecode_Os2BitmapArray<TPixel>(TestImageProvider<TPixel> provider) public void BmpDecoder_CanDecode_Os2BitmapArray<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new BmpDecoder()); using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
image.DebugSave(provider); {
image.DebugSave(provider);
// TODO: Neither System.Drawing or MagickReferenceDecoder can correctly decode this file. // TODO: Neither System.Drawing or MagickReferenceDecoder can correctly decode this file.
// image.CompareToOriginal(provider); // image.CompareToOriginal(provider);
}
} }
} }
} }

113
tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

@ -54,16 +54,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
var options = new BmpEncoder(); var options = new BmpEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
ImageMetadata meta = output.Metadata; memStream.Position = 0;
Assert.Equal(xResolution, meta.HorizontalResolution); using (var output = Image.Load<Rgba32>(memStream))
Assert.Equal(yResolution, meta.VerticalResolution); {
Assert.Equal(resolutionUnit, meta.ResolutionUnits); ImageMetadata meta = output.Metadata;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
} }
[Theory] [Theory]
@ -73,15 +79,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
var options = new BmpEncoder(); var options = new BmpEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
BmpMetadata meta = output.Metadata.GetBmpMetadata(); memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel); {
BmpMetadata meta = output.Metadata.GetBmpMetadata();
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel);
}
}
}
} }
[Theory] [Theory]
@ -180,16 +192,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
return; return;
} }
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var encoder = new BmpEncoder
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel8, var encoder = new BmpEncoder
Quantizer = new WuQuantizer(256) {
}; BitsPerPixel = BmpBitsPerPixel.Pixel8,
string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "bmp", encoder, appendPixelTypeToFileName: false); Quantizer = new WuQuantizer(256)
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); };
using var referenceImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder); string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "bmp", encoder, appendPixelTypeToFileName: false);
referenceImage.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.01f), provider, extension: "bmp", appendPixelTypeToFileName: false); IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
using (var referenceImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
{
referenceImage.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.01f), provider, extension: "bmp", appendPixelTypeToFileName: false);
}
}
} }
[Theory] [Theory]
@ -202,16 +218,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
return; return;
} }
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var encoder = new BmpEncoder
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel8, var encoder = new BmpEncoder
Quantizer = new OctreeQuantizer(256) {
}; BitsPerPixel = BmpBitsPerPixel.Pixel8,
string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "bmp", encoder, appendPixelTypeToFileName: false); Quantizer = new OctreeQuantizer(256)
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); };
using var referenceImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder); string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "bmp", encoder, appendPixelTypeToFileName: false);
referenceImage.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.01f), provider, extension: "bmp", appendPixelTypeToFileName: false); IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
using (var referenceImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
{
referenceImage.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.01f), provider, extension: "bmp", appendPixelTypeToFileName: false);
}
}
} }
[Theory] [Theory]
@ -227,18 +247,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
ImageComparer customComparer = null) ImageComparer customComparer = null)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
// There is no alpha in bmp with less then 32 bits per pixels, so the reference image will be made opaque.
if (bitsPerPixel != BmpBitsPerPixel.Pixel32)
{ {
image.Mutate(c => c.MakeOpaque()); // There is no alpha in bmp with less then 32 bits per pixels, so the reference image will be made opaque.
} if (bitsPerPixel != BmpBitsPerPixel.Pixel32)
{
image.Mutate(c => c.MakeOpaque());
}
var encoder = new BmpEncoder { BitsPerPixel = bitsPerPixel, SupportTransparency = supportTransparency }; var encoder = new BmpEncoder { BitsPerPixel = bitsPerPixel, SupportTransparency = supportTransparency };
// Does DebugSave & load reference CompareToReferenceInput(): // Does DebugSave & load reference CompareToReferenceInput():
image.VerifyEncoder(provider, "bmp", bitsPerPixel, encoder, customComparer); image.VerifyEncoder(provider, "bmp", bitsPerPixel, encoder, customComparer);
}
} }
} }
} }

14
tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs

@ -36,12 +36,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
public void Identify_DetectsCorrectBitmapInfoHeaderType(string imagePath, BmpInfoHeaderType expectedInfoHeaderType) public void Identify_DetectsCorrectBitmapInfoHeaderType(string imagePath, BmpInfoHeaderType expectedInfoHeaderType)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
IImageInfo imageInfo = Image.Identify(stream); {
Assert.NotNull(imageInfo); IImageInfo imageInfo = Image.Identify(stream);
BmpMetadata bitmapMetadata = imageInfo.Metadata.GetBmpMetadata(); Assert.NotNull(imageInfo);
Assert.NotNull(bitmapMetadata); BmpMetadata bitmapMetadata = imageInfo.Metadata.GetBmpMetadata();
Assert.Equal(expectedInfoHeaderType, bitmapMetadata.InfoHeaderType); Assert.NotNull(bitmapMetadata);
Assert.Equal(expectedInfoHeaderType, bitmapMetadata.InfoHeaderType);
}
} }
} }
} }

119
tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs

@ -23,10 +23,12 @@ namespace SixLabors.ImageSharp.Tests
public void ResolutionShouldChange<TPixel>(TestImageProvider<TPixel> provider) public void ResolutionShouldChange<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Metadata.VerticalResolution = 150; {
image.Metadata.HorizontalResolution = 150; image.Metadata.VerticalResolution = 150;
image.DebugSave(provider); image.Metadata.HorizontalResolution = 150;
image.DebugSave(provider);
}
} }
[Fact] [Fact]
@ -36,9 +38,11 @@ namespace SixLabors.ImageSharp.Tests
foreach (TestFile file in Files) foreach (TestFile file in Files)
{ {
using Image<Rgba32> image = file.CreateRgba32Image(); using (Image<Rgba32> image = file.CreateRgba32Image())
string filename = path + "/" + file.FileNameWithoutExtension + ".txt"; {
File.WriteAllText(filename, image.ToBase64String(PngFormat.Instance)); string filename = path + "/" + file.FileNameWithoutExtension + ".txt";
File.WriteAllText(filename, image.ToBase64String(PngFormat.Instance));
}
} }
} }
@ -49,8 +53,10 @@ namespace SixLabors.ImageSharp.Tests
foreach (TestFile file in Files) foreach (TestFile file in Files)
{ {
using Image<Rgba32> image = file.CreateRgba32Image(); using (Image<Rgba32> image = file.CreateRgba32Image())
image.Save($"{path}/{file.FileName}"); {
image.Save($"{path}/{file.FileName}");
}
} }
} }
@ -94,25 +100,27 @@ namespace SixLabors.ImageSharp.Tests
foreach (TestFile file in Files) foreach (TestFile file in Files)
{ {
using Image<Rgba32> image = file.CreateRgba32Image(); using (Image<Rgba32> image = file.CreateRgba32Image())
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.bmp"))
{ {
image.SaveAsBmp(output); using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.bmp"))
} {
image.SaveAsBmp(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.jpg")) }
{
image.SaveAsJpeg(output); using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.jpg"))
} {
image.SaveAsJpeg(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.png")) }
{
image.SaveAsPng(output); using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.png"))
} {
image.SaveAsPng(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.gif")) }
{
image.SaveAsGif(output); using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.gif"))
{
image.SaveAsGif(output);
}
} }
} }
} }
@ -124,14 +132,19 @@ namespace SixLabors.ImageSharp.Tests
foreach (TestFile file in Files) foreach (TestFile file in Files)
{ {
using var image = Image.Load(file.Bytes, out IImageFormat mimeType); byte[] serialized;
using var memoryStream = new MemoryStream(); using (var image = Image.Load(file.Bytes, out IImageFormat mimeType))
image.Save(memoryStream, mimeType); using (var memoryStream = new MemoryStream())
memoryStream.Flush(); {
byte[] serialized = memoryStream.ToArray(); image.Save(memoryStream, mimeType);
memoryStream.Flush();
using var image2 = Image.Load<Rgba32>(serialized); serialized = memoryStream.ToArray();
image2.Save($"{path}/{file.FileName}"); }
using (var image2 = Image.Load<Rgba32>(serialized))
{
image2.Save($"{path}/{file.FileName}");
}
} }
} }
@ -157,21 +170,25 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(10, 100, "tga")] [InlineData(10, 100, "tga")]
public void CanIdentifyImageLoadedFromBytes(int width, int height, string extension) public void CanIdentifyImageLoadedFromBytes(int width, int height, string extension)
{ {
using var image = Image.LoadPixelData(new Rgba32[width * height], width, height); using (var image = Image.LoadPixelData(new Rgba32[width * height], width, height))
using var memoryStream = new MemoryStream(); {
IImageFormat format = GetFormat(extension); using (var memoryStream = new MemoryStream())
image.Save(memoryStream, format); {
memoryStream.Position = 0; IImageFormat format = GetFormat(extension);
image.Save(memoryStream, format);
memoryStream.Position = 0;
IImageInfo imageInfo = Image.Identify(memoryStream); IImageInfo imageInfo = Image.Identify(memoryStream);
Assert.Equal(imageInfo.Width, width); Assert.Equal(imageInfo.Width, width);
Assert.Equal(imageInfo.Height, height); Assert.Equal(imageInfo.Height, height);
memoryStream.Position = 0; memoryStream.Position = 0;
imageInfo = Image.Identify(memoryStream, out IImageFormat detectedFormat); imageInfo = Image.Identify(memoryStream, out IImageFormat detectedFormat);
Assert.Equal(format, detectedFormat); Assert.Equal(format, detectedFormat);
}
}
} }
[Fact] [Fact]
@ -179,11 +196,13 @@ namespace SixLabors.ImageSharp.Tests
{ {
byte[] invalid = new byte[10]; byte[] invalid = new byte[10];
using var memoryStream = new MemoryStream(invalid); using (var memoryStream = new MemoryStream(invalid))
IImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format); {
IImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format);
Assert.Null(imageInfo); Assert.Null(imageInfo);
Assert.Null(format); Assert.Null(format);
}
} }
private static IImageFormat GetFormat(string format) private static IImageFormat GetFormat(string format)

74
tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs

@ -54,9 +54,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void Decode_VerifyAllFrames<TPixel>(TestImageProvider<TPixel> provider) public void Decode_VerifyAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.DebugSaveMultiFrame(provider); {
image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact); image.DebugSaveMultiFrame(provider);
image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact);
}
} }
[Fact] [Fact]
@ -68,11 +70,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
fixed (byte* data = testFile.Bytes.AsSpan(0, length)) fixed (byte* data = testFile.Bytes.AsSpan(0, length))
{ {
using var stream = new UnmanagedMemoryStream(data, length); using (var stream = new UnmanagedMemoryStream(data, length))
var decoder = new GifDecoder(); {
var decoder = new GifDecoder();
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream);
Assert.Equal((200, 200), (image.Width, image.Height)); using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
{
Assert.Equal((200, 200), (image.Width, image.Height));
}
}
} }
} }
@ -81,9 +87,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void GifDecoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider) public void GifDecoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.DebugSave(provider); {
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider); image.DebugSave(provider);
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider);
}
} }
[Theory] [Theory]
@ -96,10 +104,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
expectedFrameCount = 1; expectedFrameCount = 1;
} }
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Assert.Equal(expectedFrameCount, image.Frames.Count); {
image.DebugSave(provider); Assert.Equal(expectedFrameCount, image.Frames.Count);
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider); image.DebugSave(provider);
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider);
}
} }
[Theory] [Theory]
@ -107,8 +117,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void CanDecodeJustOneFrame<TPixel>(TestImageProvider<TPixel> provider) public void CanDecodeJustOneFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new GifDecoder { DecodingMode = FrameDecodingMode.First }); using (Image<TPixel> image = provider.GetImage(new GifDecoder { DecodingMode = FrameDecodingMode.First }))
Assert.Equal(1, image.Frames.Count); {
Assert.Equal(1, image.Frames.Count);
}
} }
[Theory] [Theory]
@ -116,8 +128,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void CanDecodeAllFrames<TPixel>(TestImageProvider<TPixel> provider) public void CanDecodeAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new GifDecoder { DecodingMode = FrameDecodingMode.All }); using (Image<TPixel> image = provider.GetImage(new GifDecoder { DecodingMode = FrameDecodingMode.All }))
Assert.True(image.Frames.Count > 1); {
Assert.True(image.Frames.Count > 1);
}
} }
[Theory] [Theory]
@ -128,21 +142,25 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void DetectPixelSize(string imagePath, int expectedPixelSize) public void DetectPixelSize(string imagePath, int expectedPixelSize)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel); {
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel);
}
} }
[Fact] [Fact]
public void CanDecodeIntermingledImages() public void CanDecodeIntermingledImages()
{ {
using var kumin1 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes); using (var kumin1 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes))
using var load = Image.Load(TestFile.Create(TestImages.Png.Icon).Bytes); using (Image.Load(TestFile.Create(TestImages.Png.Icon).Bytes))
using var kumin2 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes); using (var kumin2 = Image.Load(TestFile.Create(TestImages.Gif.Kumin).Bytes))
for (int i = 0; i < kumin1.Frames.Count; i++)
{ {
ImageFrame<Rgba32> first = kumin1.Frames[i]; for (int i = 0; i < kumin1.Frames.Count; i++)
ImageFrame<Rgba32> second = kumin2.Frames[i]; {
first.ComparePixelBufferTo(second.GetPixelSpan()); ImageFrame<Rgba32> first = kumin1.Frames[i];
ImageFrame<Rgba32> second = kumin2.Frames[i];
first.ComparePixelBufferTo(second.GetPixelSpan());
}
} }
} }
} }

162
tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs

@ -30,21 +30,25 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void EncodeGeneratedPatterns<TPixel>(TestImageProvider<TPixel> provider) public void EncodeGeneratedPatterns<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var encoder = new GifEncoder
{ {
// Use the palette quantizer without dithering to ensure results var encoder = new GifEncoder
// are consistent {
Quantizer = new WebSafePaletteQuantizer(false) // Use the palette quantizer without dithering to ensure results
}; // are consistent
Quantizer = new WebSafePaletteQuantizer(false)
// Always save as we need to compare the encoded output. };
provider.Utility.SaveTestOutputFile(image, "gif", encoder);
// Always save as we need to compare the encoded output.
provider.Utility.SaveTestOutputFile(image, "gif", encoder);
}
// Compare encoded result // Compare encoded result
string path = provider.Utility.GetTestOutputFileName("gif", null, true); string path = provider.Utility.GetTestOutputFileName("gif", null, true);
using var encoded = Image.Load<Rgba32>(path); using (var encoded = Image.Load<Rgba32>(path))
encoded.CompareToReferenceOutput(ValidatorComparer, provider, null, "gif"); {
encoded.CompareToReferenceOutput(ValidatorComparer, provider, null, "gif");
}
} }
[Theory] [Theory]
@ -54,16 +58,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
var options = new GifEncoder(); var options = new GifEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
ImageMetadata meta = output.Metadata; memStream.Position = 0;
Assert.Equal(xResolution, meta.HorizontalResolution); using (var output = Image.Load<Rgba32>(memStream))
Assert.Equal(yResolution, meta.VerticalResolution); {
Assert.Equal(resolutionUnit, meta.ResolutionUnits); ImageMetadata meta = output.Metadata;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
} }
[Fact] [Fact]
@ -73,15 +83,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
var testFile = TestFile.Create(TestImages.Gif.Rings); var testFile = TestFile.Create(TestImages.Gif.Rings);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
GifMetadata metadata = output.Metadata.GetGifMetadata(); memStream.Position = 0;
Assert.Equal(1, metadata.Comments.Count); using (var output = Image.Load<Rgba32>(memStream))
Assert.Equal("ImageSharp", metadata.Comments[0]); {
GifMetadata metadata = output.Metadata.GetGifMetadata();
Assert.Equal(1, metadata.Comments.Count);
Assert.Equal("ImageSharp", metadata.Comments[0]);
}
}
}
} }
[Theory] [Theory]
@ -89,65 +105,69 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void EncodeGlobalPaletteReturnsSmallerFile<TPixel>(TestImageProvider<TPixel> provider) public void EncodeGlobalPaletteReturnsSmallerFile<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var encoder = new GifEncoder
{ {
ColorTableMode = GifColorTableMode.Global, var encoder = new GifEncoder
Quantizer = new OctreeQuantizer(false) {
}; ColorTableMode = GifColorTableMode.Global,
Quantizer = new OctreeQuantizer(false)
};
// Always save as we need to compare the encoded output. // Always save as we need to compare the encoded output.
provider.Utility.SaveTestOutputFile(image, "gif", encoder, "global"); provider.Utility.SaveTestOutputFile(image, "gif", encoder, "global");
encoder.ColorTableMode = GifColorTableMode.Local; encoder.ColorTableMode = GifColorTableMode.Local;
provider.Utility.SaveTestOutputFile(image, "gif", encoder, "local"); provider.Utility.SaveTestOutputFile(image, "gif", encoder, "local");
var fileInfoGlobal = new FileInfo(provider.Utility.GetTestOutputFileName("gif", "global")); var fileInfoGlobal = new FileInfo(provider.Utility.GetTestOutputFileName("gif", "global"));
var fileInfoLocal = new FileInfo(provider.Utility.GetTestOutputFileName("gif", "local")); var fileInfoLocal = new FileInfo(provider.Utility.GetTestOutputFileName("gif", "local"));
Assert.True(fileInfoGlobal.Length < fileInfoLocal.Length); Assert.True(fileInfoGlobal.Length < fileInfoLocal.Length);
}
} }
[Fact] [Fact]
public void NonMutatingEncodePreservesPaletteCount() public void NonMutatingEncodePreservesPaletteCount()
{ {
using var inStream = new MemoryStream(TestFile.Create(TestImages.Gif.Leo).Bytes); using (var inStream = new MemoryStream(TestFile.Create(TestImages.Gif.Leo).Bytes))
using var outStream = new MemoryStream(); using (var outStream = new MemoryStream())
inStream.Position = 0;
var image = Image.Load<Rgba32>(inStream);
GifMetadata metaData = image.Metadata.GetGifMetadata();
GifFrameMetadata frameMetadata = image.Frames.RootFrame.Metadata.GetGifMetadata();
GifColorTableMode colorMode = metaData.ColorTableMode;
var encoder = new GifEncoder
{ {
ColorTableMode = colorMode, inStream.Position = 0;
Quantizer = new OctreeQuantizer(frameMetadata.ColorTableLength)
};
image.Save(outStream, encoder); var image = Image.Load<Rgba32>(inStream);
outStream.Position = 0; GifMetadata metaData = image.Metadata.GetGifMetadata();
GifFrameMetadata frameMetadata = image.Frames.RootFrame.Metadata.GetGifMetadata();
GifColorTableMode colorMode = metaData.ColorTableMode;
var encoder = new GifEncoder
{
ColorTableMode = colorMode,
Quantizer = new OctreeQuantizer(frameMetadata.ColorTableLength)
};
outStream.Position = 0; image.Save(outStream, encoder);
var clone = Image.Load<Rgba32>(outStream); outStream.Position = 0;
GifMetadata cloneMetadata = clone.Metadata.GetGifMetadata(); outStream.Position = 0;
Assert.Equal(metaData.ColorTableMode, cloneMetadata.ColorTableMode); var clone = Image.Load<Rgba32>(outStream);
// Gifiddle and Cyotek GifInfo say this image has 64 colors. GifMetadata cloneMetadata = clone.Metadata.GetGifMetadata();
Assert.Equal(64, frameMetadata.ColorTableLength); Assert.Equal(metaData.ColorTableMode, cloneMetadata.ColorTableMode);
for (int i = 0; i < image.Frames.Count; i++) // Gifiddle and Cyotek GifInfo say this image has 64 colors.
{ Assert.Equal(64, frameMetadata.ColorTableLength);
GifFrameMetadata ifm = image.Frames[i].Metadata.GetGifMetadata();
GifFrameMetadata cifm = clone.Frames[i].Metadata.GetGifMetadata();
Assert.Equal(ifm.ColorTableLength, cifm.ColorTableLength); for (int i = 0; i < image.Frames.Count; i++)
Assert.Equal(ifm.FrameDelay, cifm.FrameDelay); {
} GifFrameMetadata ifm = image.Frames[i].Metadata.GetGifMetadata();
GifFrameMetadata cifm = clone.Frames[i].Metadata.GetGifMetadata();
Assert.Equal(ifm.ColorTableLength, cifm.ColorTableLength);
Assert.Equal(ifm.FrameDelay, cifm.FrameDelay);
}
image.Dispose(); image.Dispose();
clone.Dispose(); clone.Dispose();
}
} }
} }
} }

86
tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs

@ -65,10 +65,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
var testFile = TestFile.Create(TestImages.Gif.Rings); var testFile = TestFile.Create(TestImages.Gif.Rings);
using Image<Rgba32> image = testFile.CreateRgba32Image(options); using (Image<Rgba32> image = testFile.CreateRgba32Image(options))
GifMetadata metadata = image.Metadata.GetGifMetadata(); {
Assert.Equal(1, metadata.Comments.Count); GifMetadata metadata = image.Metadata.GetGifMetadata();
Assert.Equal("ImageSharp", metadata.Comments[0]); Assert.Equal(1, metadata.Comments.Count);
Assert.Equal("ImageSharp", metadata.Comments[0]);
}
} }
[Fact] [Fact]
@ -81,9 +83,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
var testFile = TestFile.Create(TestImages.Gif.Rings); var testFile = TestFile.Create(TestImages.Gif.Rings);
using Image<Rgba32> image = testFile.CreateRgba32Image(options); using (Image<Rgba32> image = testFile.CreateRgba32Image(options))
GifMetadata metadata = image.Metadata.GetGifMetadata(); {
Assert.Equal(0, metadata.Comments.Count); GifMetadata metadata = image.Metadata.GetGifMetadata();
Assert.Equal(0, metadata.Comments.Count);
}
} }
[Fact] [Fact]
@ -92,11 +96,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
var options = new GifDecoder(); var options = new GifDecoder();
var testFile = TestFile.Create(TestImages.Gif.LargeComment); var testFile = TestFile.Create(TestImages.Gif.LargeComment);
using Image<Rgba32> image = testFile.CreateRgba32Image(options); using (Image<Rgba32> image = testFile.CreateRgba32Image(options))
GifMetadata metadata = image.Metadata.GetGifMetadata(); {
Assert.Equal(2, metadata.Comments.Count); GifMetadata metadata = image.Metadata.GetGifMetadata();
Assert.Equal(new string('c', 349), metadata.Comments[0]); Assert.Equal(2, metadata.Comments.Count);
Assert.Equal("ImageSharp", metadata.Comments[1]); Assert.Equal(new string('c', 349), metadata.Comments[0]);
Assert.Equal("ImageSharp", metadata.Comments[1]);
}
} }
[Fact] [Fact]
@ -105,16 +111,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
var decoder = new GifDecoder(); var decoder = new GifDecoder();
var testFile = TestFile.Create(TestImages.Gif.LargeComment); var testFile = TestFile.Create(TestImages.Gif.LargeComment);
using Image<Rgba32> input = testFile.CreateRgba32Image(decoder); using (Image<Rgba32> input = testFile.CreateRgba32Image(decoder))
using var memoryStream = new MemoryStream(); using (var memoryStream = new MemoryStream())
input.Save(memoryStream, new GifEncoder()); {
memoryStream.Position = 0; input.Save(memoryStream, new GifEncoder());
memoryStream.Position = 0;
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, memoryStream); using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, memoryStream))
GifMetadata metadata = image.Metadata.GetGifMetadata(); {
Assert.Equal(2, metadata.Comments.Count); GifMetadata metadata = image.Metadata.GetGifMetadata();
Assert.Equal(new string('c', 349), metadata.Comments[0]); Assert.Equal(2, metadata.Comments.Count);
Assert.Equal("ImageSharp", metadata.Comments[1]); Assert.Equal(new string('c', 349), metadata.Comments[0]);
Assert.Equal("ImageSharp", metadata.Comments[1]);
}
}
} }
[Theory] [Theory]
@ -122,13 +132,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new GifDecoder(); {
IImageInfo image = decoder.Identify(Configuration.Default, stream); var decoder = new GifDecoder();
ImageMetadata meta = image.Metadata; IImageInfo image = decoder.Identify(Configuration.Default, stream);
Assert.Equal(xResolution, meta.HorizontalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(yResolution, meta.VerticalResolution); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
} }
[Theory] [Theory]
@ -136,13 +148,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new GifDecoder(); {
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream); var decoder = new GifDecoder();
ImageMetadata meta = image.Metadata; using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
Assert.Equal(xResolution, meta.HorizontalResolution); {
Assert.Equal(yResolution, meta.VerticalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
} }
[Theory] [Theory]

12
tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs

@ -128,10 +128,14 @@ namespace SixLabors.ImageSharp.Tests
public void DetectFormatAllocatesCleanBuffer() public void DetectFormatAllocatesCleanBuffer()
{ {
byte[] jpegImage; byte[] jpegImage;
using var buffer = new MemoryStream(); using (var buffer = new MemoryStream())
using var image = new Image<Rgba32>(100, 100); {
image.SaveAsJpeg(buffer); using (var image = new Image<Rgba32>(100, 100))
jpegImage = buffer.ToArray(); {
image.SaveAsJpeg(buffer);
jpegImage = buffer.ToArray();
}
}
byte[] invalidImage = { 1, 2, 3 }; byte[] invalidImage = { 1, 2, 3 };

48
tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs

@ -41,17 +41,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{ {
Block8x8F block = CreateRandomFloatBlock(0, 100); Block8x8F block = CreateRandomFloatBlock(0, 100);
using Buffer2D<float> buffer = Configuration.Default.MemoryAllocator.Allocate2D<float>(20, 20, AllocationOptions.Clean); using (Buffer2D<float> buffer = Configuration.Default.MemoryAllocator.Allocate2D<float>(20, 20, AllocationOptions.Clean))
BufferArea<float> area = buffer.GetArea(5, 10, 8, 8); {
block.Copy1x1Scale(area); BufferArea<float> area = buffer.GetArea(5, 10, 8, 8);
block.Copy1x1Scale(area);
Assert.Equal(block[0, 0], buffer[5, 10]); Assert.Equal(block[0, 0], buffer[5, 10]);
Assert.Equal(block[1, 0], buffer[6, 10]); Assert.Equal(block[1, 0], buffer[6, 10]);
Assert.Equal(block[0, 1], buffer[5, 11]); Assert.Equal(block[0, 1], buffer[5, 11]);
Assert.Equal(block[0, 7], buffer[5, 17]); Assert.Equal(block[0, 7], buffer[5, 17]);
Assert.Equal(block[63], buffer[12, 17]); Assert.Equal(block[63], buffer[12, 17]);
VerifyAllZeroOutsideSubArea(buffer, 5, 10); VerifyAllZeroOutsideSubArea(buffer, 5, 10);
}
} }
[Theory] [Theory]
@ -67,25 +69,27 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var start = new Point(50, 50); var start = new Point(50, 50);
using Buffer2D<float> buffer = Configuration.Default.MemoryAllocator.Allocate2D<float>(100, 100, AllocationOptions.Clean); using (Buffer2D<float> buffer = Configuration.Default.MemoryAllocator.Allocate2D<float>(100, 100, AllocationOptions.Clean))
BufferArea<float> area = buffer.GetArea(start.X, start.Y, 8 * horizontalFactor, 8 * verticalFactor);
block.CopyTo(area, horizontalFactor, verticalFactor);
for (int y = 0; y < 8 * verticalFactor; y++)
{ {
for (int x = 0; x < 8 * horizontalFactor; x++) BufferArea<float> area = buffer.GetArea(start.X, start.Y, 8 * horizontalFactor, 8 * verticalFactor);
block.CopyTo(area, horizontalFactor, verticalFactor);
for (int y = 0; y < 8 * verticalFactor; y++)
{ {
int yy = y / verticalFactor; for (int x = 0; x < 8 * horizontalFactor; x++)
int xx = x / horizontalFactor; {
int yy = y / verticalFactor;
int xx = x / horizontalFactor;
float expected = block[xx, yy]; float expected = block[xx, yy];
float actual = area[x, y]; float actual = area[x, y];
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
}
} }
}
VerifyAllZeroOutsideSubArea(buffer, start.X, start.Y, horizontalFactor, verticalFactor); VerifyAllZeroOutsideSubArea(buffer, start.X, start.Y, horizontalFactor, verticalFactor);
}
} }
} }
} }

80
tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs

@ -38,21 +38,23 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void LoadAndStretchCorners_FromOrigo<TPixel>(TestImageProvider<TPixel> provider) public void LoadAndStretchCorners_FromOrigo<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> s = provider.GetImage(); using (Image<TPixel> s = provider.GetImage())
var d = default(GenericBlock8x8<TPixel>); {
d.LoadAndStretchEdges(s.Frames.RootFrame, 0, 0); var d = default(GenericBlock8x8<TPixel>);
d.LoadAndStretchEdges(s.Frames.RootFrame, 0, 0);
TPixel a = s.Frames.RootFrame[0, 0];
TPixel b = d[0, 0]; TPixel a = s.Frames.RootFrame[0, 0];
TPixel b = d[0, 0];
Assert.Equal(s[0, 0], d[0, 0]);
Assert.Equal(s[1, 0], d[1, 0]); Assert.Equal(s[0, 0], d[0, 0]);
Assert.Equal(s[7, 0], d[7, 0]); Assert.Equal(s[1, 0], d[1, 0]);
Assert.Equal(s[0, 1], d[0, 1]); Assert.Equal(s[7, 0], d[7, 0]);
Assert.Equal(s[1, 1], d[1, 1]); Assert.Equal(s[0, 1], d[0, 1]);
Assert.Equal(s[7, 0], d[7, 0]); Assert.Equal(s[1, 1], d[1, 1]);
Assert.Equal(s[0, 7], d[0, 7]); Assert.Equal(s[7, 0], d[7, 0]);
Assert.Equal(s[7, 7], d[7, 7]); Assert.Equal(s[0, 7], d[0, 7]);
Assert.Equal(s[7, 7], d[7, 7]);
}
} }
[Theory] [Theory]
@ -60,36 +62,38 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void LoadAndStretchCorners_WithOffset<TPixel>(TestImageProvider<TPixel> provider) public void LoadAndStretchCorners_WithOffset<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> s = provider.GetImage(); using (Image<TPixel> s = provider.GetImage())
var d = default(GenericBlock8x8<TPixel>); {
d.LoadAndStretchEdges(s.Frames.RootFrame, 6, 7); var d = default(GenericBlock8x8<TPixel>);
d.LoadAndStretchEdges(s.Frames.RootFrame, 6, 7);
Assert.Equal(s[6, 7], d[0, 0]); Assert.Equal(s[6, 7], d[0, 0]);
Assert.Equal(s[6, 8], d[0, 1]); Assert.Equal(s[6, 8], d[0, 1]);
Assert.Equal(s[7, 8], d[1, 1]); Assert.Equal(s[7, 8], d[1, 1]);
Assert.Equal(s[6, 9], d[0, 2]); Assert.Equal(s[6, 9], d[0, 2]);
Assert.Equal(s[6, 9], d[0, 3]); Assert.Equal(s[6, 9], d[0, 3]);
Assert.Equal(s[6, 9], d[0, 7]); Assert.Equal(s[6, 9], d[0, 7]);
Assert.Equal(s[7, 9], d[1, 2]); Assert.Equal(s[7, 9], d[1, 2]);
Assert.Equal(s[7, 9], d[1, 3]); Assert.Equal(s[7, 9], d[1, 3]);
Assert.Equal(s[7, 9], d[1, 7]); Assert.Equal(s[7, 9], d[1, 7]);
Assert.Equal(s[9, 9], d[3, 2]); Assert.Equal(s[9, 9], d[3, 2]);
Assert.Equal(s[9, 9], d[3, 3]); Assert.Equal(s[9, 9], d[3, 3]);
Assert.Equal(s[9, 9], d[3, 7]); Assert.Equal(s[9, 9], d[3, 7]);
Assert.Equal(s[9, 7], d[3, 0]); Assert.Equal(s[9, 7], d[3, 0]);
Assert.Equal(s[9, 7], d[4, 0]); Assert.Equal(s[9, 7], d[4, 0]);
Assert.Equal(s[9, 7], d[7, 0]); Assert.Equal(s[9, 7], d[7, 0]);
Assert.Equal(s[9, 9], d[3, 2]); Assert.Equal(s[9, 9], d[3, 2]);
Assert.Equal(s[9, 9], d[4, 2]); Assert.Equal(s[9, 9], d[4, 2]);
Assert.Equal(s[9, 9], d[7, 2]); Assert.Equal(s[9, 9], d[7, 2]);
Assert.Equal(s[9, 9], d[4, 3]); Assert.Equal(s[9, 9], d[4, 3]);
Assert.Equal(s[9, 9], d[7, 7]); Assert.Equal(s[9, 9], d[7, 7]);
}
} }
[Fact] [Fact]

88
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs

@ -79,13 +79,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new JpegDecoder(); {
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream); var decoder = new JpegDecoder();
ImageMetadata meta = image.Metadata; using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
Assert.Equal(xResolution, meta.HorizontalResolution); {
Assert.Equal(yResolution, meta.VerticalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
} }
[Theory] [Theory]
@ -93,13 +97,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new JpegDecoder(); {
IImageInfo image = decoder.Identify(Configuration.Default, stream); var decoder = new JpegDecoder();
ImageMetadata meta = image.Metadata; IImageInfo image = decoder.Identify(Configuration.Default, stream);
Assert.Equal(xResolution, meta.HorizontalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(yResolution, meta.VerticalResolution); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
} }
[Theory] [Theory]
@ -107,11 +113,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void Identify_VerifyQuality(string imagePath, int quality) public void Identify_VerifyQuality(string imagePath, int quality)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new JpegDecoder(); {
IImageInfo image = decoder.Identify(Configuration.Default, stream); var decoder = new JpegDecoder();
JpegMetadata meta = image.Metadata.GetJpegMetadata(); IImageInfo image = decoder.Identify(Configuration.Default, stream);
Assert.Equal(quality, meta.Quality); JpegMetadata meta = image.Metadata.GetJpegMetadata();
Assert.Equal(quality, meta.Quality);
}
} }
[Theory] [Theory]
@ -119,22 +127,28 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void Decode_VerifyQuality(string imagePath, int quality) public void Decode_VerifyQuality(string imagePath, int quality)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new JpegDecoder(); {
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream); var decoder = new JpegDecoder();
JpegMetadata meta = image.Metadata.GetJpegMetadata(); using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
Assert.Equal(quality, meta.Quality); {
JpegMetadata meta = image.Metadata.GetJpegMetadata();
Assert.Equal(quality, meta.Quality);
}
}
} }
private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action<IImageInfo> test) private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action<IImageInfo> test)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
IImageInfo imageInfo = useIdentify {
IImageInfo imageInfo = useIdentify
? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream) ? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream)
: decoder.Decode<Rgba32>(Configuration.Default, stream); : decoder.Decode<Rgba32>(Configuration.Default, stream);
test(imageInfo); test(imageInfo);
}
} }
private static void TestMetadataImpl( private static void TestMetadataImpl(
@ -201,16 +215,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
// Snake.jpg has both Exif and ICC profiles defined: // Snake.jpg has both Exif and ICC profiles defined:
var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Snake); var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Snake);
using Image<Rgba32> image = testFile.CreateRgba32Image(decoder); using (Image<Rgba32> image = testFile.CreateRgba32Image(decoder))
if (ignoreMetadata)
{ {
Assert.Null(image.Metadata.ExifProfile); if (ignoreMetadata)
Assert.Null(image.Metadata.IccProfile); {
} Assert.Null(image.Metadata.ExifProfile);
else Assert.Null(image.Metadata.IccProfile);
{ }
Assert.NotNull(image.Metadata.ExifProfile); else
Assert.NotNull(image.Metadata.IccProfile); {
Assert.NotNull(image.Metadata.ExifProfile);
Assert.NotNull(image.Metadata.IccProfile);
}
} }
} }

34
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -76,14 +76,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public void ParseStream_BasicPropertiesAreCorrect() public void ParseStream_BasicPropertiesAreCorrect()
{ {
byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes; byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes;
using var ms = new MemoryStream(bytes); using (var ms = new MemoryStream(bytes))
var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); {
decoder.ParseStream(ms); var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
decoder.ParseStream(ms);
// I don't know why these numbers are different. All I know is that the decoder works
// and spectral data is exactly correct also. // I don't know why these numbers are different. All I know is that the decoder works
// VerifyJpeg.VerifyComponentSizes3(decoder.Frame.Components, 43, 61, 22, 31, 22, 31); // and spectral data is exactly correct also.
VerifyJpeg.VerifyComponentSizes3(decoder.Frame.Components, 44, 62, 22, 31, 22, 31); // VerifyJpeg.VerifyComponentSizes3(decoder.Frame.Components, 43, 61, 22, 31, 22, 31);
VerifyJpeg.VerifyComponentSizes3(decoder.Frame.Components, 44, 62, 22, 31, 22, 31);
}
} }
public const string DecodeBaselineJpegOutputName = "DecodeBaselineJpeg"; public const string DecodeBaselineJpegOutputName = "DecodeBaselineJpeg";
@ -129,14 +131,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var comparer = ImageComparer.Tolerant(0, 0); var comparer = ImageComparer.Tolerant(0, 0);
using Image<TPixel> expectedImage = provider.GetReferenceOutputImage<TPixel>(appendPixelTypeToFileName: false); using (Image<TPixel> expectedImage = provider.GetReferenceOutputImage<TPixel>(appendPixelTypeToFileName: false))
using var pdfJsOriginalResult = Image.Load<Rgba32>(pdfJsOriginalResultPath); using (var pdfJsOriginalResult = Image.Load<Rgba32>(pdfJsOriginalResultPath))
using var pdfJsPortResult = Image.Load<Rgba32>(sourceBytes, JpegDecoder); using (var pdfJsPortResult = Image.Load<Rgba32>(sourceBytes, JpegDecoder))
ImageSimilarityReport originalReport = comparer.CompareImagesOrFrames(expectedImage, pdfJsOriginalResult); {
ImageSimilarityReport portReport = comparer.CompareImagesOrFrames(expectedImage, pdfJsPortResult); ImageSimilarityReport originalReport = comparer.CompareImagesOrFrames(expectedImage, pdfJsOriginalResult);
ImageSimilarityReport portReport = comparer.CompareImagesOrFrames(expectedImage, pdfJsPortResult);
this.Output.WriteLine($"Difference for PDF.js ORIGINAL: {originalReport.DifferencePercentageString}"); this.Output.WriteLine($"Difference for PDF.js ORIGINAL: {originalReport.DifferencePercentageString}");
this.Output.WriteLine($"Difference for PORT: {portReport.DifferencePercentageString}"); this.Output.WriteLine($"Difference for PORT: {portReport.DifferencePercentageString}");
}
} }
} }
} }

107
tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

@ -47,14 +47,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var options = new JpegEncoder(); var options = new JpegEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
JpegMetadata meta = output.Metadata.GetJpegMetadata(); memStream.Position = 0;
Assert.Equal(quality, meta.Quality); using (var output = Image.Load<Rgba32>(memStream))
{
JpegMetadata meta = output.Metadata.GetJpegMetadata();
Assert.Equal(quality, meta.Quality);
}
}
}
} }
[Theory] [Theory]
@ -102,21 +108,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
int quality = 100) int quality = 100)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
// There is no alpha in Jpeg!
image.Mutate(c => c.MakeOpaque());
var encoder = new JpegEncoder
{ {
Subsample = subsample, // There is no alpha in Jpeg!
Quality = quality image.Mutate(c => c.MakeOpaque());
};
string info = $"{subsample}-Q{quality}";
ImageComparer comparer = GetComparer(quality, subsample);
// Does DebugSave & load reference CompareToReferenceInput(): var encoder = new JpegEncoder
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png"); {
Subsample = subsample,
Quality = quality
};
string info = $"{subsample}-Q{quality}";
ImageComparer comparer = GetComparer(quality, subsample);
// Does DebugSave & load reference CompareToReferenceInput():
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png");
}
} }
[Fact] [Fact]
@ -129,15 +136,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora); var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream0 = new MemoryStream(); using (var memStream0 = new MemoryStream())
using var memStream1 = new MemoryStream(); using (var memStream1 = new MemoryStream())
input.SaveAsJpeg(memStream0, options); {
input.SaveAsJpeg(memStream0, options);
options.Quality = 1; options.Quality = 1;
input.SaveAsJpeg(memStream1, options); input.SaveAsJpeg(memStream1, options);
Assert.Equal(memStream0.ToArray(), memStream1.ToArray()); Assert.Equal(memStream0.ToArray(), memStream1.ToArray());
}
} }
[Fact] [Fact]
@ -150,15 +159,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora); var testFile = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream0 = new MemoryStream(); using (var memStream0 = new MemoryStream())
using var memStream1 = new MemoryStream(); using (var memStream1 = new MemoryStream())
input.SaveAsJpeg(memStream0, options); {
input.SaveAsJpeg(memStream0, options);
options.Quality = 100; options.Quality = 100;
input.SaveAsJpeg(memStream1, options); input.SaveAsJpeg(memStream1, options);
Assert.NotEqual(memStream0.ToArray(), memStream1.ToArray()); Assert.NotEqual(memStream0.ToArray(), memStream1.ToArray());
}
} }
[Theory] [Theory]
@ -168,16 +179,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var options = new JpegEncoder(); var options = new JpegEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
ImageMetadata meta = output.Metadata; memStream.Position = 0;
Assert.Equal(xResolution, meta.HorizontalResolution); using (var output = Image.Load<Rgba32>(memStream))
Assert.Equal(yResolution, meta.VerticalResolution); {
Assert.Equal(resolutionUnit, meta.ResolutionUnits); ImageMetadata meta = output.Metadata;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
} }
} }
} }

58
tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs

@ -34,8 +34,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
private static void SaveBuffer<TPixel>(JpegComponentPostProcessor cp, TestImageProvider<TPixel> provider) private static void SaveBuffer<TPixel>(JpegComponentPostProcessor cp, TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<Rgba32> image = cp.ColorBuffer.ToGrayscaleImage(1f / 255f); using (Image<Rgba32> image = cp.ColorBuffer.ToGrayscaleImage(1f / 255f))
image.DebugSave(provider, $"-C{cp.Component.Index}-"); {
image.DebugSave(provider, $"-C{cp.Component.Index}-");
}
} }
[Theory] [Theory]
@ -45,16 +47,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string imageFile = provider.SourceFileOrDescription; string imageFile = provider.SourceFileOrDescription;
using JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile); using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
using var pp = new JpegImagePostProcessor(Configuration.Default, decoder); using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder))
using var imageFrame = new ImageFrame<Rgba32>(Configuration.Default, decoder.ImageWidth, decoder.ImageHeight); using (var imageFrame = new ImageFrame<Rgba32>(Configuration.Default, decoder.ImageWidth, decoder.ImageHeight))
pp.DoPostProcessorStep(imageFrame); {
pp.DoPostProcessorStep(imageFrame);
JpegComponentPostProcessor[] cp = pp.ComponentProcessors; JpegComponentPostProcessor[] cp = pp.ComponentProcessors;
SaveBuffer(cp[0], provider); SaveBuffer(cp[0], provider);
SaveBuffer(cp[1], provider); SaveBuffer(cp[1], provider);
SaveBuffer(cp[2], provider); SaveBuffer(cp[2], provider);
}
} }
[Theory] [Theory]
@ -63,26 +67,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string imageFile = provider.SourceFileOrDescription; string imageFile = provider.SourceFileOrDescription;
using JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile); using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
using var pp = new JpegImagePostProcessor(Configuration.Default, decoder); using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder))
using var image = new Image<Rgba32>(decoder.ImageWidth, decoder.ImageHeight); using (var image = new Image<Rgba32>(decoder.ImageWidth, decoder.ImageHeight))
pp.PostProcess(image.Frames.RootFrame); {
pp.PostProcess(image.Frames.RootFrame);
image.DebugSave(provider); image.DebugSave(provider);
ImagingTestCaseUtility testUtil = provider.Utility; ImagingTestCaseUtility testUtil = provider.Utility;
testUtil.TestGroupName = nameof(JpegDecoderTests); testUtil.TestGroupName = nameof(JpegDecoderTests);
testUtil.TestName = JpegDecoderTests.DecodeBaselineJpegOutputName; testUtil.TestName = JpegDecoderTests.DecodeBaselineJpegOutputName;
using Image<TPixel> referenceImage = using (Image<TPixel> referenceImage =
provider.GetReferenceOutputImage<TPixel>(appendPixelTypeToFileName: false); provider.GetReferenceOutputImage<TPixel>(appendPixelTypeToFileName: false))
ImageSimilarityReport report = ImageComparer.Exact.CompareImagesOrFrames(referenceImage, image); {
ImageSimilarityReport report = ImageComparer.Exact.CompareImagesOrFrames(referenceImage, image);
this.Output.WriteLine($"*** {imageFile} ***"); this.Output.WriteLine($"*** {imageFile} ***");
this.Output.WriteLine($"Difference: {report.DifferencePercentageString}"); this.Output.WriteLine($"Difference: {report.DifferencePercentageString}");
// ReSharper disable once PossibleInvalidOperationException // ReSharper disable once PossibleInvalidOperationException
Assert.True(report.TotalNormalizedDifference.Value < 0.005f); Assert.True(report.TotalNormalizedDifference.Value < 0.005f);
}
}
} }
} }
} }

60
tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs

@ -31,24 +31,28 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{ {
var expectedColorSpace = (JpegColorSpace)expectedColorSpaceValue; var expectedColorSpace = (JpegColorSpace)expectedColorSpaceValue;
using JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile); using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
Assert.Equal(expectedColorSpace, decoder.ColorSpace); {
Assert.Equal(expectedColorSpace, decoder.ColorSpace);
}
} }
[Fact] [Fact]
public void ComponentScalingIsCorrect_1ChannelJpeg() public void ComponentScalingIsCorrect_1ChannelJpeg()
{ {
using JpegDecoderCore decoder = JpegFixture.ParseJpegStream(TestImages.Jpeg.Baseline.Jpeg400); using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(TestImages.Jpeg.Baseline.Jpeg400))
Assert.Equal(1, decoder.ComponentCount); {
Assert.Equal(1, decoder.Components.Length); Assert.Equal(1, decoder.ComponentCount);
Assert.Equal(1, decoder.Components.Length);
Size expectedSizeInBlocks = decoder.ImageSizeInPixels.DivideRoundUp(8); Size expectedSizeInBlocks = decoder.ImageSizeInPixels.DivideRoundUp(8);
Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU); Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU);
var uniform1 = new Size(1, 1); var uniform1 = new Size(1, 1);
JpegComponent c0 = decoder.Components[0]; JpegComponent c0 = decoder.Components[0];
VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1); VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1);
}
} }
[Theory] [Theory]
@ -99,30 +103,32 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var fLuma = (Size)expectedLumaFactors; var fLuma = (Size)expectedLumaFactors;
var fChroma = (Size)expectedChromaFactors; var fChroma = (Size)expectedChromaFactors;
using JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile); using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
Assert.Equal(componentCount, decoder.ComponentCount); {
Assert.Equal(componentCount, decoder.Components.Length); Assert.Equal(componentCount, decoder.ComponentCount);
Assert.Equal(componentCount, decoder.Components.Length);
JpegComponent c0 = decoder.Components[0]; JpegComponent c0 = decoder.Components[0];
JpegComponent c1 = decoder.Components[1]; JpegComponent c1 = decoder.Components[1];
JpegComponent c2 = decoder.Components[2]; JpegComponent c2 = decoder.Components[2];
var uniform1 = new Size(1, 1); var uniform1 = new Size(1, 1);
Size expectedLumaSizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(fLuma); Size expectedLumaSizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(fLuma);
Size divisor = fLuma.DivideBy(fChroma); Size divisor = fLuma.DivideBy(fChroma);
Size expectedChromaSizeInBlocks = expectedLumaSizeInBlocks.DivideRoundUp(divisor); Size expectedChromaSizeInBlocks = expectedLumaSizeInBlocks.DivideRoundUp(divisor);
VerifyJpeg.VerifyComponent(c0, expectedLumaSizeInBlocks, fLuma, uniform1); VerifyJpeg.VerifyComponent(c0, expectedLumaSizeInBlocks, fLuma, uniform1);
VerifyJpeg.VerifyComponent(c1, expectedChromaSizeInBlocks, fChroma, divisor); VerifyJpeg.VerifyComponent(c1, expectedChromaSizeInBlocks, fChroma, divisor);
VerifyJpeg.VerifyComponent(c2, expectedChromaSizeInBlocks, fChroma, divisor); VerifyJpeg.VerifyComponent(c2, expectedChromaSizeInBlocks, fChroma, divisor);
if (componentCount == 4) if (componentCount == 4)
{ {
JpegComponent c3 = decoder.Components[2]; JpegComponent c3 = decoder.Components[2];
VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, fLuma, uniform1); VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, fLuma, uniform1);
}
} }
} }
} }

20
tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs

@ -50,11 +50,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes; byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes;
using var ms = new MemoryStream(sourceBytes); using (var ms = new MemoryStream(sourceBytes))
decoder.ParseStream(ms); {
decoder.ParseStream(ms);
var data = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder); var data = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder);
VerifyJpeg.SaveSpectralImage(provider, data); VerifyJpeg.SaveSpectralImage(provider, data);
}
} }
[Theory] [Theory]
@ -71,11 +73,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes; byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes;
using var ms = new MemoryStream(sourceBytes); using (var ms = new MemoryStream(sourceBytes))
decoder.ParseStream(ms); {
var imageSharpData = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder); decoder.ParseStream(ms);
var imageSharpData = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder);
this.VerifySpectralCorrectnessImpl(provider, imageSharpData); this.VerifySpectralCorrectnessImpl(provider, imageSharpData);
}
} }
private void VerifySpectralCorrectnessImpl<TPixel>( private void VerifySpectralCorrectnessImpl<TPixel>(

10
tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs

@ -192,10 +192,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
internal static JpegDecoderCore ParseJpegStream(string testFileName, bool metaDataOnly = false) internal static JpegDecoderCore ParseJpegStream(string testFileName, bool metaDataOnly = false)
{ {
byte[] bytes = TestFile.Create(testFileName).Bytes; byte[] bytes = TestFile.Create(testFileName).Bytes;
using var ms = new MemoryStream(bytes); using (var ms = new MemoryStream(bytes))
var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); {
decoder.ParseStream(ms, metaDataOnly); var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
return decoder; decoder.ParseStream(ms, metaDataOnly);
return decoder;
}
} }
} }
} }

46
tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs

@ -98,38 +98,40 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
{ {
RunDumpJpegCoeffsTool(testFile.FullPath, coeffFileFullPath); RunDumpJpegCoeffsTool(testFile.FullPath, coeffFileFullPath);
using var dumpStream = new FileStream(coeffFileFullPath, FileMode.Open); using (var dumpStream = new FileStream(coeffFileFullPath, FileMode.Open))
using var rdr = new BinaryReader(dumpStream); using (var rdr = new BinaryReader(dumpStream))
int componentCount = rdr.ReadInt16();
var result = new ComponentData[componentCount];
for (int i = 0; i < componentCount; i++)
{ {
int widthInBlocks = rdr.ReadInt16(); int componentCount = rdr.ReadInt16();
int heightInBlocks = rdr.ReadInt16(); var result = new ComponentData[componentCount];
var resultComponent = new ComponentData(widthInBlocks, heightInBlocks, i);
result[i] = resultComponent;
}
var buffer = new byte[64 * sizeof(short)]; for (int i = 0; i < componentCount; i++)
{
int widthInBlocks = rdr.ReadInt16();
int heightInBlocks = rdr.ReadInt16();
var resultComponent = new ComponentData(widthInBlocks, heightInBlocks, i);
result[i] = resultComponent;
}
for (int i = 0; i < result.Length; i++) var buffer = new byte[64 * sizeof(short)];
{
ComponentData c = result[i];
for (int y = 0; y < c.HeightInBlocks; y++) for (int i = 0; i < result.Length; i++)
{ {
for (int x = 0; x < c.WidthInBlocks; x++) ComponentData c = result[i];
for (int y = 0; y < c.HeightInBlocks; y++)
{ {
rdr.Read(buffer, 0, buffer.Length); for (int x = 0; x < c.WidthInBlocks; x++)
{
rdr.Read(buffer, 0, buffer.Length);
short[] block = MemoryMarshal.Cast<byte, short>(buffer.AsSpan()).ToArray(); short[] block = MemoryMarshal.Cast<byte, short>(buffer.AsSpan()).ToArray();
c.MakeBlock(block, y, x); c.MakeBlock(block, y, x);
}
} }
} }
}
return new SpectralData(result); return new SpectralData(result);
}
} }
finally finally
{ {

8
tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs

@ -58,9 +58,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
output?.WriteLine("Min: " + comp.MinVal); output?.WriteLine("Min: " + comp.MinVal);
output?.WriteLine("Max: " + comp.MaxVal); output?.WriteLine("Max: " + comp.MaxVal);
using Image<Rgba32> image = comp.CreateGrayScaleImage(); using (Image<Rgba32> image = comp.CreateGrayScaleImage())
string details = $"C{comp.Index}"; {
image.DebugSave(provider, details, appendPixelTypeToFileName: false); string details = $"C{comp.Index}";
image.DebugSave(provider, details, appendPixelTypeToFileName: false);
}
} }
Image<Rgba32> fullImage = data.TryCreateRGBSpectralImage(); Image<Rgba32> fullImage = data.TryCreateRGBSpectralImage();

18
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs

@ -63,17 +63,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
{ {
string chunkName = GetChunkTypeName(chunkType); string chunkName = GetChunkTypeName(chunkType);
using var memStream = new MemoryStream(); using (var memStream = new MemoryStream())
WriteHeaderChunk(memStream); {
WriteChunk(memStream, chunkName); WriteHeaderChunk(memStream);
WriteDataChunk(memStream); WriteChunk(memStream, chunkName);
WriteDataChunk(memStream);
var decoder = new PngDecoder(); var decoder = new PngDecoder();
ImageFormatException exception = ImageFormatException exception =
Assert.Throws<ImageFormatException>(() => decoder.Decode<Rgb24>(null, memStream)); Assert.Throws<ImageFormatException>(() => decoder.Decode<Rgb24>(null, memStream));
Assert.Equal($"CRC Error. PNG {chunkName} chunk is corrupt!", exception.Message); Assert.Equal($"CRC Error. PNG {chunkName} chunk is corrupt!", exception.Message);
}
} }
private static string GetChunkTypeName(uint value) private static string GetChunkTypeName(uint value)

102
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

@ -87,20 +87,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode<TPixel>(TestImageProvider<TPixel> provider) public void Decode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider);
// 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.DebugSave(provider);
// 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)
{ {
image.CompareToOriginal(provider, ImageComparer.Exact, (IImageDecoder)SystemDrawingReferenceDecoder.Instance); if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider, ImageComparer.Exact, (IImageDecoder)SystemDrawingReferenceDecoder.Instance);
}
}
else
{
image.CompareToOriginal(provider, ImageComparer.Exact);
} }
}
else
{
image.CompareToOriginal(provider, ImageComparer.Exact);
} }
} }
@ -109,9 +111,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode_Interlaced_ImageIsCorrect<TPixel>(TestImageProvider<TPixel> provider) public void Decode_Interlaced_ImageIsCorrect<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -119,9 +123,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode_48Bpp<TPixel>(TestImageProvider<TPixel> provider) public void Decode_48Bpp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -129,9 +135,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode_64Bpp<TPixel>(TestImageProvider<TPixel> provider) public void Decode_64Bpp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -139,9 +147,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decoder_L8bitInterlaced<TPixel>(TestImageProvider<TPixel> provider) public void Decoder_L8bitInterlaced<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -149,9 +159,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode_L16Bit<TPixel>(TestImageProvider<TPixel> provider) public void Decode_L16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -159,9 +171,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode_GrayAlpha16Bit<TPixel>(TestImageProvider<TPixel> provider) public void Decode_GrayAlpha16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -169,9 +183,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decoder_CanDecodeGrey8bitWithAlpha<TPixel>(TestImageProvider<TPixel> provider) public void Decoder_CanDecodeGrey8bitWithAlpha<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -179,9 +195,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider) public void Decoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
} }
[Theory] [Theory]
@ -195,8 +213,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Identify(string imagePath, int expectedPixelSize) public void Identify(string imagePath, int expectedPixelSize)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel); {
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel);
}
} }
[Theory] [Theory]
@ -207,9 +227,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
System.Exception ex = Record.Exception( System.Exception ex = Record.Exception(
() => () =>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
image.DebugSave(provider); {
image.CompareToOriginal(provider, ImageComparer.Exact); image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}); });
Assert.Null(ex); Assert.Null(ex);
} }

224
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -278,24 +278,26 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void WritesFileMarker<TPixel>(TestImageProvider<TPixel> provider) public void WritesFileMarker<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using var ms = new MemoryStream(); using (var ms = new MemoryStream())
image.Save(ms, new PngEncoder());
byte[] data = ms.ToArray().Take(8).ToArray();
byte[] expected =
{ {
0x89, // Set the high bit. image.Save(ms, new PngEncoder());
0x50, // P
0x4E, // N byte[] data = ms.ToArray().Take(8).ToArray();
0x47, // G byte[] expected =
0x0D, // Line ending CRLF {
0x0A, // Line ending CRLF 0x89, // Set the high bit.
0x1A, // EOF 0x50, // P
0x0A // LF 0x4E, // N
}; 0x47, // G
0x0D, // Line ending CRLF
Assert.Equal(expected, data); 0x0A, // Line ending CRLF
0x1A, // EOF
0x0A // LF
};
Assert.Equal(expected, data);
}
} }
[Theory] [Theory]
@ -305,16 +307,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
var options = new PngEncoder(); var options = new PngEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
memStream.Position = 0; input.Save(memStream, options);
using var output = Image.Load<Rgba32>(memStream);
ImageMetadata meta = output.Metadata; memStream.Position = 0;
Assert.Equal(xResolution, meta.HorizontalResolution); using (var output = Image.Load<Rgba32>(memStream))
Assert.Equal(yResolution, meta.VerticalResolution); {
Assert.Equal(resolutionUnit, meta.ResolutionUnits); ImageMetadata meta = output.Metadata;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
} }
[Theory] [Theory]
@ -324,15 +332,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
var options = new PngEncoder(); var options = new PngEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
{
input.Save(memStream, options);
memStream.Position = 0; memStream.Position = 0;
using var output = Image.Load<Rgba32>(memStream); using (var output = Image.Load<Rgba32>(memStream))
PngMetadata meta = output.Metadata.GetPngMetadata(); {
PngMetadata meta = output.Metadata.GetPngMetadata();
Assert.Equal(pngBitDepth, meta.BitDepth); Assert.Equal(pngBitDepth, meta.BitDepth);
}
}
}
} }
[Theory] [Theory]
@ -342,45 +356,51 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
var options = new PngEncoder(); var options = new PngEncoder();
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
PngMetadata inMeta = input.Metadata.GetPngMetadata();
Assert.True(inMeta.HasTransparency);
using var memStream = new MemoryStream();
input.Save(memStream, options);
memStream.Position = 0;
using var output = Image.Load<Rgba32>(memStream);
PngMetadata outMeta = output.Metadata.GetPngMetadata();
Assert.True(outMeta.HasTransparency);
switch (pngColorType)
{ {
case PngColorType.Grayscale: PngMetadata inMeta = input.Metadata.GetPngMetadata();
if (pngBitDepth.Equals(PngBitDepth.Bit16)) Assert.True(inMeta.HasTransparency);
{
Assert.True(outMeta.TransparentL16.HasValue); using (var memStream = new MemoryStream())
Assert.Equal(inMeta.TransparentL16, outMeta.TransparentL16); {
} input.Save(memStream, options);
else memStream.Position = 0;
{ using (var output = Image.Load<Rgba32>(memStream))
Assert.True(outMeta.TransparentL8.HasValue);
Assert.Equal(inMeta.TransparentL8, outMeta.TransparentL8);
}
break;
case PngColorType.Rgb:
if (pngBitDepth.Equals(PngBitDepth.Bit16))
{
Assert.True(outMeta.TransparentRgb48.HasValue);
Assert.Equal(inMeta.TransparentRgb48, outMeta.TransparentRgb48);
}
else
{ {
Assert.True(outMeta.TransparentRgb24.HasValue); PngMetadata outMeta = output.Metadata.GetPngMetadata();
Assert.Equal(inMeta.TransparentRgb24, outMeta.TransparentRgb24); Assert.True(outMeta.HasTransparency);
switch (pngColorType)
{
case PngColorType.Grayscale:
if (pngBitDepth.Equals(PngBitDepth.Bit16))
{
Assert.True(outMeta.TransparentL16.HasValue);
Assert.Equal(inMeta.TransparentL16, outMeta.TransparentL16);
}
else
{
Assert.True(outMeta.TransparentL8.HasValue);
Assert.Equal(inMeta.TransparentL8, outMeta.TransparentL8);
}
break;
case PngColorType.Rgb:
if (pngBitDepth.Equals(PngBitDepth.Bit16))
{
Assert.True(outMeta.TransparentRgb48.HasValue);
Assert.Equal(inMeta.TransparentRgb48, outMeta.TransparentRgb48);
}
else
{
Assert.True(outMeta.TransparentRgb24.HasValue);
Assert.Equal(inMeta.TransparentRgb24, outMeta.TransparentRgb24);
}
break;
}
} }
}
break;
} }
} }
@ -400,37 +420,41 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
bool appendPngBitDepth = false) bool appendPngBitDepth = false)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var encoder = new PngEncoder
{ {
ColorType = pngColorType, var encoder = new PngEncoder
FilterMethod = pngFilterMethod, {
CompressionLevel = compressionLevel, ColorType = pngColorType,
BitDepth = bitDepth, FilterMethod = pngFilterMethod,
Quantizer = new WuQuantizer(paletteSize), CompressionLevel = compressionLevel,
InterlaceMethod = interlaceMode BitDepth = bitDepth,
}; Quantizer = new WuQuantizer(paletteSize),
InterlaceMethod = interlaceMode
string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : string.Empty; };
string pngFilterMethodInfo = appendPngFilterMethod ? pngFilterMethod.ToString() : string.Empty;
string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : string.Empty; string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : string.Empty;
string paletteSizeInfo = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : string.Empty; string pngFilterMethodInfo = appendPngFilterMethod ? pngFilterMethod.ToString() : string.Empty;
string pngBitDepthInfo = appendPngBitDepth ? bitDepth.ToString() : string.Empty; string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : string.Empty;
string pngInterlaceModeInfo = interlaceMode != PngInterlaceMode.None ? $"_{interlaceMode}" : string.Empty; string paletteSizeInfo = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : string.Empty;
string pngBitDepthInfo = appendPngBitDepth ? bitDepth.ToString() : string.Empty;
string debugInfo = $"{pngColorTypeInfo}{pngFilterMethodInfo}{compressionLevelInfo}{paletteSizeInfo}{pngBitDepthInfo}{pngInterlaceModeInfo}"; string pngInterlaceModeInfo = interlaceMode != PngInterlaceMode.None ? $"_{interlaceMode}" : string.Empty;
string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); string debugInfo = $"{pngColorTypeInfo}{pngFilterMethodInfo}{compressionLevelInfo}{paletteSizeInfo}{pngBitDepthInfo}{pngInterlaceModeInfo}";
// Compare to the Magick reference decoder. string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
// Compare to the Magick reference decoder.
// We compare using both our decoder and the reference decoder as pixel transformation IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
// occurs within the encoder itself leaving the input image unaffected.
// This means we are benefiting from testing our decoder also. // We compare using both our decoder and the reference decoder as pixel transformation
using var imageSharpImage = Image.Load<TPixel>(actualOutputFile, new PngDecoder()); // occurs within the encoder itself leaving the input image unaffected.
using var referenceImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder); // This means we are benefiting from testing our decoder also.
ImageComparer.Exact.VerifySimilarity(referenceImage, imageSharpImage); using (var imageSharpImage = Image.Load<TPixel>(actualOutputFile, new PngDecoder()))
using (var referenceImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
{
ImageComparer.Exact.VerifySimilarity(referenceImage, imageSharpImage);
}
}
} }
} }
} }

185
tests/ImageSharp.Tests/Formats/Png/PngMetadataTests.cs

@ -53,19 +53,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decoder_CanReadTextData<TPixel>(TestImageProvider<TPixel> provider) public void Decoder_CanReadTextData<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); {
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Comment") && m.Value.Equals("comment")); PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Author") && m.Value.Equals("ImageSharp")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Comment") && m.Value.Equals("comment"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Copyright") && m.Value.Equals("ImageSharp")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Author") && m.Value.Equals("ImageSharp"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Title") && m.Value.Equals("unittest")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Copyright") && m.Value.Equals("ImageSharp"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Description") && m.Value.Equals("compressed-text")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Title") && m.Value.Equals("unittest"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("International") && m.Value.Equals("'e', mu'tlheghvam, ghaH yu'") && m.LanguageTag.Equals("x-klingon") && m.TranslatedKeyword.Equals("warning")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Description") && m.Value.Equals("compressed-text"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("International2") && m.Value.Equals("ИМАГЕШАРП") && m.LanguageTag.Equals("rus")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("International") && m.Value.Equals("'e', mu'tlheghvam, ghaH yu'") && m.LanguageTag.Equals("x-klingon") && m.TranslatedKeyword.Equals("warning"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational") && m.Value.Equals("la plume de la mante") && m.LanguageTag.Equals("fra") && m.TranslatedKeyword.Equals("foobar")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("International2") && m.Value.Equals("ИМАГЕШАРП") && m.LanguageTag.Equals("rus"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational2") && m.Value.Equals("這是一個考驗") && m.LanguageTag.Equals("chinese")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational") && m.Value.Equals("la plume de la mante") && m.LanguageTag.Equals("fra") && m.TranslatedKeyword.Equals("foobar"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoLang") && m.Value.Equals("this text chunk is missing a language tag")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational2") && m.Value.Equals("這是一個考驗") && m.LanguageTag.Equals("chinese"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoTranslatedKeyword") && m.Value.Equals("dieser chunk hat kein übersetztes Schlüßelwort")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoLang") && m.Value.Equals("this text chunk is missing a language tag"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoTranslatedKeyword") && m.Value.Equals("dieser chunk hat kein übersetztes Schlüßelwort"));
}
} }
[Theory] [Theory]
@ -74,24 +76,28 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
var decoder = new PngDecoder(); var decoder = new PngDecoder();
using Image<TPixel> input = provider.GetImage(decoder); using (Image<TPixel> input = provider.GetImage(decoder))
using var memoryStream = new MemoryStream(); using (var memoryStream = new MemoryStream())
input.Save(memoryStream, new PngEncoder()); {
input.Save(memoryStream, new PngEncoder());
memoryStream.Position = 0;
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, memoryStream); memoryStream.Position = 0;
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, memoryStream))
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Comment") && m.Value.Equals("comment")); {
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Author") && m.Value.Equals("ImageSharp")); PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Copyright") && m.Value.Equals("ImageSharp")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Comment") && m.Value.Equals("comment"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Title") && m.Value.Equals("unittest")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Author") && m.Value.Equals("ImageSharp"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("Description") && m.Value.Equals("compressed-text")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Copyright") && m.Value.Equals("ImageSharp"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("International") && m.Value.Equals("'e', mu'tlheghvam, ghaH yu'") && m.LanguageTag.Equals("x-klingon") && m.TranslatedKeyword.Equals("warning")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Title") && m.Value.Equals("unittest"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("International2") && m.Value.Equals("ИМАГЕШАРП") && m.LanguageTag.Equals("rus")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("Description") && m.Value.Equals("compressed-text"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational") && m.Value.Equals("la plume de la mante") && m.LanguageTag.Equals("fra") && m.TranslatedKeyword.Equals("foobar")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("International") && m.Value.Equals("'e', mu'tlheghvam, ghaH yu'") && m.LanguageTag.Equals("x-klingon") && m.TranslatedKeyword.Equals("warning"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational2") && m.Value.Equals("這是一個考驗") && m.LanguageTag.Equals("chinese")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("International2") && m.Value.Equals("ИМАГЕШАРП") && m.LanguageTag.Equals("rus"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoLang") && m.Value.Equals("this text chunk is missing a language tag")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational") && m.Value.Equals("la plume de la mante") && m.LanguageTag.Equals("fra") && m.TranslatedKeyword.Equals("foobar"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoTranslatedKeyword") && m.Value.Equals("dieser chunk hat kein übersetztes Schlüßelwort")); Assert.Contains(meta.TextData, m => m.Keyword.Equals("CompressedInternational2") && m.Value.Equals("這是一個考驗") && m.LanguageTag.Equals("chinese"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoLang") && m.Value.Equals("this text chunk is missing a language tag"));
Assert.Contains(meta.TextData, m => m.Keyword.Equals("NoTranslatedKeyword") && m.Value.Equals("dieser chunk hat kein übersetztes Schlüßelwort"));
}
}
} }
[Theory] [Theory]
@ -99,14 +105,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decoder_IgnoresInvalidTextData<TPixel>(TestImageProvider<TPixel> provider) public void Decoder_IgnoresInvalidTextData<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new PngDecoder()); using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); {
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("leading space")); PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("trailing space")); Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("leading space"));
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("space")); Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("trailing space"));
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("empty")); Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("space"));
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("invalid characters")); Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("empty"));
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("too large")); Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("invalid characters"));
Assert.DoesNotContain(meta.TextData, m => m.Value.Equals("too large"));
}
} }
[Theory] [Theory]
@ -115,27 +123,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
var decoder = new PngDecoder(); var decoder = new PngDecoder();
using Image<TPixel> input = provider.GetImage(decoder); using (Image<TPixel> input = provider.GetImage(decoder))
using var memoryStream = new MemoryStream(); using (var memoryStream = new MemoryStream())
// This will be a zTXt chunk.
var expectedText = new PngTextData("large-text", new string('c', 100), string.Empty, string.Empty);
// This will be a iTXt chunk.
var expectedTextNoneLatin = new PngTextData("large-text-non-latin", new string('Ф', 100), "language-tag", "translated-keyword");
PngMetadata inputMetadata = input.Metadata.GetFormatMetadata(PngFormat.Instance);
inputMetadata.TextData.Add(expectedText);
inputMetadata.TextData.Add(expectedTextNoneLatin);
input.Save(memoryStream, new PngEncoder
{ {
TextCompressionThreshold = 50 // This will be a zTXt chunk.
}); var expectedText = new PngTextData("large-text", new string('c', 100), string.Empty, string.Empty);
memoryStream.Position = 0; // This will be a iTXt chunk.
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, memoryStream); var expectedTextNoneLatin = new PngTextData("large-text-non-latin", new string('Ф', 100), "language-tag", "translated-keyword");
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); PngMetadata inputMetadata = input.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.Contains(meta.TextData, m => m.Equals(expectedText)); inputMetadata.TextData.Add(expectedText);
Assert.Contains(meta.TextData, m => m.Equals(expectedTextNoneLatin)); inputMetadata.TextData.Add(expectedTextNoneLatin);
input.Save(memoryStream, new PngEncoder
{
TextCompressionThreshold = 50
});
memoryStream.Position = 0;
using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, memoryStream))
{
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.Contains(meta.TextData, m => m.Equals(expectedText));
Assert.Contains(meta.TextData, m => m.Equals(expectedTextNoneLatin));
}
}
} }
[Fact] [Fact]
@ -148,13 +159,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
var testFile = TestFile.Create(TestImages.Png.Blur); var testFile = TestFile.Create(TestImages.Png.Blur);
using Image<Rgba32> image = testFile.CreateRgba32Image(options); using (Image<Rgba32> image = testFile.CreateRgba32Image(options))
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); {
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.Equal(1, meta.TextData.Count); Assert.Equal(1, meta.TextData.Count);
Assert.Equal("Software", meta.TextData[0].Keyword); Assert.Equal("Software", meta.TextData[0].Keyword);
Assert.Equal("paint.net 4.0.6", meta.TextData[0].Value); Assert.Equal("paint.net 4.0.6", meta.TextData[0].Value);
Assert.Equal(0.4545d, meta.Gamma, precision: 4); Assert.Equal(0.4545d, meta.Gamma, precision: 4);
}
} }
[Fact] [Fact]
@ -167,9 +180,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
var testFile = TestFile.Create(TestImages.Png.Blur); var testFile = TestFile.Create(TestImages.Png.Blur);
using Image<Rgba32> image = testFile.CreateRgba32Image(options); using (Image<Rgba32> image = testFile.CreateRgba32Image(options))
PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance); {
Assert.Equal(0, meta.TextData.Count); PngMetadata meta = image.Metadata.GetFormatMetadata(PngFormat.Instance);
Assert.Equal(0, meta.TextData.Count);
}
} }
[Theory] [Theory]
@ -177,13 +192,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new PngDecoder(); {
using Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream); var decoder = new PngDecoder();
ImageMetadata meta = image.Metadata; using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
Assert.Equal(xResolution, meta.HorizontalResolution); {
Assert.Equal(yResolution, meta.VerticalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
} }
[Theory] [Theory]
@ -191,13 +210,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{ {
var testFile = TestFile.Create(imagePath); var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false); using (var stream = new MemoryStream(testFile.Bytes, false))
var decoder = new PngDecoder(); {
IImageInfo image = decoder.Identify(Configuration.Default, stream); var decoder = new PngDecoder();
ImageMetadata meta = image.Metadata; IImageInfo image = decoder.Identify(Configuration.Default, stream);
Assert.Equal(xResolution, meta.HorizontalResolution); ImageMetadata meta = image.Metadata;
Assert.Equal(yResolution, meta.VerticalResolution); Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits); Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
} }
} }
} }

44
tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs

@ -18,16 +18,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
// does saving a file then reopening mean both files are identical??? // does saving a file then reopening mean both files are identical???
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using var ms = new MemoryStream(); using (var ms = new MemoryStream())
{
// image.Save(provider.Utility.GetTestOutputFileName("bmp")); // image.Save(provider.Utility.GetTestOutputFileName("bmp"));
image.Save(ms, new PngEncoder()); image.Save(ms, new PngEncoder());
ms.Position = 0; ms.Position = 0;
using var img2 = Image.Load<Rgba32>(ms, new PngDecoder()); using (var img2 = Image.Load<Rgba32>(ms, new PngDecoder()))
ImageComparer.Tolerant().VerifySimilarity(image, img2); {
ImageComparer.Tolerant().VerifySimilarity(image, img2);
// img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder()); // img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder());
}
}
} }
/* JJS: Disabled for now as the decoder now correctly decodes the full pixel components if the /* JJS: Disabled for now as the decoder now correctly decodes the full pixel components if the
@ -100,17 +103,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
// does saving a file then reopening mean both files are identical??? // does saving a file then reopening mean both files are identical???
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using var ms = new MemoryStream(); using (var ms = new MemoryStream())
{
// image.Save(provider.Utility.GetTestOutputFileName("png")); // image.Save(provider.Utility.GetTestOutputFileName("png"));
image.Mutate(x => x.Resize(100, 100)); image.Mutate(x => x.Resize(100, 100));
// image.Save(provider.Utility.GetTestOutputFileName("png", "resize")); // image.Save(provider.Utility.GetTestOutputFileName("png", "resize"));
image.Save(ms, new PngEncoder()); image.Save(ms, new PngEncoder());
ms.Position = 0; ms.Position = 0;
using var img2 = Image.Load<Rgba32>(ms, new PngDecoder()); using (var img2 = Image.Load<Rgba32>(ms, new PngDecoder()))
ImageComparer.Tolerant().VerifySimilarity(image, img2); {
ImageComparer.Tolerant().VerifySimilarity(image, img2);
}
}
} }
} }
} }

120
tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs

@ -18,9 +18,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_Uncompressed_MonoChrome<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_Uncompressed_MonoChrome<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -28,9 +30,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_Uncompressed_15Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_Uncompressed_15Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -38,9 +42,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_15Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_15Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -48,9 +54,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_Uncompressed_16Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_Uncompressed_16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -58,9 +66,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_WithPalette_16Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_WithPalette_16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -68,9 +78,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_Uncompressed_24Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_Uncompressed_24Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -78,9 +90,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_WithTopLeftOrigin_24Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_WithTopLeftOrigin_24Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -88,9 +102,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_Palette_WithTopLeftOrigin_24Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_Palette_WithTopLeftOrigin_24Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -98,9 +114,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_Uncompressed_32Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_Uncompressed_32Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -108,9 +126,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -118,9 +138,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_16Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -128,9 +150,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_24Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_24Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -138,9 +162,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_RunLengthEncoded_32Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_RunLengthEncoded_32Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -148,9 +174,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_WithPalette_16Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_WithPalette_16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
[Theory] [Theory]
@ -158,9 +186,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public void TgaDecoder_CanDecode_WithPalette_24Bit<TPixel>(TestImageProvider<TPixel> provider) public void TgaDecoder_CanDecode_WithPalette_24Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(new TgaDecoder()); using (Image<TPixel> image = provider.GetImage(new TgaDecoder()))
image.DebugSave(provider); {
TgaTestUtils.CompareWithReferenceDecoder(provider, image); image.DebugSave(provider);
TgaTestUtils.CompareWithReferenceDecoder(provider, image);
}
} }
} }
} }

66
tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs

@ -37,14 +37,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
{ {
var options = new TgaEncoder(); var options = new TgaEncoder();
var testFile = TestFile.Create(imagePath); TestFile testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
memStream.Position = 0; {
using var output = Image.Load<Rgba32>(memStream); input.Save(memStream, options);
TgaMetadata meta = output.Metadata.GetTgaMetadata(); memStream.Position = 0;
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel); using (Image<Rgba32> output = Image.Load<Rgba32>(memStream))
{
TgaMetadata meta = output.Metadata.GetTgaMetadata();
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel);
}
}
}
} }
[Theory] [Theory]
@ -56,14 +62,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
Compression = TgaCompression.RunLength Compression = TgaCompression.RunLength
}; };
var testFile = TestFile.Create(imagePath); TestFile testFile = TestFile.Create(imagePath);
using Image<Rgba32> input = testFile.CreateRgba32Image(); using (Image<Rgba32> input = testFile.CreateRgba32Image())
using var memStream = new MemoryStream(); {
input.Save(memStream, options); using (var memStream = new MemoryStream())
memStream.Position = 0; {
using var output = Image.Load<Rgba32>(memStream); input.Save(memStream, options);
TgaMetadata meta = output.Metadata.GetTgaMetadata(); memStream.Position = 0;
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel); using (var output = Image.Load<Rgba32>(memStream))
{
TgaMetadata meta = output.Metadata.GetTgaMetadata();
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel);
}
}
}
} }
[Theory] [Theory]
@ -118,14 +130,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
float compareTolerance = 0.01f) float compareTolerance = 0.01f)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var encoder = new TgaEncoder { BitsPerPixel = bitsPerPixel, Compression = compression }; {
var encoder = new TgaEncoder { BitsPerPixel = bitsPerPixel, Compression = compression };
using var memStream = new MemoryStream();
image.Save(memStream, encoder); using (var memStream = new MemoryStream())
memStream.Position = 0; {
using var encodedImage = (Image<TPixel>)Image.Load(memStream); image.Save(memStream, encoder);
TgaTestUtils.CompareWithReferenceDecoder(provider, encodedImage, useExactComparer, compareTolerance); memStream.Position = 0;
using (var encodedImage = (Image<TPixel>)Image.Load(memStream))
{
TgaTestUtils.CompareWithReferenceDecoder(provider, encodedImage, useExactComparer, compareTolerance);
}
}
}
} }
} }
} }

28
tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs

@ -42,22 +42,24 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
public static Image<TPixel> DecodeWithMagick<TPixel>(Configuration configuration, FileInfo fileInfo) public static Image<TPixel> DecodeWithMagick<TPixel>(Configuration configuration, FileInfo fileInfo)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using var magickImage = new MagickImage(fileInfo); using (var magickImage = new MagickImage(fileInfo))
var result = new Image<TPixel>(configuration, magickImage.Width, magickImage.Height);
Span<TPixel> resultPixels = result.GetPixelSpan();
using (IPixelCollection pixels = magickImage.GetPixelsUnsafe())
{ {
byte[] data = pixels.ToByteArray(PixelMapping.RGBA); var result = new Image<TPixel>(configuration, magickImage.Width, magickImage.Height);
Span<TPixel> resultPixels = result.GetPixelSpan();
PixelOperations<TPixel>.Instance.FromRgba32Bytes( using (IPixelCollection pixels = magickImage.GetPixelsUnsafe())
configuration, {
data, byte[] data = pixels.ToByteArray(PixelMapping.RGBA);
resultPixels,
resultPixels.Length);
}
return result; PixelOperations<TPixel>.Instance.FromRgba32Bytes(
configuration,
data,
resultPixels,
resultPixels.Length);
}
return result;
}
} }
} }
} }

60
tests/ImageSharp.Tests/Helpers/ParallelHelperTests.cs

@ -295,41 +295,43 @@ namespace SixLabors.ImageSharp.Tests.Helpers
{ {
MemoryAllocator memoryAllocator = Configuration.Default.MemoryAllocator; MemoryAllocator memoryAllocator = Configuration.Default.MemoryAllocator;
using Buffer2D<Point> expected = memoryAllocator.Allocate2D<Point>(bufferWidth, bufferHeight, AllocationOptions.Clean); using (Buffer2D<Point> expected = memoryAllocator.Allocate2D<Point>(bufferWidth, bufferHeight, AllocationOptions.Clean))
using Buffer2D<Point> actual = memoryAllocator.Allocate2D<Point>(bufferWidth, bufferHeight, AllocationOptions.Clean); using (Buffer2D<Point> actual = memoryAllocator.Allocate2D<Point>(bufferWidth, bufferHeight, AllocationOptions.Clean))
var rect = new Rectangle(rectX, rectY, rectWidth, rectHeight);
void FillRow(int y, Buffer2D<Point> buffer)
{ {
for (int x = rect.Left; x < rect.Right; x++) var rect = new Rectangle(rectX, rectY, rectWidth, rectHeight);
{
buffer[x, y] = new Point(x, y);
}
}
// Fill Expected data: void FillRow(int y, Buffer2D<Point> buffer)
for (int y = rectY; y < rect.Bottom; y++)
{
FillRow(y, expected);
}
// Fill actual data using IterateRows:
var settings = new ParallelExecutionSettings(maxDegreeOfParallelism, memoryAllocator);
ParallelHelper.IterateRows(
rect,
settings,
rows =>
{ {
this.output.WriteLine(rows.ToString()); for (int x = rect.Left; x < rect.Right; x++)
for (int y = rows.Min; y < rows.Max; y++)
{ {
FillRow(y, actual); buffer[x, y] = new Point(x, y);
} }
}); }
// Fill Expected data:
for (int y = rectY; y < rect.Bottom; y++)
{
FillRow(y, expected);
}
// Fill actual data using IterateRows:
var settings = new ParallelExecutionSettings(maxDegreeOfParallelism, memoryAllocator);
// Assert: ParallelHelper.IterateRows(
TestImageExtensions.CompareBuffers(expected.GetSpan(), actual.GetSpan()); rect,
settings,
rows =>
{
this.output.WriteLine(rows.ToString());
for (int y = rows.Min; y < rows.Max; y++)
{
FillRow(y, actual);
}
});
// Assert:
TestImageExtensions.CompareBuffers(expected.GetSpan(), actual.GetSpan());
}
} }
[Theory] [Theory]

18
tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs

@ -19,18 +19,20 @@ namespace SixLabors.ImageSharp.Tests.Helpers
[InlineData(10, 20, 0, 1)] [InlineData(10, 20, 0, 1)]
public void GetMultiRowSpan(int width, int height, int min, int max) public void GetMultiRowSpan(int width, int height, int min, int max)
{ {
using Buffer2D<int> buffer = Configuration.Default.MemoryAllocator.Allocate2D<int>(width, height); using (Buffer2D<int> buffer = Configuration.Default.MemoryAllocator.Allocate2D<int>(width, height))
var rows = new RowInterval(min, max); {
var rows = new RowInterval(min, max);
Span<int> span = buffer.GetMultiRowSpan(rows); Span<int> span = buffer.GetMultiRowSpan(rows);
ref int expected0 = ref buffer.GetSpan()[min * width]; ref int expected0 = ref buffer.GetSpan()[min * width];
int expectedLength = (max - min) * width; int expectedLength = (max - min) * width;
ref int actual0 = ref span[0]; ref int actual0 = ref span[0];
Assert.Equal(span.Length, expectedLength); Assert.Equal(span.Length, expectedLength);
Assert.True(Unsafe.AreSame(ref expected0, ref actual0)); Assert.True(Unsafe.AreSame(ref expected0, ref actual0));
}
} }
[Fact] [Fact]

190
tests/ImageSharp.Tests/IO/DoubleBufferedStreamReaderTests.cs

@ -16,58 +16,64 @@ namespace SixLabors.ImageSharp.Tests.IO
[Fact] [Fact]
public void DoubleBufferedStreamReaderCanReadSingleByteFromOrigin() public void DoubleBufferedStreamReaderCanReadSingleByteFromOrigin()
{ {
using MemoryStream stream = this.CreateTestStream(); using (MemoryStream stream = this.CreateTestStream())
byte[] expected = stream.ToArray(); {
var reader = new DoubleBufferedStreamReader(this.allocator, stream); byte[] expected = stream.ToArray();
var reader = new DoubleBufferedStreamReader(this.allocator, stream);
Assert.Equal(expected[0], reader.ReadByte()); Assert.Equal(expected[0], reader.ReadByte());
// We've read a whole chunk but increment by 1 in our reader. // We've read a whole chunk but increment by 1 in our reader.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength); Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength);
Assert.Equal(1, reader.Position); Assert.Equal(1, reader.Position);
}
} }
[Fact] [Fact]
public void DoubleBufferedStreamReaderCanReadSingleByteFromOffset() public void DoubleBufferedStreamReaderCanReadSingleByteFromOffset()
{ {
using MemoryStream stream = this.CreateTestStream(); using (MemoryStream stream = this.CreateTestStream())
byte[] expected = stream.ToArray(); {
const int offset = 5; byte[] expected = stream.ToArray();
var reader = new DoubleBufferedStreamReader(this.allocator, stream); const int offset = 5;
reader.Position = offset; var reader = new DoubleBufferedStreamReader(this.allocator, stream);
reader.Position = offset;
Assert.Equal(expected[offset], reader.ReadByte()); Assert.Equal(expected[offset], reader.ReadByte());
// We've read a whole chunk but increment by 1 in our reader. // We've read a whole chunk but increment by 1 in our reader.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength + offset); Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength + offset);
Assert.Equal(offset + 1, reader.Position); Assert.Equal(offset + 1, reader.Position);
}
} }
[Fact] [Fact]
public void DoubleBufferedStreamReaderCanReadSubsequentSingleByteCorrectly() public void DoubleBufferedStreamReaderCanReadSubsequentSingleByteCorrectly()
{ {
using MemoryStream stream = this.CreateTestStream(); using (MemoryStream stream = this.CreateTestStream())
byte[] expected = stream.ToArray();
var reader = new DoubleBufferedStreamReader(this.allocator, stream);
for (int i = 0; i < expected.Length; i++)
{ {
Assert.Equal(expected[i], reader.ReadByte()); byte[] expected = stream.ToArray();
Assert.Equal(i + 1, reader.Position); var reader = new DoubleBufferedStreamReader(this.allocator, stream);
if (i < DoubleBufferedStreamReader.ChunkLength) for (int i = 0; i < expected.Length; i++)
{ {
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength); Assert.Equal(expected[i], reader.ReadByte());
} Assert.Equal(i + 1, reader.Position);
else if (i >= DoubleBufferedStreamReader.ChunkLength && i < DoubleBufferedStreamReader.ChunkLength * 2)
{ if (i < DoubleBufferedStreamReader.ChunkLength)
// We should have advanced to the second chunk now. {
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 2); Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength);
} }
else else if (i >= DoubleBufferedStreamReader.ChunkLength && i < DoubleBufferedStreamReader.ChunkLength * 2)
{ {
// We should have advanced to the third chunk now. // We should have advanced to the second chunk now.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 3); Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 2);
}
else
{
// We should have advanced to the third chunk now.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 3);
}
} }
} }
} }
@ -75,49 +81,53 @@ namespace SixLabors.ImageSharp.Tests.IO
[Fact] [Fact]
public void DoubleBufferedStreamReaderCanReadMultipleBytesFromOrigin() public void DoubleBufferedStreamReaderCanReadMultipleBytesFromOrigin()
{ {
using MemoryStream stream = this.CreateTestStream(); using (MemoryStream stream = this.CreateTestStream())
var buffer = new byte[2]; {
byte[] expected = stream.ToArray(); var buffer = new byte[2];
var reader = new DoubleBufferedStreamReader(this.allocator, stream); byte[] expected = stream.ToArray();
var reader = new DoubleBufferedStreamReader(this.allocator, stream);
Assert.Equal(2, reader.Read(buffer, 0, 2));
Assert.Equal(expected[0], buffer[0]); Assert.Equal(2, reader.Read(buffer, 0, 2));
Assert.Equal(expected[1], buffer[1]); Assert.Equal(expected[0], buffer[0]);
Assert.Equal(expected[1], buffer[1]);
// We've read a whole chunk but increment by the buffer length in our reader.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength); // We've read a whole chunk but increment by the buffer length in our reader.
Assert.Equal(buffer.Length, reader.Position); Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength);
Assert.Equal(buffer.Length, reader.Position);
}
} }
[Fact] [Fact]
public void DoubleBufferedStreamReaderCanReadSubsequentMultipleByteCorrectly() public void DoubleBufferedStreamReaderCanReadSubsequentMultipleByteCorrectly()
{ {
using MemoryStream stream = this.CreateTestStream(); using (MemoryStream stream = this.CreateTestStream())
var buffer = new byte[2];
byte[] expected = stream.ToArray();
var reader = new DoubleBufferedStreamReader(this.allocator, stream);
for (int i = 0, o = 0; i < expected.Length / 2; i++, o += 2)
{ {
Assert.Equal(2, reader.Read(buffer, 0, 2)); var buffer = new byte[2];
Assert.Equal(expected[o], buffer[0]); byte[] expected = stream.ToArray();
Assert.Equal(expected[o + 1], buffer[1]); var reader = new DoubleBufferedStreamReader(this.allocator, stream);
Assert.Equal(o + 2, reader.Position);
int offset = i * 2; for (int i = 0, o = 0; i < expected.Length / 2; i++, o += 2)
if (offset < DoubleBufferedStreamReader.ChunkLength)
{ {
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength); Assert.Equal(2, reader.Read(buffer, 0, 2));
} Assert.Equal(expected[o], buffer[0]);
else if (offset >= DoubleBufferedStreamReader.ChunkLength && offset < DoubleBufferedStreamReader.ChunkLength * 2) Assert.Equal(expected[o + 1], buffer[1]);
{ Assert.Equal(o + 2, reader.Position);
// We should have advanced to the second chunk now.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 2); int offset = i * 2;
} if (offset < DoubleBufferedStreamReader.ChunkLength)
else {
{ Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength);
// We should have advanced to the third chunk now. }
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 3); else if (offset >= DoubleBufferedStreamReader.ChunkLength && offset < DoubleBufferedStreamReader.ChunkLength * 2)
{
// We should have advanced to the second chunk now.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 2);
}
else
{
// We should have advanced to the third chunk now.
Assert.Equal(stream.Position, DoubleBufferedStreamReader.ChunkLength * 3);
}
} }
} }
} }
@ -125,31 +135,33 @@ namespace SixLabors.ImageSharp.Tests.IO
[Fact] [Fact]
public void DoubleBufferedStreamReaderCanSkip() public void DoubleBufferedStreamReaderCanSkip()
{ {
using MemoryStream stream = this.CreateTestStream(); using (MemoryStream stream = this.CreateTestStream())
byte[] expected = stream.ToArray(); {
var reader = new DoubleBufferedStreamReader(this.allocator, stream); byte[] expected = stream.ToArray();
var reader = new DoubleBufferedStreamReader(this.allocator, stream);
int skip = 50; int skip = 50;
int plusOne = 1; int plusOne = 1;
int skip2 = DoubleBufferedStreamReader.ChunkLength; int skip2 = DoubleBufferedStreamReader.ChunkLength;
// Skip // Skip
reader.Skip(skip); reader.Skip(skip);
Assert.Equal(skip, reader.Position); Assert.Equal(skip, reader.Position);
Assert.Equal(stream.Position, reader.Position); Assert.Equal(stream.Position, reader.Position);
// Read // Read
Assert.Equal(expected[skip], reader.ReadByte()); Assert.Equal(expected[skip], reader.ReadByte());
// Skip Again // Skip Again
reader.Skip(skip2); reader.Skip(skip2);
// First Skip + First Read + Second Skip // First Skip + First Read + Second Skip
int position = skip + plusOne + skip2; int position = skip + plusOne + skip2;
Assert.Equal(position, reader.Position); Assert.Equal(position, reader.Position);
Assert.Equal(stream.Position, reader.Position); Assert.Equal(stream.Position, reader.Position);
Assert.Equal(expected[position], reader.ReadByte()); Assert.Equal(expected[position], reader.ReadByte());
}
} }
private MemoryStream CreateTestStream() private MemoryStream CreateTestStream()

116
tests/ImageSharp.Tests/Image/ImageCloneTests.cs

@ -32,22 +32,24 @@ namespace SixLabors.ImageSharp.Tests
[WithTestPatternImages(9, 9, PixelTypes.Rgba32)] [WithTestPatternImages(9, 9, PixelTypes.Rgba32)]
public void CloneAs_ToBgra32(TestImageProvider<Rgba32> provider) public void CloneAs_ToBgra32(TestImageProvider<Rgba32> provider)
{ {
using Image<Rgba32> image = provider.GetImage(); using (Image<Rgba32> image = provider.GetImage())
using Image<Bgra32> clone = image.CloneAs<Bgra32>(); using (Image<Bgra32> clone = image.CloneAs<Bgra32>())
for (int y = 0; y < image.Height; y++)
{ {
Span<Rgba32> row = image.GetPixelRowSpan(y); for (int y = 0; y < image.Height; y++)
Span<Bgra32> rowClone = clone.GetPixelRowSpan(y);
for (int x = 0; x < image.Width; x++)
{ {
Rgba32 expected = row[x]; Span<Rgba32> row = image.GetPixelRowSpan(y);
Bgra32 actual = rowClone[x]; Span<Bgra32> rowClone = clone.GetPixelRowSpan(y);
Assert.Equal(expected.R, actual.R); for (int x = 0; x < image.Width; x++)
Assert.Equal(expected.G, actual.G); {
Assert.Equal(expected.B, actual.B); Rgba32 expected = row[x];
Assert.Equal(expected.A, actual.A); Bgra32 actual = rowClone[x];
Assert.Equal(expected.R, actual.R);
Assert.Equal(expected.G, actual.G);
Assert.Equal(expected.B, actual.B);
Assert.Equal(expected.A, actual.A);
}
} }
} }
} }
@ -56,21 +58,23 @@ namespace SixLabors.ImageSharp.Tests
[WithTestPatternImages(9, 9, PixelTypes.Rgba32)] [WithTestPatternImages(9, 9, PixelTypes.Rgba32)]
public void CloneAs_ToBgr24(TestImageProvider<Rgba32> provider) public void CloneAs_ToBgr24(TestImageProvider<Rgba32> provider)
{ {
using Image<Rgba32> image = provider.GetImage(); using (Image<Rgba32> image = provider.GetImage())
using Image<Bgr24> clone = image.CloneAs<Bgr24>(); using (Image<Bgr24> clone = image.CloneAs<Bgr24>())
for (int y = 0; y < image.Height; y++)
{ {
Span<Rgba32> row = image.GetPixelRowSpan(y); for (int y = 0; y < image.Height; y++)
Span<Bgr24> rowClone = clone.GetPixelRowSpan(y);
for (int x = 0; x < image.Width; x++)
{ {
Rgba32 expected = row[x]; Span<Rgba32> row = image.GetPixelRowSpan(y);
Bgr24 actual = rowClone[x]; Span<Bgr24> rowClone = clone.GetPixelRowSpan(y);
Assert.Equal(expected.R, actual.R); for (int x = 0; x < image.Width; x++)
Assert.Equal(expected.G, actual.G); {
Assert.Equal(expected.B, actual.B); Rgba32 expected = row[x];
Bgr24 actual = rowClone[x];
Assert.Equal(expected.R, actual.R);
Assert.Equal(expected.G, actual.G);
Assert.Equal(expected.B, actual.B);
}
} }
} }
} }
@ -79,22 +83,24 @@ namespace SixLabors.ImageSharp.Tests
[WithTestPatternImages(9, 9, PixelTypes.Rgba32)] [WithTestPatternImages(9, 9, PixelTypes.Rgba32)]
public void CloneAs_ToArgb32(TestImageProvider<Rgba32> provider) public void CloneAs_ToArgb32(TestImageProvider<Rgba32> provider)
{ {
using Image<Rgba32> image = provider.GetImage(); using (Image<Rgba32> image = provider.GetImage())
using Image<Argb32> clone = image.CloneAs<Argb32>(); using (Image<Argb32> clone = image.CloneAs<Argb32>())
for (int y = 0; y < image.Height; y++)
{ {
Span<Rgba32> row = image.GetPixelRowSpan(y); for (int y = 0; y < image.Height; y++)
Span<Argb32> rowClone = clone.GetPixelRowSpan(y);
for (int x = 0; x < image.Width; x++)
{ {
Rgba32 expected = row[x]; Span<Rgba32> row = image.GetPixelRowSpan(y);
Argb32 actual = rowClone[x]; Span<Argb32> rowClone = clone.GetPixelRowSpan(y);
Assert.Equal(expected.R, actual.R); for (int x = 0; x < image.Width; x++)
Assert.Equal(expected.G, actual.G); {
Assert.Equal(expected.B, actual.B); Rgba32 expected = row[x];
Assert.Equal(expected.A, actual.A); Argb32 actual = rowClone[x];
Assert.Equal(expected.R, actual.R);
Assert.Equal(expected.G, actual.G);
Assert.Equal(expected.B, actual.B);
Assert.Equal(expected.A, actual.A);
}
} }
} }
} }
@ -103,21 +109,23 @@ namespace SixLabors.ImageSharp.Tests
[WithTestPatternImages(9, 9, PixelTypes.Rgba32)] [WithTestPatternImages(9, 9, PixelTypes.Rgba32)]
public void CloneAs_ToRgb24(TestImageProvider<Rgba32> provider) public void CloneAs_ToRgb24(TestImageProvider<Rgba32> provider)
{ {
using Image<Rgba32> image = provider.GetImage(); using (Image<Rgba32> image = provider.GetImage())
using Image<Rgb24> clone = image.CloneAs<Rgb24>(); using (Image<Rgb24> clone = image.CloneAs<Rgb24>())
for (int y = 0; y < image.Height; y++)
{ {
Span<Rgba32> row = image.GetPixelRowSpan(y); for (int y = 0; y < image.Height; y++)
Span<Rgb24> rowClone = clone.GetPixelRowSpan(y);
for (int x = 0; x < image.Width; x++)
{ {
Rgba32 expected = row[x]; Span<Rgba32> row = image.GetPixelRowSpan(y);
Rgb24 actual = rowClone[x]; Span<Rgb24> rowClone = clone.GetPixelRowSpan(y);
Assert.Equal(expected.R, actual.R); for (int x = 0; x < image.Width; x++)
Assert.Equal(expected.G, actual.G); {
Assert.Equal(expected.B, actual.B); Rgba32 expected = row[x];
Rgb24 actual = rowClone[x];
Assert.Equal(expected.R, actual.R);
Assert.Equal(expected.G, actual.G);
Assert.Equal(expected.B, actual.B);
}
} }
} }
} }

30
tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs

@ -192,11 +192,15 @@ namespace SixLabors.ImageSharp.Tests
public void CloneFrame<TPixel>(TestImageProvider<TPixel> provider) public void CloneFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> img = provider.GetImage(); using (Image<TPixel> img = provider.GetImage())
img.Frames.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10)); // add a frame anyway {
using Image<TPixel> cloned = img.Frames.CloneFrame(0); img.Frames.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10)); // add a frame anyway
Assert.Equal(2, img.Frames.Count); using (Image<TPixel> cloned = img.Frames.CloneFrame(0))
cloned.ComparePixelBufferTo(img.GetPixelSpan()); {
Assert.Equal(2, img.Frames.Count);
cloned.ComparePixelBufferTo(img.GetPixelSpan());
}
}
} }
[Theory] [Theory]
@ -204,13 +208,17 @@ namespace SixLabors.ImageSharp.Tests
public void ExtractFrame<TPixel>(TestImageProvider<TPixel> provider) public void ExtractFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> img = provider.GetImage(); using (Image<TPixel> img = provider.GetImage())
var sourcePixelData = img.GetPixelSpan().ToArray(); {
var sourcePixelData = img.GetPixelSpan().ToArray();
img.Frames.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10)); img.Frames.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10));
using Image<TPixel> cloned = img.Frames.ExportFrame(0); using (Image<TPixel> cloned = img.Frames.ExportFrame(0))
Assert.Equal(1, img.Frames.Count); {
cloned.ComparePixelBufferTo(sourcePixelData); Assert.Equal(1, img.Frames.Count);
cloned.ComparePixelBufferTo(sourcePixelData);
}
}
} }
[Fact] [Fact]

81
tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs

@ -148,16 +148,20 @@ namespace SixLabors.ImageSharp.Tests
public void CloneFrame<TPixel>(TestImageProvider<TPixel> provider) public void CloneFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> img = provider.GetImage(); using (Image<TPixel> img = provider.GetImage())
ImageFrameCollection nonGenericFrameCollection = img.Frames; {
ImageFrameCollection nonGenericFrameCollection = img.Frames;
nonGenericFrameCollection.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10)); // add a frame anyway nonGenericFrameCollection.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10)); // add a frame anyway
using Image cloned = nonGenericFrameCollection.CloneFrame(0); using (Image cloned = nonGenericFrameCollection.CloneFrame(0))
Assert.Equal(2, img.Frames.Count); {
Assert.Equal(2, img.Frames.Count);
var expectedClone = (Image<TPixel>)cloned; var expectedClone = (Image<TPixel>)cloned;
expectedClone.ComparePixelBufferTo(img.GetPixelSpan()); expectedClone.ComparePixelBufferTo(img.GetPixelSpan());
}
}
} }
[Theory] [Theory]
@ -165,17 +169,21 @@ namespace SixLabors.ImageSharp.Tests
public void ExtractFrame<TPixel>(TestImageProvider<TPixel> provider) public void ExtractFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> img = provider.GetImage(); using (Image<TPixel> img = provider.GetImage())
var sourcePixelData = img.GetPixelSpan().ToArray(); {
var sourcePixelData = img.GetPixelSpan().ToArray();
ImageFrameCollection nonGenericFrameCollection = img.Frames; ImageFrameCollection nonGenericFrameCollection = img.Frames;
nonGenericFrameCollection.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10)); nonGenericFrameCollection.AddFrame(new ImageFrame<TPixel>(Configuration.Default, 10, 10));
using Image cloned = nonGenericFrameCollection.ExportFrame(0); using (Image cloned = nonGenericFrameCollection.ExportFrame(0))
Assert.Equal(1, img.Frames.Count); {
Assert.Equal(1, img.Frames.Count);
var expectedClone = (Image<TPixel>)cloned; var expectedClone = (Image<TPixel>)cloned;
expectedClone.ComparePixelBufferTo(sourcePixelData); expectedClone.ComparePixelBufferTo(sourcePixelData);
}
}
} }
[Fact] [Fact]
@ -262,34 +270,39 @@ namespace SixLabors.ImageSharp.Tests
public void ConstructGif_FromDifferentPixelTypes<TPixel>(TestImageProvider<TPixel> provider) public void ConstructGif_FromDifferentPixelTypes<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image source = provider.GetImage(); using (Image source = provider.GetImage())
using var dest = new Image<TPixel>(source.GetConfiguration(), source.Width, source.Height); using (var dest = new Image<TPixel>(source.GetConfiguration(), source.Width, source.Height))
{
// Giphy.gif has 5 frames // Giphy.gif has 5 frames
ImportFrameAs<Bgra32>(source.Frames, dest.Frames, 0); ImportFrameAs<Bgra32>(source.Frames, dest.Frames, 0);
ImportFrameAs<Argb32>(source.Frames, dest.Frames, 1); ImportFrameAs<Argb32>(source.Frames, dest.Frames, 1);
ImportFrameAs<Rgba64>(source.Frames, dest.Frames, 2); ImportFrameAs<Rgba64>(source.Frames, dest.Frames, 2);
ImportFrameAs<Rgba32>(source.Frames, dest.Frames, 3); ImportFrameAs<Rgba32>(source.Frames, dest.Frames, 3);
ImportFrameAs<Bgra32>(source.Frames, dest.Frames, 4); ImportFrameAs<Bgra32>(source.Frames, dest.Frames, 4);
// Drop the original empty root frame: // Drop the original empty root frame:
dest.Frames.RemoveFrame(0); dest.Frames.RemoveFrame(0);
dest.DebugSave(provider, appendSourceFileOrDescription: false, extension: "gif"); dest.DebugSave(provider, appendSourceFileOrDescription: false, extension: "gif");
dest.CompareToOriginal(provider); dest.CompareToOriginal(provider);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
CompareGifMetadata(source.Frames[i], dest.Frames[i]); CompareGifMetadata(source.Frames[i], dest.Frames[i]);
}
} }
} }
private static void ImportFrameAs<TPixel>(ImageFrameCollection source, ImageFrameCollection destination, int index) private static void ImportFrameAs<TPixel>(ImageFrameCollection source, ImageFrameCollection destination, int index)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image temp = source.CloneFrame(index); using (Image temp = source.CloneFrame(index))
using Image<TPixel> temp2 = temp.CloneAs<TPixel>(); {
destination.AddFrame(temp2.Frames.RootFrame); using (Image<TPixel> temp2 = temp.CloneAs<TPixel>())
{
destination.AddFrame(temp2.Frames.RootFrame);
}
}
} }
private static void CompareGifMetadata(ImageFrame a, ImageFrame b) private static void CompareGifMetadata(ImageFrame a, ImageFrame b)

12
tests/ImageSharp.Tests/Image/ImageRotationTests.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. // Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -47,10 +47,12 @@ namespace SixLabors.ImageSharp.Tests
private static (Size original, Size rotated) Rotate(int angle) private static (Size original, Size rotated) Rotate(int angle)
{ {
var file = TestFile.Create(TestImages.Bmp.Car); var file = TestFile.Create(TestImages.Bmp.Car);
using var image = Image.Load<Rgba32>(file.FullPath); using (var image = Image.Load<Rgba32>(file.FullPath))
Size original = image.Size(); {
image.Mutate(x => x.Rotate(angle)); Size original = image.Size();
return (original, image.Size()); image.Mutate(x => x.Rotate(angle));
return (original, image.Size());
}
} }
} }
} }

8
tests/ImageSharp.Tests/Image/ImageTests.DetectFormat.cs

@ -71,9 +71,11 @@ namespace SixLabors.ImageSharp.Tests
[Fact] [Fact]
public void FromStream_GlobalConfiguration() public void FromStream_GlobalConfiguration()
{ {
using var stream = new MemoryStream(this.ActualImageBytes); using (var stream = new MemoryStream(this.ActualImageBytes))
IImageFormat type = Image.DetectFormat(stream); {
Assert.Equal(ExpectedGlobalFormat, type); IImageFormat type = Image.DetectFormat(stream);
Assert.Equal(ExpectedGlobalFormat, type);
}
} }
[Fact] [Fact]

40
tests/ImageSharp.Tests/Image/ImageTests.LoadPixelData.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. // Licensed under the Apache License, Version 2.0.
using System; using System;
@ -18,15 +18,17 @@ namespace SixLabors.ImageSharp.Tests
{ {
Rgba32[] data = { Rgba32.Black, Rgba32.White, Rgba32.White, Rgba32.Black, }; Rgba32[] data = { Rgba32.Black, Rgba32.White, Rgba32.White, Rgba32.Black, };
using Image<Rgba32> img = useSpan using (Image<Rgba32> img = useSpan
? Image.LoadPixelData<Rgba32>(data.AsSpan(), 2, 2) ? Image.LoadPixelData<Rgba32>(data.AsSpan(), 2, 2)
: Image.LoadPixelData<Rgba32>(data, 2, 2); : Image.LoadPixelData<Rgba32>(data, 2, 2))
Assert.NotNull(img); {
Assert.Equal(Rgba32.Black, img[0, 0]); Assert.NotNull(img);
Assert.Equal(Rgba32.White, img[0, 1]); Assert.Equal(Rgba32.Black, img[0, 0]);
Assert.Equal(Rgba32.White, img[0, 1]);
Assert.Equal(Rgba32.White, img[1, 0]); Assert.Equal(Rgba32.White, img[1, 0]);
Assert.Equal(Rgba32.Black, img[1, 1]); Assert.Equal(Rgba32.Black, img[1, 1]);
}
} }
[Theory] [Theory]
@ -41,16 +43,18 @@ namespace SixLabors.ImageSharp.Tests
255, 255, 255, 255, // 1,0 255, 255, 255, 255, // 1,0
0, 0, 0, 255, // 1,1 0, 0, 0, 255, // 1,1
}; };
using Image<Rgba32> img = useSpan using (Image<Rgba32> img = useSpan
? Image.LoadPixelData<Rgba32>(data.AsSpan(), 2, 2) ? Image.LoadPixelData<Rgba32>(data.AsSpan(), 2, 2)
: Image.LoadPixelData<Rgba32>(data, 2, 2); : Image.LoadPixelData<Rgba32>(data, 2, 2))
Assert.NotNull(img); {
Assert.Equal(Rgba32.Black, img[0, 0]); Assert.NotNull(img);
Assert.Equal(Rgba32.White, img[0, 1]); Assert.Equal(Rgba32.Black, img[0, 0]);
Assert.Equal(Rgba32.White, img[0, 1]);
Assert.Equal(Rgba32.White, img[1, 0]); Assert.Equal(Rgba32.White, img[1, 0]);
Assert.Equal(Rgba32.Black, img[1, 1]); Assert.Equal(Rgba32.Black, img[1, 1]);
}
} }
} }
} }
} }

40
tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_UseDefaultConfiguration.cs

@ -25,45 +25,57 @@ namespace SixLabors.ImageSharp.Tests
[Fact] [Fact]
public void Path_Specific() public void Path_Specific()
{ {
using var img = Image.Load<Rgba32>(this.Path); using (var img = Image.Load<Rgba32>(this.Path))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Path_Agnostic() public void Path_Agnostic()
{ {
using var img = Image.Load(this.Path); using (var img = Image.Load(this.Path))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Path_Decoder_Specific() public void Path_Decoder_Specific()
{ {
using var img = Image.Load<Rgba32>(this.Path, new BmpDecoder()); using (var img = Image.Load<Rgba32>(this.Path, new BmpDecoder()))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Path_Decoder_Agnostic() public void Path_Decoder_Agnostic()
{ {
using var img = Image.Load(this.Path, new BmpDecoder()); using (var img = Image.Load(this.Path, new BmpDecoder()))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Path_OutFormat_Specific() public void Path_OutFormat_Specific()
{ {
using var img = Image.Load<Rgba32>(this.Path, out IImageFormat format); using (var img = Image.Load<Rgba32>(this.Path, out IImageFormat format))
VerifyDecodedImage(img); {
Assert.IsType<BmpFormat>(format); VerifyDecodedImage(img);
Assert.IsType<BmpFormat>(format);
}
} }
[Fact] [Fact]
public void Path_OutFormat_Agnostic() public void Path_OutFormat_Agnostic()
{ {
using var img = Image.Load(this.Path, out IImageFormat format); using (var img = Image.Load(this.Path, out IImageFormat format))
VerifyDecodedImage(img); {
Assert.IsType<BmpFormat>(format); VerifyDecodedImage(img);
Assert.IsType<BmpFormat>(format);
}
} }
[Fact] [Fact]

40
tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs

@ -29,8 +29,10 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(true)] [InlineData(true)]
public void Bytes_Specific(bool useSpan) public void Bytes_Specific(bool useSpan)
{ {
using var img = useSpan ? Image.Load<Rgba32>(ByteSpan) : Image.Load<Rgba32>(ByteArray); using (var img = useSpan ? Image.Load<Rgba32>(ByteSpan) : Image.Load<Rgba32>(ByteArray))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Theory] [Theory]
@ -38,8 +40,10 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(true)] [InlineData(true)]
public void Bytes_Agnostic(bool useSpan) public void Bytes_Agnostic(bool useSpan)
{ {
using var img = useSpan ? Image.Load(ByteSpan) : Image.Load(ByteArray); using (var img = useSpan ? Image.Load(ByteSpan) : Image.Load(ByteArray))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Theory] [Theory]
@ -47,8 +51,10 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(true)] [InlineData(true)]
public void Bytes_Decoder_Specific(bool useSpan) public void Bytes_Decoder_Specific(bool useSpan)
{ {
using var img = useSpan ? Image.Load<Rgba32>(ByteSpan, new BmpDecoder()) : Image.Load<Rgba32>(ByteArray, new BmpDecoder()); using (var img = useSpan ? Image.Load<Rgba32>(ByteSpan, new BmpDecoder()) : Image.Load<Rgba32>(ByteArray, new BmpDecoder()))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Theory] [Theory]
@ -56,8 +62,10 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(true)] [InlineData(true)]
public void Bytes_Decoder_Agnostic(bool useSpan) public void Bytes_Decoder_Agnostic(bool useSpan)
{ {
using var img = useSpan ? Image.Load(ByteSpan, new BmpDecoder()) : Image.Load(ByteArray, new BmpDecoder()); using (var img = useSpan ? Image.Load(ByteSpan, new BmpDecoder()) : Image.Load(ByteArray, new BmpDecoder()))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Theory] [Theory]
@ -66,9 +74,11 @@ namespace SixLabors.ImageSharp.Tests
public void Bytes_OutFormat_Specific(bool useSpan) public void Bytes_OutFormat_Specific(bool useSpan)
{ {
IImageFormat format; IImageFormat format;
using var img = useSpan ? Image.Load<Rgba32>(ByteSpan, out format) : Image.Load<Rgba32>(ByteArray, out format); using (var img = useSpan ? Image.Load<Rgba32>(ByteSpan, out format) : Image.Load<Rgba32>(ByteArray, out format))
VerifyDecodedImage(img); {
Assert.IsType<BmpFormat>(format); VerifyDecodedImage(img);
Assert.IsType<BmpFormat>(format);
}
} }
[Theory] [Theory]
@ -77,9 +87,11 @@ namespace SixLabors.ImageSharp.Tests
public void Bytes_OutFormat_Agnostic(bool useSpan) public void Bytes_OutFormat_Agnostic(bool useSpan)
{ {
IImageFormat format; IImageFormat format;
using var img = useSpan ? Image.Load(ByteSpan, out format) : Image.Load(ByteArray, out format); using (var img = useSpan ? Image.Load(ByteSpan, out format) : Image.Load(ByteArray, out format))
VerifyDecodedImage(img); {
Assert.IsType<BmpFormat>(format); VerifyDecodedImage(img);
Assert.IsType<BmpFormat>(format);
}
} }
} }
} }

40
tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_UseDefaultConfiguration.cs

@ -28,45 +28,57 @@ namespace SixLabors.ImageSharp.Tests
[Fact] [Fact]
public void Stream_Specific() public void Stream_Specific()
{ {
using var img = Image.Load<Rgba32>(this.Stream); using (var img = Image.Load<Rgba32>(this.Stream))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Stream_Agnostic() public void Stream_Agnostic()
{ {
using var img = Image.Load(this.Stream); using (var img = Image.Load(this.Stream))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Stream_OutFormat_Specific() public void Stream_OutFormat_Specific()
{ {
using var img = Image.Load<Rgba32>(this.Stream, out IImageFormat format); using (var img = Image.Load<Rgba32>(this.Stream, out IImageFormat format))
VerifyDecodedImage(img); {
Assert.IsType<BmpFormat>(format); VerifyDecodedImage(img);
Assert.IsType<BmpFormat>(format);
}
} }
[Fact] [Fact]
public void Stream_Decoder_Specific() public void Stream_Decoder_Specific()
{ {
using var img = Image.Load<Rgba32>(this.Stream, new BmpDecoder()); using (var img = Image.Load<Rgba32>(this.Stream, new BmpDecoder()))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Stream_Decoder_Agnostic() public void Stream_Decoder_Agnostic()
{ {
using var img = Image.Load(this.Stream, new BmpDecoder()); using (var img = Image.Load(this.Stream, new BmpDecoder()))
VerifyDecodedImage(img); {
VerifyDecodedImage(img);
}
} }
[Fact] [Fact]
public void Stream_OutFormat_Agnostic() public void Stream_OutFormat_Agnostic()
{ {
using var img = Image.Load(this.Stream, out IImageFormat format); using (var img = Image.Load(this.Stream, out IImageFormat format))
VerifyDecodedImage(img); {
Assert.IsType<BmpFormat>(format); VerifyDecodedImage(img);
Assert.IsType<BmpFormat>(format);
}
} }
public void Dispose() public void Dispose()

28
tests/ImageSharp.Tests/Image/ImageTests.Save.cs

@ -44,10 +44,12 @@ namespace SixLabors.ImageSharp.Tests
Assert.Throws<NotSupportedException>( Assert.Throws<NotSupportedException>(
() => () =>
{ {
using var image = new Image<Rgba32>(10, 10); using (var image = new Image<Rgba32>(10, 10))
image.Save(file); {
}); image.Save(file);
}
});
} }
[Fact] [Fact]
@ -56,11 +58,15 @@ namespace SixLabors.ImageSharp.Tests
string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests)); string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageTests));
string file = System.IO.Path.Combine(dir, "SetEncoding.dat"); string file = System.IO.Path.Combine(dir, "SetEncoding.dat");
using var image = new Image<Rgba32>(10, 10); using (var image = new Image<Rgba32>(10, 10))
image.Save(file, new PngEncoder()); {
image.Save(file, new PngEncoder());
}
using var load = Image.Load(file, out var mime); using (Image.Load(file, out var mime))
Assert.Equal("image/png", mime.DefaultMimeType); {
Assert.Equal("image/png", mime.DefaultMimeType);
}
} }
[Fact] [Fact]
@ -69,8 +75,10 @@ namespace SixLabors.ImageSharp.Tests
var image = new Image<Rgba32>(5, 5); var image = new Image<Rgba32>(5, 5);
image.Dispose(); image.Dispose();
IImageEncoder encoder = Mock.Of<IImageEncoder>(); IImageEncoder encoder = Mock.Of<IImageEncoder>();
using var stream = new MemoryStream(); using (var stream = new MemoryStream())
Assert.Throws<ObjectDisposedException>(() => image.Save(stream, encoder)); {
Assert.Throws<ObjectDisposedException>(() => image.Save(stream, encoder));
}
} }
} }
} }

88
tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs

@ -88,12 +88,14 @@ namespace SixLabors.ImageSharp.Tests
var array = new Rgba32[25]; var array = new Rgba32[25];
var memory = new Memory<Rgba32>(array); var memory = new Memory<Rgba32>(array);
using var image = Image.WrapMemory(cfg, memory, 5, 5, metaData); using (var image = Image.WrapMemory(cfg, memory, 5, 5, metaData))
ref Rgba32 pixel0 = ref image.GetPixelSpan()[0]; {
Assert.True(Unsafe.AreSame(ref array[0], ref pixel0)); ref Rgba32 pixel0 = ref image.GetPixelSpan()[0];
Assert.True(Unsafe.AreSame(ref array[0], ref pixel0));
Assert.Equal(cfg, image.GetConfiguration()); Assert.Equal(cfg, image.GetConfiguration());
Assert.Equal(metaData, image.Metadata); Assert.Equal(metaData, image.Metadata);
}
} }
[Fact] [Fact]
@ -104,27 +106,33 @@ namespace SixLabors.ImageSharp.Tests
return; return;
} }
using var bmp = new Bitmap(51, 23); using (var bmp = new Bitmap(51, 23))
using var memoryManager = new BitmapMemoryManager(bmp);
Memory<Bgra32> memory = memoryManager.Memory;
Bgra32 bg = Color.Red;
Bgra32 fg = Color.Green;
using var image = Image.WrapMemory(memory, bmp.Width, bmp.Height);
Assert.Equal(memory, image.GetPixelMemory());
image.GetPixelSpan().Fill(bg);
for (var i = 10; i < 20; i++)
{ {
image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg); using (var memoryManager = new BitmapMemoryManager(bmp))
} {
Memory<Bgra32> memory = memoryManager.Memory;
Assert.False(memoryManager.IsDisposed); Bgra32 bg = Color.Red;
Bgra32 fg = Color.Green;
using (var image = Image.WrapMemory(memory, bmp.Width, bmp.Height))
{
Assert.Equal(memory, image.GetPixelMemory());
image.GetPixelSpan().Fill(bg);
for (var i = 10; i < 20; i++)
{
image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg);
}
}
Assert.False(memoryManager.IsDisposed);
}
string fn = System.IO.Path.Combine( string fn = System.IO.Path.Combine(
TestEnvironment.ActualOutputDirectoryFullPath, TestEnvironment.ActualOutputDirectoryFullPath,
$"{nameof(this.WrapSystemDrawingBitmap_WhenObserved)}.bmp"); $"{nameof(this.WrapSystemDrawingBitmap_WhenObserved)}.bmp");
bmp.Save(fn, ImageFormat.Bmp); bmp.Save(fn, ImageFormat.Bmp);
}
} }
[Fact] [Fact]
@ -135,29 +143,31 @@ namespace SixLabors.ImageSharp.Tests
return; return;
} }
using var bmp = new Bitmap(51, 23); using (var bmp = new Bitmap(51, 23))
var memoryManager = new BitmapMemoryManager(bmp);
Bgra32 bg = Color.Red;
Bgra32 fg = Color.Green;
using (var image = Image.WrapMemory(memoryManager, bmp.Width, bmp.Height))
{ {
Assert.Equal(memoryManager.Memory, image.GetPixelMemory()); var memoryManager = new BitmapMemoryManager(bmp);
Bgra32 bg = Color.Red;
Bgra32 fg = Color.Green;
image.GetPixelSpan().Fill(bg); using (var image = Image.WrapMemory(memoryManager, bmp.Width, bmp.Height))
for (var i = 10; i < 20; i++)
{ {
image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg); Assert.Equal(memoryManager.Memory, image.GetPixelMemory());
image.GetPixelSpan().Fill(bg);
for (var i = 10; i < 20; i++)
{
image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg);
}
} }
}
Assert.True(memoryManager.IsDisposed); Assert.True(memoryManager.IsDisposed);
string fn = System.IO.Path.Combine( string fn = System.IO.Path.Combine(
TestEnvironment.ActualOutputDirectoryFullPath, TestEnvironment.ActualOutputDirectoryFullPath,
$"{nameof(this.WrapSystemDrawingBitmap_WhenOwned)}.bmp"); $"{nameof(this.WrapSystemDrawingBitmap_WhenOwned)}.bmp");
bmp.Save(fn, ImageFormat.Bmp); bmp.Save(fn, ImageFormat.Bmp);
}
} }
private static bool ShouldSkipBitmapTest => private static bool ShouldSkipBitmapTest =>

56
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -21,13 +21,15 @@ namespace SixLabors.ImageSharp.Tests
[Fact] [Fact]
public void Width_Height() public void Width_Height()
{ {
using var image = new Image<Rgba32>(11, 23); using (var image = new Image<Rgba32>(11, 23))
Assert.Equal(11, image.Width); {
Assert.Equal(23, image.Height); Assert.Equal(11, image.Width);
Assert.Equal(11 * 23, image.GetPixelSpan().Length); Assert.Equal(23, image.Height);
image.ComparePixelBufferTo(default(Rgba32)); Assert.Equal(11 * 23, image.GetPixelSpan().Length);
image.ComparePixelBufferTo(default(Rgba32));
Assert.Equal(Configuration.Default, image.GetConfiguration()); Assert.Equal(Configuration.Default, image.GetConfiguration());
}
} }
[Fact] [Fact]
@ -35,13 +37,15 @@ namespace SixLabors.ImageSharp.Tests
{ {
Configuration configuration = Configuration.Default.Clone(); Configuration configuration = Configuration.Default.Clone();
using var image = new Image<Rgba32>(configuration, 11, 23); using (var image = new Image<Rgba32>(configuration, 11, 23))
Assert.Equal(11, image.Width); {
Assert.Equal(23, image.Height); Assert.Equal(11, image.Width);
Assert.Equal(11 * 23, image.GetPixelSpan().Length); Assert.Equal(23, image.Height);
image.ComparePixelBufferTo(default(Rgba32)); Assert.Equal(11 * 23, image.GetPixelSpan().Length);
image.ComparePixelBufferTo(default(Rgba32));
Assert.Equal(configuration, image.GetConfiguration()); Assert.Equal(configuration, image.GetConfiguration());
}
} }
[Fact] [Fact]
@ -50,13 +54,15 @@ namespace SixLabors.ImageSharp.Tests
Configuration configuration = Configuration.Default.Clone(); Configuration configuration = Configuration.Default.Clone();
Rgba32 color = Rgba32.Aquamarine; Rgba32 color = Rgba32.Aquamarine;
using var image = new Image<Rgba32>(configuration, 11, 23, color); using (var image = new Image<Rgba32>(configuration, 11, 23, color))
Assert.Equal(11, image.Width); {
Assert.Equal(23, image.Height); Assert.Equal(11, image.Width);
Assert.Equal(11 * 23, image.GetPixelSpan().Length); Assert.Equal(23, image.Height);
image.ComparePixelBufferTo(color); Assert.Equal(11 * 23, image.GetPixelSpan().Length);
image.ComparePixelBufferTo(color);
Assert.Equal(configuration, image.GetConfiguration()); Assert.Equal(configuration, image.GetConfiguration());
}
} }
[Fact] [Fact]
@ -68,13 +74,15 @@ namespace SixLabors.ImageSharp.Tests
configuration.MemoryAllocator = new TestMemoryAllocator(dirtyValue); configuration.MemoryAllocator = new TestMemoryAllocator(dirtyValue);
var metadata = new ImageMetadata(); var metadata = new ImageMetadata();
using var image = Image.CreateUninitialized<L8>(configuration, 21, 22, metadata); using (var image = Image.CreateUninitialized<L8>(configuration, 21, 22, metadata))
Assert.Equal(21, image.Width); {
Assert.Equal(22, image.Height); Assert.Equal(21, image.Width);
Assert.Same(configuration, image.GetConfiguration()); Assert.Equal(22, image.Height);
Assert.Same(metadata, image.Metadata); Assert.Same(configuration, image.GetConfiguration());
Assert.Same(metadata, image.Metadata);
Assert.Equal(dirtyValue, image[5, 5].PackedValue); Assert.Equal(dirtyValue, image[5, 5].PackedValue);
}
} }
} }
} }

106
tests/ImageSharp.Tests/Memory/Buffer2DTests.cs

@ -35,20 +35,24 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(1025, 17)] [InlineData(1025, 17)]
public void Construct(int width, int height) public void Construct(int width, int height)
{ {
using Buffer2D<TestStructs.Foo> buffer = this.MemoryAllocator.Allocate2D<TestStructs.Foo>(width, height); using (Buffer2D<TestStructs.Foo> buffer = this.MemoryAllocator.Allocate2D<TestStructs.Foo>(width, height))
Assert.Equal(width, buffer.Width); {
Assert.Equal(height, buffer.Height); Assert.Equal(width, buffer.Width);
Assert.Equal(width * height, buffer.GetMemory().Length); Assert.Equal(height, buffer.Height);
Assert.Equal(width * height, buffer.GetMemory().Length);
}
} }
[Fact] [Fact]
public void CreateClean() public void CreateClean()
{ {
using Buffer2D<int> buffer = this.MemoryAllocator.Allocate2D<int>(42, 42, AllocationOptions.Clean); using (Buffer2D<int> buffer = this.MemoryAllocator.Allocate2D<int>(42, 42, AllocationOptions.Clean))
Span<int> span = buffer.GetSpan();
for (int j = 0; j < span.Length; j++)
{ {
Assert.Equal(0, span[j]); Span<int> span = buffer.GetSpan();
for (int j = 0; j < span.Length; j++)
{
Assert.Equal(0, span[j]);
}
} }
} }
@ -58,12 +62,14 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(17, 42, 41)] [InlineData(17, 42, 41)]
public void GetRowSpanY(int width, int height, int y) public void GetRowSpanY(int width, int height, int y)
{ {
using Buffer2D<TestStructs.Foo> buffer = this.MemoryAllocator.Allocate2D<TestStructs.Foo>(width, height); using (Buffer2D<TestStructs.Foo> buffer = this.MemoryAllocator.Allocate2D<TestStructs.Foo>(width, height))
Span<TestStructs.Foo> span = buffer.GetRowSpan(y); {
Span<TestStructs.Foo> span = buffer.GetRowSpan(y);
// Assert.Equal(width * y, span.Start); // Assert.Equal(width * y, span.Start);
Assert.Equal(width, span.Length); Assert.Equal(width, span.Length);
Assert.SpanPointsTo(span, buffer.MemorySource.MemoryOwner, width * y); Assert.SpanPointsTo(span, buffer.MemorySource.MemoryOwner, width * y);
}
} }
[Theory] [Theory]
@ -72,31 +78,35 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(99, 88, 98, 87)] [InlineData(99, 88, 98, 87)]
public void Indexer(int width, int height, int x, int y) public void Indexer(int width, int height, int x, int y)
{ {
using Buffer2D<TestStructs.Foo> buffer = this.MemoryAllocator.Allocate2D<TestStructs.Foo>(width, height); using (Buffer2D<TestStructs.Foo> buffer = this.MemoryAllocator.Allocate2D<TestStructs.Foo>(width, height))
Span<TestStructs.Foo> span = buffer.MemorySource.GetSpan(); {
Span<TestStructs.Foo> span = buffer.MemorySource.GetSpan();
ref TestStructs.Foo actual = ref buffer[x, y]; ref TestStructs.Foo actual = ref buffer[x, y];
ref TestStructs.Foo expected = ref span[(y * width) + x]; ref TestStructs.Foo expected = ref span[(y * width) + x];
Assert.True(Unsafe.AreSame(ref expected, ref actual)); Assert.True(Unsafe.AreSame(ref expected, ref actual));
}
} }
[Fact] [Fact]
public void SwapOrCopyContent() public void SwapOrCopyContent()
{ {
using Buffer2D<int> a = this.MemoryAllocator.Allocate2D<int>(10, 5); using (Buffer2D<int> a = this.MemoryAllocator.Allocate2D<int>(10, 5))
using Buffer2D<int> b = this.MemoryAllocator.Allocate2D<int>(3, 7); using (Buffer2D<int> b = this.MemoryAllocator.Allocate2D<int>(3, 7))
IMemoryOwner<int> aa = a.MemorySource.MemoryOwner; {
IMemoryOwner<int> bb = b.MemorySource.MemoryOwner; IMemoryOwner<int> aa = a.MemorySource.MemoryOwner;
IMemoryOwner<int> bb = b.MemorySource.MemoryOwner;
Buffer2D<int>.SwapOrCopyContent(a, b); Buffer2D<int>.SwapOrCopyContent(a, b);
Assert.Equal(bb, a.MemorySource.MemoryOwner); Assert.Equal(bb, a.MemorySource.MemoryOwner);
Assert.Equal(aa, b.MemorySource.MemoryOwner); Assert.Equal(aa, b.MemorySource.MemoryOwner);
Assert.Equal(new Size(3, 7), a.Size()); Assert.Equal(new Size(3, 7), a.Size());
Assert.Equal(new Size(10, 5), b.Size()); Assert.Equal(new Size(10, 5), b.Size());
}
} }
[Theory] [Theory]
@ -109,19 +119,21 @@ namespace SixLabors.ImageSharp.Tests.Memory
public void CopyColumns(int width, int height, int startIndex, int destIndex, int columnCount) public void CopyColumns(int width, int height, int startIndex, int destIndex, int columnCount)
{ {
var rnd = new Random(123); var rnd = new Random(123);
using Buffer2D<float> b = this.MemoryAllocator.Allocate2D<float>(width, height); using (Buffer2D<float> b = this.MemoryAllocator.Allocate2D<float>(width, height))
rnd.RandomFill(b.GetSpan(), 0, 1); {
rnd.RandomFill(b.GetSpan(), 0, 1);
b.CopyColumns(startIndex, destIndex, columnCount); b.CopyColumns(startIndex, destIndex, columnCount);
for (int y = 0; y < b.Height; y++) for (int y = 0; y < b.Height; y++)
{ {
Span<float> row = b.GetRowSpan(y); Span<float> row = b.GetRowSpan(y);
Span<float> s = row.Slice(startIndex, columnCount); Span<float> s = row.Slice(startIndex, columnCount);
Span<float> d = row.Slice(destIndex, columnCount); Span<float> d = row.Slice(destIndex, columnCount);
Xunit.Assert.True(s.SequenceEqual(d)); Xunit.Assert.True(s.SequenceEqual(d));
}
} }
} }
@ -129,20 +141,22 @@ namespace SixLabors.ImageSharp.Tests.Memory
public void CopyColumns_InvokeMultipleTimes() public void CopyColumns_InvokeMultipleTimes()
{ {
var rnd = new Random(123); var rnd = new Random(123);
using Buffer2D<float> b = this.MemoryAllocator.Allocate2D<float>(100, 100); using (Buffer2D<float> b = this.MemoryAllocator.Allocate2D<float>(100, 100))
rnd.RandomFill(b.GetSpan(), 0, 1); {
rnd.RandomFill(b.GetSpan(), 0, 1);
b.CopyColumns(0, 50, 22); b.CopyColumns(0, 50, 22);
b.CopyColumns(0, 50, 22); b.CopyColumns(0, 50, 22);
for (int y = 0; y < b.Height; y++) for (int y = 0; y < b.Height; y++)
{ {
Span<float> row = b.GetRowSpan(y); Span<float> row = b.GetRowSpan(y);
Span<float> s = row.Slice(0, 22); Span<float> s = row.Slice(0, 22);
Span<float> d = row.Slice(50, 22); Span<float> d = row.Slice(50, 22);
Xunit.Assert.True(s.SequenceEqual(d)); Xunit.Assert.True(s.SequenceEqual(d));
}
} }
} }
} }

112
tests/ImageSharp.Tests/Memory/BufferAreaTests.cs

@ -12,12 +12,14 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void Construct() public void Construct()
{ {
using var buffer = Configuration.Default.MemoryAllocator.Allocate2D<int>(10, 20); using (var buffer = Configuration.Default.MemoryAllocator.Allocate2D<int>(10, 20))
var rectangle = new Rectangle(3, 2, 5, 6); {
var area = new BufferArea<int>(buffer, rectangle); var rectangle = new Rectangle(3, 2, 5, 6);
var area = new BufferArea<int>(buffer, rectangle);
Assert.Equal(buffer, area.DestinationBuffer); Assert.Equal(buffer, area.DestinationBuffer);
Assert.Equal(rectangle, area.Rectangle); Assert.Equal(rectangle, area.Rectangle);
}
} }
private static Buffer2D<int> CreateTestBuffer(int w, int h) private static Buffer2D<int> CreateTestBuffer(int w, int h)
@ -39,14 +41,16 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(5, 4, 3, 2)] [InlineData(5, 4, 3, 2)]
public void Indexer(int rx, int ry, int x, int y) public void Indexer(int rx, int ry, int x, int y)
{ {
using Buffer2D<int> buffer = CreateTestBuffer(20, 30); using (Buffer2D<int> buffer = CreateTestBuffer(20, 30))
var r = new Rectangle(rx, ry, 5, 6); {
var r = new Rectangle(rx, ry, 5, 6);
BufferArea<int> area = buffer.GetArea(r); BufferArea<int> area = buffer.GetArea(r);
int value = area[x, y]; int value = area[x, y];
int expected = ((ry + y) * 100) + rx + x; int expected = ((ry + y) * 100) + rx + x;
Assert.Equal(expected, value); Assert.Equal(expected, value);
}
} }
[Theory] [Theory]
@ -54,79 +58,89 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(5, 4, 3, 6, 5)] [InlineData(5, 4, 3, 6, 5)]
public void GetRowSpan(int rx, int ry, int y, int w, int h) public void GetRowSpan(int rx, int ry, int y, int w, int h)
{ {
using Buffer2D<int> buffer = CreateTestBuffer(20, 30); using (Buffer2D<int> buffer = CreateTestBuffer(20, 30))
var r = new Rectangle(rx, ry, w, h); {
var r = new Rectangle(rx, ry, w, h);
BufferArea<int> area = buffer.GetArea(r); BufferArea<int> area = buffer.GetArea(r);
Span<int> span = area.GetRowSpan(y); Span<int> span = area.GetRowSpan(y);
Assert.Equal(w, span.Length); Assert.Equal(w, span.Length);
for (int i = 0; i < w; i++) for (int i = 0; i < w; i++)
{ {
int expected = ((ry + y) * 100) + rx + i; int expected = ((ry + y) * 100) + rx + i;
int value = span[i]; int value = span[i];
Assert.Equal(expected, value); Assert.Equal(expected, value);
}
} }
} }
[Fact] [Fact]
public void GetSubArea() public void GetSubArea()
{ {
using Buffer2D<int> buffer = CreateTestBuffer(20, 30); using (Buffer2D<int> buffer = CreateTestBuffer(20, 30))
BufferArea<int> area0 = buffer.GetArea(6, 8, 10, 10); {
BufferArea<int> area0 = buffer.GetArea(6, 8, 10, 10);
BufferArea<int> area1 = area0.GetSubArea(4, 4, 5, 5); BufferArea<int> area1 = area0.GetSubArea(4, 4, 5, 5);
var expectedRect = new Rectangle(10, 12, 5, 5); var expectedRect = new Rectangle(10, 12, 5, 5);
Assert.Equal(buffer, area1.DestinationBuffer); Assert.Equal(buffer, area1.DestinationBuffer);
Assert.Equal(expectedRect, area1.Rectangle); Assert.Equal(expectedRect, area1.Rectangle);
int value00 = (12 * 100) + 10; int value00 = (12 * 100) + 10;
Assert.Equal(value00, area1[0, 0]); Assert.Equal(value00, area1[0, 0]);
}
} }
[Fact] [Fact]
public void DangerousGetPinnableReference() public void DangerousGetPinnableReference()
{ {
using Buffer2D<int> buffer = CreateTestBuffer(20, 30); using (Buffer2D<int> buffer = CreateTestBuffer(20, 30))
BufferArea<int> area0 = buffer.GetArea(6, 8, 10, 10); {
BufferArea<int> area0 = buffer.GetArea(6, 8, 10, 10);
ref int r = ref area0.GetReferenceToOrigin(); ref int r = ref area0.GetReferenceToOrigin();
int expected = buffer[6, 8]; int expected = buffer[6, 8];
Assert.Equal(expected, r); Assert.Equal(expected, r);
}
} }
[Fact] [Fact]
public void Clear_FullArea() public void Clear_FullArea()
{ {
using Buffer2D<int> buffer = CreateTestBuffer(22, 13); using (Buffer2D<int> buffer = CreateTestBuffer(22, 13))
buffer.GetArea().Clear(); {
Span<int> fullSpan = buffer.GetSpan(); buffer.GetArea().Clear();
Assert.True(fullSpan.SequenceEqual(new int[fullSpan.Length])); Span<int> fullSpan = buffer.GetSpan();
Assert.True(fullSpan.SequenceEqual(new int[fullSpan.Length]));
}
} }
[Fact] [Fact]
public void Clear_SubArea() public void Clear_SubArea()
{ {
using Buffer2D<int> buffer = CreateTestBuffer(20, 30); using (Buffer2D<int> buffer = CreateTestBuffer(20, 30))
BufferArea<int> area = buffer.GetArea(5, 5, 10, 10); {
area.Clear(); BufferArea<int> area = buffer.GetArea(5, 5, 10, 10);
area.Clear();
Assert.NotEqual(0, buffer[4, 4]); Assert.NotEqual(0, buffer[4, 4]);
Assert.NotEqual(0, buffer[15, 15]); Assert.NotEqual(0, buffer[15, 15]);
Assert.Equal(0, buffer[5, 5]); Assert.Equal(0, buffer[5, 5]);
Assert.Equal(0, buffer[14, 14]); Assert.Equal(0, buffer[14, 14]);
for (int y = area.Rectangle.Y; y < area.Rectangle.Bottom; y++) for (int y = area.Rectangle.Y; y < area.Rectangle.Bottom; y++)
{ {
Span<int> span = buffer.GetRowSpan(y).Slice(area.Rectangle.X, area.Width); Span<int> span = buffer.GetRowSpan(y).Slice(area.Rectangle.X, area.Width);
Assert.True(span.SequenceEqual(new int[area.Width])); Assert.True(span.SequenceEqual(new int[area.Width]));
}
} }
} }
} }

16
tests/ImageSharp.Tests/Metadata/ImageMetadataTests.cs

@ -90,15 +90,17 @@ namespace SixLabors.ImageSharp.Tests.Metadata
exifProfile.SetValue(ExifTag.XResolution, new Rational(200)); exifProfile.SetValue(ExifTag.XResolution, new Rational(200));
exifProfile.SetValue(ExifTag.YResolution, new Rational(300)); exifProfile.SetValue(ExifTag.YResolution, new Rational(300));
using var image = new Image<Rgba32>(1, 1); using (var image = new Image<Rgba32>(1, 1))
image.Metadata.ExifProfile = exifProfile; {
image.Metadata.HorizontalResolution = 400; image.Metadata.ExifProfile = exifProfile;
image.Metadata.VerticalResolution = 500; image.Metadata.HorizontalResolution = 400;
image.Metadata.VerticalResolution = 500;
image.Metadata.SyncProfiles(); image.Metadata.SyncProfiles();
Assert.Equal(400, ((Rational)image.Metadata.ExifProfile.GetValue(ExifTag.XResolution).Value).ToDouble()); Assert.Equal(400, ((Rational)image.Metadata.ExifProfile.GetValue(ExifTag.XResolution).Value).ToDouble());
Assert.Equal(500, ((Rational)image.Metadata.ExifProfile.GetValue(ExifTag.YResolution).Value).ToDouble()); Assert.Equal(500, ((Rational)image.Metadata.ExifProfile.GetValue(ExifTag.YResolution).Value).ToDouble());
}
} }
} }
} }

70
tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs

@ -92,40 +92,42 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(TestImageWriteFormat.Png)] [InlineData(TestImageWriteFormat.Png)]
public void WriteFraction(TestImageWriteFormat imageFormat) public void WriteFraction(TestImageWriteFormat imageFormat)
{ {
using var memStream = new MemoryStream(); using (var memStream = new MemoryStream())
double exposureTime = 1.0 / 1600; {
double exposureTime = 1.0 / 1600;
ExifProfile profile = GetExifProfile(); ExifProfile profile = GetExifProfile();
profile.SetValue(ExifTag.ExposureTime, new Rational(exposureTime)); profile.SetValue(ExifTag.ExposureTime, new Rational(exposureTime));
var image = new Image<Rgba32>(1, 1); var image = new Image<Rgba32>(1, 1);
image.Metadata.ExifProfile = profile; image.Metadata.ExifProfile = profile;
image = WriteAndRead(image, imageFormat); image = WriteAndRead(image, imageFormat);
profile = image.Metadata.ExifProfile; profile = image.Metadata.ExifProfile;
Assert.NotNull(profile); Assert.NotNull(profile);
IExifValue<Rational> value = profile.GetValue(ExifTag.ExposureTime); IExifValue<Rational> value = profile.GetValue(ExifTag.ExposureTime);
Assert.NotNull(value); Assert.NotNull(value);
Assert.NotEqual(exposureTime, value.Value.ToDouble()); Assert.NotEqual(exposureTime, value.Value.ToDouble());
memStream.Position = 0; memStream.Position = 0;
profile = GetExifProfile(); profile = GetExifProfile();
profile.SetValue(ExifTag.ExposureTime, new Rational(exposureTime, true)); profile.SetValue(ExifTag.ExposureTime, new Rational(exposureTime, true));
image.Metadata.ExifProfile = profile; image.Metadata.ExifProfile = profile;
image = WriteAndRead(image, imageFormat); image = WriteAndRead(image, imageFormat);
profile = image.Metadata.ExifProfile; profile = image.Metadata.ExifProfile;
Assert.NotNull(profile); Assert.NotNull(profile);
value = profile.GetValue(ExifTag.ExposureTime); value = profile.GetValue(ExifTag.ExposureTime);
Assert.Equal(exposureTime, value.Value.ToDouble()); Assert.Equal(exposureTime, value.Value.ToDouble());
image.Dispose(); image.Dispose();
}
} }
[Theory] [Theory]
@ -449,22 +451,26 @@ namespace SixLabors.ImageSharp.Tests
private static Image<Rgba32> WriteAndReadJpeg(Image<Rgba32> image) private static Image<Rgba32> WriteAndReadJpeg(Image<Rgba32> image)
{ {
using var memStream = new MemoryStream(); using (var memStream = new MemoryStream())
image.SaveAsJpeg(memStream); {
image.Dispose(); image.SaveAsJpeg(memStream);
image.Dispose();
memStream.Position = 0; memStream.Position = 0;
return Image.Load<Rgba32>(memStream); return Image.Load<Rgba32>(memStream);
}
} }
private static Image<Rgba32> WriteAndReadPng(Image<Rgba32> image) private static Image<Rgba32> WriteAndReadPng(Image<Rgba32> image)
{ {
using var memStream = new MemoryStream(); using (var memStream = new MemoryStream())
image.SaveAsPng(memStream); {
image.Dispose(); image.SaveAsPng(memStream);
image.Dispose();
memStream.Position = 0; memStream.Position = 0;
return Image.Load<Rgba32>(memStream); return Image.Load<Rgba32>(memStream);
}
} }
private static void TestProfile(ExifProfile profile) private static void TestProfile(ExifProfile profile)

6
tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifValueTests.cs

@ -13,8 +13,10 @@ namespace SixLabors.ImageSharp.Tests
public ExifValueTests() public ExifValueTests()
{ {
using Image<Rgba32> image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image(); using (Image<Rgba32> image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image())
this.profile = image.Metadata.ExifProfile; {
this.profile = image.Metadata.ExifProfile;
}
} }
private IExifValue<string> GetExifValue() private IExifValue<string> GetExifValue()

32
tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs

@ -33,24 +33,28 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders
public void PorterDuffOutputIsCorrect(TestImageProvider<Rgba32> provider, PixelAlphaCompositionMode mode) public void PorterDuffOutputIsCorrect(TestImageProvider<Rgba32> provider, PixelAlphaCompositionMode mode)
{ {
var srcFile = TestFile.Create(TestImages.Png.PDSrc); var srcFile = TestFile.Create(TestImages.Png.PDSrc);
using Image<Rgba32> src = srcFile.CreateRgba32Image(); using (Image<Rgba32> src = srcFile.CreateRgba32Image())
using Image<Rgba32> dest = provider.GetImage(); using (Image<Rgba32> dest = provider.GetImage())
var options = new GraphicsOptions
{ {
Antialias = false, var options = new GraphicsOptions
AlphaCompositionMode = mode {
}; Antialias = false,
AlphaCompositionMode = mode
};
using (Image<Rgba32> res = dest.Clone(x => x.DrawImage(src, options)))
{
string combinedMode = mode.ToString();
using Image<Rgba32> res = dest.Clone(x => x.DrawImage(src, options)); if (combinedMode != "Src" && combinedMode.StartsWith("Src"))
string combinedMode = mode.ToString(); {
combinedMode = combinedMode.Substring(3);
}
if (combinedMode != "Src" && combinedMode.StartsWith("Src")) res.DebugSave(provider, combinedMode);
{ res.CompareToReferenceOutput(provider, combinedMode);
combinedMode = combinedMode.Substring(3); }
} }
res.DebugSave(provider, combinedMode);
res.CompareToReferenceOutput(provider, combinedMode);
} }
} }
} }

22
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.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. // Licensed under the Apache License, Version 2.0.
using System.Buffers; using System.Buffers;
@ -30,15 +30,17 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
const int times = 200000; const int times = 200000;
const int count = 1024; const int count = 1024;
using IMemoryOwner<Rgba32> source = Configuration.Default.MemoryAllocator.Allocate<Rgba32>(count); using (IMemoryOwner<Rgba32> source = Configuration.Default.MemoryAllocator.Allocate<Rgba32>(count))
using IMemoryOwner<Vector4> dest = Configuration.Default.MemoryAllocator.Allocate<Vector4>(count); using (IMemoryOwner<Vector4> dest = Configuration.Default.MemoryAllocator.Allocate<Vector4>(count))
this.Measure( {
times, this.Measure(
() => PixelOperations<Rgba32>.Instance.ToVector4( times,
this.Configuration, () => PixelOperations<Rgba32>.Instance.ToVector4(
source.GetSpan(), this.Configuration,
dest.GetSpan())); source.GetSpan(),
dest.GetSpan()));
}
} }
} }
} }
} }

8
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

@ -997,9 +997,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
where TSource : struct where TSource : struct
where TDest : struct where TDest : struct
{ {
using var buffers = new TestBuffers<TSource, TDest>(source, expected); using (var buffers = new TestBuffers<TSource, TDest>(source, expected))
action(buffers.SourceBuffer, buffers.ActualDestBuffer); {
buffers.Verify(); action(buffers.SourceBuffer, buffers.ActualDestBuffer);
buffers.Verify();
}
} }
internal static Vector4[] CreateVector4TestData(int length, RefAction<Vector4> vectorModifier = null) internal static Vector4[] CreateVector4TestData(int length, RefAction<Vector4> vectorModifier = null)

114
tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs

@ -32,18 +32,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
70, 87, 69, 68, 65, 73, 78, 90 70, 87, 69, 68, 65, 73, 78, 90
}; };
using var image = new Image<Rgba32>(8, 8); using (var image = new Image<Rgba32>(8, 8))
for (int y = 0; y < 8; y++)
{ {
for (int x = 0; x < 8; x++) for (int y = 0; y < 8; y++)
{ {
byte luminance = pixels[(y * 8) + x]; for (int x = 0; x < 8; x++)
image[x, y] = new Rgba32(luminance, luminance, luminance); {
byte luminance = pixels[(y * 8) + x];
image[x, y] = new Rgba32(luminance, luminance, luminance);
}
} }
}
var expected = new byte[] var expected = new byte[]
{ {
0, 12, 53, 32, 146, 53, 174, 53, 0, 12, 53, 32, 146, 53, 174, 53,
57, 32, 12, 227, 219, 202, 32, 154, 57, 32, 12, 227, 219, 202, 32, 154,
65, 85, 93, 239, 251, 227, 65, 158, 65, 85, 93, 239, 251, 227, 65, 158,
@ -52,23 +53,24 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
117, 190, 36, 190, 178, 93, 20, 170, 117, 190, 36, 190, 178, 93, 20, 170,
130, 202, 73, 20, 12, 53, 85, 194, 130, 202, 73, 20, 12, 53, 85, 194,
146, 206, 130, 117, 85, 166, 182, 215 146, 206, 130, 117, 85, 166, 182, 215
}; };
// Act // Act
image.Mutate(x => x.HistogramEqualization(new HistogramEqualizationOptions image.Mutate(x => x.HistogramEqualization(new HistogramEqualizationOptions
{ {
LuminanceLevels = luminanceLevels LuminanceLevels = luminanceLevels
})); }));
// Assert // Assert
for (int y = 0; y < 8; y++) for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 8; x++)
{ {
Rgba32 actual = image[x, y]; for (int x = 0; x < 8; x++)
Assert.Equal(expected[(y * 8) + x], actual.R); {
Assert.Equal(expected[(y * 8) + x], actual.G); Rgba32 actual = image[x, y];
Assert.Equal(expected[(y * 8) + x], actual.B); Assert.Equal(expected[(y * 8) + x], actual.R);
Assert.Equal(expected[(y * 8) + x], actual.G);
Assert.Equal(expected[(y * 8) + x], actual.B);
}
} }
} }
} }
@ -78,17 +80,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
public void Adaptive_SlidingWindow_15Tiles_WithClipping<TPixel>(TestImageProvider<TPixel> provider) public void Adaptive_SlidingWindow_15Tiles_WithClipping<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new HistogramEqualizationOptions
{ {
Method = HistogramEqualizationMethod.AdaptiveSlidingWindow, var options = new HistogramEqualizationOptions
LuminanceLevels = 256, {
ClipHistogram = true, Method = HistogramEqualizationMethod.AdaptiveSlidingWindow,
NumberOfTiles = 15 LuminanceLevels = 256,
}; ClipHistogram = true,
image.Mutate(x => x.HistogramEqualization(options)); NumberOfTiles = 15
image.DebugSave(provider); };
image.CompareToReferenceOutput(ValidatorComparer, provider); image.Mutate(x => x.HistogramEqualization(options));
image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -96,17 +100,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
public void Adaptive_TileInterpolation_10Tiles_WithClipping<TPixel>(TestImageProvider<TPixel> provider) public void Adaptive_TileInterpolation_10Tiles_WithClipping<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new HistogramEqualizationOptions
{ {
Method = HistogramEqualizationMethod.AdaptiveTileInterpolation, var options = new HistogramEqualizationOptions
LuminanceLevels = 256, {
ClipHistogram = true, Method = HistogramEqualizationMethod.AdaptiveTileInterpolation,
NumberOfTiles = 10 LuminanceLevels = 256,
}; ClipHistogram = true,
image.Mutate(x => x.HistogramEqualization(options)); NumberOfTiles = 10
image.DebugSave(provider); };
image.CompareToReferenceOutput(ValidatorComparer, provider); image.Mutate(x => x.HistogramEqualization(options));
image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
/// <summary> /// <summary>
@ -121,18 +127,20 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
public void Issue984<TPixel>(TestImageProvider<TPixel> provider) public void Issue984<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new HistogramEqualizationOptions()
{ {
Method = HistogramEqualizationMethod.AdaptiveTileInterpolation, var options = new HistogramEqualizationOptions()
LuminanceLevels = 256, {
ClipHistogram = true, Method = HistogramEqualizationMethod.AdaptiveTileInterpolation,
ClipLimit = 5, LuminanceLevels = 256,
NumberOfTiles = 10 ClipHistogram = true,
}; ClipLimit = 5,
image.Mutate(x => x.HistogramEqualization(options)); NumberOfTiles = 10
image.DebugSave(provider); };
image.CompareToReferenceOutput(ValidatorComparer, provider); image.Mutate(x => x.HistogramEqualization(options));
image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
} }
} }

60
tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryDitherTests.cs

@ -51,9 +51,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void BinaryDitherFilter_WorksWithAllDitherers<TPixel>(TestImageProvider<TPixel> provider, string name, IOrderedDither ditherer) public void BinaryDitherFilter_WorksWithAllDitherers<TPixel>(TestImageProvider<TPixel> provider, string name, IOrderedDither ditherer)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.BinaryDither(ditherer)); {
image.DebugSave(provider, name); image.Mutate(x => x.BinaryDither(ditherer));
image.DebugSave(provider, name);
}
} }
[Theory] [Theory]
@ -62,9 +64,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void DiffusionFilter_WorksWithAllErrorDiffusers<TPixel>(TestImageProvider<TPixel> provider, string name, IErrorDiffuser diffuser) public void DiffusionFilter_WorksWithAllErrorDiffusers<TPixel>(TestImageProvider<TPixel> provider, string name, IErrorDiffuser diffuser)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.BinaryDiffuse(diffuser, .5F)); {
image.DebugSave(provider, name); image.Mutate(x => x.BinaryDiffuse(diffuser, .5F));
image.DebugSave(provider, name);
}
} }
[Theory] [Theory]
@ -72,9 +76,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void BinaryDitherFilter_ShouldNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider) public void BinaryDitherFilter_ShouldNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.BinaryDither(DefaultDitherer)); {
image.DebugSave(provider); image.Mutate(x => x.BinaryDither(DefaultDitherer));
image.DebugSave(provider);
}
} }
[Theory] [Theory]
@ -82,9 +88,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void DiffusionFilter_ShouldNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider) public void DiffusionFilter_ShouldNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.BinaryDiffuse(DefaultErrorDiffuser, 0.5f)); {
image.DebugSave(provider); image.Mutate(x => x.BinaryDiffuse(DefaultErrorDiffuser, 0.5f));
image.DebugSave(provider);
}
} }
[Theory] [Theory]
@ -92,14 +100,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void ApplyDitherFilterInBox<TPixel>(TestImageProvider<TPixel> provider) public void ApplyDitherFilterInBox<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> source = provider.GetImage(); using (Image<TPixel> source = provider.GetImage())
using Image<TPixel> image = source.Clone(); using (Image<TPixel> image = source.Clone())
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); {
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
image.Mutate(x => x.BinaryDither(DefaultDitherer, bounds)); image.Mutate(x => x.BinaryDither(DefaultDitherer, bounds));
image.DebugSave(provider); image.DebugSave(provider);
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
}
} }
[Theory] [Theory]
@ -107,14 +117,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void ApplyDiffusionFilterInBox<TPixel>(TestImageProvider<TPixel> provider) public void ApplyDiffusionFilterInBox<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> source = provider.GetImage(); using (Image<TPixel> source = provider.GetImage())
using Image<TPixel> image = source.Clone(); using (Image<TPixel> image = source.Clone())
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); {
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
image.Mutate(x => x.BinaryDiffuse(DefaultErrorDiffuser, .5F, bounds)); image.Mutate(x => x.BinaryDiffuse(DefaultErrorDiffuser, .5F, bounds));
image.DebugSave(provider); image.DebugSave(provider);
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
}
} }
} }
} }

22
tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs

@ -30,9 +30,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void ImageShouldApplyBinaryThresholdFilter<TPixel>(TestImageProvider<TPixel> provider, float value) public void ImageShouldApplyBinaryThresholdFilter<TPixel>(TestImageProvider<TPixel> provider, float value)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.BinaryThreshold(value)); {
image.DebugSave(provider, value); image.Mutate(x => x.BinaryThreshold(value));
image.DebugSave(provider, value);
}
} }
[Theory] [Theory]
@ -40,14 +42,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
public void ImageShouldApplyBinaryThresholdInBox<TPixel>(TestImageProvider<TPixel> provider, float value) public void ImageShouldApplyBinaryThresholdInBox<TPixel>(TestImageProvider<TPixel> provider, float value)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> source = provider.GetImage(); using (Image<TPixel> source = provider.GetImage())
using var image = source.Clone(); using (var image = source.Clone())
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); {
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
image.Mutate(x => x.BinaryThreshold(value, bounds)); image.Mutate(x => x.BinaryThreshold(value, bounds));
image.DebugSave(provider, value); image.DebugSave(provider, value);
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
}
} }
} }
} }

26
tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs

@ -60,19 +60,23 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
} }
// Make sure the kernel components are the same // Make sure the kernel components are the same
using var image = new Image<Rgb24>(1, 1); using (var image = new Image<Rgb24>(1, 1))
Configuration configuration = image.GetConfiguration();
var definition = new BokehBlurProcessor(10, BokehBlurProcessor.DefaultComponents, BokehBlurProcessor.DefaultGamma);
using var processor = (BokehBlurProcessor<Rgb24>)definition.CreatePixelSpecificProcessor(configuration, image, image.Bounds());
Assert.Equal(components.Count, processor.Kernels.Count);
foreach ((Complex64[] a, Complex64[] b) in components.Zip(processor.Kernels, (a, b) => (a, b)))
{ {
Span<Complex64> spanA = a.AsSpan(), spanB = b.AsSpan(); Configuration configuration = image.GetConfiguration();
Assert.Equal(spanA.Length, spanB.Length); var definition = new BokehBlurProcessor(10, BokehBlurProcessor.DefaultComponents, BokehBlurProcessor.DefaultGamma);
for (int i = 0; i < spanA.Length; i++) using (var processor = (BokehBlurProcessor<Rgb24>)definition.CreatePixelSpecificProcessor(configuration, image, image.Bounds()))
{ {
Assert.True(Math.Abs(Math.Abs(spanA[i].Real) - Math.Abs(spanB[i].Real)) < 0.0001f); Assert.Equal(components.Count, processor.Kernels.Count);
Assert.True(Math.Abs(Math.Abs(spanA[i].Imaginary) - Math.Abs(spanB[i].Imaginary)) < 0.0001f); foreach ((Complex64[] a, Complex64[] b) in components.Zip(processor.Kernels, (a, b) => (a, b)))
{
Span<Complex64> spanA = a.AsSpan(), spanB = b.AsSpan();
Assert.Equal(spanA.Length, spanB.Length);
for (int i = 0; i < spanA.Length; i++)
{
Assert.True(Math.Abs(Math.Abs(spanA[i].Real) - Math.Abs(spanB[i].Real)) < 0.0001f);
Assert.True(Math.Abs(Math.Abs(spanA[i].Imaginary) - Math.Abs(spanB[i].Imaginary)) < 0.0001f);
}
}
} }
} }
} }

40
tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs

@ -56,10 +56,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
public void DetectEdges_WorksWithAllFilters<TPixel>(TestImageProvider<TPixel> provider, EdgeDetectionOperators detector) public void DetectEdges_WorksWithAllFilters<TPixel>(TestImageProvider<TPixel> provider, EdgeDetectionOperators detector)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.DetectEdges(detector)); {
image.DebugSave(provider, detector.ToString()); image.Mutate(x => x.DetectEdges(detector));
image.CompareToReferenceOutput(ValidatorComparer, provider, detector.ToString()); image.DebugSave(provider, detector.ToString());
image.CompareToReferenceOutput(ValidatorComparer, provider, detector.ToString());
}
} }
[Theory] [Theory]
@ -67,10 +69,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
public void DetectEdges_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider) public void DetectEdges_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.DetectEdges()); {
image.DebugSave(provider); image.Mutate(x => x.DetectEdges());
image.CompareToReferenceOutput(ValidatorComparer, provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -78,9 +82,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
public void DetectEdges_IsAppliedToAllFrames<TPixel>(TestImageProvider<TPixel> provider) public void DetectEdges_IsAppliedToAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.DetectEdges()); {
image.DebugSave(provider, extension: "gif"); image.Mutate(x => x.DetectEdges());
image.DebugSave(provider, extension: "gif");
}
} }
[Theory] [Theory]
@ -88,12 +94,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
public void DetectEdges_InBox<TPixel>(TestImageProvider<TPixel> provider) public void DetectEdges_InBox<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); {
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
image.Mutate(x => x.DetectEdges(bounds)); image.Mutate(x => x.DetectEdges(bounds));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
} }
} }

28
tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs

@ -44,13 +44,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void AutoOrient_WorksForAllExifOrientations<TPixel>(TestImageProvider<TPixel> provider, ushort orientation) public void AutoOrient_WorksForAllExifOrientations<TPixel>(TestImageProvider<TPixel> provider, ushort orientation)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Metadata.ExifProfile = new ExifProfile(); {
image.Metadata.ExifProfile.SetValue(ExifTag.Orientation, orientation); image.Metadata.ExifProfile = new ExifProfile();
image.Metadata.ExifProfile.SetValue(ExifTag.Orientation, orientation);
image.Mutate(x => x.AutoOrient()); image.Mutate(x => x.AutoOrient());
image.DebugSave(provider, orientation, appendPixelTypeToFileName: false); image.DebugSave(provider, orientation, appendPixelTypeToFileName: false);
image.CompareToReferenceOutput(provider, orientation, appendPixelTypeToFileName: false); image.CompareToReferenceOutput(provider, orientation, appendPixelTypeToFileName: false);
}
} }
[Theory] [Theory]
@ -78,12 +80,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
ulong orientationCode = BitConverter.ToUInt64(orientationCodeData, 0); ulong orientationCode = BitConverter.ToUInt64(orientationCodeData, 0);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> reference = image.Clone(); using (Image<TPixel> reference = image.Clone())
image.Metadata.ExifProfile = new ExifProfile(bytes); {
image.Mutate(x => x.AutoOrient()); image.Metadata.ExifProfile = new ExifProfile(bytes);
image.DebugSave(provider, $"{dataType}-{orientationCode}", appendPixelTypeToFileName: false); image.Mutate(x => x.AutoOrient());
ImageComparer.Exact.VerifySimilarity(image, reference); image.DebugSave(provider, $"{dataType}-{orientationCode}", appendPixelTypeToFileName: false);
ImageComparer.Exact.VerifySimilarity(image, reference);
}
} }
} }
} }

36
tests/ImageSharp.Tests/Processing/Processors/Transforms/PadTest.cs

@ -19,16 +19,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ImageShouldPad<TPixel>(TestImageProvider<TPixel> provider) public void ImageShouldPad<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Pad(image.Width + 50, image.Height + 50));
image.DebugSave(provider);
// Check pixels are empty
for (int y = 0; y < 25; y++)
{ {
for (int x = 0; x < 25; x++) image.Mutate(x => x.Pad(image.Width + 50, image.Height + 50));
image.DebugSave(provider);
// Check pixels are empty
for (int y = 0; y < 25; y++)
{ {
Assert.Equal(default, image[x, y]); for (int x = 0; x < 25; x++)
{
Assert.Equal(default, image[x, y]);
}
} }
} }
} }
@ -40,16 +42,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{ {
var color = Color.Red; var color = Color.Red;
TPixel expected = color.ToPixel<TPixel>(); TPixel expected = color.ToPixel<TPixel>();
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Pad(image.Width + 50, image.Height + 50, color));
image.DebugSave(provider);
// Check pixels are filled
for (int y = 0; y < 25; y++)
{ {
for (int x = 0; x < 25; x++) image.Mutate(x => x.Pad(image.Width + 50, image.Height + 50, color));
image.DebugSave(provider);
// Check pixels are filled
for (int y = 0; y < 25; y++)
{ {
Assert.Equal(expected, image[x, y]); for (int x = 0; x < 25; x++)
{
Assert.Equal(expected, image[x, y]);
}
} }
} }
} }

407
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs

@ -5,14 +5,12 @@ using System;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.Memory; using SixLabors.ImageSharp.Tests.Memory;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit; using Xunit;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
@ -44,13 +42,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{ {
string filePath = TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora); string filePath = TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora);
using var image = Image.Load(filePath); using (var image = Image.Load(filePath))
image.Mutate(x => x.Resize(image.Size() / 2)); {
string path = System.IO.Path.Combine( image.Mutate(x => x.Resize(image.Size() / 2));
TestEnvironment.CreateOutputDirectory(nameof(ResizeTests)), string path = System.IO.Path.Combine(
nameof(this.Resize_PixelAgnostic) + ".png"); TestEnvironment.CreateOutputDirectory(nameof(ResizeTests)),
nameof(this.Resize_PixelAgnostic) + ".png");
image.Save(path); image.Save(path);
}
} }
[Theory(Skip = "Debug only, enable manually")] [Theory(Skip = "Debug only, enable manually")]
@ -67,9 +67,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
provider.Configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInKilobytes * 1024; provider.Configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInKilobytes * 1024;
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(destSize, destSize)); {
image.DebugSave(provider, appendPixelTypeToFileName: false); image.Mutate(x => x.Resize(destSize, destSize));
image.DebugSave(provider, appendPixelTypeToFileName: false);
}
} }
[Theory] [Theory]
@ -83,12 +85,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
// [WithBasicTestPatternImages(15, 12, PixelTypes.Rgba32, 2, 3, 1, 2)] means: // [WithBasicTestPatternImages(15, 12, PixelTypes.Rgba32, 2, 3, 1, 2)] means:
// resizing: (15, 12) -> (10, 6) // resizing: (15, 12) -> (10, 6)
// kernel dimensions: (3, 4) // kernel dimensions: (3, 4)
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var destSize = new Size(image.Width * wN / wD, image.Height * hN / hD); {
image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false)); var destSize = new Size(image.Width * wN / wD, image.Height * hN / hD);
FormattableString outputInfo = $"({wN}÷{wD},{hN}÷{hD})"; image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false));
image.DebugSave(provider, outputInfo, appendPixelTypeToFileName: false); FormattableString outputInfo = $"({wN}÷{wD},{hN}÷{hD})";
image.CompareToReferenceOutput(provider, outputInfo, appendPixelTypeToFileName: false); image.DebugSave(provider, outputInfo, appendPixelTypeToFileName: false);
image.CompareToReferenceOutput(provider, outputInfo, appendPixelTypeToFileName: false);
}
} }
private static readonly int SizeOfVector4 = Unsafe.SizeOf<Vector4>(); private static readonly int SizeOfVector4 = Unsafe.SizeOf<Vector4>();
@ -106,43 +110,47 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
int workingBufferLimitInRows) int workingBufferLimitInRows)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image0 = provider.GetImage(); using (Image<TPixel> image0 = provider.GetImage())
Size destSize = image0.Size() / 4; {
Size destSize = image0.Size() / 4;
var configuration = Configuration.CreateDefaultInstance();
int workingBufferSizeHintInBytes = workingBufferLimitInRows * destSize.Width * SizeOfVector4;
var allocator = new TestMemoryAllocator();
configuration.MemoryAllocator = allocator;
configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInBytes;
var verticalKernelMap = ResizeKernelMap.Calculate(
KnownResamplers.Bicubic,
destSize.Height,
image0.Height,
Configuration.Default.MemoryAllocator);
int minimumWorkerAllocationInBytes = verticalKernelMap.MaxDiameter * 2 * destSize.Width * SizeOfVector4;
verticalKernelMap.Dispose();
using Image<TPixel> image = image0.Clone(configuration);
image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false));
image.DebugSave(
provider,
testOutputDetails: workingBufferLimitInRows,
appendPixelTypeToFileName: false);
image.CompareToReferenceOutput(
ImageComparer.TolerantPercentage(0.001f),
provider,
testOutputDetails: workingBufferLimitInRows,
appendPixelTypeToFileName: false);
Assert.NotEmpty(allocator.AllocationLog); var configuration = Configuration.CreateDefaultInstance();
int maxAllocationSize = allocator.AllocationLog.Where( int workingBufferSizeHintInBytes = workingBufferLimitInRows * destSize.Width * SizeOfVector4;
e => e.ElementType == typeof(Vector4)).Max(e => e.LengthInBytes); var allocator = new TestMemoryAllocator();
configuration.MemoryAllocator = allocator;
configuration.WorkingBufferSizeHintInBytes = workingBufferSizeHintInBytes;
Assert.True(maxAllocationSize <= Math.Max(workingBufferSizeHintInBytes, minimumWorkerAllocationInBytes)); var verticalKernelMap = ResizeKernelMap.Calculate(
KnownResamplers.Bicubic,
destSize.Height,
image0.Height,
Configuration.Default.MemoryAllocator);
int minimumWorkerAllocationInBytes = verticalKernelMap.MaxDiameter * 2 * destSize.Width * SizeOfVector4;
verticalKernelMap.Dispose();
using (Image<TPixel> image = image0.Clone(configuration))
{
image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false));
image.DebugSave(
provider,
testOutputDetails: workingBufferLimitInRows,
appendPixelTypeToFileName: false);
image.CompareToReferenceOutput(
ImageComparer.TolerantPercentage(0.001f),
provider,
testOutputDetails: workingBufferLimitInRows,
appendPixelTypeToFileName: false);
Assert.NotEmpty(allocator.AllocationLog);
int maxAllocationSize = allocator.AllocationLog.Where(
e => e.ElementType == typeof(Vector4)).Max(e => e.LengthInBytes);
Assert.True(maxAllocationSize <= Math.Max(workingBufferSizeHintInBytes, minimumWorkerAllocationInBytes));
}
}
} }
[Theory] [Theory]
@ -150,11 +158,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void Resize_Compand<TPixel>(TestImageProvider<TPixel> provider) public void Resize_Compand<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(image.Size() / 2, true)); {
image.Mutate(x => x.Resize(image.Size() / 2, true));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -177,11 +187,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void Resize_IsAppliedToAllFrames<TPixel>(TestImageProvider<TPixel> provider) public void Resize_IsAppliedToAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2, KnownResamplers.Bicubic)); {
image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2, KnownResamplers.Bicubic));
// Comparer fights decoder with gif-s. Could not use CompareToReferenceOutput here :( // Comparer fights decoder with gif-s. Could not use CompareToReferenceOutput here :(
image.DebugSave(provider, extension: "gif"); image.DebugSave(provider, extension: "gif");
}
} }
[Theory] [Theory]
@ -197,12 +209,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void Resize_ThrowsForWrappedMemoryImage<TPixel>(TestImageProvider<TPixel> provider) public void Resize_ThrowsForWrappedMemoryImage<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image0 = provider.GetImage(); using (Image<TPixel> image0 = provider.GetImage())
var mmg = TestMemoryManager<TPixel>.CreateAsCopyOf(image0.GetPixelSpan()); {
var mmg = TestMemoryManager<TPixel>.CreateAsCopyOf(image0.GetPixelSpan());
using var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height); using (var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height))
Assert.ThrowsAny<Exception>( {
() => { image1.Mutate(x => x.Resize(image0.Width / 2, image0.Height / 2, true)); }); Assert.ThrowsAny<Exception>(
() => { image1.Mutate(x => x.Resize(image0.Width / 2, image0.Height / 2, true)); });
}
}
} }
[Theory] [Theory]
@ -275,31 +291,31 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
provider.RunValidatingProcessorTest( provider.RunValidatingProcessorTest(
ctx => ctx =>
{
SizeF newSize;
string destSizeInfo;
if (ratio.HasValue)
{ {
SizeF newSize; newSize = ctx.GetCurrentSize() * ratio.Value;
string destSizeInfo; destSizeInfo = ratio.Value.ToString(System.Globalization.CultureInfo.InvariantCulture);
if (ratio.HasValue) }
{ else
newSize = ctx.GetCurrentSize() * ratio.Value; {
destSizeInfo = ratio.Value.ToString(System.Globalization.CultureInfo.InvariantCulture); if (!specificDestWidth.HasValue || !specificDestHeight.HasValue)
}
else
{ {
if (!specificDestWidth.HasValue || !specificDestHeight.HasValue) throw new InvalidOperationException(
{ "invalid dimensional input for Resize_WorksWithAllResamplers!");
throw new InvalidOperationException(
"invalid dimensional input for Resize_WorksWithAllResamplers!");
}
newSize = new SizeF(specificDestWidth.Value, specificDestHeight.Value);
destSizeInfo = $"{newSize.Width}x{newSize.Height}";
} }
FormattableString testOutputDetails = $"{samplerName}-{destSizeInfo}"; newSize = new SizeF(specificDestWidth.Value, specificDestHeight.Value);
destSizeInfo = $"{newSize.Width}x{newSize.Height}";
}
FormattableString testOutputDetails = $"{samplerName}-{destSizeInfo}";
ctx.Resize((Size)newSize, sampler, false); ctx.Resize((Size)newSize, sampler, false);
return testOutputDetails; return testOutputDetails;
}, },
comparer, comparer,
appendPixelTypeToFileName: false); appendPixelTypeToFileName: false);
} }
@ -309,25 +325,27 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeFromSourceRectangle<TPixel>(TestImageProvider<TPixel> provider) public void ResizeFromSourceRectangle<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var sourceRectangle = new Rectangle( {
image.Width / 8, var sourceRectangle = new Rectangle(
image.Height / 8, image.Width / 8,
image.Width / 4, image.Height / 8,
image.Height / 4); image.Width / 4,
var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); image.Height / 4);
var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2);
image.Mutate(
x => x.Resize( image.Mutate(
image.Width, x => x.Resize(
image.Height, image.Width,
KnownResamplers.Bicubic, image.Height,
sourceRectangle, KnownResamplers.Bicubic,
destRectangle, sourceRectangle,
false)); destRectangle,
false));
image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -335,11 +353,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeHeightAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider) public void ResizeHeightAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(0, image.Height / 3, false)); {
image.Mutate(x => x.Resize(0, image.Height / 3, false));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -347,10 +367,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeHeightCannotKeepAspectKeepsOnePixel<TPixel>(TestImageProvider<TPixel> provider) public void ResizeHeightCannotKeepAspectKeepsOnePixel<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(0, 5)); {
Assert.Equal(1, image.Width); image.Mutate(x => x.Resize(0, 5));
Assert.Equal(5, image.Height); Assert.Equal(1, image.Width);
Assert.Equal(5, image.Height);
}
} }
[Theory] [Theory]
@ -358,11 +380,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWidthAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWidthAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(image.Width / 3, 0, false)); {
image.Mutate(x => x.Resize(image.Width / 3, 0, false));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -370,10 +394,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWidthCannotKeepAspectKeepsOnePixel<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWidthCannotKeepAspectKeepsOnePixel<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.Resize(5, 0)); {
Assert.Equal(5, image.Width); image.Mutate(x => x.Resize(5, 0));
Assert.Equal(1, image.Height); Assert.Equal(5, image.Width);
Assert.Equal(1, image.Height);
}
} }
[Theory] [Theory]
@ -381,17 +407,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithBoxPadMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithBoxPadMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions
{ {
Size = new Size(image.Width + 200, image.Height + 200), var options = new ResizeOptions
Mode = ResizeMode.BoxPad {
}; Size = new Size(image.Width + 200, image.Height + 200),
Mode = ResizeMode.BoxPad
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -399,13 +427,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithCropHeightMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithCropHeightMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions { Size = new Size(image.Width, image.Height / 2) }; {
var options = new ResizeOptions { Size = new Size(image.Width, image.Height / 2) };
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -413,13 +443,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithCropWidthMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithCropWidthMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions { Size = new Size(image.Width / 2, image.Height) }; {
var options = new ResizeOptions { Size = new Size(image.Width / 2, image.Height) };
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -427,17 +459,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void CanResizeLargeImageWithCropMode<TPixel>(TestImageProvider<TPixel> provider) public void CanResizeLargeImageWithCropMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions
{ {
Size = new Size(480, 600), var options = new ResizeOptions
Mode = ResizeMode.Crop {
}; Size = new Size(480, 600),
Mode = ResizeMode.Crop
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -445,13 +479,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithMaxMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithMaxMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions { Size = new Size(300, 300), Mode = ResizeMode.Max }; {
var options = new ResizeOptions { Size = new Size(300, 300), Mode = ResizeMode.Max };
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -459,19 +495,21 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithMinMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithMinMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions
{ {
Size = new Size( var options = new ResizeOptions
(int)Math.Round(image.Width * .75F), {
(int)Math.Round(image.Height * .95F)), Size = new Size(
Mode = ResizeMode.Min (int)Math.Round(image.Width * .75F),
}; (int)Math.Round(image.Height * .95F)),
Mode = ResizeMode.Min
image.Mutate(x => x.Resize(options)); };
image.DebugSave(provider); image.Mutate(x => x.Resize(options));
image.CompareToReferenceOutput(ValidatorComparer, provider);
image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -479,17 +517,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithPadMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithPadMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions
{ {
Size = new Size(image.Width + 200, image.Height), var options = new ResizeOptions
Mode = ResizeMode.Pad {
}; Size = new Size(image.Width + 200, image.Height),
Mode = ResizeMode.Pad
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -497,17 +537,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void ResizeWithStretchMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithStretchMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
var options = new ResizeOptions
{ {
Size = new Size(image.Width / 2, image.Height), var options = new ResizeOptions
Mode = ResizeMode.Stretch {
}; Size = new Size(image.Width / 2, image.Height),
Mode = ResizeMode.Stretch
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -523,10 +565,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
return; return;
} }
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
{
// Don't bother saving, we're testing the EXIF metadata updates. // Don't bother saving, we're testing the EXIF metadata updates.
image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2)); image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2));
}
} }
} }
} }

12
tests/ImageSharp.Tests/Processing/Processors/Transforms/RotateFlipTests.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. // Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -29,9 +29,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void RotateFlip<TPixel>(TestImageProvider<TPixel> provider, RotateMode rotateType, FlipMode flipType) public void RotateFlip<TPixel>(TestImageProvider<TPixel> provider, RotateMode rotateType, FlipMode flipType)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.Mutate(x => x.RotateFlip(rotateType, flipType)); {
image.DebugSave(provider, string.Join("_", rotateType, flipType)); image.Mutate(x => x.RotateFlip(rotateType, flipType));
image.DebugSave(provider, string.Join("_", rotateType, flipType));
}
} }
} }
} }

102
tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs

@ -80,14 +80,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
IResampler resampler = GetResampler(resamplerName); IResampler resampler = GetResampler(resamplerName);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
AffineTransformBuilder builder = new AffineTransformBuilder() {
.AppendRotationDegrees(30); AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendRotationDegrees(30);
image.Mutate(c => c.Transform(builder, resampler)); image.Mutate(c => c.Transform(builder, resampler));
image.DebugSave(provider, resamplerName); image.DebugSave(provider, resamplerName);
VerifyAllPixelsAreWhiteOrTransparent(image); VerifyAllPixelsAreWhiteOrTransparent(image);
}
} }
[Theory] [Theory]
@ -101,20 +103,22 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
float ty) float ty)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.DebugSave(provider, $"_original"); {
AffineTransformBuilder builder = new AffineTransformBuilder() image.DebugSave(provider, $"_original");
.AppendRotationDegrees(angleDeg) AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendScale(new SizeF(sx, sy)) .AppendRotationDegrees(angleDeg)
.AppendTranslation(new PointF(tx, ty)); .AppendScale(new SizeF(sx, sy))
.AppendTranslation(new PointF(tx, ty));
this.PrintMatrix(builder.BuildMatrix(image.Size())); this.PrintMatrix(builder.BuildMatrix(image.Size()));
image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic));
FormattableString testOutputDetails = $"R({angleDeg})_S({sx},{sy})_T({tx},{ty})"; FormattableString testOutputDetails = $"R({angleDeg})_S({sx},{sy})_T({tx},{ty})";
image.DebugSave(provider, testOutputDetails); image.DebugSave(provider, testOutputDetails);
image.CompareToReferenceOutput(ValidatorComparer, provider, testOutputDetails); image.CompareToReferenceOutput(ValidatorComparer, provider, testOutputDetails);
}
} }
[Theory] [Theory]
@ -122,16 +126,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
public void Transform_RotateScale_ManuallyCentered<TPixel>(TestImageProvider<TPixel> provider, float angleDeg, float s) public void Transform_RotateScale_ManuallyCentered<TPixel>(TestImageProvider<TPixel> provider, float angleDeg, float s)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
AffineTransformBuilder builder = new AffineTransformBuilder() {
.AppendRotationDegrees(angleDeg) AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendScale(new SizeF(s, s)); .AppendRotationDegrees(angleDeg)
.AppendScale(new SizeF(s, s));
image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic));
FormattableString testOutputDetails = $"R({angleDeg})_S({s})"; FormattableString testOutputDetails = $"R({angleDeg})_S({s})";
image.DebugSave(provider, testOutputDetails); image.DebugSave(provider, testOutputDetails);
image.CompareToReferenceOutput(ValidatorComparer, provider, testOutputDetails); image.CompareToReferenceOutput(ValidatorComparer, provider, testOutputDetails);
}
} }
public static readonly TheoryData<int, int, int, int> Transform_IntoRectangle_Data = public static readonly TheoryData<int, int, int, int> Transform_IntoRectangle_Data =
@ -156,15 +162,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
{ {
var rectangle = new Rectangle(48, 0, 48, 24); var rectangle = new Rectangle(48, 0, 48, 24);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.DebugSave(provider, $"_original"); {
AffineTransformBuilder builder = new AffineTransformBuilder() image.DebugSave(provider, $"_original");
.AppendScale(new SizeF(2, 1.5F)); AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendScale(new SizeF(2, 1.5F));
image.Mutate(i => i.Transform(rectangle, builder, KnownResamplers.Spline)); image.Mutate(i => i.Transform(rectangle, builder, KnownResamplers.Spline));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -174,14 +182,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
{ {
var rectangle = new Rectangle(0, 24, 48, 24); var rectangle = new Rectangle(0, 24, 48, 24);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
AffineTransformBuilder builder = new AffineTransformBuilder() {
.AppendScale(new SizeF(1F, 2F)); AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendScale(new SizeF(1F, 2F));
image.Mutate(i => i.Transform(rectangle, builder, KnownResamplers.Spline)); image.Mutate(i => i.Transform(rectangle, builder, KnownResamplers.Spline));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
}
} }
[Theory] [Theory]
@ -190,15 +200,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
IResampler sampler = GetResampler(resamplerName); IResampler sampler = GetResampler(resamplerName);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
AffineTransformBuilder builder = new AffineTransformBuilder() {
.AppendRotationDegrees(50) AffineTransformBuilder builder = new AffineTransformBuilder()
.AppendScale(new SizeF(.6F, .6F)); .AppendRotationDegrees(50)
.AppendScale(new SizeF(.6F, .6F));
image.Mutate(i => i.Transform(builder, sampler)); image.Mutate(i => i.Transform(builder, sampler));
image.DebugSave(provider, resamplerName); image.DebugSave(provider, resamplerName);
image.CompareToReferenceOutput(ValidatorComparer, provider, resamplerName); image.CompareToReferenceOutput(ValidatorComparer, provider, resamplerName);
}
} }
private static IResampler GetResampler(string name) private static IResampler GetResampler(string name)

68
tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs

@ -64,14 +64,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
IResampler sampler = GetResampler(resamplerName); IResampler sampler = GetResampler(resamplerName);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() {
.AppendTaper(TaperSide.Right, TaperCorner.Both, .5F); ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder()
.AppendTaper(TaperSide.Right, TaperCorner.Both, .5F);
image.Mutate(i => i.Transform(builder, sampler)); image.Mutate(i => i.Transform(builder, sampler));
image.DebugSave(provider, resamplerName); image.DebugSave(provider, resamplerName);
image.CompareToReferenceOutput(ValidatorComparer, provider, resamplerName); image.CompareToReferenceOutput(ValidatorComparer, provider, resamplerName);
}
} }
[Theory] [Theory]
@ -79,15 +81,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
public void Transform_WithTaperMatrix<TPixel>(TestImageProvider<TPixel> provider, TaperSide taperSide, TaperCorner taperCorner) public void Transform_WithTaperMatrix<TPixel>(TestImageProvider<TPixel> provider, TaperSide taperSide, TaperCorner taperCorner)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() {
.AppendTaper(taperSide, taperCorner, .5F); ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder()
.AppendTaper(taperSide, taperCorner, .5F);
image.Mutate(i => i.Transform(builder)); image.Mutate(i => i.Transform(builder));
FormattableString testOutputDetails = $"{taperSide}-{taperCorner}"; FormattableString testOutputDetails = $"{taperSide}-{taperCorner}";
image.DebugSave(provider, testOutputDetails); image.DebugSave(provider, testOutputDetails);
image.CompareFirstFrameToReferenceOutput(TolerantComparer, provider, testOutputDetails); image.CompareFirstFrameToReferenceOutput(TolerantComparer, provider, testOutputDetails);
}
} }
[Theory] [Theory]
@ -100,17 +104,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
// This test matches the output described in the example at // This test matches the output described in the example at
// https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/transforms/non-affine // https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/transforms/non-affine
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Matrix4x4 matrix = Matrix4x4.Identity; {
matrix.M14 = 0.01F; Matrix4x4 matrix = Matrix4x4.Identity;
matrix.M14 = 0.01F;
ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder()
.AppendMatrix(matrix); .AppendMatrix(matrix);
image.Mutate(i => i.Transform(builder)); image.Mutate(i => i.Transform(builder));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(TolerantComparer, provider); image.CompareToReferenceOutput(TolerantComparer, provider);
}
} }
[Theory] [Theory]
@ -120,22 +126,24 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
{ {
// https://jsfiddle.net/dFrHS/545/ // https://jsfiddle.net/dFrHS/545/
// https://github.com/SixLabors/ImageSharp/issues/787 // https://github.com/SixLabors/ImageSharp/issues/787
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
{
#pragma warning disable SA1117 // Parameters should be on same line or separate lines #pragma warning disable SA1117 // Parameters should be on same line or separate lines
var matrix = new Matrix4x4( var matrix = new Matrix4x4(
0.260987f, -0.434909f, 0, -0.0022184f, 0.260987f, -0.434909f, 0, -0.0022184f,
0.373196f, 0.949882f, 0, -0.000312129f, 0.373196f, 0.949882f, 0, -0.000312129f,
0, 0, 1, 0, 0, 0, 1, 0,
52, 165, 0, 1); 52, 165, 0, 1);
#pragma warning restore SA1117 // Parameters should be on same line or separate lines #pragma warning restore SA1117 // Parameters should be on same line or separate lines
ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder()
.AppendMatrix(matrix); .AppendMatrix(matrix);
image.Mutate(i => i.Transform(builder)); image.Mutate(i => i.Transform(builder));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(TolerantComparer, provider); image.CompareToReferenceOutput(TolerantComparer, provider);
}
} }
private static IResampler GetResampler(string name) private static IResampler GetResampler(string name)

22
tests/ImageSharp.Tests/Processing/Transforms/TransformsHelpersTest.cs

@ -15,19 +15,21 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
{ {
int xy = 1; int xy = 1;
using var img = new Image<A8>(xy, xy); using (var img = new Image<A8>(xy, xy))
var profile = new ExifProfile(); {
img.Metadata.ExifProfile = profile; var profile = new ExifProfile();
profile.SetValue(ExifTag.PixelXDimension, xy + ushort.MaxValue); img.Metadata.ExifProfile = profile;
profile.SetValue(ExifTag.PixelYDimension, xy + ushort.MaxValue); profile.SetValue(ExifTag.PixelXDimension, xy + ushort.MaxValue);
profile.SetValue(ExifTag.PixelYDimension, xy + ushort.MaxValue);
Assert.Equal(ExifDataType.Long, profile.GetValue(ExifTag.PixelXDimension).DataType); Assert.Equal(ExifDataType.Long, profile.GetValue(ExifTag.PixelXDimension).DataType);
Assert.Equal(ExifDataType.Long, profile.GetValue(ExifTag.PixelYDimension).DataType); Assert.Equal(ExifDataType.Long, profile.GetValue(ExifTag.PixelYDimension).DataType);
TransformProcessorHelpers.UpdateDimensionalMetadata(img); TransformProcessorHelpers.UpdateDimensionalMetadata(img);
Assert.Equal(ExifDataType.Short, profile.GetValue(ExifTag.PixelXDimension).DataType); Assert.Equal(ExifDataType.Short, profile.GetValue(ExifTag.PixelXDimension).DataType);
Assert.Equal(ExifDataType.Short, profile.GetValue(ExifTag.PixelYDimension).DataType); Assert.Equal(ExifDataType.Short, profile.GetValue(ExifTag.PixelYDimension).DataType);
}
} }
} }
} }

28
tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs

@ -26,19 +26,21 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks
byte[] imageBytes = TestFile.Create(imagePath).Bytes; byte[] imageBytes = TestFile.Create(imagePath).Bytes;
using var ms = new MemoryStream(); using (var ms = new MemoryStream())
this.Measure( {
30, this.Measure(
() => 30,
{ () =>
using (var image = Image.Load(configuration, imageBytes)) {
{ using (var image = Image.Load(configuration, imageBytes))
image.Mutate(x => x.Resize(image.Size() / 4)); {
image.SaveAsJpeg(ms); image.Mutate(x => x.Resize(image.Size() / 4));
} image.SaveAsJpeg(ms);
}
ms.Seek(0, SeekOrigin.Begin);
}); ms.Seek(0, SeekOrigin.Begin);
});
}
} }
} }
} }

10
tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs

@ -29,10 +29,12 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks
this.Measure( this.Measure(
this.ExecutionCount, this.ExecutionCount,
() => () =>
{ {
using var image = new Image<Rgba32>(this.configuration, width, height); using (var image = new Image<Rgba32>(this.configuration, width, height))
image.Mutate(x => x.Resize(width / 5, height / 5)); {
}); image.Mutate(x => x.Resize(width / 5, height / 5));
}
});
} }
} }
} }

40
tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs

@ -41,18 +41,20 @@ namespace SixLabors.ImageSharp.Tests
bool dither) bool dither)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Assert.True(image[0, 0].Equals(default(TPixel))); {
Assert.True(image[0, 0].Equals(default(TPixel)));
var quantizer = new OctreeQuantizer(dither); var quantizer = new OctreeQuantizer(dither);
foreach (ImageFrame<TPixel> frame in image.Frames) foreach (ImageFrame<TPixel> frame in image.Frames)
{ {
IQuantizedFrame<TPixel> quantized = IQuantizedFrame<TPixel> quantized =
quantizer.CreateFrameQuantizer<TPixel>(this.Configuration).QuantizeFrame(frame); quantizer.CreateFrameQuantizer<TPixel>(this.Configuration).QuantizeFrame(frame);
int index = this.GetTransparentIndex(quantized); int index = this.GetTransparentIndex(quantized);
Assert.Equal(index, quantized.GetPixelSpan()[0]); Assert.Equal(index, quantized.GetPixelSpan()[0]);
}
} }
} }
@ -62,18 +64,20 @@ namespace SixLabors.ImageSharp.Tests
public void WuQuantizerYieldsCorrectTransparentPixel<TPixel>(TestImageProvider<TPixel> provider, bool dither) public void WuQuantizerYieldsCorrectTransparentPixel<TPixel>(TestImageProvider<TPixel> provider, bool dither)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Assert.True(image[0, 0].Equals(default(TPixel))); {
Assert.True(image[0, 0].Equals(default(TPixel)));
var quantizer = new WuQuantizer(dither); var quantizer = new WuQuantizer(dither);
foreach (ImageFrame<TPixel> frame in image.Frames) foreach (ImageFrame<TPixel> frame in image.Frames)
{ {
IQuantizedFrame<TPixel> quantized = IQuantizedFrame<TPixel> quantized =
quantizer.CreateFrameQuantizer<TPixel>(this.Configuration).QuantizeFrame(frame); quantizer.CreateFrameQuantizer<TPixel>(this.Configuration).QuantizeFrame(frame);
int index = this.GetTransparentIndex(quantized); int index = this.GetTransparentIndex(quantized);
Assert.Equal(index, quantized.GetPixelSpan()[0]); Assert.Equal(index, quantized.GetPixelSpan()[0]);
}
} }
} }

176
tests/ImageSharp.Tests/Quantization/WuQuantizerTests.cs

@ -17,13 +17,15 @@ namespace SixLabors.ImageSharp.Tests.Quantization
Configuration config = Configuration.Default; Configuration config = Configuration.Default;
var quantizer = new WuQuantizer(false); var quantizer = new WuQuantizer(false);
using var image = new Image<Rgba32>(config, 1, 1, Rgba32.Black); using (var image = new Image<Rgba32>(config, 1, 1, Rgba32.Black))
using IQuantizedFrame<Rgba32> result = quantizer.CreateFrameQuantizer<Rgba32>(config).QuantizeFrame(image.Frames[0]); using (IQuantizedFrame<Rgba32> result = quantizer.CreateFrameQuantizer<Rgba32>(config).QuantizeFrame(image.Frames[0]))
Assert.Equal(1, result.Palette.Length); {
Assert.Equal(1, result.GetPixelSpan().Length); Assert.Equal(1, result.Palette.Length);
Assert.Equal(1, result.GetPixelSpan().Length);
Assert.Equal(Rgba32.Black, result.Palette.Span[0]); Assert.Equal(Rgba32.Black, result.Palette.Span[0]);
Assert.Equal(0, result.GetPixelSpan()[0]); Assert.Equal(0, result.GetPixelSpan()[0]);
}
} }
[Fact] [Fact]
@ -32,13 +34,15 @@ namespace SixLabors.ImageSharp.Tests.Quantization
Configuration config = Configuration.Default; Configuration config = Configuration.Default;
var quantizer = new WuQuantizer(false); var quantizer = new WuQuantizer(false);
using var image = new Image<Rgba32>(config, 1, 1, default(Rgba32)); using (var image = new Image<Rgba32>(config, 1, 1, default(Rgba32)))
using IQuantizedFrame<Rgba32> result = quantizer.CreateFrameQuantizer<Rgba32>(config).QuantizeFrame(image.Frames[0]); using (IQuantizedFrame<Rgba32> result = quantizer.CreateFrameQuantizer<Rgba32>(config).QuantizeFrame(image.Frames[0]))
Assert.Equal(1, result.Palette.Length); {
Assert.Equal(1, result.GetPixelSpan().Length); Assert.Equal(1, result.Palette.Length);
Assert.Equal(1, result.GetPixelSpan().Length);
Assert.Equal(default, result.Palette.Span[0]); Assert.Equal(default, result.Palette.Span[0]);
Assert.Equal(0, result.GetPixelSpan()[0]); Assert.Equal(0, result.GetPixelSpan()[0]);
}
} }
[Fact] [Fact]
@ -59,42 +63,46 @@ namespace SixLabors.ImageSharp.Tests.Quantization
[Fact] [Fact]
public void Palette256() public void Palette256()
{ {
using var image = new Image<Rgba32>(1, 256); using (var image = new Image<Rgba32>(1, 256))
for (int i = 0; i < 256; i++)
{ {
byte r = (byte)((i % 4) * 85); for (int i = 0; i < 256; i++)
byte g = (byte)(((i / 4) % 4) * 85); {
byte b = (byte)(((i / 16) % 4) * 85); byte r = (byte)((i % 4) * 85);
byte a = (byte)((i / 64) * 85); byte g = (byte)(((i / 4) % 4) * 85);
byte b = (byte)(((i / 16) % 4) * 85);
image[0, i] = new Rgba32(r, g, b, a); byte a = (byte)((i / 64) * 85);
}
Configuration config = Configuration.Default;
var quantizer = new WuQuantizer(false);
using IFrameQuantizer<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(config);
using IQuantizedFrame<Rgba32> result = frameQuantizer.QuantizeFrame(image.Frames[0]);
Assert.Equal(256, result.Palette.Length);
Assert.Equal(256, result.GetPixelSpan().Length);
var actualImage = new Image<Rgba32>(1, 256);
ReadOnlySpan<Rgba32> paletteSpan = result.Palette.Span; image[0, i] = new Rgba32(r, g, b, a);
int paletteCount = result.Palette.Length - 1; }
for (int y = 0; y < actualImage.Height; y++)
{
Span<Rgba32> row = actualImage.GetPixelRowSpan(y);
ReadOnlySpan<byte> quantizedPixelSpan = result.GetPixelSpan();
int yy = y * actualImage.Width;
for (int x = 0; x < actualImage.Width; x++) Configuration config = Configuration.Default;
var quantizer = new WuQuantizer(false);
using (IFrameQuantizer<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(config))
using (IQuantizedFrame<Rgba32> result = frameQuantizer.QuantizeFrame(image.Frames[0]))
{ {
int i = x + yy; Assert.Equal(256, result.Palette.Length);
row[x] = paletteSpan[Math.Min(paletteCount, quantizedPixelSpan[i])]; Assert.Equal(256, result.GetPixelSpan().Length);
var actualImage = new Image<Rgba32>(1, 256);
ReadOnlySpan<Rgba32> paletteSpan = result.Palette.Span;
int paletteCount = result.Palette.Length - 1;
for (int y = 0; y < actualImage.Height; y++)
{
Span<Rgba32> row = actualImage.GetPixelRowSpan(y);
ReadOnlySpan<byte> quantizedPixelSpan = result.GetPixelSpan();
int yy = y * actualImage.Width;
for (int x = 0; x < actualImage.Width; x++)
{
int i = x + yy;
row[x] = paletteSpan[Math.Min(paletteCount, quantizedPixelSpan[i])];
}
}
Assert.True(image.GetPixelSpan().SequenceEqual(actualImage.GetPixelSpan()));
} }
} }
Assert.True(image.GetPixelSpan().SequenceEqual(actualImage.GetPixelSpan()));
} }
[Theory] [Theory]
@ -103,55 +111,63 @@ namespace SixLabors.ImageSharp.Tests.Quantization
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
// See https://github.com/SixLabors/ImageSharp/issues/866 // See https://github.com/SixLabors/ImageSharp/issues/866
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Configuration config = Configuration.Default; {
var quantizer = new WuQuantizer(false); Configuration config = Configuration.Default;
using IFrameQuantizer<TPixel> frameQuantizer = quantizer.CreateFrameQuantizer<TPixel>(config); var quantizer = new WuQuantizer(false);
using IQuantizedFrame<TPixel> result = frameQuantizer.QuantizeFrame(image.Frames[0]); using (IFrameQuantizer<TPixel> frameQuantizer = quantizer.CreateFrameQuantizer<TPixel>(config))
Assert.Equal(48, result.Palette.Length); using (IQuantizedFrame<TPixel> result = frameQuantizer.QuantizeFrame(image.Frames[0]))
{
Assert.Equal(48, result.Palette.Length);
}
}
} }
private static void TestScale(Func<byte, Rgba32> pixelBuilder) private static void TestScale(Func<byte, Rgba32> pixelBuilder)
{ {
using var image = new Image<Rgba32>(1, 256); using (var image = new Image<Rgba32>(1, 256))
using var expectedImage = new Image<Rgba32>(1, 256); using (var expectedImage = new Image<Rgba32>(1, 256))
using var actualImage = new Image<Rgba32>(1, 256); using (var actualImage = new Image<Rgba32>(1, 256))
for (int i = 0; i < 256; i++)
{ {
byte c = (byte)i; for (int i = 0; i < 256; i++)
image[0, i] = pixelBuilder.Invoke(c); {
} byte c = (byte)i;
image[0, i] = pixelBuilder.Invoke(c);
for (int i = 0; i < 256; i++) }
{
byte c = (byte)((i & ~7) + 4);
expectedImage[0, i] = pixelBuilder.Invoke(c);
}
Configuration config = Configuration.Default;
var quantizer = new WuQuantizer(false);
using IFrameQuantizer<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(config); for (int i = 0; i < 256; i++)
using IQuantizedFrame<Rgba32> result = frameQuantizer.QuantizeFrame(image.Frames[0]); {
Assert.Equal(4 * 8, result.Palette.Length); byte c = (byte)((i & ~7) + 4);
Assert.Equal(256, result.GetPixelSpan().Length); expectedImage[0, i] = pixelBuilder.Invoke(c);
}
ReadOnlySpan<Rgba32> paletteSpan = result.Palette.Span; Configuration config = Configuration.Default;
int paletteCount = result.Palette.Length - 1; var quantizer = new WuQuantizer(false);
for (int y = 0; y < actualImage.Height; y++)
{
Span<Rgba32> row = actualImage.GetPixelRowSpan(y);
ReadOnlySpan<byte> quantizedPixelSpan = result.GetPixelSpan();
int yy = y * actualImage.Width;
for (int x = 0; x < actualImage.Width; x++) using (IFrameQuantizer<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(config))
using (IQuantizedFrame<Rgba32> result = frameQuantizer.QuantizeFrame(image.Frames[0]))
{ {
int i = x + yy; Assert.Equal(4 * 8, result.Palette.Length);
row[x] = paletteSpan[Math.Min(paletteCount, quantizedPixelSpan[i])]; Assert.Equal(256, result.GetPixelSpan().Length);
ReadOnlySpan<Rgba32> paletteSpan = result.Palette.Span;
int paletteCount = result.Palette.Length - 1;
for (int y = 0; y < actualImage.Height; y++)
{
Span<Rgba32> row = actualImage.GetPixelRowSpan(y);
ReadOnlySpan<byte> quantizedPixelSpan = result.GetPixelSpan();
int yy = y * actualImage.Width;
for (int x = 0; x < actualImage.Width; x++)
{
int i = x + yy;
row[x] = paletteSpan[Math.Min(paletteCount, quantizedPixelSpan[i])];
}
}
} }
}
Assert.True(expectedImage.GetPixelSpan().SequenceEqual(actualImage.GetPixelSpan())); Assert.True(expectedImage.GetPixelSpan().SequenceEqual(actualImage.GetPixelSpan()));
}
} }
} }
} }

12
tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs

@ -223,10 +223,14 @@ namespace SixLabors.ImageSharp.Tests
for (int i = 0; i < image.Frames.Count; i++) for (int i = 0; i < image.Frames.Count; i++)
{ {
using Image<TPixel> frameImage = image.Frames.CloneFrame(i); using (Image<TPixel> frameImage = image.Frames.CloneFrame(i))
string filePath = files[i]; {
using FileStream stream = File.OpenWrite(filePath); string filePath = files[i];
frameImage.Save(stream, encoder); using (FileStream stream = File.OpenWrite(filePath))
{
frameImage.Save(stream, encoder);
}
}
} }
return files; return files;

64
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs

@ -20,38 +20,42 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using var magickImage = new MagickImage(stream); using (var magickImage = new MagickImage(stream))
var result = new Image<TPixel>(configuration, magickImage.Width, magickImage.Height);
Span<TPixel> resultPixels = result.GetPixelSpan();
using IPixelCollection pixels = magickImage.GetPixelsUnsafe();
if (magickImage.Depth == 8)
{
byte[] data = pixels.ToByteArray(PixelMapping.RGBA);
PixelOperations<TPixel>.Instance.FromRgba32Bytes(
configuration,
data,
resultPixels,
resultPixels.Length);
}
else if (magickImage.Depth == 16)
{ {
ushort[] data = pixels.ToShortArray(PixelMapping.RGBA); var result = new Image<TPixel>(configuration, magickImage.Width, magickImage.Height);
Span<byte> bytes = MemoryMarshal.Cast<ushort, byte>(data.AsSpan()); Span<TPixel> resultPixels = result.GetPixelSpan();
PixelOperations<TPixel>.Instance.FromRgba64Bytes( using (IPixelCollection pixels = magickImage.GetPixelsUnsafe())
configuration, {
bytes, if (magickImage.Depth == 8)
resultPixels, {
resultPixels.Length); byte[] data = pixels.ToByteArray(PixelMapping.RGBA);
PixelOperations<TPixel>.Instance.FromRgba32Bytes(
configuration,
data,
resultPixels,
resultPixels.Length);
}
else if (magickImage.Depth == 16)
{
ushort[] data = pixels.ToShortArray(PixelMapping.RGBA);
Span<byte> bytes = MemoryMarshal.Cast<ushort, byte>(data.AsSpan());
PixelOperations<TPixel>.Instance.FromRgba64Bytes(
configuration,
bytes,
resultPixels,
resultPixels.Length);
}
else
{
throw new InvalidOperationException();
}
}
return result;
} }
else
{
throw new InvalidOperationException();
}
return result;
} }
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream); public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);

60
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs

@ -49,20 +49,22 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
Configuration configuration = image.GetConfiguration(); Configuration configuration = image.GetConfiguration();
using IMemoryOwner<Bgra32> workBuffer = Configuration.Default.MemoryAllocator.Allocate<Bgra32>(w); using (IMemoryOwner<Bgra32> workBuffer = Configuration.Default.MemoryAllocator.Allocate<Bgra32>(w))
fixed (Bgra32* destPtr = &workBuffer.GetReference())
{ {
for (int y = 0; y < h; y++) fixed (Bgra32* destPtr = &workBuffer.GetReference())
{ {
Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y); for (int y = 0; y < h; y++)
{
byte* sourcePtr = sourcePtrBase + (data.Stride * y); Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y);
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); byte* sourcePtr = sourcePtrBase + (data.Stride * y);
PixelOperations<TPixel>.Instance.FromBgra32(
configuration, Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);
workBuffer.GetSpan().Slice(0, w), PixelOperations<TPixel>.Instance.FromBgra32(
row); configuration,
workBuffer.GetSpan().Slice(0, w),
row);
}
} }
} }
} }
@ -106,17 +108,19 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
Configuration configuration = image.GetConfiguration(); Configuration configuration = image.GetConfiguration();
using IMemoryOwner<Bgr24> workBuffer = Configuration.Default.MemoryAllocator.Allocate<Bgr24>(w); using (IMemoryOwner<Bgr24> workBuffer = Configuration.Default.MemoryAllocator.Allocate<Bgr24>(w))
fixed (Bgr24* destPtr = &workBuffer.GetReference())
{ {
for (int y = 0; y < h; y++) fixed (Bgr24* destPtr = &workBuffer.GetReference())
{ {
Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y); for (int y = 0; y < h; y++)
{
Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y);
byte* sourcePtr = sourcePtrBase + (data.Stride * y); byte* sourcePtr = sourcePtrBase + (data.Stride * y);
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);
PixelOperations<TPixel>.Instance.FromBgr24(configuration, workBuffer.GetSpan().Slice(0, w), row); PixelOperations<TPixel>.Instance.FromBgr24(configuration, workBuffer.GetSpan().Slice(0, w), row);
}
} }
} }
} }
@ -145,16 +149,18 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
long destRowByteCount = data.Stride; long destRowByteCount = data.Stride;
long sourceRowByteCount = w * sizeof(Bgra32); long sourceRowByteCount = w * sizeof(Bgra32);
using IMemoryOwner<Bgra32> workBuffer = image.GetConfiguration().MemoryAllocator.Allocate<Bgra32>(w); using (IMemoryOwner<Bgra32> workBuffer = image.GetConfiguration().MemoryAllocator.Allocate<Bgra32>(w))
fixed (Bgra32* sourcePtr = &workBuffer.GetReference())
{ {
for (int y = 0; y < h; y++) fixed (Bgra32* sourcePtr = &workBuffer.GetReference())
{ {
Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y); for (int y = 0; y < h; y++)
PixelOperations<TPixel>.Instance.ToBgra32(configuration, row, workBuffer.GetSpan()); {
byte* destPtr = destPtrBase + (data.Stride * y); Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y);
PixelOperations<TPixel>.Instance.ToBgra32(configuration, row, workBuffer.GetSpan());
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); byte* destPtr = destPtrBase + (data.Stride * y);
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);
}
} }
} }
} }

48
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceDecoder.cs

@ -16,32 +16,40 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using var sourceBitmap = new System.Drawing.Bitmap(stream); using (var sourceBitmap = new System.Drawing.Bitmap(stream))
if (sourceBitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb)
{ {
return SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(sourceBitmap); if (sourceBitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb)
{
return SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(sourceBitmap);
}
using (var convertedBitmap = new System.Drawing.Bitmap(
sourceBitmap.Width,
sourceBitmap.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
using (var g = System.Drawing.Graphics.FromImage(convertedBitmap))
{
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.DrawImage(sourceBitmap, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
}
return SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(convertedBitmap);
}
} }
using var convertedBitmap = new System.Drawing.Bitmap(
sourceBitmap.Width,
sourceBitmap.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using var g = System.Drawing.Graphics.FromImage(convertedBitmap);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.DrawImage(sourceBitmap, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
return SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(convertedBitmap);
} }
public IImageInfo Identify(Configuration configuration, Stream stream) public IImageInfo Identify(Configuration configuration, Stream stream)
{ {
using var sourceBitmap = new System.Drawing.Bitmap(stream); using (var sourceBitmap = new System.Drawing.Bitmap(stream))
var pixelType = new PixelTypeInfo(System.Drawing.Image.GetPixelFormatSize(sourceBitmap.PixelFormat)); {
return new ImageInfo(pixelType, sourceBitmap.Width, sourceBitmap.Height, new ImageMetadata()); var pixelType = new PixelTypeInfo(System.Drawing.Image.GetPixelFormatSize(sourceBitmap.PixelFormat));
return new ImageInfo(pixelType, sourceBitmap.Width, sourceBitmap.Height, new ImageMetadata());
}
} }
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream); public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);

8
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.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. // Licensed under the Apache License, Version 2.0.
using System.Drawing.Imaging; using System.Drawing.Imaging;
@ -25,8 +25,10 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
public void Encode<TPixel>(Image<TPixel> image, Stream stream) public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image); using (System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image))
sdBitmap.Save(stream, this.imageFormat); {
sdBitmap.Save(stream, this.imageFormat);
}
} }
} }
} }

62
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -286,17 +286,19 @@ namespace SixLabors.ImageSharp.Tests
bool appendSourceFileOrDescription = true) bool appendSourceFileOrDescription = true)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using var firstFrameOnlyImage = new Image<TPixel>(image.Width, image.Height); using (var firstFrameOnlyImage = new Image<TPixel>(image.Width, image.Height))
using Image<TPixel> referenceImage = GetReferenceOutputImage<TPixel>( using (Image<TPixel> referenceImage = GetReferenceOutputImage<TPixel>(
provider, provider,
testOutputDetails, testOutputDetails,
extension, extension,
appendPixelTypeToFileName, appendPixelTypeToFileName,
appendSourceFileOrDescription); appendSourceFileOrDescription))
firstFrameOnlyImage.Frames.AddFrame(image.Frames.RootFrame); {
firstFrameOnlyImage.Frames.RemoveFrame(0); firstFrameOnlyImage.Frames.AddFrame(image.Frames.RootFrame);
firstFrameOnlyImage.Frames.RemoveFrame(0);
comparer.VerifySimilarity(referenceImage, firstFrameOnlyImage); comparer.VerifySimilarity(referenceImage, firstFrameOnlyImage);
}
return image; return image;
} }
@ -402,11 +404,13 @@ namespace SixLabors.ImageSharp.Tests
bool appendPixelTypeToFileName = true) bool appendPixelTypeToFileName = true)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> referenceImage = provider.GetReferenceOutputImage<TPixel>( using (Image<TPixel> referenceImage = provider.GetReferenceOutputImage<TPixel>(
testOutputDetails, testOutputDetails,
extension, extension,
appendPixelTypeToFileName); appendPixelTypeToFileName))
return comparer.CompareImages(referenceImage, image); {
return comparer.CompareImages(referenceImage, image);
}
} }
public static Image<TPixel> ComparePixelBufferTo<TPixel>( public static Image<TPixel> ComparePixelBufferTo<TPixel>(
@ -551,21 +555,23 @@ namespace SixLabors.ImageSharp.Tests
bool appendSourceFileOrDescription = true) bool appendSourceFileOrDescription = true)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
operation(image); {
operation(image);
image.DebugSave(
provider, image.DebugSave(
testOutputDetails, provider,
appendPixelTypeToFileName: appendPixelTypeToFileName, testOutputDetails,
appendSourceFileOrDescription: appendSourceFileOrDescription); appendPixelTypeToFileName: appendPixelTypeToFileName,
appendSourceFileOrDescription: appendSourceFileOrDescription);
image.CompareToReferenceOutput(
comparer, image.CompareToReferenceOutput(
provider, comparer,
testOutputDetails, provider,
appendPixelTypeToFileName: appendPixelTypeToFileName, testOutputDetails,
appendSourceFileOrDescription: appendSourceFileOrDescription); appendPixelTypeToFileName: appendPixelTypeToFileName,
appendSourceFileOrDescription: appendSourceFileOrDescription);
}
} }
/// <summary> /// <summary>
@ -653,9 +659,11 @@ namespace SixLabors.ImageSharp.Tests
referenceDecoder = referenceDecoder ?? TestEnvironment.GetReferenceDecoder(actualOutputFile); referenceDecoder = referenceDecoder ?? TestEnvironment.GetReferenceDecoder(actualOutputFile);
using var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder); using (var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
ImageComparer comparer = customComparer ?? ImageComparer.Exact; {
comparer.VerifySimilarity(actualImage, image); ImageComparer comparer = customComparer ?? ImageComparer.Exact;
comparer.VerifySimilarity(actualImage, image);
}
} }
internal static Image<Rgba32> ToGrayscaleImage(this Buffer2D<float> buffer, float scale) internal static Image<Rgba32> ToGrayscaleImage(this Buffer2D<float> buffer, float scale)

104
tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs

@ -33,10 +33,14 @@ namespace SixLabors.ImageSharp.Tests
int pixelThreshold) int pixelThreshold)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(); {
var comparer = ImageComparer.Tolerant(imageThreshold, pixelThreshold); using (Image<TPixel> clone = image.Clone())
comparer.VerifySimilarity(image, clone); {
var comparer = ImageComparer.Tolerant(imageThreshold, pixelThreshold);
comparer.VerifySimilarity(image, clone);
}
}
} }
[Theory] [Theory]
@ -44,12 +48,16 @@ namespace SixLabors.ImageSharp.Tests
public void TolerantImageComparer_ApprovesSimilarityBelowTolerance<TPixel>(TestImageProvider<TPixel> provider) public void TolerantImageComparer_ApprovesSimilarityBelowTolerance<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(); {
ImagingTestCaseUtility.ModifyPixel(clone, 0, 0, 1); using (Image<TPixel> clone = image.Clone())
{
ImagingTestCaseUtility.ModifyPixel(clone, 0, 0, 1);
var comparer = ImageComparer.Tolerant(); var comparer = ImageComparer.Tolerant();
comparer.VerifySimilarity(image, clone); comparer.VerifySimilarity(image, clone);
}
}
} }
[Theory] [Theory]
@ -57,18 +65,22 @@ namespace SixLabors.ImageSharp.Tests
public void TolerantImageComparer_DoesNotApproveSimilarityAboveTolerance<TPixel>(TestImageProvider<TPixel> provider) public void TolerantImageComparer_DoesNotApproveSimilarityAboveTolerance<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(); {
byte perChannelChange = 20; using (Image<TPixel> clone = image.Clone())
ImagingTestCaseUtility.ModifyPixel(clone, 3, 1, perChannelChange); {
byte perChannelChange = 20;
ImagingTestCaseUtility.ModifyPixel(clone, 3, 1, perChannelChange);
var comparer = ImageComparer.Tolerant(); var comparer = ImageComparer.Tolerant();
ImageDifferenceIsOverThresholdException ex = Assert.ThrowsAny<ImageDifferenceIsOverThresholdException>( ImageDifferenceIsOverThresholdException ex = Assert.ThrowsAny<ImageDifferenceIsOverThresholdException>(
() => comparer.VerifySimilarity(image, clone)); () => comparer.VerifySimilarity(image, clone));
PixelDifference diff = ex.Reports.Single().Differences.Single(); PixelDifference diff = ex.Reports.Single().Differences.Single();
Assert.Equal(new Point(3, 1), diff.Position); Assert.Equal(new Point(3, 1), diff.Position);
}
}
} }
[Theory] [Theory]
@ -76,14 +88,18 @@ namespace SixLabors.ImageSharp.Tests
public void TolerantImageComparer_TestPerPixelThreshold<TPixel>(TestImageProvider<TPixel> provider) public void TolerantImageComparer_TestPerPixelThreshold<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(); {
ImagingTestCaseUtility.ModifyPixel(clone, 0, 0, 1); using (Image<TPixel> clone = image.Clone())
ImagingTestCaseUtility.ModifyPixel(clone, 1, 0, 1); {
ImagingTestCaseUtility.ModifyPixel(clone, 2, 0, 1); ImagingTestCaseUtility.ModifyPixel(clone, 0, 0, 1);
ImagingTestCaseUtility.ModifyPixel(clone, 1, 0, 1);
var comparer = ImageComparer.Tolerant(perPixelManhattanThreshold: 257 * 3); ImagingTestCaseUtility.ModifyPixel(clone, 2, 0, 1);
comparer.VerifySimilarity(image, clone);
var comparer = ImageComparer.Tolerant(perPixelManhattanThreshold: 257 * 3);
comparer.VerifySimilarity(image, clone);
}
}
} }
[Theory] [Theory]
@ -92,15 +108,19 @@ namespace SixLabors.ImageSharp.Tests
public void VerifySimilarity_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h) public void VerifySimilarity_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(ctx => ctx.Resize(w, h)); {
ImageDimensionsMismatchException ex = Assert.ThrowsAny<ImageDimensionsMismatchException>( using (Image<TPixel> clone = image.Clone(ctx => ctx.Resize(w, h)))
() =>
{ {
ImageComparer comparer = Mock.Of<ImageComparer>(); ImageDimensionsMismatchException ex = Assert.ThrowsAny<ImageDimensionsMismatchException>(
comparer.VerifySimilarity(image, clone); () =>
}); {
this.Output.WriteLine(ex.Message); ImageComparer comparer = Mock.Of<ImageComparer>();
comparer.VerifySimilarity(image, clone);
});
this.Output.WriteLine(ex.Message);
}
}
} }
[Theory] [Theory]
@ -108,14 +128,18 @@ namespace SixLabors.ImageSharp.Tests
public void VerifySimilarity_WhenAnImageFrameIsDifferent_Reports<TPixel>(TestImageProvider<TPixel> provider) public void VerifySimilarity_WhenAnImageFrameIsDifferent_Reports<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(); {
ImagingTestCaseUtility.ModifyPixel(clone.Frames[0], 42, 43, 1); using (Image<TPixel> clone = image.Clone())
{
ImagingTestCaseUtility.ModifyPixel(clone.Frames[0], 42, 43, 1);
IEnumerable<ImageSimilarityReport> reports = ImageComparer.Exact.CompareImages(image, clone); IEnumerable<ImageSimilarityReport> reports = ImageComparer.Exact.CompareImages(image, clone);
PixelDifference difference = reports.Single().Differences.Single(); PixelDifference difference = reports.Single().Differences.Single();
Assert.Equal(new Point(42, 43), difference.Position); Assert.Equal(new Point(42, 43), difference.Position);
}
}
} }
[Theory] [Theory]

32
tests/ImageSharp.Tests/TestUtilities/Tests/MagickReferenceCodecTests.cs

@ -39,15 +39,17 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
ImageComparer comparer = ImageComparer.Exact; ImageComparer comparer = ImageComparer.Exact;
using var mImage = Image.Load<TPixel>(path, magickDecoder); using (var mImage = Image.Load<TPixel>(path, magickDecoder))
using var sdImage = Image.Load<TPixel>(path, sdDecoder); using (var sdImage = Image.Load<TPixel>(path, sdDecoder))
ImageSimilarityReport<TPixel, TPixel> report = comparer.CompareImagesOrFrames(mImage, sdImage); {
ImageSimilarityReport<TPixel, TPixel> report = comparer.CompareImagesOrFrames(mImage, sdImage);
mImage.DebugSave(dummyProvider); mImage.DebugSave(dummyProvider);
if (TestEnvironment.IsWindows) if (TestEnvironment.IsWindows)
{ {
Assert.True(report.IsEmpty); Assert.True(report.IsEmpty);
}
} }
} }
@ -68,15 +70,17 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
// 1020 == 4 * 255 (Equivalent to manhattan distance of 1+1+1+1=4 in Rgba32 space) // 1020 == 4 * 255 (Equivalent to manhattan distance of 1+1+1+1=4 in Rgba32 space)
var comparer = ImageComparer.TolerantPercentage(1, 1020); var comparer = ImageComparer.TolerantPercentage(1, 1020);
using var mImage = Image.Load<TPixel>(path, magickDecoder); using (var mImage = Image.Load<TPixel>(path, magickDecoder))
using var sdImage = Image.Load<TPixel>(path, sdDecoder); using (var sdImage = Image.Load<TPixel>(path, sdDecoder))
ImageSimilarityReport<TPixel, TPixel> report = comparer.CompareImagesOrFrames(mImage, sdImage); {
ImageSimilarityReport<TPixel, TPixel> report = comparer.CompareImagesOrFrames(mImage, sdImage);
mImage.DebugSave(dummyProvider); mImage.DebugSave(dummyProvider);
if (TestEnvironment.IsWindows) if (TestEnvironment.IsWindows)
{ {
Assert.True(report.IsEmpty); Assert.True(report.IsEmpty);
}
} }
} }
} }

78
tests/ImageSharp.Tests/TestUtilities/Tests/SystemDrawingReferenceCodecTests.cs

@ -26,10 +26,14 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
public void To32bppArgbSystemDrawingBitmap<TPixel>(TestImageProvider<TPixel> provider) public void To32bppArgbSystemDrawingBitmap<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image); {
string fileName = provider.Utility.GetTestOutputFileName("png"); using (System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image))
sdBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png); {
string fileName = provider.Utility.GetTestOutputFileName("png");
sdBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
}
}
} }
[Theory] [Theory]
@ -39,22 +43,28 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
{ {
string path = TestFile.GetInputFileFullPath(TestImages.Png.Splash); string path = TestFile.GetInputFileFullPath(TestImages.Png.Splash);
using var sdBitmap = new System.Drawing.Bitmap(path); using (var sdBitmap = new System.Drawing.Bitmap(path))
using Image<TPixel> image = SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(sdBitmap); {
image.DebugSave(dummyProvider); using (Image<TPixel> image = SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(sdBitmap))
{
image.DebugSave(dummyProvider);
}
}
} }
private static string SavePng<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType) private static string SavePng<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> sourceImage = provider.GetImage(); using (Image<TPixel> sourceImage = provider.GetImage())
if (pngColorType != PngColorType.RgbWithAlpha)
{ {
sourceImage.Mutate(c => c.MakeOpaque()); if (pngColorType != PngColorType.RgbWithAlpha)
} {
sourceImage.Mutate(c => c.MakeOpaque());
}
var encoder = new PngEncoder { ColorType = pngColorType }; var encoder = new PngEncoder { ColorType = pngColorType };
return provider.Utility.SaveTestOutputFile(sourceImage, "png", encoder); return provider.Utility.SaveTestOutputFile(sourceImage, "png", encoder);
}
} }
[Theory] [Theory]
@ -69,11 +79,15 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
string path = SavePng(provider, PngColorType.RgbWithAlpha); string path = SavePng(provider, PngColorType.RgbWithAlpha);
using var sdBitmap = new System.Drawing.Bitmap(path); using (var sdBitmap = new System.Drawing.Bitmap(path))
using Image<TPixel> original = provider.GetImage(); {
using Image<TPixel> resaved = SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(sdBitmap); using (Image<TPixel> original = provider.GetImage())
ImageComparer comparer = ImageComparer.Exact; using (Image<TPixel> resaved = SystemDrawingBridge.From32bppArgbSystemDrawingBitmap<TPixel>(sdBitmap))
comparer.VerifySimilarity(original, resaved); {
ImageComparer comparer = ImageComparer.Exact;
comparer.VerifySimilarity(original, resaved);
}
}
} }
[Theory] [Theory]
@ -83,11 +97,17 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
{ {
string path = SavePng(provider, PngColorType.Rgb); string path = SavePng(provider, PngColorType.Rgb);
using Image<TPixel> original = provider.GetImage(); using (Image<TPixel> original = provider.GetImage())
using var sdBitmap = new System.Drawing.Bitmap(path); {
using Image<TPixel> resaved = SystemDrawingBridge.From24bppRgbSystemDrawingBitmap<TPixel>(sdBitmap); using (var sdBitmap = new System.Drawing.Bitmap(path))
ImageComparer comparer = ImageComparer.Exact; {
comparer.VerifySimilarity(original, resaved); using (Image<TPixel> resaved = SystemDrawingBridge.From24bppRgbSystemDrawingBitmap<TPixel>(sdBitmap))
{
ImageComparer comparer = ImageComparer.Exact;
comparer.VerifySimilarity(original, resaved);
}
}
}
} }
[Theory] [Theory]
@ -96,8 +116,10 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string path = TestFile.GetInputFileFullPath(TestImages.Png.Splash); string path = TestFile.GetInputFileFullPath(TestImages.Png.Splash);
using var image = Image.Load<TPixel>(path, SystemDrawingReferenceDecoder.Instance); using (var image = Image.Load<TPixel>(path, SystemDrawingReferenceDecoder.Instance))
image.DebugSave(dummyProvider); {
image.DebugSave(dummyProvider);
}
} }
[Theory] [Theory]
@ -105,8 +127,10 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
public void SaveWithReferenceEncoder<TPixel>(TestImageProvider<TPixel> provider) public void SaveWithReferenceEncoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
provider.Utility.SaveTestOutputFile(image, "png", SystemDrawingReferenceEncoder.Png); {
provider.Utility.SaveTestOutputFile(image, "png", SystemDrawingReferenceEncoder.Png);
}
} }
} }
} }

60
tests/ImageSharp.Tests/TestUtilities/Tests/TestImageExtensionsTests.cs

@ -20,8 +20,10 @@ namespace SixLabors.ImageSharp.Tests
TestImageProvider<TPixel> provider) TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.CompareToReferenceOutput(provider); {
image.CompareToReferenceOutput(provider);
}
} }
[Theory] [Theory]
@ -30,8 +32,10 @@ namespace SixLabors.ImageSharp.Tests
TestImageProvider<TPixel> provider) TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Assert.ThrowsAny<Exception>(() => image.CompareToReferenceOutput(provider)); {
Assert.ThrowsAny<Exception>(() => image.CompareToReferenceOutput(provider));
}
} }
[Theory] [Theory]
@ -40,9 +44,11 @@ namespace SixLabors.ImageSharp.Tests
TestImageProvider<TPixel> provider) TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
image.DebugSave(provider, appendPixelTypeToFileName: false); {
image.CompareToReferenceOutput(provider, appendPixelTypeToFileName: false); image.DebugSave(provider, appendPixelTypeToFileName: false);
image.CompareToReferenceOutput(provider, appendPixelTypeToFileName: false);
}
} }
[Theory] [Theory]
@ -50,8 +56,10 @@ namespace SixLabors.ImageSharp.Tests
public void CompareToReferenceOutput_WhenReferenceFileMissing_Throws<TPixel>(TestImageProvider<TPixel> provider) public void CompareToReferenceOutput_WhenReferenceFileMissing_Throws<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Assert.ThrowsAny<Exception>(() => image.CompareToReferenceOutput(provider)); {
Assert.ThrowsAny<Exception>(() => image.CompareToReferenceOutput(provider));
}
} }
[Theory] [Theory]
@ -59,9 +67,13 @@ namespace SixLabors.ImageSharp.Tests
public void CompareToOriginal_WhenSimilar<TPixel>(TestImageProvider<TPixel> provider) public void CompareToOriginal_WhenSimilar<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
using Image<TPixel> clone = image.Clone(); {
clone.CompareToOriginal(provider, ImageComparer.Exact); using (Image<TPixel> clone = image.Clone())
{
clone.CompareToOriginal(provider, ImageComparer.Exact);
}
}
} }
[Theory] [Theory]
@ -69,13 +81,15 @@ namespace SixLabors.ImageSharp.Tests
public void CompareToOriginal_WhenDifferent_Throws<TPixel>(TestImageProvider<TPixel> provider) public void CompareToOriginal_WhenDifferent_Throws<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
ImagingTestCaseUtility.ModifyPixel(image, 3, 1, 1);
Assert.ThrowsAny<ImageDifferenceIsOverThresholdException>(() =>
{ {
image.CompareToOriginal(provider, ImageComparer.Exact); ImagingTestCaseUtility.ModifyPixel(image, 3, 1, 1);
});
Assert.ThrowsAny<ImageDifferenceIsOverThresholdException>(() =>
{
image.CompareToOriginal(provider, ImageComparer.Exact);
});
}
} }
[Theory] [Theory]
@ -83,11 +97,13 @@ namespace SixLabors.ImageSharp.Tests
public void CompareToOriginal_WhenInputIsNotFromFile_Throws<TPixel>(TestImageProvider<TPixel> provider) public void CompareToOriginal_WhenInputIsNotFromFile_Throws<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
Assert.ThrowsAny<Exception>(() =>
{ {
image.CompareToOriginal(provider, Mock.Of<ImageComparer>()); Assert.ThrowsAny<Exception>(() =>
}); {
image.CompareToOriginal(provider, Mock.Of<ImageComparer>());
});
}
} }
} }
} }

50
tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

@ -179,14 +179,16 @@ namespace SixLabors.ImageSharp.Tests
public void SaveTestOutputFileMultiFrame<TPixel>(TestImageProvider<TPixel> provider) public void SaveTestOutputFileMultiFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
string[] files = provider.Utility.SaveTestOutputFileMultiFrame(image);
Assert.True(files.Length > 2);
foreach (string path in files)
{ {
this.Output.WriteLine(path); string[] files = provider.Utility.SaveTestOutputFileMultiFrame(image);
Assert.True(File.Exists(path));
Assert.True(files.Length > 2);
foreach (string path in files)
{
this.Output.WriteLine(path);
Assert.True(File.Exists(path));
}
} }
} }
@ -197,8 +199,10 @@ namespace SixLabors.ImageSharp.Tests
public void Use_WithBasicTestPatternImages<TPixel>(TestImageProvider<TPixel> provider) public void Use_WithBasicTestPatternImages<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using Image<TPixel> img = provider.GetImage(); using (Image<TPixel> img = provider.GetImage())
img.DebugSave(provider); {
img.DebugSave(provider);
}
} }
[Theory] [Theory]
@ -234,13 +238,15 @@ namespace SixLabors.ImageSharp.Tests
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
Assert.NotNull(provider.Utility.SourceFileOrDescription); Assert.NotNull(provider.Utility.SourceFileOrDescription);
using Image<TPixel> img = provider.GetImage(); using (Image<TPixel> img = provider.GetImage())
Assert.True(img.Width * img.Height > 0); {
Assert.True(img.Width * img.Height > 0);
Assert.Equal(123, yo); Assert.Equal(123, yo);
string fn = provider.Utility.GetTestOutputFileName("jpg"); string fn = provider.Utility.GetTestOutputFileName("jpg");
this.Output.WriteLine(fn); this.Output.WriteLine(fn);
}
} }
[Theory] [Theory]
@ -257,8 +263,10 @@ namespace SixLabors.ImageSharp.Tests
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
Assert.NotNull(provider.Utility.SourceFileOrDescription); Assert.NotNull(provider.Utility.SourceFileOrDescription);
using Image<TPixel> image = provider.GetImage(); using (Image<TPixel> image = provider.GetImage())
provider.Utility.SaveTestOutputFile(image, "png"); {
provider.Utility.SaveTestOutputFile(image, "png");
}
} }
[Theory] [Theory]
@ -326,10 +334,12 @@ namespace SixLabors.ImageSharp.Tests
var customConfiguration = Configuration.CreateDefaultInstance(); var customConfiguration = Configuration.CreateDefaultInstance();
provider.Configuration = customConfiguration; provider.Configuration = customConfiguration;
using Image<TPixel> image2 = provider.GetImage(); using (Image<TPixel> image2 = provider.GetImage())
using Image<TPixel> image3 = provider.GetImage(); using (Image<TPixel> image3 = provider.GetImage())
Assert.Same(customConfiguration, image2.GetConfiguration()); {
Assert.Same(customConfiguration, image3.GetConfiguration()); Assert.Same(customConfiguration, image2.GetConfiguration());
Assert.Same(customConfiguration, image3.GetConfiguration());
}
} }
} }

Loading…
Cancel
Save