Browse Source

Add PhotometricInterpretation to the tiff metadata

pull/1570/head
Brian Popow 5 years ago
parent
commit
572f616ae3
  1. 2
      src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs
  2. 4
      src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs
  3. 5
      src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
  4. 10
      src/ImageSharp/Formats/Tiff/TiffMetadata.cs
  5. 1
      tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
  6. 27
      tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs

2
src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs

@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
DeflateCompressionLevel CompressionLevel { get; }
/// <summary>
/// Gets the encoding mode to use. RGB, RGB with color palette or gray.
/// Gets the encoding mode to use. Possible options are RGB, RGB with a color palette, gray or BiColor.
/// If no mode is specified in the options, RGB will be used.
/// </summary>
TiffEncodingMode Mode { get; }

4
src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs

@ -2,10 +2,9 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -43,6 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
tiffMetadata.ByteOrder = byteOrder;
tiffMetadata.BitsPerPixel = GetBitsPerPixel(rootFrameMetadata);
tiffMetadata.Compression = rootFrameMetadata.Compression;
tiffMetadata.PhotometricInterpretation = rootFrameMetadata.PhotometricInterpretation;
if (!ignoreMetadata)
{

5
src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

@ -70,10 +70,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
public TiffEncoderCore(ITiffEncoderOptions options, MemoryAllocator memoryAllocator)
{
this.memoryAllocator = memoryAllocator;
this.CompressionType = options.Compression;
this.Mode = options.Mode;
this.quantizer = options.Quantizer ?? KnownQuantizers.Octree;
this.UseHorizontalPredictor = options.UseHorizontalPredictor;
this.CompressionType = options.Compression;
this.compressionLevel = options.CompressionLevel;
this.maxStripBytes = options.MaxStripBytes;
}
@ -271,8 +271,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
this.Mode = TiffEncodingMode.BiColor;
break;
case TiffBitsPerPixel.Pixel8:
// todo: can gray or palette
this.Mode = TiffEncodingMode.Gray;
this.Mode = tiffMetadata.PhotometricInterpretation != TiffPhotometricInterpretation.PaletteColor ? TiffEncodingMode.Gray : TiffEncodingMode.Rgb;
break;
default:
this.Mode = TiffEncodingMode.Rgb;

10
src/ImageSharp/Formats/Tiff/TiffMetadata.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
@ -24,9 +25,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
private TiffMetadata(TiffMetadata other)
{
this.ByteOrder = other.ByteOrder;
this.XmpProfile = other.XmpProfile;
this.BitsPerPixel = other.BitsPerPixel;
this.Compression = other.Compression;
this.PhotometricInterpretation = other.PhotometricInterpretation;
this.XmpProfile = other.XmpProfile != null ? new byte[other.XmpProfile.Length] : null;
other.XmpProfile?.AsSpan().CopyTo(this.XmpProfile.AsSpan());
}
/// <summary>
@ -44,6 +47,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public TiffCompression Compression { get; internal set; } = TiffCompression.None;
/// <summary>
/// Gets the photometric interpretation which indicates how the pixels are to be interpreted, e.g. if the image is bicolor, RGB, color paletted etc.
/// </summary>
public TiffPhotometricInterpretation PhotometricInterpretation { get; internal set; }
/// <summary>
/// Gets or sets the XMP profile.
/// For internal use only. ImageSharp not support XMP profile.

1
tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs

@ -73,6 +73,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
[WithFile(Calliphora_BiColorUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Pixel1)]
[WithFile(GrayscaleUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Pixel8)]
[WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Pixel24)]
[WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Pixel24)]
public void TiffEncoder_PreserveBitsPerPixel<TPixel>(TestImageProvider<TPixel> provider, TiffBitsPerPixel expectedBitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel>
{

27
tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs

@ -36,12 +36,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
[Fact]
public void CloneIsDeep()
{
byte[] xmpData = { 1, 1, 1 };
var meta = new TiffMetadata
{
Compression = TiffCompression.Deflate,
BitsPerPixel = TiffBitsPerPixel.Pixel8,
ByteOrder = ByteOrder.BigEndian,
XmpProfile = new byte[3]
XmpProfile = xmpData,
PhotometricInterpretation = TiffPhotometricInterpretation.Rgb
};
var clone = (TiffMetadata)meta.DeepClone();
@ -49,12 +51,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
clone.Compression = TiffCompression.None;
clone.BitsPerPixel = TiffBitsPerPixel.Pixel24;
clone.ByteOrder = ByteOrder.LittleEndian;
clone.XmpProfile = new byte[1];
clone.PhotometricInterpretation = TiffPhotometricInterpretation.YCbCr;
Assert.False(meta.Compression == clone.Compression);
Assert.False(meta.BitsPerPixel == clone.BitsPerPixel);
Assert.False(meta.ByteOrder == clone.ByteOrder);
Assert.False(meta.XmpProfile.SequenceEqual(clone.XmpProfile));
Assert.False(meta.PhotometricInterpretation == clone.PhotometricInterpretation);
Assert.False(meta.XmpProfile.Equals(clone.XmpProfile));
Assert.True(meta.XmpProfile.SequenceEqual(clone.XmpProfile));
}
[Theory]
@ -95,6 +99,23 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
Assert.Equal(expectedCompression, tiffMetadata.Compression);
}
[Theory]
[InlineData(Calliphora_RgbUncompressed, TiffPhotometricInterpretation.Rgb)]
[InlineData(Calliphora_BiColorUncompressed, TiffPhotometricInterpretation.BlackIsZero)]
[InlineData(Calliphora_PaletteUncompressed, TiffPhotometricInterpretation.PaletteColor)]
public void Identify_DetectsCorrectPhotometricInterpretation(string imagePath, TiffPhotometricInterpretation expectedPhotometricInterpretation)
{
var testFile = TestFile.Create(imagePath);
using var stream = new MemoryStream(testFile.Bytes, false);
IImageInfo imageInfo = Image.Identify(this.configuration, stream);
Assert.NotNull(imageInfo);
TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata();
Assert.NotNull(tiffMetadata);
Assert.Equal(expectedPhotometricInterpretation, tiffMetadata.PhotometricInterpretation);
}
[Theory]
[InlineData(GrayscaleUncompressed, ByteOrder.BigEndian)]
[InlineData(LittleEndianByteOrder, ByteOrder.LittleEndian)]

Loading…
Cancel
Save