diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
new file mode 100644
index 0000000000..8cceecbc18
--- /dev/null
+++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Runtime.InteropServices;
+using SixLabors.ImageSharp.Formats.Tiff.Constants;
+using SixLabors.ImageSharp.Formats.Webp;
+using SixLabors.ImageSharp.IO;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
+{
+ ///
+ /// Class to handle cases where TIFF image data is compressed as a webp stream.
+ ///
+ internal class WebpTiffCompression : TiffBaseDecompressor
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The memory allocator.
+ /// The width of the image.
+ /// The bits per pixel.
+ /// The predictor.
+ public WebpTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffPredictor predictor = TiffPredictor.None)
+ : base(memoryAllocator, width, bitsPerPixel, predictor)
+ {
+ }
+
+ ///
+ protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer)
+ {
+ using var image = Image.Load(stream, new WebpDecoder());
+ CopyImageBytesToBuffer(buffer, image.Frames.RootFrame.PixelBuffer);
+ }
+
+ private static void CopyImageBytesToBuffer(Span buffer, Buffer2D pixelBuffer)
+ {
+ int offset = 0;
+ for (int y = 0; y < pixelBuffer.Height; y++)
+ {
+ Span pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y);
+ Span rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan);
+ rgbBytes.CopyTo(buffer.Slice(offset));
+ offset += rgbBytes.Length;
+ }
+ }
+
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs
index d8843c1078..77d77f98f5 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs
@@ -47,5 +47,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression
/// The image data is compressed as a JPEG stream.
///
Jpeg = 7,
+
+ ///
+ /// The image data is compressed as a WEBP stream.
+ ///
+ Webp = 8,
}
}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
index a7e2e276bd..0e526f3d93 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
@@ -60,6 +60,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");
return new JpegTiffCompression(configuration, allocator, width, bitsPerPixel, jpegTables, photometricInterpretation);
+ case TiffDecoderCompressionType.Webp:
+ DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");
+ return new WebpTiffCompression(allocator, width, bitsPerPixel);
+
default:
throw TiffThrowHelper.NotSupportedDecompressor(nameof(method));
}
diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffCompression.cs
index 765f2c237d..0591c24dd5 100644
--- a/src/ImageSharp/Formats/Tiff/Constants/TiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Constants/TiffCompression.cs
@@ -103,5 +103,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Constants
/// if this is chosen.
///
OldDeflate = 32946,
+
+ ///
+ /// Pixel data is compressed with webp encoder.
+ ///
+ /// Note: The TIFF encoder does not support this compression and will default to use no compression instead,
+ /// if this is chosen.
+ ///
+ Webp = 50001,
}
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
index 6d99fed3e1..1d52b95ac6 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
@@ -470,6 +470,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff
break;
}
+ case TiffCompression.Webp:
+ {
+ options.CompressionType = TiffDecoderCompressionType.Webp;
+ break;
+ }
+
default:
{
TiffThrowHelper.ThrowNotSupported($"The specified TIFF compression format '{compression}' is not supported");