Browse Source

Merge remote-tracking branch 'origin/antonfirsov/cover-all-codecs' into feature/memory-manager

af/merge-core
Anton Firszov 8 years ago
parent
commit
a9d4dfda56
  1. 4
      src/ImageSharp/Processing/ColorMatrix/Opacity.cs
  2. 6
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
  3. 30
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
  4. 62
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  5. 45
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  6. 6
      tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs
  7. 2
      tests/Images/External

4
src/ImageSharp/Processing/ColorMatrix/Opacity.cs

@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the alpha component of the image. /// Multiplies the alpha component of the image.
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam> /// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp
=> source.ApplyProcessor(new OpacityProcessor<TPixel>(amount)); => source.ApplyProcessor(new OpacityProcessor<TPixel>(amount));
/// <summary> /// <summary>
/// Alters the alpha component of the image. /// Multiplies the alpha component of the image.
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam> /// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>

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

@ -51,13 +51,15 @@ namespace SixLabors.ImageSharp.Tests
TestBmpEncoderCore(provider, bitsPerPixel); TestBmpEncoderCore(provider, bitsPerPixel);
} }
private static void TestBmpEncoderCore<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) private static void TestBmpEncoderCore<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
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! // there is no alpha in bmp!
image.Mutate(c => c.Opacity(1)); image.Mutate(c => c.MakeOpaque());
var encoder = new BmpEncoder { BitsPerPixel = bitsPerPixel }; var encoder = new BmpEncoder { BitsPerPixel = bitsPerPixel };

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

@ -15,6 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using SixLabors.Primitives;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -55,20 +56,27 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
TestJpegEncoderCore(provider, subsample, quality); TestJpegEncoderCore(provider, subsample, quality);
} }
private static ImageComparer GetComparer(int quality) /// <summary>
/// Anton's SUPER-SCIENTIFIC tolerance threshold calculation
/// </summary>
private static ImageComparer GetComparer(int quality, JpegSubsample subsample)
{ {
if (quality > 90) float tolerance = 0.015f; // ~1.5%
{
return ImageComparer.Tolerant(0.0005f / 100); if (quality < 50)
}
else if (quality > 50)
{ {
return ImageComparer.Tolerant(0.005f / 100); tolerance *= 10f;
} }
else else if (quality < 75 || subsample == JpegSubsample.Ratio420)
{ {
return ImageComparer.Tolerant(0.01f / 100); tolerance *= 5f;
if (subsample == JpegSubsample.Ratio420)
{
tolerance *= 2f;
}
} }
return ImageComparer.Tolerant(tolerance);
} }
private static void TestJpegEncoderCore<TPixel>( private static void TestJpegEncoderCore<TPixel>(
@ -80,7 +88,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
// There is no alpha in Jpeg! // There is no alpha in Jpeg!
image.Mutate(c => c.Opacity(1)); image.Mutate(c => c.MakeOpaque());
var encoder = new JpegEncoder() var encoder = new JpegEncoder()
{ {
@ -88,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
Quality = quality Quality = quality
}; };
string info = $"{subsample}-Q{quality}"; string info = $"{subsample}-Q{quality}";
ImageComparer comparer = GetComparer(quality); ImageComparer comparer = GetComparer(quality, subsample);
// Does DebugSave & load reference CompareToReferenceInput(): // Does DebugSave & load reference CompareToReferenceInput():
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png"); image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png");

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

@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests
public void IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType) public void IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
TestPngEncoderCore(provider, pngColorType, appendPixelType: true); TestPngEncoderCore(provider, pngColorType, appendPixelType: true, appendPngColorType: true);
} }
[Theory] [Theory]
@ -78,33 +78,13 @@ namespace SixLabors.ImageSharp.Tests
{ {
TestPngEncoderCore(provider, PngColorType.RgbWithAlpha, compressionLevel, appendCompressionLevel: true); TestPngEncoderCore(provider, PngColorType.RgbWithAlpha, compressionLevel, appendCompressionLevel: true);
} }
[Theory] [Theory]
[WithFile(TestImages.Png.Palette8Bpp, nameof(PaletteLargeOnly), PixelTypes.Rgba32)] [WithFile(TestImages.Png.Palette8Bpp, nameof(PaletteLargeOnly), PixelTypes.Rgba32)]
public void PaletteColorType_WuQuantizer_File<TPixel>(
TestImageProvider<TPixel> provider,
int paletteSize)
where TPixel : struct, IPixel<TPixel>
{
this.PaletteColorType_WuQuantizer(provider, paletteSize);
}
[Theory]
[WithTestPatternImages(nameof(PaletteSizes), 72, 72, PixelTypes.Rgba32)]
public void PaletteColorType_WuQuantizer<TPixel>(TestImageProvider<TPixel> provider, int paletteSize) public void PaletteColorType_WuQuantizer<TPixel>(TestImageProvider<TPixel> provider, int paletteSize)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) TestPngEncoderCore(provider, PngColorType.Palette, paletteSize: paletteSize, appendPaletteSize: true);
{
var encoder = new PngEncoder
{
PngColorType = PngColorType.Palette,
PaletteSize = paletteSize,
Quantizer = new WuQuantizer<TPixel>()
};
image.VerifyEncoder(provider, "png", $"PaletteSize-{paletteSize}", encoder, appendPixelTypeToFileName: false);
}
} }
private static bool HasAlpha(PngColorType pngColorType) => private static bool HasAlpha(PngColorType pngColorType) =>
@ -114,35 +94,47 @@ namespace SixLabors.ImageSharp.Tests
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
PngColorType pngColorType, PngColorType pngColorType,
int compressionLevel = 6, int compressionLevel = 6,
int paletteSize = 0,
bool appendPngColorType = false, bool appendPngColorType = false,
bool appendPixelType = false, bool appendPixelType = false,
bool appendCompressionLevel = false) bool appendCompressionLevel = false,
bool appendPaletteSize = false)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
if (!HasAlpha(pngColorType)) if (!HasAlpha(pngColorType))
{ {
image.Mutate(c => c.Opacity(1)); image.Mutate(c => c.MakeOpaque());
} }
var encoder = new PngEncoder { PngColorType = pngColorType, CompressionLevel = compressionLevel}; var encoder = new PngEncoder
{
PngColorType = pngColorType,
CompressionLevel = compressionLevel,
PaletteSize = paletteSize
};
string pngColorTypeInfo = appendPixelType ? pngColorType.ToString() : ""; string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : "";
string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : ""; string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : "";
string debugInfo = $"{pngColorTypeInfo}{compressionLevelInfo}"; string paletteSizeInfo = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : "";
string referenceInfo = $"{pngColorTypeInfo}"; string debugInfo = $"{pngColorTypeInfo}{compressionLevelInfo}{paletteSizeInfo}";
//string referenceInfo = $"{pngColorTypeInfo}";
// Does DebugSave & load reference CompareToReferenceInput(): // Does DebugSave & load reference CompareToReferenceInput():
string path = ((ITestImageProvider)provider).Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); string actualOutputFile = ((ITestImageProvider)provider).Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(path); IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", referenceInfo, appendPixelType); string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", debugInfo, appendPixelType);
using (var encodedImage = Image.Load<TPixel>(referenceOutputFile, referenceDecoder)) using (var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
using (var referenceImage = Image.Load<TPixel>(referenceOutputFile, referenceDecoder))
{ {
ImageComparer comparer = pngColorType== PngColorType.Palette ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder) : ImageComparer.Exact; ImageComparer comparer = pngColorType == PngColorType.Palette
comparer.CompareImagesOrFrames(image, encodedImage); ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder)
: ImageComparer.Exact;
comparer.VerifySimilarity(referenceImage, actualImage);
} }
} }
} }

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

@ -22,6 +22,38 @@ namespace SixLabors.ImageSharp.Tests
public static class TestImageExtensions public static class TestImageExtensions
{ {
/// <summary>
/// TODO: This should be a common processing method! The image.Opacity(val) multiplies the alpha channel!
/// </summary>
/// <typeparam name="TPixel"></typeparam>
/// <param name="ctx"></param>
public static void MakeOpaque<TPixel>(this IImageProcessingContext<TPixel> ctx)
where TPixel : struct, IPixel<TPixel>
{
ctx.Apply(
img =>
{
using (var temp = new Buffer2D<Vector4>(img.Width, img.Height))
{
Span<Vector4> tempSpan = temp.Span;
foreach (ImageFrame<TPixel> frame in img.Frames)
{
Span<TPixel> pixelSpan = frame.GetPixelSpan();
PixelOperations<TPixel>.Instance.ToVector4(pixelSpan, tempSpan, pixelSpan.Length);
for (int i = 0; i < tempSpan.Length; i++)
{
ref Vector4 v = ref tempSpan[i];
v.W = 1.0f;
}
PixelOperations<TPixel>.Instance.PackFromVector4(tempSpan, pixelSpan, pixelSpan.Length);
}
}
});
}
/// <summary> /// <summary>
/// Saves the image only when not running in the CI server. /// Saves the image only when not running in the CI server.
/// </summary> /// </summary>
@ -357,18 +389,13 @@ namespace SixLabors.ImageSharp.Tests
) )
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string actualOutputFile = provider.Utility.SaveTestOutputFile(image, extension, encoder, testOutputDetails, appendPixelTypeToFileName);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
provider.Utility.SaveTestOutputFile(image, extension, encoder, testOutputDetails, appendPixelTypeToFileName); using (var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
referenceImageExtension = referenceImageExtension ?? extension;
string referenceOutputFile = provider.Utility.GetReferenceOutputFileName(referenceImageExtension, testOutputDetails, appendPixelTypeToFileName);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(referenceOutputFile);
using (var encodedImage = Image.Load<TPixel>(referenceOutputFile, referenceDecoder))
{ {
ImageComparer comparer = customComparer ?? ImageComparer.Exact; ImageComparer comparer = customComparer ?? ImageComparer.Exact;
comparer.CompareImagesOrFrames(image, encodedImage); comparer.VerifySimilarity(actualImage, image);
} }
} }

6
tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs

@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Tests
{ {
if (pngColorType != PngColorType.RgbWithAlpha) if (pngColorType != PngColorType.RgbWithAlpha)
{ {
sourceImage.Mutate(c => c.Opacity(1)); sourceImage.Mutate(c => c.MakeOpaque());
} }
var encoder = new PngEncoder() { PngColorType = pngColorType }; var encoder = new PngEncoder() { PngColorType = pngColorType };
@ -93,12 +93,12 @@ namespace SixLabors.ImageSharp.Tests
using (Image<TPixel> original = provider.GetImage()) using (Image<TPixel> original = provider.GetImage())
{ {
original.Mutate(c => c.Opacity(1)); original.Mutate(c => c.MakeOpaque());
using (var sdBitmap = new System.Drawing.Bitmap(path)) using (var sdBitmap = new System.Drawing.Bitmap(path))
{ {
using (Image<TPixel> resaved = SystemDrawingBridge.FromFromRgb24SystemDrawingBitmap<TPixel>(sdBitmap)) using (Image<TPixel> resaved = SystemDrawingBridge.FromFromRgb24SystemDrawingBitmap<TPixel>(sdBitmap))
{ {
resaved.Mutate(c => c.Opacity(1)); resaved.Mutate(c => c.MakeOpaque());
ImageComparer comparer = ImageComparer.Exact; ImageComparer comparer = ImageComparer.Exact;
comparer.VerifySimilarity(original, resaved); comparer.VerifySimilarity(original, resaved);
} }

2
tests/Images/External

@ -1 +1 @@
Subproject commit 0e1b5fd3987081c8fbee9d5cf6d74142b942df60 Subproject commit 20f83891ce75597486f5532010a8c5dea1419a4d
Loading…
Cancel
Save