diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs
new file mode 100644
index 0000000000..57a6eda5f3
--- /dev/null
+++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Formats.Tiff
+{
+ ///
+ /// Enumerates the available bits per pixel the tiff encoder supports.
+ ///
+ public enum TiffBitsPerPixel
+ {
+ ///
+ /// 8 bits per pixel. Each pixel consists of 1 byte.
+ ///
+ Pixel8 = 8,
+
+ ///
+ /// 24 bits per pixel. Each pixel consists of 3 bytes.
+ ///
+ Pixel24 = 24,
+ }
+}
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
index bbf361e0d6..08b00d5bac 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
@@ -33,6 +33,19 @@ namespace SixLabors.ImageSharp.Formats.Tiff
///
private readonly bool ignoreMetadata;
+ ///
+ /// The image metadata.
+ ///
+ private ImageMetadata metadata;
+
+ ///
+ /// The tiff specific metadata.
+ ///
+ private TiffMetadata tiffMetaData;
+
+ ///
+ /// The stream to decode from.
+ ///
private BufferedReadStream inputStream;
///
@@ -104,7 +117,9 @@ namespace SixLabors.ImageSharp.Formats.Tiff
framesMetadata.Add(frameMetadata);
}
- ImageMetadata metadata = framesMetadata.CreateMetadata(this.ignoreMetadata, tiffStream.ByteOrder);
+ this.metadata = framesMetadata.CreateMetadata(this.ignoreMetadata, tiffStream.ByteOrder);
+ this.tiffMetaData = this.metadata.GetTiffMetadata();
+ this.SetBitsPerPixel(framesMetadata);
// todo: tiff frames can have different sizes
{
@@ -119,11 +134,31 @@ namespace SixLabors.ImageSharp.Formats.Tiff
}
}
- var image = new Image(this.configuration, metadata, frames);
+ var image = new Image(this.configuration, this.metadata, frames);
return image;
}
+ private void SetBitsPerPixel(List framesMetadata)
+ {
+ TiffFrameMetadata firstMetaData = framesMetadata.First();
+ ushort[] bitsPerSample = firstMetaData.BitsPerSample;
+ var bitsPerPixel = 0;
+ foreach (var bps in bitsPerSample)
+ {
+ bitsPerPixel += bps;
+ }
+
+ if (bitsPerPixel == 24)
+ {
+ this.tiffMetaData.BitsPerPixel = TiffBitsPerPixel.Pixel24;
+ }
+ else if (bitsPerPixel == 8)
+ {
+ this.tiffMetaData.BitsPerPixel = TiffBitsPerPixel.Pixel8;
+ }
+ }
+
///
public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{
@@ -168,7 +203,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
private static TiffByteOrder ReadByteOrder(Stream stream)
{
- byte[] headerBytes = new byte[2];
+ var headerBytes = new byte[2];
stream.Read(headerBytes, 0, 2);
if (headerBytes[0] == TiffConstants.ByteOrderLittleEndian && headerBytes[1] == TiffConstants.ByteOrderLittleEndian)
{
@@ -187,26 +222,26 @@ namespace SixLabors.ImageSharp.Formats.Tiff
///
/// The pixel format.
/// The IFD tags.
- /// The frame metadata.
+ /// The frame metadata.
///
/// The tiff frame.
///
- private ImageFrame DecodeFrame(IExifValue[] tags, out TiffFrameMetadata metadata)
+ private ImageFrame DecodeFrame(IExifValue[] tags, out TiffFrameMetadata frameMetaData)
where TPixel : unmanaged, IPixel
{
var coreMetadata = new ImageFrameMetadata();
- metadata = coreMetadata.GetTiffMetadata();
- metadata.Tags = tags;
+ frameMetaData = coreMetadata.GetTiffMetadata();
+ frameMetaData.Tags = tags;
- this.VerifyAndParseOptions(metadata);
+ this.VerifyAndParseOptions(frameMetaData);
- int width = (int)metadata.Width;
- int height = (int)metadata.Height;
+ int width = (int)frameMetaData.Width;
+ int height = (int)frameMetaData.Height;
var frame = new ImageFrame(this.configuration, width, height, coreMetadata);
- int rowsPerStrip = (int)metadata.RowsPerStrip;
- uint[] stripOffsets = metadata.StripOffsets;
- uint[] stripByteCounts = metadata.StripByteCounts;
+ int rowsPerStrip = (int)frameMetaData.RowsPerStrip;
+ uint[] stripOffsets = frameMetaData.StripOffsets;
+ uint[] stripByteCounts = frameMetaData.StripByteCounts;
if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar)
{
diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
index 250fb23895..10d22b25b8 100644
--- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
@@ -5,8 +5,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
+
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.PixelFormats;
@@ -32,6 +34,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
///
private Configuration configuration;
+ ///
+ /// The color depth, in number of bits per pixel.
+ ///
+ private TiffBitsPerPixel? bitsPerPixel;
+
///
/// Initializes a new instance of the class.
///
@@ -66,9 +73,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
Guard.NotNull(stream, nameof(stream));
this.configuration = image.GetConfiguration();
+ ImageMetadata metadata = image.Metadata;
+ TiffMetadata tiffMetadata = metadata.GetTiffMetadata();
+ this.bitsPerPixel ??= tiffMetadata.BitsPerPixel;
- // TODO: bits per pixel hardcoded to 24 for the start.
- short bpp = 24;
+ short bpp = (short)this.bitsPerPixel;
int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);
this.padding = bytesPerLine - (int)(image.Width * (bpp / 8F));
diff --git a/src/ImageSharp/Formats/Tiff/TiffMetadata.cs b/src/ImageSharp/Formats/Tiff/TiffMetadata.cs
index ae25480ed6..fd1d84ef38 100644
--- a/src/ImageSharp/Formats/Tiff/TiffMetadata.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffMetadata.cs
@@ -1,9 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
-using System.Collections;
-using System.Collections.Generic;
-
namespace SixLabors.ImageSharp.Formats.Tiff
{
///
@@ -26,6 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
this.ByteOrder = other.ByteOrder;
this.XmpProfile = other.XmpProfile;
+ this.BitsPerPixel = other.BitsPerPixel;
}
///
@@ -33,6 +31,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
///
public TiffByteOrder ByteOrder { get; set; }
+ ///
+ /// Gets or sets the number of bits per pixel.
+ ///
+ public TiffBitsPerPixel BitsPerPixel { get; set; } = TiffBitsPerPixel.Pixel24;
+
///
/// Gets or sets the XMP profile.
///