Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;

Expand Down
9 changes: 9 additions & 0 deletions src/ImageSharp/Advanced/AdvancedImageExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ namespace SixLabors.ImageSharp.Advanced
/// </summary>
public static class AdvancedImageExtensions
{
/// <summary>
/// Accepts a <see cref="IImageVisitor"/> to implement a double-dispatch pattern in order to
/// apply pixel-specific operations on non-generic <see cref="Image"/> instances
/// </summary>
/// <param name="source">The source.</param>
/// <param name="visitor">The visitor.</param>
public static void AcceptVisitor(this Image source, IImageVisitor visitor)
=> source.Accept(visitor);

/// <summary>
/// Gets the configuration for the image.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

using SixLabors.ImageSharp.PixelFormats;

namespace SixLabors.ImageSharp
namespace SixLabors.ImageSharp.Advanced
{
/// <summary>
/// A visitor to implement double-dispatch pattern in order to apply pixel-specific operations
/// on non-generic <see cref="Image"/> instances. The operation is dispatched by <see cref="Image.AcceptVisitor"/>.
/// A visitor to implement a double-dispatch pattern in order to apply pixel-specific operations
/// on non-generic <see cref="Image"/> instances.
/// </summary>
internal interface IImageVisitor
public interface IImageVisitor
{
/// <summary>
/// Provides a pixel-specific implementation for a given operation.
Expand All @@ -19,4 +19,4 @@ internal interface IImageVisitor
void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>;
}
}
}
18 changes: 9 additions & 9 deletions src/ImageSharp/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ public void Save(Stream stream, IImageEncoder encoder)
Guard.NotNull(encoder, nameof(encoder));
this.EnsureNotDisposed();

var visitor = new EncodeVisitor(encoder, stream);
this.AcceptVisitor(visitor);
this.AcceptVisitor(new EncodeVisitor(encoder, stream));
}

/// <summary>
Expand All @@ -121,13 +120,6 @@ public Image<TPixel2> CloneAs<TPixel2>()
public abstract Image<TPixel2> CloneAs<TPixel2>(Configuration configuration)
where TPixel2 : struct, IPixel<TPixel2>;

/// <summary>
/// Accept a <see cref="IImageVisitor"/>.
/// Implemented by <see cref="Image{TPixel}"/> invoking <see cref="IImageVisitor.Visit{TPixel}"/>
/// with the pixel type of the image.
/// </summary>
internal abstract void AcceptVisitor(IImageVisitor visitor);

/// <summary>
/// Update the size of the image after mutation.
/// </summary>
Expand All @@ -145,6 +137,14 @@ public abstract Image<TPixel2> CloneAs<TPixel2>(Configuration configuration)
/// </summary>
internal abstract void EnsureNotDisposed();

/// <summary>
/// Accepts a <see cref="IImageVisitor"/>.
/// Implemented by <see cref="Image{TPixel}"/> invoking <see cref="IImageVisitor.Visit{TPixel}"/>
/// with the pixel type of the image.
/// </summary>
/// <param name="visitor">The visitor.</param>
internal abstract void Accept(IImageVisitor visitor);

private class EncodeVisitor : IImageVisitor
{
private readonly IImageEncoder encoder;
Expand Down
8 changes: 4 additions & 4 deletions src/ImageSharp/Image{TPixel}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,17 @@ internal override void EnsureNotDisposed()
}
}

/// <inheritdoc/>
public override string ToString() => $"Image<{typeof(TPixel).Name}>: {this.Width}x{this.Height}";

/// <inheritdoc />
internal override void AcceptVisitor(IImageVisitor visitor)
internal override void Accept(IImageVisitor visitor)
{
this.EnsureNotDisposed();

visitor.Visit(this);
}

/// <inheritdoc/>
public override string ToString() => $"Image<{typeof(TPixel).Name}>: {this.Width}x{this.Height}";

/// <summary>
/// Switches the buffers used by the image and the pixelSource meaning that the Image will "own" the buffer from the pixelSource and the pixelSource will now own the Images buffer.
/// </summary>
Expand Down
33 changes: 21 additions & 12 deletions src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ public static void Mutate(this Image source, Action<IImageProcessingContext> ope
Guard.NotNull(operation, nameof(operation));
source.EnsureNotDisposed();

var visitor = new ProcessingVisitor(operation, true);
source.AcceptVisitor(visitor);
source.AcceptVisitor(new ProcessingVisitor(operation, true));
}

/// <summary>
Expand All @@ -42,8 +41,10 @@ public static void Mutate<TPixel>(this Image<TPixel> source, Action<IImageProces
Guard.NotNull(operation, nameof(operation));
source.EnsureNotDisposed();

IInternalImageProcessingContext<TPixel> operationsRunner = source.GetConfiguration().ImageOperationsProvider
.CreateImageProcessingContext(source, true);
IInternalImageProcessingContext<TPixel> operationsRunner
= source.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(source, true);

operation(operationsRunner);
}

Expand All @@ -60,8 +61,10 @@ public static void Mutate<TPixel>(this Image<TPixel> source, params IImageProces
Guard.NotNull(operations, nameof(operations));
source.EnsureNotDisposed();

IInternalImageProcessingContext<TPixel> operationsRunner = source.GetConfiguration().ImageOperationsProvider
.CreateImageProcessingContext(source, true);
IInternalImageProcessingContext<TPixel> operationsRunner
= source.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(source, true);

operationsRunner.ApplyProcessors(operations);
}

Expand Down Expand Up @@ -96,8 +99,10 @@ public static Image<TPixel> Clone<TPixel>(this Image<TPixel> source, Action<IIma
Guard.NotNull(operation, nameof(operation));
source.EnsureNotDisposed();

IInternalImageProcessingContext<TPixel> operationsRunner = source.GetConfiguration().ImageOperationsProvider
.CreateImageProcessingContext(source, false);
IInternalImageProcessingContext<TPixel> operationsRunner
= source.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(source, false);

operation(operationsRunner);
return operationsRunner.GetResultImage();
}
Expand All @@ -116,8 +121,10 @@ public static Image<TPixel> Clone<TPixel>(this Image<TPixel> source, params IIma
Guard.NotNull(operations, nameof(operations));
source.EnsureNotDisposed();

IInternalImageProcessingContext<TPixel> operationsRunner = source.GetConfiguration().ImageOperationsProvider
.CreateImageProcessingContext(source, false);
IInternalImageProcessingContext<TPixel> operationsRunner
= source.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(source, false);

operationsRunner.ApplyProcessors(operations);
return operationsRunner.GetResultImage();
}
Expand Down Expand Up @@ -157,8 +164,10 @@ public ProcessingVisitor(Action<IImageProcessingContext> operation, bool mutate)
public void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>
{
IInternalImageProcessingContext<TPixel> operationsRunner = image.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(image, this.mutate);
IInternalImageProcessingContext<TPixel> operationsRunner =
image.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(image, this.mutate);

this.operation(operationsRunner);
this.ResultImage = operationsRunner.GetResultImage();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;

Expand Down