diff --git a/src/ImageSharp/Formats/ImageExtensions.Save.cs b/src/ImageSharp/Formats/ImageExtensions.Save.cs
index 7084f1542..07c6b37b8 100644
--- a/src/ImageSharp/Formats/ImageExtensions.Save.cs
+++ b/src/ImageSharp/Formats/ImageExtensions.Save.cs
@@ -6,13 +6,14 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Formats.Experimental.Tiff;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Tga;
-using SixLabors.ImageSharp.Formats.Experimental.Tiff;
+using SixLabors.ImageSharp.Formats.Tiff;
namespace SixLabors.ImageSharp
{
@@ -537,7 +538,7 @@ namespace SixLabors.ImageSharp
cancellationToken);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -545,7 +546,7 @@ namespace SixLabors.ImageSharp
public static void SaveAsTiff(this Image source, string path) => SaveAsTiff(source, path, null);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -554,7 +555,7 @@ namespace SixLabors.ImageSharp
public static Task SaveAsTiffAsync(this Image source, string path) => SaveAsTiffAsync(source, path, null);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -565,7 +566,7 @@ namespace SixLabors.ImageSharp
=> SaveAsTiffAsync(source, path, null, cancellationToken);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -577,7 +578,7 @@ namespace SixLabors.ImageSharp
encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TiffFormat.Instance));
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -592,7 +593,7 @@ namespace SixLabors.ImageSharp
cancellationToken);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The stream to save the image to.
@@ -601,7 +602,7 @@ namespace SixLabors.ImageSharp
=> SaveAsTiff(source, stream, null);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The stream to save the image to.
@@ -612,7 +613,7 @@ namespace SixLabors.ImageSharp
=> SaveAsTiffAsync(source, stream, null, cancellationToken);
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The stream to save the image to.
@@ -625,7 +626,7 @@ namespace SixLabors.ImageSharp
encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(TiffFormat.Instance));
///
- /// Saves the image to the given stream with the Tiff format.
+ /// EXPERIMENTAL! Saves the image to the given stream with the Tiff format.
///
/// The image this method extends.
/// The stream to save the image to.
diff --git a/src/ImageSharp/Formats/ImageExtensions.Save.tt b/src/ImageSharp/Formats/ImageExtensions.Save.tt
index af9531225..8954c19e5 100644
--- a/src/ImageSharp/Formats/ImageExtensions.Save.tt
+++ b/src/ImageSharp/Formats/ImageExtensions.Save.tt
@@ -9,6 +9,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Formats.Experimental.Tiff;
<#
var formats = new []{
@@ -39,9 +40,10 @@ namespace SixLabors.ImageSharp
<#
foreach (string fmt in formats)
{
+ string experimentalString = fmt == "Tiff" || fmt == "Webp" ? @"EXPERIMENTAL! " : "";
#>
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -49,7 +51,7 @@ namespace SixLabors.ImageSharp
public static void SaveAs<#= fmt #>(this Image source, string path) => SaveAs<#= fmt #>(source, path, null);
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -58,7 +60,7 @@ namespace SixLabors.ImageSharp
public static Task SaveAs<#= fmt #>Async(this Image source, string path) => SaveAs<#= fmt #>Async(source, path, null);
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -69,7 +71,7 @@ namespace SixLabors.ImageSharp
=> SaveAs<#= fmt #>Async(source, path, null, cancellationToken);
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -81,7 +83,7 @@ namespace SixLabors.ImageSharp
encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(<#= fmt #>Format.Instance));
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The file path to save the image to.
@@ -96,7 +98,7 @@ namespace SixLabors.ImageSharp
cancellationToken);
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The stream to save the image to.
@@ -105,7 +107,7 @@ namespace SixLabors.ImageSharp
=> SaveAs<#= fmt #>(source, stream, null);
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The stream to save the image to.
@@ -116,7 +118,7 @@ namespace SixLabors.ImageSharp
=> SaveAs<#= fmt #>Async(source, stream, null, cancellationToken);
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The stream to save the image to.
@@ -129,7 +131,7 @@ namespace SixLabors.ImageSharp
encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(<#= fmt #>Format.Instance));
///
- /// Saves the image to the given stream with the <#= fmt #> format.
+ /// <#= experimentalString #>Saves the image to the given stream with the <#= fmt #> format.
///
/// The image this method extends.
/// The stream to save the image to.
diff --git a/src/ImageSharp/Formats/Tiff/ImageExtensions.cs b/src/ImageSharp/Formats/Tiff/ImageExtensions.cs
deleted file mode 100644
index 2583dbd01..000000000
--- a/src/ImageSharp/Formats/Tiff/ImageExtensions.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.IO;
-using SixLabors.ImageSharp.Formats.Experimental.Tiff;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Saves the image to the given stream with the tiff format.
- ///
- /// The pixel format.
- /// The image this method extends.
- /// The stream to save the image to.
- /// Thrown if the stream is null.
- ///
- /// The .
- ///
- public static Image SaveAsTiff(this Image source, Stream stream)
- where TPixel : unmanaged, IPixel
- {
- return SaveAsTiff(source, stream, null);
- }
-
- ///
- /// Saves the image to the given stream with the tiff format.
- ///
- /// The pixel format.
- /// The image this method extends.
- /// The stream to save the image to.
- /// The options for the encoder.
- /// Thrown if the stream is null.
- ///
- /// The .
- ///
- public static Image SaveAsTiff(this Image source, Stream stream, TiffEncoder encoder)
- where TPixel : unmanaged, IPixel
- {
- encoder = encoder ?? new TiffEncoder();
- encoder.Encode(source, stream);
-
- return source;
- }
- }
-}
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
index ec67c815e..455d71aae 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs
@@ -4,7 +4,6 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs
index ec4a87664..e81a7f4c4 100644
--- a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs
+++ b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs
@@ -23,6 +23,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
while (count > 0)
{
+ int bytesLeftInBuffer = buffer.Length - offset;
+ if (bytesLeftInBuffer < count)
+ {
+ TiffThrowHelper.ThrowImageFormatException("Error reading data from the stream. The provided buffer was too small.");
+ }
+
int bytesRead = stream.Read(buffer, offset, count);
if (bytesRead == 0)
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs
new file mode 100644
index 000000000..45a86185e
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/Tiff/ImageExtensionsTest.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.IO;
+using System.Threading.Tasks;
+using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.Formats.Experimental.Tiff;
+using SixLabors.ImageSharp.PixelFormats;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Formats.Tiff
+{
+ [Trait("Format", "Tiff")]
+ public class ImageExtensionsTest
+ {
+ [Fact]
+ public void SaveAsTiff_Path()
+ {
+ string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest));
+ string file = Path.Combine(dir, "SaveAsTiff_Path.tiff");
+
+ using (var image = new Image(10, 10))
+ {
+ image.SaveAsTiff(file);
+ }
+
+ using (Image.Load(file, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public async Task SaveAsTiffAsync_Path()
+ {
+ string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest));
+ string file = Path.Combine(dir, "SaveAsTiffAsync_Path.tiff");
+
+ using (var image = new Image(10, 10))
+ {
+ await image.SaveAsTiffAsync(file);
+ }
+
+ using (Image.Load(file, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public void SaveAsTiff_Path_Encoder()
+ {
+ string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions));
+ string file = Path.Combine(dir, "SaveAsTiff_Path_Encoder.tiff");
+
+ using (var image = new Image(10, 10))
+ {
+ image.SaveAsTiff(file, new TiffEncoder());
+ }
+
+ using (Image.Load(file, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public async Task SaveAsTiffAsync_Path_Encoder()
+ {
+ string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions));
+ string file = Path.Combine(dir, "SaveAsTiffAsync_Path_Encoder.tiff");
+
+ using (var image = new Image(10, 10))
+ {
+ await image.SaveAsTiffAsync(file, new TiffEncoder());
+ }
+
+ using (Image.Load(file, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public void SaveAsTiff_Stream()
+ {
+ using var memoryStream = new MemoryStream();
+
+ using (var image = new Image(10, 10))
+ {
+ image.SaveAsTiff(memoryStream);
+ }
+
+ memoryStream.Position = 0;
+
+ using (Image.Load(memoryStream, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public async Task SaveAsTiffAsync_StreamAsync()
+ {
+ using var memoryStream = new MemoryStream();
+
+ using (var image = new Image(10, 10))
+ {
+ await image.SaveAsTiffAsync(memoryStream);
+ }
+
+ memoryStream.Position = 0;
+
+ using (Image.Load(memoryStream, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public void SaveAsTiff_Stream_Encoder()
+ {
+ using var memoryStream = new MemoryStream();
+
+ using (var image = new Image(10, 10))
+ {
+ image.SaveAsTiff(memoryStream, new TiffEncoder());
+ }
+
+ memoryStream.Position = 0;
+
+ using (Image.Load(memoryStream, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+
+ [Fact]
+ public async Task SaveAsTiffAsync_Stream_Encoder()
+ {
+ using var memoryStream = new MemoryStream();
+
+ using (var image = new Image(10, 10))
+ {
+ await image.SaveAsTiffAsync(memoryStream, new TiffEncoder());
+ }
+
+ memoryStream.Position = 0;
+
+ using (Image.Load(memoryStream, out IImageFormat mime))
+ {
+ Assert.Equal("image/tiff", mime.DefaultMimeType);
+ }
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
index f66012b08..16f174720 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
@@ -6,7 +6,6 @@ using System;
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff;
-using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;