diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 5791c6e92..19d6334e3 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Memory; @@ -73,9 +74,10 @@ namespace SixLabors.ImageSharp.Advanced /// /// The source image. /// The image visitor. + /// The token to monitor for cancellation requests. /// A representing the asynchronous operation. - public static Task AcceptVisitorAsync(this Image source, IImageVisitorAsync visitor) - => source.AcceptAsync(visitor); + public static Task AcceptVisitorAsync(this Image source, IImageVisitorAsync visitor, CancellationToken cancellationToken) + => source.AcceptAsync(visitor, cancellationToken); /// /// Gets the configuration for the image. diff --git a/src/ImageSharp/Advanced/IImageVisitor.cs b/src/ImageSharp/Advanced/IImageVisitor.cs index fbfdafeb1..ccff18026 100644 --- a/src/ImageSharp/Advanced/IImageVisitor.cs +++ b/src/ImageSharp/Advanced/IImageVisitor.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.PixelFormats; @@ -31,9 +32,10 @@ namespace SixLabors.ImageSharp.Advanced /// Provides a pixel-specific implementation for a given operation. /// /// The image. + /// The token to monitor for cancellation requests. /// The pixel type. /// A representing the asynchronous operation. - Task VisitAsync(Image image) + Task VisitAsync(Image image, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel; } } diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoder.cs b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs index 08c9bde00..2f5c4b7cf 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoder.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -42,11 +43,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp } /// - public Task EncodeAsync(Image image, Stream stream) + public Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { var encoder = new BmpEncoderCore(this, image.GetMemoryAllocator()); - return encoder.EncodeAsync(image, stream); + return encoder.EncodeAsync(image, stream, cancellationToken); } } } diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index b3f64eea6..eb29c4405 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -5,6 +5,7 @@ using System; using System.Buffers; using System.IO; using System.Runtime.InteropServices; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Common.Helpers; @@ -19,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// /// Image encoder for writing an image to a stream as a Windows bitmap. /// - internal sealed class BmpEncoderCore + internal sealed class BmpEncoderCore : IImageEncoderInternals { /// /// The amount to pad each row by. @@ -97,32 +98,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// The pixel format. /// The to encode from. /// The to encode the image data to. - public async Task EncodeAsync(Image image, Stream stream) + /// The token to request cancellation. + public void Encode(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel - { - if (stream.CanSeek) - { - this.Encode(image, stream); - } - else - { - using (var ms = new MemoryStream()) - { - this.Encode(image, ms); - ms.Position = 0; - await ms.CopyToAsync(stream).ConfigureAwait(false); - } - } - } - - /// - /// Encodes the image to the specified stream from the . - /// - /// The pixel format. - /// The to encode from. - /// The to encode the image data to. - public void Encode(Image image, Stream stream) - where TPixel : unmanaged, IPixel { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Gif/GifEncoder.cs b/src/ImageSharp/Formats/Gif/GifEncoder.cs index 539ab0fb3..116ee3dae 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoder.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -41,11 +42,11 @@ namespace SixLabors.ImageSharp.Formats.Gif } /// - public Task EncodeAsync(Image image, Stream stream) + public Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { var encoder = new GifEncoderCore(image.GetConfiguration(), this); - return encoder.EncodeAsync(image, stream); + return encoder.EncodeAsync(image, stream, cancellationToken); } } } diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index 556ace203..070864e60 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -6,6 +6,7 @@ using System.Buffers; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; @@ -18,7 +19,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// /// Implements the GIF encoding protocol. /// - internal sealed class GifEncoderCore + internal sealed class GifEncoderCore : IImageEncoderInternals { /// /// Used for allocating memory during processing operations. @@ -75,25 +76,9 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The pixel format. /// The to encode from. /// The to encode the image data to. - public async Task EncodeAsync(Image image, Stream stream) + /// The token to request cancellation. + public void Encode(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel - { - using (var ms = new MemoryStream()) - { - this.Encode(image, ms); - ms.Position = 0; - await ms.CopyToAsync(stream).ConfigureAwait(false); - } - } - - /// - /// Encodes the image to the specified stream from the . - /// - /// The pixel format. - /// The to encode from. - /// The to encode the image data to. - public void Encode(Image image, Stream stream) - where TPixel : unmanaged, IPixel { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/IImageEncoder.cs b/src/ImageSharp/Formats/IImageEncoder.cs index 646e0ecc0..e5a1b1c83 100644 --- a/src/ImageSharp/Formats/IImageEncoder.cs +++ b/src/ImageSharp/Formats/IImageEncoder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.PixelFormats; @@ -27,8 +28,9 @@ namespace SixLabors.ImageSharp.Formats /// The pixel format. /// The to encode from. /// The to encode the image data to. + /// The token to monitor for cancellation requests. /// A representing the asynchronous operation. - Task EncodeAsync(Image image, Stream stream) + Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel; } } diff --git a/src/ImageSharp/Formats/IImageEncoderInternals.cs b/src/ImageSharp/Formats/IImageEncoderInternals.cs new file mode 100644 index 000000000..d44ac45f2 --- /dev/null +++ b/src/ImageSharp/Formats/IImageEncoderInternals.cs @@ -0,0 +1,25 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using System.Threading; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats +{ + /// + /// Abstraction for shared internals for ***DecoderCore implementations to be used with . + /// + internal interface IImageEncoderInternals + { + /// + /// Encodes the image. + /// + /// The image. + /// The stream. + /// The token to monitor for cancellation requests. + /// The pixel type. + void Encode(Image image, Stream stream, CancellationToken cancellationToken) + where TPixel : unmanaged, IPixel; + } +} diff --git a/src/ImageSharp/Formats/ImageEncoderUtilities.cs b/src/ImageSharp/Formats/ImageEncoderUtilities.cs new file mode 100644 index 000000000..29f0a14c3 --- /dev/null +++ b/src/ImageSharp/Formats/ImageEncoderUtilities.cs @@ -0,0 +1,43 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats +{ + internal static class ImageEncoderUtilities + { + public static async Task EncodeAsync( + this IImageEncoderInternals encoder, + Image image, + Stream stream, + CancellationToken cancellationToken) + where TPixel : unmanaged, IPixel + { + Configuration configuration = image.GetConfiguration(); + if (stream.CanSeek) + { + encoder.Encode(image, stream, cancellationToken); + } + else + { + using var ms = new MemoryStream(); + encoder.Encode(image, ms, cancellationToken); + ms.Position = 0; + await ms.CopyToAsync(stream, configuration.StreamProcessingBufferSize, cancellationToken) + .ConfigureAwait(false); + } + } + + public static void Encode( + this IImageEncoderInternals encoder, + Image image, + Stream stream) + where TPixel : unmanaged, IPixel + => encoder.Encode(image, stream, default); + } +} diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs index 08d793401..b549bd8a3 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.PixelFormats; @@ -43,26 +44,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// The pixel format. /// The to encode from. /// The to encode the image data to. + /// The token to monitor for cancellation requests. /// A representing the asynchronous operation. - public async Task EncodeAsync(Image image, Stream stream) + public Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { var encoder = new JpegEncoderCore(this); - - if (stream.CanSeek) - { - encoder.Encode(image, stream); - } - else - { - // this hack has to be be here because JpegEncoderCore is unsafe - using (var ms = new MemoryStream()) - { - encoder.Encode(image, ms); - ms.Position = 0; - await ms.CopyToAsync(stream).ConfigureAwait(false); - } - } + return encoder.EncodeAsync(image, stream, cancellationToken); } } } diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs index f755028db..acc639eb7 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs @@ -6,6 +6,7 @@ using System.Buffers.Binary; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Formats.Jpeg.Components; @@ -23,7 +24,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// Image encoder for writing an image to a stream as a jpeg. /// - internal sealed unsafe class JpegEncoderCore + internal sealed unsafe class JpegEncoderCore : IImageEncoderInternals { /// /// The number of quantization tables. @@ -194,8 +195,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// The pixel format. /// The image to write from. /// The stream to write to. - public void Encode(Image image, Stream stream) - where TPixel : unmanaged, IPixel + /// The token to request cancellation. + public void Encode(Image image, Stream stream, CancellationToken cancellationToken) + where TPixel : unmanaged, IPixel { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); diff --git a/src/ImageSharp/Formats/Png/PngEncoder.cs b/src/ImageSharp/Formats/Png/PngEncoder.cs index 61ea7c468..7e563596e 100644 --- a/src/ImageSharp/Formats/Png/PngEncoder.cs +++ b/src/ImageSharp/Formats/Png/PngEncoder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -71,13 +72,14 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The to encode from. /// The to encode the image data to. + /// The token to monitor for cancellation requests. /// A representing the asynchronous operation. - public async Task EncodeAsync(Image image, Stream stream) + public async Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { using (var encoder = new PngEncoderCore(image.GetMemoryAllocator(), image.GetConfiguration(), new PngEncoderOptions(this))) { - await encoder.EncodeAsync(image, stream).ConfigureAwait(false); + await encoder.EncodeAsync(image, stream, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index a39fdd91f..5cf11099c 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -7,6 +7,7 @@ using System.Buffers.Binary; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Png.Chunks; @@ -21,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// Performs the png encoding operation. /// - internal sealed class PngEncoderCore : IDisposable + internal sealed class PngEncoderCore : IImageEncoderInternals, IDisposable { /// /// The maximum block size, defaults at 64k for uncompressed blocks. @@ -127,31 +128,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The to encode from. /// The to encode the image data to. - public async Task EncodeAsync(Image image, Stream stream) - where TPixel : unmanaged, IPixel - { - if (stream.CanSeek) - { - this.Encode(image, stream); - } - else - { - using (var ms = new MemoryStream()) - { - this.Encode(image, ms); - ms.Position = 0; - await ms.CopyToAsync(stream).ConfigureAwait(false); - } - } - } - - /// - /// Encodes the image to the specified stream from the . - /// - /// The pixel format. - /// The to encode from. - /// The to encode the image data to. - public void Encode(Image image, Stream stream) + /// The token to request cancellation. + public void Encode(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { Guard.NotNull(image, nameof(image)); diff --git a/src/ImageSharp/Formats/Tga/TgaEncoder.cs b/src/ImageSharp/Formats/Tga/TgaEncoder.cs index c8f8fb1a5..529d951cd 100644 --- a/src/ImageSharp/Formats/Tga/TgaEncoder.cs +++ b/src/ImageSharp/Formats/Tga/TgaEncoder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -32,11 +33,11 @@ namespace SixLabors.ImageSharp.Formats.Tga } /// - public Task EncodeAsync(Image image, Stream stream) + public Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { var encoder = new TgaEncoderCore(this, image.GetMemoryAllocator()); - return encoder.EncodeAsync(image, stream); + return encoder.EncodeAsync(image, stream, cancellationToken); } } } diff --git a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs index d9e7c0e6b..d3a628531 100644 --- a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs @@ -5,6 +5,7 @@ using System; using System.Buffers.Binary; using System.IO; using System.Runtime.CompilerServices; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; @@ -16,7 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Tga /// /// Image encoder for writing an image to a stream as a truevision targa image. /// - internal sealed class TgaEncoderCore + internal sealed class TgaEncoderCore : IImageEncoderInternals { /// /// Used for allocating memory during processing operations. @@ -61,31 +62,8 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The pixel format. /// The to encode from. /// The to encode the image data to. - public async Task EncodeAsync(Image image, Stream stream) - where TPixel : unmanaged, IPixel - { - if (stream.CanSeek) - { - this.Encode(image, stream); - } - else - { - using (var ms = new MemoryStream()) - { - this.Encode(image, ms); - ms.Position = 0; - await ms.CopyToAsync(stream).ConfigureAwait(false); - } - } - } - - /// - /// Encodes the image to the specified stream from the . - /// - /// The pixel format. - /// The to encode from. - /// The to encode the image data to. - public void Encode(Image image, Stream stream) + /// The token to request cancellation. + public void Encode(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { Guard.NotNull(image, nameof(image)); diff --git a/src/ImageSharp/Image.cs b/src/ImageSharp/Image.cs index 605f5e0da..3560d9960 100644 --- a/src/ImageSharp/Image.cs +++ b/src/ImageSharp/Image.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats; @@ -106,12 +107,23 @@ namespace SixLabors.ImageSharp /// Thrown if the stream or encoder is null. /// A representing the asynchronous operation. public Task SaveAsync(Stream stream, IImageEncoder encoder) + => this.SaveAsync(stream, encoder, default); + + /// + /// Saves the image to the given stream using the given image encoder. + /// + /// The stream to save the image to. + /// The encoder to save the image with. + /// The token to monitor for cancellation requests. + /// Thrown if the stream or encoder is null. + /// A representing the asynchronous operation. + public Task SaveAsync(Stream stream, IImageEncoder encoder, CancellationToken cancellationToken) { Guard.NotNull(stream, nameof(stream)); Guard.NotNull(encoder, nameof(encoder)); this.EnsureNotDisposed(); - return this.AcceptVisitorAsync(new EncodeVisitor(encoder, stream)); + return this.AcceptVisitorAsync(new EncodeVisitor(encoder, stream), cancellationToken); } /// @@ -162,7 +174,8 @@ namespace SixLabors.ImageSharp /// with the pixel type of the image. /// /// The visitor. - internal abstract Task AcceptAsync(IImageVisitorAsync visitor); + /// The token to monitor for cancellation requests. + internal abstract Task AcceptAsync(IImageVisitorAsync visitor, CancellationToken cancellationToken); private class EncodeVisitor : IImageVisitor, IImageVisitorAsync { @@ -179,8 +192,8 @@ namespace SixLabors.ImageSharp public void Visit(Image image) where TPixel : unmanaged, IPixel => this.encoder.Encode(image, this.stream); - public Task VisitAsync(Image image) - where TPixel : unmanaged, IPixel => this.encoder.EncodeAsync(image, this.stream); + public Task VisitAsync(Image image, CancellationToken cancellationToken) + where TPixel : unmanaged, IPixel => this.encoder.EncodeAsync(image, this.stream, cancellationToken); } } } diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 9d3abc1e8..255193c8e 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats; @@ -290,11 +291,11 @@ namespace SixLabors.ImageSharp } /// - internal override Task AcceptAsync(IImageVisitorAsync visitor) + internal override Task AcceptAsync(IImageVisitorAsync visitor, CancellationToken cancellationToken) { this.EnsureNotDisposed(); - return visitor.VisitAsync(this); + return visitor.VisitAsync(this, cancellationToken); } /// diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs index e5b35ffd2..72de3fcc4 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs @@ -172,7 +172,6 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(ExpectedImageSize, info.Size()); } - [Fact] public async Task FromStreamAsync_CustomConfiguration() { diff --git a/tests/ImageSharp.Tests/TestFormat.cs b/tests/ImageSharp.Tests/TestFormat.cs index 5a380f783..7273a65f7 100644 --- a/tests/ImageSharp.Tests/TestFormat.cs +++ b/tests/ImageSharp.Tests/TestFormat.cs @@ -270,7 +270,7 @@ namespace SixLabors.ImageSharp.Tests // TODO record this happened so we can verify it. } - public Task EncodeAsync(Image image, Stream stream) + public Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { // TODO record this happened so we can verify it. diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs index 2aaf7bf80..4c28079c1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs @@ -3,6 +3,7 @@ using System.Drawing.Imaging; using System.IO; +using System.Threading; using System.Threading.Tasks; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; @@ -31,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs } } - public Task EncodeAsync(Image image, Stream stream) + public Task EncodeAsync(Image image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { using (System.Drawing.Bitmap sdBitmap = SystemDrawingBridge.To32bppArgbSystemDrawingBitmap(image))