mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
14 KiB
318 lines
14 KiB
// Copyright (c) Six Labors.
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
using SixLabors.ImageSharp.Formats.Experimental.Tiff;
|
|
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
|
|
using SixLabors.ImageSharp.Metadata;
|
|
using SixLabors.ImageSharp.PixelFormats;
|
|
|
|
using Xunit;
|
|
|
|
using static SixLabors.ImageSharp.Tests.TestImages.Tiff;
|
|
|
|
namespace SixLabors.ImageSharp.Tests.Formats.Tiff
|
|
{
|
|
[Trait("Format", "Tiff")]
|
|
public class TiffMetadataTests
|
|
{
|
|
public TiffMetadataTests()
|
|
{
|
|
Configuration.Default.ImageFormatsManager.AddImageFormat(TiffFormat.Instance);
|
|
Configuration.Default.ImageFormatsManager.AddImageFormatDetector(new TiffImageFormatDetector());
|
|
Configuration.Default.ImageFormatsManager.SetDecoder(TiffFormat.Instance, new TiffDecoder());
|
|
Configuration.Default.ImageFormatsManager.SetEncoder(TiffFormat.Instance, new TiffEncoder());
|
|
}
|
|
|
|
[Fact]
|
|
public void CloneIsDeep()
|
|
{
|
|
var meta = new TiffMetadata
|
|
{
|
|
Compression = TiffCompression.Deflate,
|
|
BitsPerPixel = TiffBitsPerPixel.Pixel8,
|
|
ByteOrder = ByteOrder.BigEndian,
|
|
XmpProfile = new byte[3]
|
|
};
|
|
|
|
var clone = (TiffMetadata)meta.DeepClone();
|
|
|
|
clone.Compression = TiffCompression.None;
|
|
clone.BitsPerPixel = TiffBitsPerPixel.Pixel24;
|
|
clone.ByteOrder = ByteOrder.LittleEndian;
|
|
clone.XmpProfile = new byte[1];
|
|
|
|
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));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(Calliphora_BiColorUncompressed, TiffBitsPerPixel.Pixel1)]
|
|
[InlineData(GrayscaleUncompressed, TiffBitsPerPixel.Pixel8)]
|
|
[InlineData(RgbUncompressed, TiffBitsPerPixel.Pixel24)]
|
|
public void Identify_DetectsCorrectBitPerPixel(string imagePath, TiffBitsPerPixel expectedBitsPerPixel)
|
|
{
|
|
var testFile = TestFile.Create(imagePath);
|
|
using var stream = new MemoryStream(testFile.Bytes, false);
|
|
|
|
IImageInfo imageInfo = Image.Identify(stream);
|
|
|
|
Assert.NotNull(imageInfo);
|
|
TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata();
|
|
Assert.NotNull(tiffMetadata);
|
|
Assert.Equal(expectedBitsPerPixel, tiffMetadata.BitsPerPixel);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(GrayscaleUncompressed, TiffCompression.None)]
|
|
[InlineData(RgbDeflate, TiffCompression.Deflate)]
|
|
[InlineData(SmallRgbLzw, TiffCompression.Lzw)]
|
|
[InlineData(Calliphora_Fax3Compressed, TiffCompression.CcittGroup3Fax)]
|
|
[InlineData(Calliphora_Fax4Compressed, TiffCompression.CcittGroup4Fax)]
|
|
[InlineData(Calliphora_HuffmanCompressed, TiffCompression.Ccitt1D)]
|
|
[InlineData(Calliphora_RgbPackbits, TiffCompression.PackBits)]
|
|
public void Identify_DetectsCorrectCompression(string imagePath, TiffCompression expectedCompression)
|
|
{
|
|
var testFile = TestFile.Create(imagePath);
|
|
using var stream = new MemoryStream(testFile.Bytes, false);
|
|
|
|
IImageInfo imageInfo = Image.Identify(stream);
|
|
|
|
Assert.NotNull(imageInfo);
|
|
TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata();
|
|
Assert.NotNull(tiffMetadata);
|
|
Assert.Equal(expectedCompression, tiffMetadata.Compression);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(GrayscaleUncompressed, ByteOrder.BigEndian)]
|
|
[InlineData(LittleEndianByteOrder, ByteOrder.LittleEndian)]
|
|
public void Identify_DetectsCorrectByteOrder(string imagePath, ByteOrder expectedByteOrder)
|
|
{
|
|
var testFile = TestFile.Create(imagePath);
|
|
using var stream = new MemoryStream(testFile.Bytes, false);
|
|
|
|
IImageInfo imageInfo = Image.Identify(stream);
|
|
|
|
Assert.NotNull(imageInfo);
|
|
TiffMetadata tiffMetadata = imageInfo.Metadata.GetTiffMetadata();
|
|
Assert.NotNull(tiffMetadata);
|
|
Assert.Equal(expectedByteOrder, tiffMetadata.ByteOrder);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(SampleMetadata, PixelTypes.Rgba32, false)]
|
|
[WithFile(SampleMetadata, PixelTypes.Rgba32, true)]
|
|
public void MetadataProfiles<TPixel>(TestImageProvider<TPixel> provider, bool ignoreMetadata)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using (Image<TPixel> image = provider.GetImage(new TiffDecoder() { IgnoreMetadata = ignoreMetadata }))
|
|
{
|
|
TiffMetadata meta = image.Metadata.GetTiffMetadata();
|
|
Assert.NotNull(meta);
|
|
if (ignoreMetadata)
|
|
{
|
|
Assert.Null(meta.XmpProfile);
|
|
}
|
|
else
|
|
{
|
|
Assert.NotNull(meta.XmpProfile);
|
|
Assert.Equal(2599, meta.XmpProfile.Length);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(SampleMetadata, PixelTypes.Rgba32)]
|
|
public void BaselineTags<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using (Image<TPixel> image = provider.GetImage(new TiffDecoder()))
|
|
{
|
|
TiffMetadata meta = image.Metadata.GetTiffMetadata();
|
|
|
|
Assert.NotNull(meta);
|
|
Assert.Equal(ByteOrder.LittleEndian, meta.ByteOrder);
|
|
Assert.Equal(PixelResolutionUnit.PixelsPerInch, image.Metadata.ResolutionUnits);
|
|
Assert.Equal(10, image.Metadata.HorizontalResolution);
|
|
Assert.Equal(10, image.Metadata.VerticalResolution);
|
|
|
|
TiffFrameMetadata frame = image.Frames.RootFrame.Metadata.GetTiffMetadata();
|
|
Assert.Equal(32u, frame.Width);
|
|
Assert.Equal(32u, frame.Height);
|
|
Assert.Equal(new ushort[] { 4 }, frame.BitsPerSample);
|
|
Assert.Equal(TiffCompression.Lzw, frame.Compression);
|
|
Assert.Equal(TiffPhotometricInterpretation.PaletteColor, frame.PhotometricInterpretation);
|
|
Assert.Equal("This is Название", frame.ImageDescription);
|
|
Assert.Equal("This is Изготовитель камеры", frame.Make);
|
|
Assert.Equal("This is Модель камеры", frame.Model);
|
|
Assert.Equal(new uint[] { 8 }, frame.StripOffsets);
|
|
Assert.Equal(1, frame.SamplesPerPixel);
|
|
Assert.Equal(32u, frame.RowsPerStrip);
|
|
Assert.Equal(new uint[] { 297 }, frame.StripByteCounts);
|
|
Assert.Equal(10, frame.HorizontalResolution);
|
|
Assert.Equal(10, frame.VerticalResolution);
|
|
Assert.Equal(TiffPlanarConfiguration.Chunky, frame.PlanarConfiguration);
|
|
Assert.Equal(TiffResolutionUnit.Inch, frame.ResolutionUnit);
|
|
Assert.Equal("IrfanView", frame.Software);
|
|
Assert.Null(frame.DateTime);
|
|
Assert.Equal("This is author1;Author2", frame.Artist);
|
|
Assert.Null(frame.HostComputer);
|
|
Assert.Equal(48, frame.ColorMap.Length);
|
|
Assert.Equal(10537, frame.ColorMap[0]);
|
|
Assert.Equal(14392, frame.ColorMap[1]);
|
|
Assert.Equal(58596, frame.ColorMap[46]);
|
|
Assert.Equal(3855, frame.ColorMap[47]);
|
|
|
|
Assert.Null(frame.ExtraSamples);
|
|
Assert.Equal(TiffPredictor.None, frame.Predictor);
|
|
Assert.Null(frame.SampleFormat);
|
|
Assert.Equal("This is Авторские права", frame.Copyright);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(MultiframeDeflateWithPreview, PixelTypes.Rgba32)]
|
|
public void SubfileType<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using (Image<TPixel> image = provider.GetImage(new TiffDecoder()))
|
|
{
|
|
TiffMetadata meta = image.Metadata.GetTiffMetadata();
|
|
Assert.NotNull(meta);
|
|
|
|
Assert.Equal(2, image.Frames.Count);
|
|
|
|
TiffFrameMetadata frame0 = image.Frames[0].Metadata.GetTiffMetadata();
|
|
Assert.Equal(TiffNewSubfileType.FullImage, frame0.NewSubfileType);
|
|
Assert.Null(frame0.SubfileType);
|
|
Assert.Equal(255u, frame0.Width);
|
|
Assert.Equal(255u, frame0.Height);
|
|
|
|
TiffFrameMetadata frame1 = image.Frames[1].Metadata.GetTiffMetadata();
|
|
Assert.Equal(TiffNewSubfileType.Preview, frame1.NewSubfileType);
|
|
Assert.Equal(TiffSubfileType.Preview, frame1.SubfileType);
|
|
Assert.Equal(255u, frame1.Width);
|
|
Assert.Equal(255u, frame1.Height);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(SampleMetadata, PixelTypes.Rgba32, true)]
|
|
[WithFile(SampleMetadata, PixelTypes.Rgba32, false)]
|
|
public void Tiff_PreserveMetadata<TPixel>(TestImageProvider<TPixel> provider, bool preserveMetadata)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(new TiffDecoder() { IgnoreMetadata = false });
|
|
|
|
ImageMetadata coreMeta = image.Metadata;
|
|
TiffMetadata tiffMeta = image.Metadata.GetTiffMetadata();
|
|
TiffFrameMetadata frameMeta = image.Frames.RootFrame.Metadata.GetTiffMetadata();
|
|
|
|
var tiffEncoder = new TiffEncoder() { PreserveMetadata = preserveMetadata };
|
|
using var ms = new MemoryStream();
|
|
|
|
// act
|
|
image.Save(ms, tiffEncoder);
|
|
|
|
// assert
|
|
ms.Position = 0;
|
|
using var output = Image.Load<Rgba32>(ms);
|
|
|
|
ImageMetadata coreMetaOut = output.Metadata;
|
|
TiffMetadata tiffMetaOut = output.Metadata.GetTiffMetadata();
|
|
TiffFrameMetadata frameMetaOut = output.Frames.RootFrame.Metadata.GetTiffMetadata();
|
|
|
|
Assert.Equal(coreMeta.HorizontalResolution, coreMetaOut.HorizontalResolution);
|
|
Assert.Equal(coreMeta.VerticalResolution, coreMetaOut.VerticalResolution);
|
|
Assert.Equal(coreMeta.ResolutionUnits, coreMetaOut.ResolutionUnits);
|
|
|
|
Assert.Equal(frameMeta.Width, frameMetaOut.Width);
|
|
Assert.Equal(frameMeta.Height, frameMetaOut.Height);
|
|
Assert.Equal(frameMeta.ResolutionUnit, frameMetaOut.ResolutionUnit);
|
|
Assert.Equal(frameMeta.HorizontalResolution, frameMetaOut.HorizontalResolution);
|
|
Assert.Equal(frameMeta.VerticalResolution, frameMetaOut.VerticalResolution);
|
|
|
|
Assert.Equal("IrfanView", frameMeta.Software);
|
|
Assert.Equal("This is Название", frameMeta.ImageDescription);
|
|
Assert.Equal("This is Изготовитель камеры", frameMeta.Make);
|
|
Assert.Equal("This is Авторские права", frameMeta.Copyright);
|
|
|
|
if (preserveMetadata)
|
|
{
|
|
Assert.Equal("ImageSharp", frameMetaOut.Software);
|
|
|
|
Assert.Equal(frameMeta.ImageDescription, frameMetaOut.ImageDescription);
|
|
Assert.Equal(frameMeta.Make, frameMetaOut.Make);
|
|
Assert.Equal(frameMeta.Copyright, frameMetaOut.Copyright);
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal("ImageSharp", frameMetaOut.Software);
|
|
|
|
Assert.Null(frameMetaOut.ImageDescription);
|
|
Assert.Null(frameMetaOut.Make);
|
|
Assert.Null(frameMetaOut.Copyright);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void Tiff_CreateMetadata(bool preserveMetadata)
|
|
{
|
|
var tiffEncoder = new TiffEncoder { Mode = TiffEncodingMode.Default, Compression = TiffEncoderCompression.Deflate, PreserveMetadata = preserveMetadata };
|
|
|
|
int w = 10;
|
|
int h = 20;
|
|
using Image input = new Image<Rgb24>(w, h);
|
|
ImageMetadata coreMeta = input.Metadata;
|
|
TiffMetadata tiffMeta = input.Metadata.GetTiffMetadata();
|
|
TiffFrameMetadata frameMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata();
|
|
|
|
coreMeta.ResolutionUnits = PixelResolutionUnit.PixelsPerInch;
|
|
coreMeta.HorizontalResolution = 45;
|
|
coreMeta.VerticalResolution = 54;
|
|
|
|
frameMeta.ImageDescription = "test ImageDescription";
|
|
frameMeta.DateTime = System.DateTime.Now.ToString();
|
|
|
|
using var ms = new MemoryStream();
|
|
input.Save(ms, tiffEncoder);
|
|
|
|
// assert
|
|
ms.Position = 0;
|
|
using var output = Image.Load<Rgba32>(ms);
|
|
TiffMetadata meta = output.Metadata.GetTiffMetadata();
|
|
|
|
ImageMetadata coreMetaOut = output.Metadata;
|
|
TiffMetadata tiffMetaOut = output.Metadata.GetTiffMetadata();
|
|
TiffFrameMetadata frameMetaOut = output.Frames.RootFrame.Metadata.GetTiffMetadata();
|
|
|
|
Assert.Equal(coreMeta.HorizontalResolution, coreMetaOut.HorizontalResolution);
|
|
Assert.Equal(coreMeta.VerticalResolution, coreMetaOut.VerticalResolution);
|
|
Assert.Equal(coreMeta.ResolutionUnits, coreMetaOut.ResolutionUnits);
|
|
|
|
Assert.Equal((uint)w, frameMetaOut.Width);
|
|
Assert.Equal((uint)h, frameMetaOut.Height);
|
|
Assert.Equal(frameMeta.ResolutionUnit, frameMetaOut.ResolutionUnit);
|
|
Assert.Equal(frameMeta.HorizontalResolution, frameMetaOut.HorizontalResolution);
|
|
Assert.Equal(frameMeta.VerticalResolution, frameMetaOut.VerticalResolution);
|
|
|
|
if (preserveMetadata)
|
|
{
|
|
Assert.Equal(frameMeta.ImageDescription, frameMetaOut.ImageDescription);
|
|
Assert.Equal(frameMeta.DateTime, frameMetaOut.DateTime);
|
|
}
|
|
else
|
|
{
|
|
Assert.Null(frameMetaOut.ImageDescription);
|
|
Assert.Null(frameMetaOut.DateTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|