Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 0 additions & 1 deletion src/ImageSharp/Formats/Gif/GifDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Threading;
using System.Threading.Tasks;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;

Expand Down
7 changes: 7 additions & 0 deletions src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.

using SixLabors.ImageSharp.Metadata;

namespace SixLabors.ImageSharp.Formats.Tiff
{
/// <summary>
Expand All @@ -12,5 +14,10 @@ internal interface ITiffDecoderOptions
/// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
/// </summary>
bool IgnoreMetadata { get; }

/// <summary>
/// Gets the decoding mode for multi-frame images.
/// </summary>
FrameDecodingMode DecodingMode { get; }
}
}
2 changes: 1 addition & 1 deletion src/ImageSharp/Formats/Tiff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

## Implementation Status

- The Decoder currently only supports a single frame per image.
- The Decoder currently only supports decoding multiframe images, which have the same dimensions.
- Some compression formats are not yet supported. See the list below.

### Deviations from the TIFF spec (to be fixed)
Expand Down
6 changes: 6 additions & 0 deletions src/ImageSharp/Formats/Tiff/TiffDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;

namespace SixLabors.ImageSharp.Formats.Tiff
Expand All @@ -18,6 +19,11 @@ public class TiffDecoder : IImageDecoder, ITiffDecoderOptions, IImageInfoDetecto
/// </summary>
public bool IgnoreMetadata { get; set; }

/// <summary>
/// Gets or sets the decoding mode for multi-frame images.
/// </summary>
public FrameDecodingMode DecodingMode { get; set; }

/// <inheritdoc/>
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
Expand Down
14 changes: 12 additions & 2 deletions src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.Metadata.Profiles.Xmp;
using SixLabors.ImageSharp.PixelFormats;

namespace SixLabors.ImageSharp.Formats.Tiff
Expand All @@ -33,6 +32,11 @@ internal class TiffDecoderCore : IImageDecoderInternals
/// </summary>
private readonly bool ignoreMetadata;

/// <summary>
/// Gets the decoding mode for multi-frame images
/// </summary>
private FrameDecodingMode decodingMode;

/// <summary>
/// The stream to decode from.
/// </summary>
Expand All @@ -59,6 +63,7 @@ public TiffDecoderCore(Configuration configuration, ITiffDecoderOptions options)

this.Configuration = configuration ?? Configuration.Default;
this.ignoreMetadata = options.IgnoreMetadata;
this.decodingMode = options.DecodingMode;
this.memoryAllocator = this.Configuration.MemoryAllocator;
}

Expand Down Expand Up @@ -160,11 +165,16 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
cancellationToken.ThrowIfCancellationRequested();
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, cancellationToken);
frames.Add(frame);

if (this.decodingMode is FrameDecodingMode.First)
{
break;
}
}

ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, this.ignoreMetadata, reader.ByteOrder, reader.IsBigTiff);

// TODO: Tiff frames can have different sizes
// TODO: Tiff frames can have different sizes.
ImageFrame<TPixel> root = frames[0];
this.Dimensions = root.Size();
foreach (ImageFrame<TPixel> frame in frames)
Expand Down
12 changes: 12 additions & 0 deletions tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// ReSharper disable InconsistentNaming
using System;
using System.IO;
using SixLabors.ImageSharp.Formats.Tiff;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
Expand Down Expand Up @@ -365,6 +366,17 @@ public void TiffDecoder_CanDecode_Compressed_LowerOrderBitsFirst<TPixel>(TestIma
public void TiffDecoder_CanDecode_PackBitsCompressed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);

[Theory]
[WithFile(MultiFrameMipMap, PixelTypes.Rgba32)]
public void CanDecodeJustOneFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new TiffDecoder() { DecodingMode = FrameDecodingMode.First }))
{
Assert.Equal(1, image.Frames.Count);
}
}

[Theory]
[WithFile(RgbJpegCompressed, PixelTypes.Rgba32)]
[WithFile(RgbWithStripsJpegCompressed, PixelTypes.Rgba32)]
Expand Down
1 change: 1 addition & 0 deletions tests/ImageSharp.Tests/TestImages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ public static class Tiff
public const string MultiframeDeflateWithPreview = "Tiff/multipage_deflate_withPreview.tiff";
public const string MultiframeDifferentSize = "Tiff/multipage_differentSize.tiff";
public const string MultiframeDifferentVariants = "Tiff/multipage_differentVariants.tiff";
public const string MultiFrameMipMap = "Tiff/SKC1H3.tiff";

public const string LittleEndianByteOrder = "Tiff/little_endian.tiff";

Expand Down
3 changes: 3 additions & 0 deletions tests/Images/Input/Tiff/SKC1H3.tiff
Git LFS file not shown