Skip to content

Commit c40359f

Browse files
Merge pull request #2013 from SixLabors/bp/tiffonlyfirstframe
Tiff Decoder option to decode only first frame
2 parents 739aa39 + 5b2413a commit c40359f

File tree

8 files changed

+42
-4
lines changed

8 files changed

+42
-4
lines changed

src/ImageSharp/Formats/Gif/GifDecoder.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using SixLabors.ImageSharp.IO;
8-
using SixLabors.ImageSharp.Memory;
98
using SixLabors.ImageSharp.Metadata;
109
using SixLabors.ImageSharp.PixelFormats;
1110

src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using SixLabors.ImageSharp.Metadata;
5+
46
namespace SixLabors.ImageSharp.Formats.Tiff
57
{
68
/// <summary>
@@ -12,5 +14,10 @@ internal interface ITiffDecoderOptions
1214
/// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
1315
/// </summary>
1416
bool IgnoreMetadata { get; }
17+
18+
/// <summary>
19+
/// Gets the decoding mode for multi-frame images.
20+
/// </summary>
21+
FrameDecodingMode DecodingMode { get; }
1522
}
1623
}

src/ImageSharp/Formats/Tiff/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
## Implementation Status
2727

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

3131
### Deviations from the TIFF spec (to be fixed)

src/ImageSharp/Formats/Tiff/TiffDecoder.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Threading;
66
using System.Threading.Tasks;
7+
using SixLabors.ImageSharp.Metadata;
78
using SixLabors.ImageSharp.PixelFormats;
89

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

22+
/// <summary>
23+
/// Gets or sets the decoding mode for multi-frame images.
24+
/// </summary>
25+
public FrameDecodingMode DecodingMode { get; set; }
26+
2127
/// <inheritdoc/>
2228
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
2329
where TPixel : unmanaged, IPixel<TPixel>

src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
using SixLabors.ImageSharp.Memory;
1414
using SixLabors.ImageSharp.Metadata;
1515
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
16-
using SixLabors.ImageSharp.Metadata.Profiles.Xmp;
1716
using SixLabors.ImageSharp.PixelFormats;
1817

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

35+
/// <summary>
36+
/// Gets the decoding mode for multi-frame images
37+
/// </summary>
38+
private FrameDecodingMode decodingMode;
39+
3640
/// <summary>
3741
/// The stream to decode from.
3842
/// </summary>
@@ -59,6 +63,7 @@ public TiffDecoderCore(Configuration configuration, ITiffDecoderOptions options)
5963

6064
this.Configuration = configuration ?? Configuration.Default;
6165
this.ignoreMetadata = options.IgnoreMetadata;
66+
this.decodingMode = options.DecodingMode;
6267
this.memoryAllocator = this.Configuration.MemoryAllocator;
6368
}
6469

@@ -160,11 +165,16 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
160165
cancellationToken.ThrowIfCancellationRequested();
161166
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, cancellationToken);
162167
frames.Add(frame);
168+
169+
if (this.decodingMode is FrameDecodingMode.First)
170+
{
171+
break;
172+
}
163173
}
164174

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

167-
// TODO: Tiff frames can have different sizes
177+
// TODO: Tiff frames can have different sizes.
168178
ImageFrame<TPixel> root = frames[0];
169179
this.Dimensions = root.Size();
170180
foreach (ImageFrame<TPixel> frame in frames)

tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// ReSharper disable InconsistentNaming
55
using System;
66
using System.IO;
7+
using SixLabors.ImageSharp.Formats.Tiff;
78
using SixLabors.ImageSharp.Metadata;
89
using SixLabors.ImageSharp.PixelFormats;
910
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
@@ -365,6 +366,17 @@ public void TiffDecoder_CanDecode_Compressed_LowerOrderBitsFirst<TPixel>(TestIma
365366
public void TiffDecoder_CanDecode_PackBitsCompressed<TPixel>(TestImageProvider<TPixel> provider)
366367
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
367368

369+
[Theory]
370+
[WithFile(MultiFrameMipMap, PixelTypes.Rgba32)]
371+
public void CanDecodeJustOneFrame<TPixel>(TestImageProvider<TPixel> provider)
372+
where TPixel : unmanaged, IPixel<TPixel>
373+
{
374+
using (Image<TPixel> image = provider.GetImage(new TiffDecoder() { DecodingMode = FrameDecodingMode.First }))
375+
{
376+
Assert.Equal(1, image.Frames.Count);
377+
}
378+
}
379+
368380
[Theory]
369381
[WithFile(RgbJpegCompressed, PixelTypes.Rgba32)]
370382
[WithFile(RgbWithStripsJpegCompressed, PixelTypes.Rgba32)]

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ public static class Tiff
874874
public const string MultiframeDeflateWithPreview = "Tiff/multipage_deflate_withPreview.tiff";
875875
public const string MultiframeDifferentSize = "Tiff/multipage_differentSize.tiff";
876876
public const string MultiframeDifferentVariants = "Tiff/multipage_differentVariants.tiff";
877+
public const string MultiFrameMipMap = "Tiff/SKC1H3.tiff";
877878

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:938bbf1c0f8bdbea0c632bb8d51c1150f757f88b3779d7fa18c296a3a3f61e9b
3+
size 13720193

0 commit comments

Comments
 (0)