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
4 changes: 2 additions & 2 deletions src/ImageSharp/IImage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System;
Expand All @@ -11,4 +11,4 @@ namespace SixLabors.ImageSharp
public interface IImage : IImageInfo, IDisposable
{
}
}
}
27 changes: 12 additions & 15 deletions src/ImageSharp/Image.cs
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 System;
using System.IO;

using SixLabors.ImageSharp.Advanced;
Expand Down Expand Up @@ -80,21 +81,11 @@ internal Image(
/// </summary>
Configuration IConfigurable.Configuration => this.Configuration;

/// <summary>
/// Gets a value indicating whether the image instance is disposed.
/// </summary>
public bool IsDisposed { get; private set; }

/// <inheritdoc />
public void Dispose()
{
if (this.IsDisposed)
{
return;
}

this.IsDisposed = true;
this.DisposeImpl();
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
Expand All @@ -109,7 +100,7 @@ public void Save(Stream stream, IImageEncoder encoder)
Guard.NotNull(encoder, nameof(encoder));
this.EnsureNotDisposed();

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

Expand Down Expand Up @@ -144,9 +135,15 @@ public abstract Image<TPixel2> CloneAs<TPixel2>(Configuration configuration)
protected void UpdateSize(Size size) => this.size = size;

/// <summary>
/// Implements the Dispose logic.
/// Disposes the object and frees resources for the Garbage Collector.
/// </summary>
/// <param name="disposing">Whether to dispose of managed and unmanaged objects.</param>
protected abstract void Dispose(bool disposing);

/// <summary>
/// Throws <see cref="ObjectDisposedException"/> if the image is disposed.
/// </summary>
protected abstract void DisposeImpl();
internal abstract void EnsureNotDisposed();

private class EncodeVisitor : IImageVisitor
{
Expand Down
13 changes: 1 addition & 12 deletions src/ImageSharp/ImageExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System;
Expand Down Expand Up @@ -119,16 +119,5 @@ public static string ToBase64String<TPixel>(this Image<TPixel> source, IImageFor
return $"data:{format.DefaultMimeType};base64,{Convert.ToBase64String(stream.ToArray())}";
}
}

/// <summary>
/// Throws <see cref="ObjectDisposedException"/> if the image is disposed.
/// </summary>
internal static void EnsureNotDisposed(this Image image)
{
if (image.IsDisposed)
{
throw new ObjectDisposedException(nameof(image), "Trying to execute an operation on a disposed image.");
}
}
}
}
12 changes: 11 additions & 1 deletion src/ImageSharp/ImageFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,17 @@ protected ImageFrame(Configuration configuration, int width, int height, ImageFr
public Rectangle Bounds() => new Rectangle(0, 0, this.Width, this.Height);

/// <inheritdoc />
public abstract void Dispose();
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Disposes the object and frees resources for the Garbage Collector.
/// </summary>
/// <param name="disposing">Whether to dispose of managed and unmanaged objects.</param>
protected abstract void Dispose(bool disposing);

internal abstract void CopyPixelsTo<TDestinationPixel>(Span<TDestinationPixel> destination)
where TDestinationPixel : struct, IPixel<TDestinationPixel>;
Expand Down
16 changes: 8 additions & 8 deletions src/ImageSharp/ImageFrame{TPixel}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp
/// In all other cases it is the only frame of the image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>, IDisposable
public sealed class ImageFrame<TPixel> : ImageFrame, IPixelSource<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private bool isDisposed;
Expand Down Expand Up @@ -196,20 +196,20 @@ internal void SwapOrCopyPixelsBufferFrom(ImageFrame<TPixel> pixelSource)
this.UpdateSize(this.PixelBuffer.Size());
}

/// <summary>
/// Disposes the object and frees resources for the Garbage Collector.
/// </summary>
public override void Dispose()
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
if (this.isDisposed)
{
return;
}

this.PixelBuffer?.Dispose();
this.PixelBuffer = null;
if (disposing)
{
this.PixelBuffer?.Dispose();
this.PixelBuffer = null;
}

// Note disposing is done.
this.isDisposed = true;
}

Expand Down
28 changes: 26 additions & 2 deletions src/ImageSharp/Image{TPixel}.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System;
Expand All @@ -21,6 +21,8 @@ namespace SixLabors.ImageSharp
public sealed class Image<TPixel> : Image
where TPixel : struct, IPixel<TPixel>
{
private bool isDisposed;

/// <summary>
/// Initializes a new instance of the <see cref="Image{TPixel}"/> class
/// with the height and the width of the image.
Expand Down Expand Up @@ -185,7 +187,29 @@ public override Image<TPixel2> CloneAs<TPixel2>(Configuration configuration)
}

/// <inheritdoc/>
protected override void DisposeImpl() => this.Frames.Dispose();
protected override void Dispose(bool disposing)
{
if (this.isDisposed)
{
return;
}

if (disposing)
{
this.Frames.Dispose();
}

this.isDisposed = true;
}

/// <inheritdoc/>
internal override void EnsureNotDisposed()
{
if (this.isDisposed)
{
throw new ObjectDisposedException("Trying to execute an operation on a disposed image.");
}
}

/// <inheritdoc />
internal override void AcceptVisitor(IImageVisitor visitor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Processing.Processors
internal abstract class CloningImageProcessor<TPixel> : ICloningImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private bool isDisposed;

/// <summary>
/// Initializes a new instance of the <see cref="CloningImageProcessor{TPixel}"/> class.
/// </summary>
Expand Down Expand Up @@ -104,6 +102,7 @@ public void Apply()
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
Expand Down Expand Up @@ -160,10 +159,6 @@ protected virtual void AfterImageApply(Image<TPixel> destination)
/// <param name="disposing">Whether to dispose managed and unmanaged objects.</param>
protected virtual void Dispose(bool disposing)
{
if (!this.isDisposed)
{
this.isDisposed = true;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Processing.Processors
internal abstract class ImageProcessor<TPixel> : IImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private bool isDisposed;

/// <summary>
/// Initializes a new instance of the <see cref="ImageProcessor{TPixel}"/> class.
/// </summary>
Expand Down Expand Up @@ -97,6 +95,8 @@ public void Apply(ImageFrame<TPixel> source)
/// <inheritdoc/>
public virtual void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
Expand Down Expand Up @@ -142,10 +142,6 @@ protected virtual void AfterImageApply()
/// <param name="disposing">Whether to dispose managed and unmanaged objects.</param>
protected virtual void Dispose(bool disposing)
{
if (!this.isDisposed)
{
this.isDisposed = true;
}
}
}
}