Browse Source

Merge remote-tracking branch 'remotes/origin/master' into IFileSystem

af/merge-core
Scott Williams 9 years ago
parent
commit
f4b913b4a8
  1. 6
      README.md
  2. 2
      src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
  3. 2
      src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
  4. 2
      src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs
  5. 4
      src/ImageSharp.Drawing/Processors/FillProcessor.cs
  6. 2
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  7. 2
      src/ImageSharp/Common/Memory/Fast2DArray{T}.cs
  8. 12
      src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs
  9. 2
      src/ImageSharp/Common/Memory/PixelDataPool{T}.cs
  10. 23
      src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs
  11. 5
      src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
  12. 17
      src/ImageSharp/Dithering/Ordered/Bayer.cs
  13. 9
      src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
  14. 17
      src/ImageSharp/Dithering/Ordered/Ordered.cs
  15. 38
      src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs
  16. 70
      src/ImageSharp/Image/PixelAccessor{TColor}.cs
  17. 4
      src/ImageSharp/Image/PixelArea{TColor}.cs
  18. 2
      src/ImageSharp/ImageProcessor.cs
  19. 2
      src/ImageSharp/ImageSharp.csproj
  20. 2
      src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs
  21. 2
      src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs
  22. 2
      src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs
  23. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/BlackWhiteProcessor.cs
  24. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs
  25. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs
  26. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs
  27. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs
  28. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs
  29. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs
  30. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs
  31. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs
  32. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/ColorMatrixProcessor.cs
  33. 6
      src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt601Processor.cs
  34. 6
      src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt709Processor.cs
  35. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/HueProcessor.cs
  36. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/IColorMatrixFilter.cs
  37. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/KodachromeProcessor.cs
  38. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs
  39. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs
  40. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/SaturationProcessor.cs
  41. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/SepiaProcessor.cs
  42. 2
      src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
  43. 2
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs
  44. 2
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs
  45. 2
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs
  46. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs
  47. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs
  48. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs
  49. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
  50. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs
  51. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
  52. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
  53. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
  54. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
  55. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
  56. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs
  57. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
  58. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs
  59. 2
      src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs
  60. 2
      src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs
  61. 2
      src/ImageSharp/Processing/Processors/Effects/AlphaProcessor.cs
  62. 2
      src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs
  63. 2
      src/ImageSharp/Processing/Processors/Effects/BrightnessProcessor.cs
  64. 2
      src/ImageSharp/Processing/Processors/Effects/ContrastProcessor.cs
  65. 2
      src/ImageSharp/Processing/Processors/Effects/InvertProcessor.cs
  66. 2
      src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs
  67. 2
      src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs
  68. 2
      src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
  69. 2
      src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs
  70. 2
      src/ImageSharp/Processing/Processors/Transforms/CompandingResizeProcessor.cs
  71. 2
      src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs
  72. 2
      src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor.cs
  73. 2
      src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs
  74. 2
      src/ImageSharp/Processing/Processors/Transforms/Matrix3x2Processor.cs
  75. 2
      src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs
  76. 2
      src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
  77. 2
      src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs
  78. 2
      src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs
  79. 2
      src/ImageSharp/Quantizers/IQuantizer.cs
  80. 94
      src/ImageSharp/Quantizers/Octree/OctreeQuantizer.cs
  81. 55
      src/ImageSharp/Quantizers/Octree/Quantizer.cs
  82. 67
      src/ImageSharp/Quantizers/Palette/PaletteQuantizer.cs
  83. 104
      tests/ImageSharp.Benchmarks/Image/EncodeIndexedPng.cs
  84. 18
      tests/ImageSharp.Tests/Common/PinnedBufferTests.cs
  85. 185
      tests/ImageSharp.Tests/Drawing/Text/DrawText.cs
  86. 2
      tests/ImageSharp.Tests/TestFile.cs
  87. 2
      tests/ImageSharp.Tests/TestFont.cs

6
README.md

@ -93,12 +93,6 @@ using (Image image = new Image(stream))
}
```
Individual processors can be initialised and apply processing against images. This allows nesting which brings the potential for powerful combinations of processing methods:
```csharp
new BrightnessProcessor(50).Apply(sourceImage, sourceImage.Bounds);
```
Setting individual pixel values is perfomed as follows:
```csharp

2
src/ImageSharp.Drawing/ImageSharp.Drawing.csproj

@ -2,7 +2,7 @@
<PropertyGroup>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<AssemblyTitle>ImageSharp.Drawing</AssemblyTitle>
<VersionPrefix>1.0.0-alpha3</VersionPrefix>
<VersionPrefix>1.0.0-alpha4</VersionPrefix>
<Authors>James Jackson-South and contributors</Authors>
<TargetFramework>netstandard1.1</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

2
src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs

@ -15,7 +15,7 @@ namespace ImageSharp.Drawing.Processors
/// Combines two images together by blending the pixels.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class DrawImageProcessor<TColor> : ImageProcessor<TColor>
internal class DrawImageProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs

@ -17,7 +17,7 @@ namespace ImageSharp.Drawing.Processors
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <seealso cref="ImageSharp.Processing.ImageProcessor{TColor}" />
public class DrawPathProcessor<TColor> : ImageProcessor<TColor>
internal class DrawPathProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
private const float AntialiasFactor = 1f;

4
src/ImageSharp.Drawing/Processors/FillProcessor.cs

@ -16,8 +16,8 @@ namespace ImageSharp.Drawing.Processors
/// Using the bursh as a source of pixels colors blends the brush color with source.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class FillProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
internal class FillProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>
/// The brush.

2
src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs

@ -17,7 +17,7 @@ namespace ImageSharp.Drawing.Processors
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <seealso cref="ImageSharp.Processing.ImageProcessor{TColor}" />
public class FillRegionProcessor<TColor> : ImageProcessor<TColor>
internal class FillRegionProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
private const float AntialiasFactor = 1f;

2
src/ImageSharp/Common/Memory/Fast2DArray{T}.cs

@ -13,7 +13,7 @@ namespace ImageSharp
/// Provides fast access to 2D arrays.
/// </summary>
/// <typeparam name="T">The type of elements in the array.</typeparam>
public struct Fast2DArray<T>
internal struct Fast2DArray<T>
{
/// <summary>
/// The 1D representation of the 2D array.

12
src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs

@ -109,6 +109,18 @@ namespace ImageSharp
return buffer.Slice();
}
/// <summary>
/// Creates a clean instance of <see cref="PinnedBuffer{T}"/> initializing it's elements with 'default(T)'.
/// </summary>
/// <param name="count">The desired count of elements. (Minimum size for <see cref="Array"/>)</param>
/// <returns>The <see cref="PinnedBuffer{T}"/> instance</returns>
public static PinnedBuffer<T> CreateClean(int count)
{
PinnedBuffer<T> buffer = new PinnedBuffer<T>(count);
buffer.Clear();
return buffer;
}
/// <summary>
/// Gets a <see cref="BufferPointer{T}"/> to the beginning of the raw data of the buffer.
/// </summary>

2
src/ImageSharp/Common/Memory/PixelDataPool{T}.cs

@ -12,7 +12,7 @@ namespace ImageSharp
/// Provides a resource pool that enables reusing instances of value type arrays for image data <see cref="T:T[]"/>.
/// </summary>
/// <typeparam name="T">The value type.</typeparam>
public class PixelDataPool<T>
internal class PixelDataPool<T>
where T : struct
{
/// <summary>

23
src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs

@ -5,12 +5,11 @@
namespace ImageSharp.Dithering
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// The base class for performing effor diffusion based dithering.
/// The base class for performing error diffusion based dithering.
/// </summary>
public abstract class ErrorDiffuser : IErrorDiffuser
{
@ -34,19 +33,24 @@ namespace ImageSharp.Dithering
/// </summary>
private readonly int startingOffset;
/// <summary>
/// The diffusion matrix
/// </summary>
private readonly Fast2DArray<float> matrix;
/// <summary>
/// Initializes a new instance of the <see cref="ErrorDiffuser"/> class.
/// </summary>
/// <param name="matrix">The dithering matrix.</param>
/// <param name="divisor">The divisor.</param>
protected ErrorDiffuser(Fast2DArray<float> matrix, byte divisor)
internal ErrorDiffuser(Fast2DArray<float> matrix, byte divisor)
{
Guard.NotNull(matrix, nameof(matrix));
Guard.MustBeGreaterThan(divisor, 0, nameof(divisor));
this.Matrix = matrix;
this.matrixWidth = this.Matrix.Width;
this.matrixHeight = this.Matrix.Height;
this.matrix = matrix;
this.matrixWidth = this.matrix.Width;
this.matrixHeight = this.matrix.Height;
this.divisorVector = new Vector4(divisor);
this.startingOffset = 0;
@ -62,9 +66,6 @@ namespace ImageSharp.Dithering
}
}
/// <inheritdoc />
public Fast2DArray<float> Matrix { get; }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dither<TColor>(PixelAccessor<TColor> pixels, TColor source, TColor transformed, int x, int y, int width, int height)
@ -87,9 +88,9 @@ namespace ImageSharp.Dithering
if (matrixX > 0 && matrixX < width && matrixY > 0 && matrixY < height)
{
float coefficient = this.Matrix[row, col];
float coefficient = this.matrix[row, col];
// Good to disable here as we are not comparing matematical output.
// Good to disable here as we are not comparing mathematical output.
// ReSharper disable once CompareOfFloatsByEqualityOperator
if (coefficient == 0)
{

5
src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs

@ -12,11 +12,6 @@ namespace ImageSharp.Dithering
/// </summary>
public interface IErrorDiffuser
{
/// <summary>
/// Gets the dithering matrix
/// </summary>
Fast2DArray<float> Matrix { get; }
/// <summary>
/// Transforms the image applying the dither matrix. This method alters the input pixels array
/// </summary>

17
src/ImageSharp/Dithering/Ordered/Bayer.cs

@ -5,13 +5,11 @@
namespace ImageSharp.Dithering.Ordered
{
using System;
/// <summary>
/// Applies error diffusion based dithering using the 4x4 Bayer dithering matrix.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>
/// </summary>
public class Bayer : IOrderedDither
public sealed class Bayer : OrderedDither4x4
{
/// <summary>
/// The threshold matrix.
@ -26,15 +24,12 @@ namespace ImageSharp.Dithering.Ordered
{ 255, 127, 223, 95 }
};
/// <inheritdoc />
public Fast2DArray<byte> Matrix { get; } = ThresholdMatrix;
/// <inheritdoc />
public void Dither<TColor>(PixelAccessor<TColor> pixels, TColor source, TColor upper, TColor lower, byte[] bytes, int index, int x, int y, int width, int height)
where TColor : struct, IPixel<TColor>
/// <summary>
/// Initializes a new instance of the <see cref="Bayer"/> class.
/// </summary>
public Bayer()
: base(ThresholdMatrix)
{
source.ToXyzwBytes(bytes, 0);
pixels[x, y] = ThresholdMatrix[y % 3, x % 3] >= bytes[index] ? lower : upper;
}
}
}

9
src/ImageSharp/Dithering/Ordered/IOrderedDither.cs

@ -5,18 +5,11 @@
namespace ImageSharp.Dithering
{
using System;
/// <summary>
/// Encapsulates properties and methods required to perfom ordered dithering on an image.
/// </summary>
public interface IOrderedDither
{
/// <summary>
/// Gets the dithering matrix
/// </summary>
Fast2DArray<byte> Matrix { get; }
/// <summary>
/// Transforms the image applying the dither matrix. This method alters the input pixels array
/// </summary>
@ -34,4 +27,4 @@ namespace ImageSharp.Dithering
void Dither<TColor>(PixelAccessor<TColor> pixels, TColor source, TColor upper, TColor lower, byte[] bytes, int index, int x, int y, int width, int height)
where TColor : struct, IPixel<TColor>;
}
}
}

17
src/ImageSharp/Dithering/Ordered/Ordered.cs

@ -5,13 +5,11 @@
namespace ImageSharp.Dithering.Ordered
{
using System;
/// <summary>
/// Applies error diffusion based dithering using the 4x4 ordered dithering matrix.
/// <see href="https://en.wikipedia.org/wiki/Ordered_dithering"/>
/// </summary>
public class Ordered : IOrderedDither
public sealed class Ordered : OrderedDither4x4
{
/// <summary>
/// The threshold matrix.
@ -26,15 +24,12 @@ namespace ImageSharp.Dithering.Ordered
{ 240, 112, 208, 80 }
};
/// <inheritdoc />
public Fast2DArray<byte> Matrix { get; } = ThresholdMatrix;
/// <inheritdoc />
public void Dither<TColor>(PixelAccessor<TColor> pixels, TColor source, TColor upper, TColor lower, byte[] bytes, int index, int x, int y, int width, int height)
where TColor : struct, IPixel<TColor>
/// <summary>
/// Initializes a new instance of the <see cref="Ordered"/> class.
/// </summary>
public Ordered()
: base(ThresholdMatrix)
{
source.ToXyzwBytes(bytes, 0);
pixels[x, y] = ThresholdMatrix[y % 3, x % 3] >= bytes[index] ? lower : upper;
}
}
}

38
src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs

@ -0,0 +1,38 @@
// <copyright file="OrderedDither4x4.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Dithering.Ordered
{
/// <summary>
/// The base class for performing ordered ditheroing using a 4x4 matrix.
/// </summary>
public abstract class OrderedDither4x4 : IOrderedDither
{
/// <summary>
/// The dithering matrix
/// </summary>
private Fast2DArray<byte> matrix;
/// <summary>
/// Initializes a new instance of the <see cref="OrderedDither4x4"/> class.
/// </summary>
/// <param name="matrix">The thresholding matrix. </param>
internal OrderedDither4x4(Fast2DArray<byte> matrix)
{
this.matrix = matrix;
}
/// <inheritdoc />
public void Dither<TColor>(PixelAccessor<TColor> pixels, TColor source, TColor upper, TColor lower, byte[] bytes, int index, int x, int y, int width, int height)
where TColor : struct, IPixel<TColor>
{
// TODO: This doesn't really cut it for me.
// I'd rather be using float but we need to add some sort of movalization vector methods to all IPixel implementations
// before we can do that as the vectors all cover different ranges.
source.ToXyzwBytes(bytes, 0);
pixels[x, y] = this.matrix[y % 3, x % 3] >= bytes[index] ? lower : upper;
}
}
}

70
src/ImageSharp/Image/PixelAccessor{TColor}.cs

@ -59,7 +59,7 @@ namespace ImageSharp
/// <param name="width">The width of the image represented by the pixel buffer.</param>
/// <param name="height">The height of the image represented by the pixel buffer.</param>
public PixelAccessor(int width, int height)
: this(width, height, new PinnedBuffer<TColor>(width * height))
: this(width, height, PinnedBuffer<TColor>.CreateClean(width * height))
{
}
@ -148,6 +148,37 @@ namespace ImageSharp
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (this.isDisposed)
{
return;
}
// Note disposing is done.
this.isDisposed = true;
this.pixelBuffer.Dispose();
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SuppressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
/// <summary>
/// Resets all the pixels to it's initial value.
/// </summary>
public void Reset()
{
Unsafe.InitBlock(this.pixelsBase, 0, (uint)(this.RowStride * this.Height));
}
/// <summary>
/// Copy an area of pixels to the image.
/// </summary>
@ -157,7 +188,7 @@ namespace ImageSharp
/// <exception cref="NotSupportedException">
/// Thrown when an unsupported component order value is passed.
/// </exception>
public void CopyFrom(PixelArea<TColor> area, int targetY, int targetX = 0)
internal void CopyFrom(PixelArea<TColor> area, int targetY, int targetX = 0)
{
this.CheckCoordinates(area, targetX, targetY);
@ -173,7 +204,7 @@ namespace ImageSharp
/// <exception cref="NotSupportedException">
/// Thrown when an unsupported component order value is passed.
/// </exception>
public void CopyTo(PixelArea<TColor> area, int sourceY, int sourceX = 0)
internal void CopyTo(PixelArea<TColor> area, int sourceY, int sourceX = 0)
{
this.CheckCoordinates(area, sourceX, sourceY);
@ -190,7 +221,7 @@ namespace ImageSharp
/// <exception cref="NotSupportedException">
/// Thrown when an unsupported component order value is passed.
/// </exception>
public void SafeCopyTo(PixelArea<TColor> area, int sourceY, int sourceX = 0)
internal void SafeCopyTo(PixelArea<TColor> area, int sourceY, int sourceX = 0)
{
int width = Math.Min(area.Width, this.Width - sourceX);
if (width < 1)
@ -207,37 +238,6 @@ namespace ImageSharp
this.CopyTo(area, sourceX, sourceY, width, height);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (this.isDisposed)
{
return;
}
// Note disposing is done.
this.isDisposed = true;
this.pixelBuffer.Dispose();
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SuppressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
/// <summary>
/// Resets all the pixels to it's initial value.
/// </summary>
public void Reset()
{
Unsafe.InitBlock(this.pixelsBase, 0, (uint)(this.RowStride * this.Height));
}
/// <summary>
/// Gets a <see cref="BufferPointer{TColor}"/> to the row 'y' beginning from the pixel at 'x'.
/// </summary>

4
src/ImageSharp/Image/PixelArea{TColor}.cs

@ -5,17 +5,15 @@
namespace ImageSharp
{
using System;
using System.Buffers;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Represents an area of generic <see cref="Image{TColor}"/> pixels.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public sealed unsafe class PixelArea<TColor> : IDisposable
internal sealed unsafe class PixelArea<TColor> : IDisposable
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/ImageProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing
/// Allows the application of processors to images.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class ImageProcessor<TColor> : IImageProcessor<TColor>
internal abstract class ImageProcessor<TColor> : IImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/ImageSharp.csproj

@ -2,7 +2,7 @@
<PropertyGroup>
<Description>A cross-platform library for the processing of image files; written in C#</Description>
<AssemblyTitle>ImageSharp</AssemblyTitle>
<VersionPrefix>1.0.0-alpha3</VersionPrefix>
<VersionPrefix>1.0.0-alpha4</VersionPrefix>
<Authors>James Jackson-South and contributors</Authors>
<TargetFrameworks>netstandard1.3;netstandard1.1</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

2
src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// <see cref="Image"/>. The image will be converted to grayscale before thresholding occurs.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class BinaryThresholdProcessor<TColor> : ImageProcessor<TColor>
internal class BinaryThresholdProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> that dithers an image using error diffusion.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class ErrorDiffusionDitherProcessor<TColor> : ImageProcessor<TColor>
internal class ErrorDiffusionDitherProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> that dithers an image using error diffusion.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class OrderedDitherProcessor<TColor> : ImageProcessor<TColor>
internal class OrderedDitherProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/ColorMatrix/BlackWhiteProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image to their black and white equivalent.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class BlackWhiteProcessor<TColor> : ColorMatrixFilter<TColor>
internal class BlackWhiteProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class AchromatomalyProcessor<TColor> : ColorMatrixFilter<TColor>
internal class AchromatomalyProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class AchromatopsiaProcessor<TColor> : ColorMatrixFilter<TColor>
internal class AchromatopsiaProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class DeuteranomalyProcessor<TColor> : ColorMatrixFilter<TColor>
internal class DeuteranomalyProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class DeuteranopiaProcessor<TColor> : ColorMatrixFilter<TColor>
internal class DeuteranopiaProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class ProtanomalyProcessor<TColor> : ColorMatrixFilter<TColor>
internal class ProtanomalyProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class ProtanopiaProcessor<TColor> : ColorMatrixFilter<TColor>
internal class ProtanopiaProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class TritanomalyProcessor<TColor> : ColorMatrixFilter<TColor>
internal class TritanomalyProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class TritanopiaProcessor<TColor> : ColorMatrixFilter<TColor>
internal class TritanopiaProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/ColorMatrixFilter.cs → src/ImageSharp/Processing/Processors/ColorMatrix/ColorMatrixProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// The color matrix filter. Inherit from this class to perform operation involving color matrices.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class ColorMatrixFilter<TColor> : ImageProcessor<TColor>, IColorMatrixFilter<TColor>
internal abstract class ColorMatrixProcessor<TColor> : ImageProcessor<TColor>, IColorMatrixFilter<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

6
src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt601Processor.cs

@ -9,11 +9,11 @@ namespace ImageSharp.Processing.Processors
using System.Numerics;
/// <summary>
/// Converts the colors of the image to Grayscale applying the formula as specified by
/// ITU-R Recommendation BT.601 <see href="https://en.wikipedia.org/wiki/Luma_%28video%29#Rec._601_luma_versus_Rec._709_luma_coefficients"/>.
/// Converts the colors of the image to Grayscale applying the formula as specified by ITU-R Recommendation BT.601
/// <see href="https://en.wikipedia.org/wiki/Luma_%28video%29#Rec._601_luma_versus_Rec._709_luma_coefficients"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class GrayscaleBt601Processor<TColor> : ColorMatrixFilter<TColor>
internal class GrayscaleBt601Processor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

6
src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt709Processor.cs

@ -9,11 +9,11 @@ namespace ImageSharp.Processing.Processors
using System.Numerics;
/// <summary>
/// Converts the colors of the image to Grayscale applying the formula as specified by
/// ITU-R Recommendation BT.709 <see href="https://en.wikipedia.org/wiki/Rec._709#Luma_coefficients"/>.
/// Converts the colors of the image to Grayscale applying the formula as specified by ITU-R Recommendation BT.709
/// <see href="https://en.wikipedia.org/wiki/Rec._709#Luma_coefficients"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class GrayscaleBt709Processor<TColor> : ColorMatrixFilter<TColor>
internal class GrayscaleBt709Processor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/HueProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="ImageProcessor{TColor}"/> to change the hue of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class HueProcessor<TColor> : ColorMatrixFilter<TColor>
internal class HueProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/ColorMatrix/IColorMatrixFilter.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// alter the image pixels.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public interface IColorMatrixFilter<TColor> : IImageProcessor<TColor>
internal interface IColorMatrixFilter<TColor> : IImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/ColorMatrix/KodachromeProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating an old Kodachrome camera effect.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class KodachromeProcessor<TColor> : ColorMatrixFilter<TColor>
internal class KodachromeProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating an old Lomograph effect.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class LomographProcessor<TColor> : ColorMatrixFilter<TColor>
internal class LomographProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
private static readonly TColor VeryDarkGreen = ColorBuilder<TColor>.FromRGBA(0, 10, 0, 255);

2
src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Converts the colors of the image recreating an old Polaroid effect.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class PolaroidProcessor<TColor> : ColorMatrixFilter<TColor>
internal class PolaroidProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
private static TColor veryDarkOrange = ColorBuilder<TColor>.FromRGB(102, 34, 0);

2
src/ImageSharp/Processing/Processors/ColorMatrix/SaturationProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="ImageProcessor{TColor}"/> to change the saturation of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class SaturationProcessor<TColor> : ColorMatrixFilter<TColor>
internal class SaturationProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/ColorMatrix/SepiaProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// The formula used matches the svg specification. <see href="http://www.w3.org/TR/filter-effects/#sepiaEquivalent"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class SepiaProcessor<TColor> : ColorMatrixFilter<TColor>
internal class SepiaProcessor<TColor> : ColorMatrixProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs

@ -11,7 +11,7 @@ namespace ImageSharp.Processing.Processors
/// Applies a Box blur sampler to the image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class BoxBlurProcessor<TColor> : ImageProcessor<TColor>
internal class BoxBlurProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Defines a sampler that uses two one-dimensional matrices to perform convolution against an image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class Convolution2DProcessor<TColor> : ImageProcessor<TColor>
internal class Convolution2DProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Defines a sampler that uses two one-dimensional matrices to perform two-pass convolution against an image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class Convolution2PassProcessor<TColor> : ImageProcessor<TColor>
internal class Convolution2PassProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Defines a sampler that uses a 2 dimensional matrix to perform convolution against an image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class ConvolutionProcessor<TColor> : ImageProcessor<TColor>
internal class ConvolutionProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs

@ -11,7 +11,7 @@ namespace ImageSharp.Processing.Processors
/// Defines a sampler that detects edges within an image using two one-dimensional matrices.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class EdgeDetector2DProcessor<TColor> : ImageProcessor<TColor>, IEdgeDetectorProcessor<TColor>
internal abstract class EdgeDetector2DProcessor<TColor> : ImageProcessor<TColor>, IEdgeDetectorProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Defines a sampler that detects edges within an image using a eight two dimensional matrices.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class EdgeDetectorCompassProcessor<TColor> : ImageProcessor<TColor>, IEdgeDetectorProcessor<TColor>
internal abstract class EdgeDetectorCompassProcessor<TColor> : ImageProcessor<TColor>, IEdgeDetectorProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs

@ -11,7 +11,7 @@ namespace ImageSharp.Processing.Processors
/// Defines a sampler that detects edges within an image using a single two dimensional matrix.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class EdgeDetectorProcessor<TColor> : ImageProcessor<TColor>, IEdgeDetectorProcessor<TColor>
internal abstract class EdgeDetectorProcessor<TColor> : ImageProcessor<TColor>, IEdgeDetectorProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class KayyaliProcessor<TColor> : EdgeDetector2DProcessor<TColor>
internal class KayyaliProcessor<TColor> : EdgeDetector2DProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class KirschProcessor<TColor> : EdgeDetectorCompassProcessor<TColor>
internal class KirschProcessor<TColor> : EdgeDetectorCompassProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class Laplacian3X3Processor<TColor> : EdgeDetectorProcessor<TColor>
internal class Laplacian3X3Processor<TColor> : EdgeDetectorProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class Laplacian5X5Processor<TColor> : EdgeDetectorProcessor<TColor>
internal class Laplacian5X5Processor<TColor> : EdgeDetectorProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class LaplacianOfGaussianProcessor<TColor> : EdgeDetectorProcessor<TColor>
internal class LaplacianOfGaussianProcessor<TColor> : EdgeDetectorProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class PrewittProcessor<TColor> : EdgeDetector2DProcessor<TColor>
internal class PrewittProcessor<TColor> : EdgeDetector2DProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class RobertsCrossProcessor<TColor> : EdgeDetector2DProcessor<TColor>
internal class RobertsCrossProcessor<TColor> : EdgeDetector2DProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class RobinsonProcessor<TColor> : EdgeDetectorCompassProcessor<TColor>
internal class RobinsonProcessor<TColor> : EdgeDetectorCompassProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class ScharrProcessor<TColor> : EdgeDetector2DProcessor<TColor>
internal class ScharrProcessor<TColor> : EdgeDetector2DProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class SobelProcessor<TColor> : EdgeDetector2DProcessor<TColor>
internal class SobelProcessor<TColor> : EdgeDetector2DProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs

@ -11,7 +11,7 @@ namespace ImageSharp.Processing.Processors
/// Applies a Gaussian blur sampler to the image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class GaussianBlurProcessor<TColor> : ImageProcessor<TColor>
internal class GaussianBlurProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs

@ -11,7 +11,7 @@ namespace ImageSharp.Processing.Processors
/// Applies a Gaussian sharpening sampler to the image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class GaussianSharpenProcessor<TColor> : ImageProcessor<TColor>
internal class GaussianSharpenProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Effects/AlphaProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> to change the alpha component of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class AlphaProcessor<TColor> : ImageProcessor<TColor>
internal class AlphaProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Sets the background color of the image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class BackgroundColorProcessor<TColor> : ImageProcessor<TColor>
internal class BackgroundColorProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Effects/BrightnessProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> to change the brightness of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class BrightnessProcessor<TColor> : ImageProcessor<TColor>
internal class BrightnessProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Effects/ContrastProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> to change the contrast of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class ContrastProcessor<TColor> : ImageProcessor<TColor>
internal class ContrastProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Effects/InvertProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> to invert the colors of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class InvertProcessor<TColor> : ImageProcessor<TColor>
internal class InvertProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <inheritdoc/>

2
src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// </summary>
/// <remarks>Adapted from <see href="https://softwarebydefault.com/2013/06/29/oil-painting-cartoon-filter/"/> by Dewald Esterhuizen.</remarks>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class OilPaintingProcessor<TColor> : ImageProcessor<TColor>
internal class OilPaintingProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> to pixelate the colors of an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class PixelateProcessor<TColor> : ImageProcessor<TColor>
internal class PixelateProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> that applies a radial glow effect an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class GlowProcessor<TColor> : ImageProcessor<TColor>
internal class GlowProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// An <see cref="IImageProcessor{TColor}"/> that applies a radial vignette effect to an <see cref="Image{TColor}"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class VignetteProcessor<TColor> : ImageProcessor<TColor>
internal class VignetteProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/CompandingResizeProcessor.cs

@ -14,7 +14,7 @@ namespace ImageSharp.Processing.Processors
/// This version will expand and compress the image to and from a linear color space during processing.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class CompandingResizeProcessor<TColor> : ResamplingWeightedProcessor<TColor>
internal class CompandingResizeProcessor<TColor> : ResamplingWeightedProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Provides methods to allow the cropping of an image.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class CropProcessor<TColor> : ImageProcessor<TColor>
internal class CropProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// entropy.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class EntropyCropProcessor<TColor> : ImageProcessor<TColor>
internal class EntropyCropProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Provides methods that allow the flipping of an image around its center point.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class FlipProcessor<TColor> : ImageProcessor<TColor>
internal class FlipProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/Matrix3x2Processor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Provides methods to transform an image using a <see cref="Matrix3x2"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class Matrix3x2Processor<TColor> : ImageProcessor<TColor>
internal abstract class Matrix3x2Processor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Processing.Processors
/// Adapted from <see href="http://www.realtimerendering.com/resources/GraphicsGems/gemsiii/filter_rcg.c"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public abstract class ResamplingWeightedProcessor<TColor> : ImageProcessor<TColor>
internal abstract class ResamplingWeightedProcessor<TColor> : ImageProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs

@ -16,7 +16,7 @@ namespace ImageSharp.Processing.Processors
/// This version and the <see cref="CompandingResizeProcessor{TColor}"/> have been separated out to improve performance.
/// </remarks>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class ResizeProcessor<TColor> : ResamplingWeightedProcessor<TColor>
internal class ResizeProcessor<TColor> : ResamplingWeightedProcessor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Provides methods that allow the rotating of images.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class RotateProcessor<TColor> : Matrix3x2Processor<TColor>
internal class RotateProcessor<TColor> : Matrix3x2Processor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs

@ -13,7 +13,7 @@ namespace ImageSharp.Processing.Processors
/// Provides methods that allow the skewing of images.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public class SkewProcessor<TColor> : Matrix3x2Processor<TColor>
internal class SkewProcessor<TColor> : Matrix3x2Processor<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>

2
src/ImageSharp/Quantizers/IQuantizer.cs

@ -5,8 +5,6 @@
namespace ImageSharp.Quantizers
{
using System;
using ImageSharp.Dithering;
/// <summary>

94
src/ImageSharp/Quantizers/Octree/OctreeQuantizer.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Quantizers
{
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
/// <summary>
/// Encapsulates methods to calculate the color palette if an image using an Octree pattern.
@ -16,6 +17,11 @@ namespace ImageSharp.Quantizers
public sealed class OctreeQuantizer<TColor> : Quantizer<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>
/// A lookup table for colors
/// </summary>
private readonly Dictionary<TColor, byte> colorMap = new Dictionary<TColor, byte>();
/// <summary>
/// The pixel buffer, used to reduce allocations.
/// </summary>
@ -31,6 +37,11 @@ namespace ImageSharp.Quantizers
/// </summary>
private int colors;
/// <summary>
/// The reduced image palette
/// </summary>
private TColor[] palette;
/// <summary>
/// Initializes a new instance of the <see cref="OctreeQuantizer{TColor}"/> class.
/// </summary>
@ -52,6 +63,58 @@ namespace ImageSharp.Quantizers
return base.Quantize(image, maxColors);
}
/// <summary>
/// Execute a second pass through the bitmap
/// </summary>
/// <param name="source">The source image.</param>
/// <param name="output">The output pixel array</param>
/// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param>
protected override void SecondPass(PixelAccessor<TColor> source, byte[] output, int width, int height)
{
// Load up the values for the first pixel. We can use these to speed up the second
// pass of the algorithm by avoiding transforming rows of identical color.
TColor sourcePixel = source[0, 0];
TColor previousPixel = sourcePixel;
byte pixelValue = this.QuantizePixel(sourcePixel);
TColor[] colorPalette = this.GetPalette();
TColor transformedPixel = colorPalette[pixelValue];
for (int y = 0; y < height; y++)
{
// And loop through each column
for (int x = 0; x < width; x++)
{
// Get the pixel.
sourcePixel = source[x, y];
// Check if this is the same as the last pixel. If so use that value
// rather than calculating it again. This is an inexpensive optimization.
if (!previousPixel.Equals(sourcePixel))
{
// Quantize the pixel
pixelValue = this.QuantizePixel(sourcePixel);
// And setup the previous pointer
previousPixel = sourcePixel;
if (this.Dither)
{
transformedPixel = colorPalette[pixelValue];
}
}
if (this.Dither)
{
// Apply the dithering matrix. We have to reapply the value now as the original has changed.
this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, width, height);
}
output[(y * source.Width) + x] = pixelValue;
}
}
}
/// <summary>
/// Process the pixel in the first pass of the algorithm
/// </summary>
@ -69,26 +132,39 @@ namespace ImageSharp.Quantizers
}
/// <summary>
/// Override this to process the pixel in the second pass of the algorithm
/// Retrieve the palette for the quantized image.
/// </summary>
/// <param name="pixel">The pixel to quantize</param>
/// <returns>
/// The quantized value
/// The new color palette
/// </returns>
protected override byte QuantizePixel(TColor pixel)
protected override TColor[] GetPalette()
{
return (byte)this.octree.GetPaletteIndex(pixel, this.pixelBuffer);
if (this.palette == null)
{
this.palette = this.octree.Palletize(Math.Max(this.colors, 1));
}
return this.palette;
}
/// <summary>
/// Retrieve the palette for the quantized image.
/// Process the pixel in the second pass of the algorithm
/// </summary>
/// <param name="pixel">The pixel to quantize</param>
/// <returns>
/// The new color palette
/// The quantized value
/// </returns>
protected override TColor[] GetPalette()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte QuantizePixel(TColor pixel)
{
return this.octree.Palletize(Math.Max(this.colors, 1));
if (this.Dither)
{
// The colors have changed so we need to use Euclidean distance caclulation to find the closest value.
// This palette can never be null here.
return this.GetClosestColor(pixel, this.palette, this.colorMap);
}
return (byte)this.octree.GetPaletteIndex(pixel, this.pixelBuffer);
}
/// <summary>

55
src/ImageSharp/Quantizers/Octree/Quantizer.cs

@ -9,7 +9,6 @@ namespace ImageSharp.Quantizers
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using ImageSharp.Dithering;
/// <summary>
@ -19,21 +18,11 @@ namespace ImageSharp.Quantizers
public abstract class Quantizer<TColor> : IDitheredQuantizer<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>
/// A lookup table for colors
/// </summary>
private readonly Dictionary<TColor, byte> colorMap = new Dictionary<TColor, byte>();
/// <summary>
/// Flag used to indicate whether a single pass or two passes are needed for quantization.
/// </summary>
private readonly bool singlePass;
/// <summary>
/// The reduced image palette
/// </summary>
private TColor[] palette;
/// <summary>
/// Initializes a new instance of the <see cref="Quantizer{TColor}"/> class.
/// </summary>
@ -65,6 +54,7 @@ namespace ImageSharp.Quantizers
int height = image.Height;
int width = image.Width;
byte[] quantizedPixels = new byte[width * height];
TColor[] colorPalette;
using (PixelAccessor<TColor> pixels = image.Lock())
{
@ -76,8 +66,8 @@ namespace ImageSharp.Quantizers
this.FirstPass(pixels, width, height);
}
// Get the palette
this.palette = this.GetPalette();
// Collect the palette. Octree requires this to be done before the second pass runs.
colorPalette = this.GetPalette();
if (this.Dither)
{
@ -94,7 +84,7 @@ namespace ImageSharp.Quantizers
}
}
return new QuantizedImage<TColor>(width, height, this.palette, quantizedPixels);
return new QuantizedImage<TColor>(width, height, colorPalette, quantizedPixels);
}
/// <summary>
@ -124,25 +114,7 @@ namespace ImageSharp.Quantizers
/// <param name="output">The output pixel array</param>
/// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param>
protected virtual void SecondPass(PixelAccessor<TColor> source, byte[] output, int width, int height)
{
for (int y = 0; y < height; y++)
{
// And loop through each column
for (int x = 0; x < width; x++)
{
if (this.Dither)
{
// Apply the dithering matrix
TColor sourcePixel = source[x, y];
TColor transformedPixel = this.palette[this.GetClosestColor(sourcePixel, this.palette, this.colorMap)];
this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, width, height);
}
output[(y * source.Width) + x] = this.QuantizePixel(source[x, y]);
}
}
}
protected abstract void SecondPass(PixelAccessor<TColor> source, byte[] output, int width, int height);
/// <summary>
/// Override this to process the pixel in the first pass of the algorithm
@ -157,16 +129,7 @@ namespace ImageSharp.Quantizers
}
/// <summary>
/// Override this to process the pixel in the second pass of the algorithm
/// </summary>
/// <param name="pixel">The pixel to quantize</param>
/// <returns>
/// The quantized value
/// </returns>
protected abstract byte QuantizePixel(TColor pixel);
/// <summary>
/// Retrieve the palette for the quantized image
/// Retrieve the palette for the quantized image. Can be called more than once so make sure calls are cached.
/// </summary>
/// <returns>
/// <see cref="T:TColor[]"/>
@ -184,9 +147,9 @@ namespace ImageSharp.Quantizers
protected byte GetClosestColor(TColor pixel, TColor[] colorPalette, Dictionary<TColor, byte> cache)
{
// Check if the color is in the lookup table
if (this.colorMap.ContainsKey(pixel))
if (cache.ContainsKey(pixel))
{
return this.colorMap[pixel];
return cache[pixel];
}
// Not found - loop through the palette and find the nearest match.
@ -215,7 +178,7 @@ namespace ImageSharp.Quantizers
}
// Now I have the index, pop it into the cache for next time
this.colorMap.Add(pixel, colorIndex);
cache.Add(pixel, colorIndex);
return colorIndex;
}

67
src/ImageSharp/Quantizers/Palette/PaletteQuantizer.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Quantizers
{
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Encapsulates methods to create a quantized image based upon the given palette.
@ -69,10 +71,56 @@ namespace ImageSharp.Quantizers
return base.Quantize(image, maxColors);
}
/// <inheritdoc/>
protected override byte QuantizePixel(TColor pixel)
/// <summary>
/// Execute a second pass through the bitmap
/// </summary>
/// <param name="source">The source image.</param>
/// <param name="output">The output pixel array</param>
/// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param>
protected override void SecondPass(PixelAccessor<TColor> source, byte[] output, int width, int height)
{
return this.GetClosestColor(pixel, this.colors, this.colorMap);
// Load up the values for the first pixel. We can use these to speed up the second
// pass of the algorithm by avoiding transforming rows of identical color.
TColor sourcePixel = source[0, 0];
TColor previousPixel = sourcePixel;
byte pixelValue = this.QuantizePixel(sourcePixel);
TColor[] colorPalette = this.GetPalette();
TColor transformedPixel = colorPalette[pixelValue];
for (int y = 0; y < height; y++)
{
// And loop through each column
for (int x = 0; x < width; x++)
{
// Get the pixel.
sourcePixel = source[x, y];
// Check if this is the same as the last pixel. If so use that value
// rather than calculating it again. This is an inexpensive optimization.
if (!previousPixel.Equals(sourcePixel))
{
// Quantize the pixel
pixelValue = this.QuantizePixel(sourcePixel);
// And setup the previous pointer
previousPixel = sourcePixel;
if (this.Dither)
{
transformedPixel = colorPalette[pixelValue];
}
}
if (this.Dither)
{
// Apply the dithering matrix. We have to reapply the value now as the original has changed.
this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, width, height);
}
output[(y * source.Width) + x] = pixelValue;
}
}
}
/// <inheritdoc/>
@ -80,5 +128,18 @@ namespace ImageSharp.Quantizers
{
return this.colors;
}
/// <summary>
/// Process the pixel in the second pass of the algorithm
/// </summary>
/// <param name="pixel">The pixel to quantize</param>
/// <returns>
/// The quantized value
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte QuantizePixel(TColor pixel)
{
return this.GetClosestColor(pixel, this.GetPalette(), this.colorMap);
}
}
}

104
tests/ImageSharp.Benchmarks/Image/EncodeIndexedPng.cs

@ -0,0 +1,104 @@
// <copyright file="EncodeIndexedPng.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Benchmarks.Image
{
using System.IO;
using BenchmarkDotNet.Attributes;
using ImageSharp;
using ImageSharp.Formats;
using ImageSharp.Quantizers;
/// <summary>
/// Benchmarks saving png files using different quantizers. System.Drawing cannot save indexed png files so we cannot compare.
/// </summary>
public class EncodeIndexedPng : BenchmarkBase
{
// System.Drawing needs this.
private Stream bmpStream;
private Image bmpCore;
[Params(false)]
public bool LargeImage { get; set; }
[Setup]
public void ReadImages()
{
if (this.bmpStream == null)
{
string path = this.LargeImage
? "../ImageSharp.Tests/TestImages/Formats/Jpg/baseline/jpeg420exif.jpg"
: "../ImageSharp.Tests/TestImages/Formats/Bmp/Car.bmp";
this.bmpStream = File.OpenRead(path);
this.bmpCore = new Image(this.bmpStream);
this.bmpStream.Position = 0;
}
}
[Cleanup]
public void Cleanup()
{
this.bmpStream.Dispose();
this.bmpCore.Dispose();
}
[Benchmark(Baseline = true, Description = "ImageSharp Octree Png")]
public void PngCoreOctree()
{
using (MemoryStream memoryStream = new MemoryStream())
{
PngEncoderOptions options = new PngEncoderOptions() { Quantizer = new OctreeQuantizer<Color>(), Quality = 256 };
this.bmpCore.SaveAsPng(memoryStream, options);
}
}
[Benchmark(Description = "ImageSharp Octree NoDither Png")]
public void PngCoreOctreeNoDIther()
{
using (MemoryStream memoryStream = new MemoryStream())
{
PngEncoderOptions options = new PngEncoderOptions { Quantizer = new OctreeQuantizer<Color> { Dither = false }, Quality = 256 };
this.bmpCore.SaveAsPng(memoryStream, options);
}
}
[Benchmark(Description = "ImageSharp Palette Png")]
public void PngCorePalette()
{
using (MemoryStream memoryStream = new MemoryStream())
{
PngEncoderOptions options = new PngEncoderOptions { Quantizer = new PaletteQuantizer<Color>(), Quality = 256 };
this.bmpCore.SaveAsPng(memoryStream, options);
}
}
[Benchmark(Description = "ImageSharp Palette NoDither Png")]
public void PngCorePaletteNoDither()
{
using (MemoryStream memoryStream = new MemoryStream())
{
PngEncoderOptions options = new PngEncoderOptions { Quantizer = new PaletteQuantizer<Color> { Dither = false }, Quality = 256 };
this.bmpCore.SaveAsPng(memoryStream, options);
}
}
[Benchmark(Description = "ImageSharp Wu Png")]
public void PngCoreWu()
{
using (MemoryStream memoryStream = new MemoryStream())
{
PngEncoderOptions options = new PngEncoderOptions() { Quantizer = new WuQuantizer<Color>(), Quality = 256 };
this.bmpCore.SaveAsPng(memoryStream, options);
}
}
}
}

18
tests/ImageSharp.Tests/Common/PinnedBufferTests.cs

@ -3,6 +3,7 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Xunit;
@ -62,6 +63,23 @@
}
}
[Fact]
public void CreateClean()
{
Parallel.For(0, 100,
i =>
{
using (PinnedBuffer<int> buffer = PinnedBuffer<int>.CreateClean(42))
{
for (int j = 0; j < buffer.Count; j++)
{
Assert.Equal(0, buffer.Array[j]);
buffer.Array[j] = 666;
}
}
});
}
[Fact]
public void Dispose()
{

185
tests/ImageSharp.Tests/Drawing/Text/DrawText.cs

@ -1,96 +1,107 @@

// <copyright file="DrawText.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Tests.Drawing.Text
{
using System;
using System.IO;
using ImageSharp;
using ImageSharp.Drawing.Brushes;
using Processing;
using System.Collections.Generic;
using Xunit;
using ImageSharp.Drawing;
using System.Numerics;
using SixLabors.Shapes;
using ImageSharp.Drawing.Processors;
using ImageSharp.Drawing;
using ImageSharp.Drawing.Brushes;
using ImageSharp.Drawing.Pens;
using ImageSharp.Drawing.Processors;
using ImageSharp.Tests.Drawing.Paths;
using SixLabors.Fonts;
using Paths;
using SixLabors.Shapes;
using Xunit;
public class DrawText : IDisposable
{
Color color = Color.HotPink;
SolidBrush brush = Brushes.Solid(Color.HotPink);
IPath path = new SixLabors.Shapes.Path(new LinearLineSegment(new Vector2[] {
new Vector2(10,10),
new Vector2(20,10),
new Vector2(20,10),
new Vector2(30,10),
}));
IPath path = new SixLabors.Shapes.Path(
new LinearLineSegment(
new Vector2[] { new Vector2(10, 10), new Vector2(20, 10), new Vector2(20, 10), new Vector2(30, 10), }));
private ProcessorWatchingImage img;
private readonly FontCollection FontCollection;
private readonly Font Font;
public DrawText()
{
this.FontCollection = new FontCollection();
this.Font = FontCollection.Install(TestFontUtilities.GetPath("SixLaborsSampleAB.woff"));
this.Font = this.FontCollection.Install(TestFontUtilities.GetPath("SixLaborsSampleAB.woff"));
this.img = new ProcessorWatchingImage(10, 10);
}
public void Dispose()
{
img.Dispose();
this.img.Dispose();
}
[Fact]
public void FillsForEachACharachterWhenBrushSetAndNotPen()
{
img.DrawText("123", this.Font, Brushes.Solid(Color.Red), null, Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText(
"123",
this.Font,
Brushes.Solid(Color.Red),
null,
Vector2.Zero,
new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void FillsForEachACharachterWhenBrushSetAndNotPenDefaultOptions()
{
img.DrawText("123", this.Font, Brushes.Solid(Color.Red), null, Vector2.Zero);
this.img.DrawText("123", this.Font, Brushes.Solid(Color.Red), null, Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void FillsForEachACharachterWhenBrushSet()
{
img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero, new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void FillsForEachACharachterWhenBrushSetDefaultOptions()
{
img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero);
this.img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void FillsForEachACharachterWhenColorSet()
{
img.DrawText("123", this.Font, Color.Red, Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText("123", this.Font, Color.Red, Vector2.Zero, new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count);
FillRegionProcessor<Color> processor = Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count);
FillRegionProcessor<Color> processor =
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
SolidBrush<Color> brush = Assert.IsType<SolidBrush<Color>>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
@ -99,12 +110,13 @@ namespace ImageSharp.Tests.Drawing.Text
[Fact]
public void FillsForEachACharachterWhenColorSetDefaultOptions()
{
img.DrawText("123", this.Font, Color.Red, Vector2.Zero);
this.img.DrawText("123", this.Font, Color.Red, Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count);
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
FillRegionProcessor<Color> processor = Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count);
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
FillRegionProcessor<Color> processor =
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
SolidBrush<Color> brush = Assert.IsType<SolidBrush<Color>>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
@ -113,82 +125,99 @@ namespace ImageSharp.Tests.Drawing.Text
[Fact]
public void DrawForEachACharachterWhenPenSetAndNotBrush()
{
img.DrawText("123", this.Font, null, Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText(
"123",
this.Font,
null,
Pens.Dash(Color.Red, 1),
Vector2.Zero,
new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void DrawForEachACharachterWhenPenSetAndNotBrushDefaultOptions()
{
img.DrawText("123", this.Font, null, Pens.Dash(Color.Red, 1), Vector2.Zero);
this.img.DrawText("123", this.Font, null, Pens.Dash(Color.Red, 1), Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void DrawForEachACharachterWhenPenSet()
{
img.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void DrawForEachACharachterWhenPenSetDefaultOptions()
{
img.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero);
this.img.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(3, this.img.ProcessorApplications.Count); // 3 fills where applied
Assert.IsType<DrawPathProcessor<Color>>(this.img.ProcessorApplications[0].processor);
}
[Fact]
public void DrawForEachACharachterWhenPenSetAndFillFroEachWhenBrushSet()
{
img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText(
"123",
this.Font,
Brushes.Solid(Color.Red),
Pens.Dash(Color.Red, 1),
Vector2.Zero,
new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(6, img.ProcessorApplications.Count);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(6, this.img.ProcessorApplications.Count);
}
[Fact]
public void DrawForEachACharachterWhenPenSetAndFillFroEachWhenBrushSetDefaultOptions()
{
img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero);
this.img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(6, img.ProcessorApplications.Count);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(6, this.img.ProcessorApplications.Count);
}
[Fact]
public void BrushAppliesBeforPen()
{
img.DrawText("1", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true));
this.img.DrawText(
"1",
this.Font,
Brushes.Solid(Color.Red),
Pens.Dash(Color.Red, 1),
Vector2.Zero,
new TextGraphicsOptions(true));
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(2, img.ProcessorApplications.Count);
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.IsType<DrawPathProcessor<Color>>(img.ProcessorApplications[1].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(2, this.img.ProcessorApplications.Count);
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
Assert.IsType<DrawPathProcessor<Color>>(this.img.ProcessorApplications[1].processor);
}
[Fact]
public void BrushAppliesBeforPenDefaultOptions()
{
img.DrawText("1", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero);
this.img.DrawText("1", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero);
Assert.NotEmpty(img.ProcessorApplications);
Assert.Equal(2, img.ProcessorApplications.Count);
Assert.IsType<FillRegionProcessor<Color>>(img.ProcessorApplications[0].processor);
Assert.IsType<DrawPathProcessor<Color>>(img.ProcessorApplications[1].processor);
Assert.NotEmpty(this.img.ProcessorApplications);
Assert.Equal(2, this.img.ProcessorApplications.Count);
Assert.IsType<FillRegionProcessor<Color>>(this.img.ProcessorApplications[0].processor);
Assert.IsType<DrawPathProcessor<Color>>(this.img.ProcessorApplications[1].processor);
}
}
}

2
tests/ImageSharp.Tests/TestFile.cs

@ -153,7 +153,7 @@ namespace ImageSharp.Tests
List<string> directories = new List< string > {
"TestImages/Formats/", // Here for code coverage tests.
"tests/ImageSharp.Tests/TestImages/Formats/", // from travis/build script
"../../../ImageSharp.Tests/TestImages/Formats/", // from Sandbox46
"../../../../../ImageSharp.Tests/TestImages/Formats/", // from Sandbox46
"../../../../TestImages/Formats/",
"../../../TestImages/Formats/"
};

2
tests/ImageSharp.Tests/TestFont.cs

@ -47,7 +47,7 @@ namespace ImageSharp.Tests
List<string> directories = new List< string > {
"TestFonts/", // Here for code coverage tests.
"tests/ImageSharp.Tests/TestFonts/", // from travis/build script
"../../../ImageSharp.Tests/TestFonts/", // from Sandbox46
"../../../../../ImageSharp.Tests/TestFonts/", // from Sandbox46
"../../../../TestFonts/"
};

Loading…
Cancel
Save