Browse Source

Merge branch 'master' into colorspace-transforms

pull/664/head
James Jackson-South 8 years ago
committed by GitHub
parent
commit
391fbea169
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/ImageSharp/Formats/ImageFormatManager.cs
  2. 31
      tests/ImageSharp.Tests/ConfigurationTests.cs
  3. 53
      tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
  4. 3
      tests/ImageSharp.Tests/TestImages.cs
  5. 2
      tests/Images/External
  6. BIN
      tests/Images/Input/Png/ducky.png
  7. BIN
      tests/Images/Input/Png/rainbow.png

23
src/ImageSharp/Formats/ImageFormatManager.cs

@ -13,6 +13,12 @@ namespace SixLabors.ImageSharp.Formats
/// </summary> /// </summary>
public class ImageFormatManager public class ImageFormatManager
{ {
/// <summary>
/// Used for locking against as there is no ConcurrentSet type.
/// <see href="https://github.com/dotnet/corefx/issues/6318"/>
/// </summary>
private static readonly object HashLock = new object();
/// <summary> /// <summary>
/// The list of supported <see cref="IImageEncoder"/> keyed to mime types. /// The list of supported <see cref="IImageEncoder"/> keyed to mime types.
/// </summary> /// </summary>
@ -26,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats
/// <summary> /// <summary>
/// The list of supported <see cref="IImageFormat"/>s. /// The list of supported <see cref="IImageFormat"/>s.
/// </summary> /// </summary>
private readonly ConcurrentBag<IImageFormat> imageFormats = new ConcurrentBag<IImageFormat>(); private readonly HashSet<IImageFormat> imageFormats = new HashSet<IImageFormat>();
/// <summary> /// <summary>
/// The list of supported <see cref="IImageFormatDetector"/>s. /// The list of supported <see cref="IImageFormatDetector"/>s.
@ -74,7 +80,14 @@ namespace SixLabors.ImageSharp.Formats
Guard.NotNull(format, nameof(format)); Guard.NotNull(format, nameof(format));
Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes)); Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes));
Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions)); Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions));
this.imageFormats.Add(format);
lock (HashLock)
{
if (!this.imageFormats.Contains(format))
{
this.imageFormats.Add(format);
}
}
} }
/// <summary> /// <summary>
@ -86,9 +99,9 @@ namespace SixLabors.ImageSharp.Formats
{ {
Guard.NotNullOrWhiteSpace(extension, nameof(extension)); Guard.NotNullOrWhiteSpace(extension, nameof(extension));
if (extension[0] == '.') if (extension[0] == '.')
{ {
extension = extension.Substring(1); extension = extension.Substring(1);
} }
return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase));

31
tests/ImageSharp.Tests/ConfigurationTests.cs

@ -2,13 +2,9 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.PixelFormats;
using Moq; using Moq;
using SixLabors.ImageSharp.IO;
using Xunit; using Xunit;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
@ -19,8 +15,8 @@ namespace SixLabors.ImageSharp.Tests
/// </summary> /// </summary>
public class ConfigurationTests public class ConfigurationTests
{ {
public Configuration ConfigurationEmpty { get; private set; } public Configuration ConfigurationEmpty { get; }
public Configuration DefaultConfiguration { get; private set; } public Configuration DefaultConfiguration { get; }
public ConfigurationTests() public ConfigurationTests()
{ {
@ -96,5 +92,26 @@ namespace SixLabors.ImageSharp.Tests
provider.Verify(x => x.Configure(config)); provider.Verify(x => x.Configure(config));
} }
[Fact]
public void ConfigurationCannotAddDuplicates()
{
const int count = 4;
Configuration config = Configuration.Default;
Assert.Equal(count, config.ImageFormats.Count());
config.ImageFormatsManager.AddImageFormat(ImageFormats.Bmp);
Assert.Equal(count, config.ImageFormats.Count());
}
[Fact]
public void DefaultConfigurationHasCorrectFormatCount()
{
Configuration config = Configuration.Default;
Assert.Equal(4, config.ImageFormats.Count());
}
} }
} }

53
tests/ImageSharp.Tests/Drawing/DrawImageTest.cs

@ -5,14 +5,14 @@ using System;
using System.Numerics; using System.Numerics;
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.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives; using SixLabors.Primitives;
using Xunit; using Xunit;
namespace SixLabors.ImageSharp.Tests namespace SixLabors.ImageSharp.Tests
{ {
using SixLabors.ImageSharp.Processing; [GroupOutput("Drawing")]
using SixLabors.ImageSharp.Processing.Processors.Transforms;
public class DrawImageTest : FileTestBase public class DrawImageTest : FileTestBase
{ {
private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32; private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32;
@ -41,11 +41,32 @@ namespace SixLabors.ImageSharp.Tests
using (var blend = Image.Load<TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes)) using (var blend = Image.Load<TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes))
{ {
blend.Mutate(x => x.Resize(image.Width / 2, image.Height / 2)); blend.Mutate(x => x.Resize(image.Width / 2, image.Height / 2));
image.Mutate(x => x.DrawImage(blend, new Point(image.Width / 4, image.Height / 4), mode, .75f) ); image.Mutate(x => x.DrawImage(blend, new Point(image.Width / 4, image.Height / 4), mode, .75f));
image.DebugSave(provider, new { mode }); image.DebugSave(provider, new { mode });
} }
} }
[Theory]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Normal)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Multiply)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Add)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Subtract)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Screen)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Darken)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Lighten)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Overlay)]
[WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.HardLight)]
public void ImageBlendingMatchesSvgSpecExamples<TPixel>(TestImageProvider<TPixel> provider, PixelColorBlendingMode mode)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> background = provider.GetImage())
using (var source = Image.Load<TPixel>(TestFile.Create(TestImages.Png.Ducky).Bytes))
{
background.Mutate(x => x.DrawImage(source, mode, 1F));
VerifyImage(provider, mode, background);
}
}
[Theory] [Theory]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelColorBlendingMode.Normal)] [WithFileCollection(nameof(TestFiles), PixelTypes, PixelColorBlendingMode.Normal)]
public void ImageShouldDrawTransformedImage<TPixel>(TestImageProvider<TPixel> provider, PixelColorBlendingMode mode) public void ImageShouldDrawTransformedImage<TPixel>(TestImageProvider<TPixel> provider, PixelColorBlendingMode mode)
@ -84,7 +105,7 @@ namespace SixLabors.ImageSharp.Tests
{ {
overlay.Mutate(x => x.Fill(Rgba32.Black)); overlay.Mutate(x => x.Fill(Rgba32.Black));
int xy = -25; const int xy = -25;
Rgba32 backgroundPixel = background[0, 0]; Rgba32 backgroundPixel = background[0, 0];
Rgba32 overlayPixel = overlay[Math.Abs(xy) + 1, Math.Abs(xy) + 1]; Rgba32 overlayPixel = overlay[Math.Abs(xy) + 1, Math.Abs(xy) + 1];
@ -106,7 +127,7 @@ namespace SixLabors.ImageSharp.Tests
{ {
overlay.Mutate(x => x.Fill(Rgba32.Black)); overlay.Mutate(x => x.Fill(Rgba32.Black));
int xy = 25; const int xy = 25;
Rgba32 backgroundPixel = background[xy - 1, xy - 1]; Rgba32 backgroundPixel = background[xy - 1, xy - 1];
Rgba32 overlayPixel = overlay[0, 0]; Rgba32 overlayPixel = overlay[0, 0];
@ -118,5 +139,25 @@ namespace SixLabors.ImageSharp.Tests
background.DebugSave(provider, testOutputDetails: "Positive"); background.DebugSave(provider, testOutputDetails: "Positive");
} }
} }
private static void VerifyImage<TPixel>(
TestImageProvider<TPixel> provider,
PixelColorBlendingMode mode,
Image<TPixel> img)
where TPixel : struct, IPixel<TPixel>
{
img.DebugSave(
provider,
new { mode },
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
var comparer = ImageComparer.TolerantPercentage(0.01F, 3);
img.CompareFirstFrameToReferenceOutput(comparer,
provider,
new { mode },
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
} }
} }

3
tests/ImageSharp.Tests/TestImages.cs

@ -68,6 +68,9 @@ namespace SixLabors.ImageSharp.Tests
public const string Ratio1x4 = "Png/ratio-1x4.png"; public const string Ratio1x4 = "Png/ratio-1x4.png";
public const string Ratio4x1 = "Png/ratio-4x1.png"; public const string Ratio4x1 = "Png/ratio-4x1.png";
public const string Ducky = "Png/ducky.png";
public const string Rainbow = "Png/rainbow.png";
public static class Bad public static class Bad
{ {
// Odd chunk lengths // Odd chunk lengths

2
tests/Images/External

@ -1 +1 @@
Subproject commit 6a43d335f216d6325a6a9fd8d35942ade12b7c7b Subproject commit fcf311bf15bea061e552e4cc357cafe2d4f4bd70

BIN
tests/Images/Input/Png/ducky.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
tests/Images/Input/Png/rainbow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Loading…
Cancel
Save