mirror of https://github.com/SixLabors/ImageSharp
9 changed files with 164 additions and 197 deletions
@ -0,0 +1,16 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Tiff |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Indicates which tiff compression is used.
|
||||
|
/// </summary>
|
||||
|
public enum TiffEncoderCompression |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// No compression is used.
|
||||
|
/// </summary>
|
||||
|
None, |
||||
|
} |
||||
|
} |
||||
@ -1,172 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.IO; |
|
||||
using System.Threading.Tasks; |
|
||||
using SixLabors.ImageSharp.Formats; |
|
||||
using SixLabors.ImageSharp.Formats.Tiff; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using Xunit; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|
||||
{ |
|
||||
[Trait("Category", "Tiff.BlackBox.Encoder")] |
|
||||
[Trait("Category", "Tiff")] |
|
||||
public class ImageExtensionsTest |
|
||||
{ |
|
||||
[Theory] |
|
||||
[WithFile(TestImages.Tiff.RgbUncompressed, PixelTypes.Rgba32)] |
|
||||
public void ThrowsSavingNotImplemented<TPixel>(TestImageProvider<TPixel> provider) |
|
||||
where TPixel : unmanaged, IPixel<TPixel> |
|
||||
{ |
|
||||
Assert.Throws<NotImplementedException>(() => |
|
||||
{ |
|
||||
string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); |
|
||||
string file = Path.Combine(dir, "SaveAsTiff_Path.tiff"); |
|
||||
using var image = provider.GetImage(new TiffDecoder()); |
|
||||
image.SaveAsTiff(file); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public void SaveAsTiff_Path() |
|
||||
{ |
|
||||
string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); |
|
||||
string file = Path.Combine(dir, "SaveAsTiff_Path.tiff"); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
image.SaveAsTiff(file); |
|
||||
} |
|
||||
|
|
||||
using (Image.Load(file, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public async Task SaveAsTiffAsync_Path() |
|
||||
{ |
|
||||
string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest)); |
|
||||
string file = Path.Combine(dir, "SaveAsTiffAsync_Path.tiff"); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
await image.SaveAsTiffAsync(file); |
|
||||
} |
|
||||
|
|
||||
using (Image.Load(file, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public void SaveAsTiff_Path_Encoder() |
|
||||
{ |
|
||||
string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); |
|
||||
string file = Path.Combine(dir, "SaveAsTiff_Path_Encoder.tiff"); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
image.SaveAsTiff(file, new TiffEncoder()); |
|
||||
} |
|
||||
|
|
||||
using (Image.Load(file, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public async Task SaveAsTiffAsync_Path_Encoder() |
|
||||
{ |
|
||||
string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); |
|
||||
string file = Path.Combine(dir, "SaveAsTiffAsync_Path_Encoder.tiff"); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
await image.SaveAsTiffAsync(file, new TiffEncoder()); |
|
||||
} |
|
||||
|
|
||||
using (Image.Load(file, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public void SaveAsTiff_Stream() |
|
||||
{ |
|
||||
using var memoryStream = new MemoryStream(); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
image.SaveAsTiff(memoryStream); |
|
||||
} |
|
||||
|
|
||||
memoryStream.Position = 0; |
|
||||
|
|
||||
using (Image.Load(memoryStream, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public async Task SaveAsTiffAsync_StreamAsync() |
|
||||
{ |
|
||||
using var memoryStream = new MemoryStream(); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
await image.SaveAsTiffAsync(memoryStream); |
|
||||
} |
|
||||
|
|
||||
memoryStream.Position = 0; |
|
||||
|
|
||||
using (Image.Load(memoryStream, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public void SaveAsTiff_Stream_Encoder() |
|
||||
{ |
|
||||
using var memoryStream = new MemoryStream(); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
image.SaveAsTiff(memoryStream, new TiffEncoder()); |
|
||||
} |
|
||||
|
|
||||
memoryStream.Position = 0; |
|
||||
|
|
||||
using (Image.Load(memoryStream, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[Fact(Skip = "Saving not implemented")] |
|
||||
public async Task SaveAsTiffAsync_Stream_Encoder() |
|
||||
{ |
|
||||
using var memoryStream = new MemoryStream(); |
|
||||
|
|
||||
using (var image = new Image<Rgba32>(10, 10)) |
|
||||
{ |
|
||||
await image.SaveAsTiffAsync(memoryStream, new TiffEncoder()); |
|
||||
} |
|
||||
|
|
||||
memoryStream.Position = 0; |
|
||||
|
|
||||
using (Image.Load(memoryStream, out IImageFormat mime)) |
|
||||
{ |
|
||||
Assert.Equal("image/tiff", mime.DefaultMimeType); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,70 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.IO; |
||||
|
|
||||
|
using SixLabors.ImageSharp.Formats.Tiff; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
||||
|
{ |
||||
|
public class TiffEncoderTests |
||||
|
{ |
||||
|
public static readonly TheoryData<string, TiffBitsPerPixel> TiffBitsPerPixelFiles = |
||||
|
new TheoryData<string, TiffBitsPerPixel> |
||||
|
{ |
||||
|
{ TestImages.Tiff.GrayscaleUncompressed, TiffBitsPerPixel.Pixel8 }, |
||||
|
{ TestImages.Tiff.RgbUncompressed, TiffBitsPerPixel.Pixel24 }, |
||||
|
}; |
||||
|
|
||||
|
[Theory] |
||||
|
[MemberData(nameof(TiffBitsPerPixelFiles))] |
||||
|
public void TiffEncoder_PreserveBitsPerPixel(string imagePath, TiffBitsPerPixel expectedBitsPerPixel) |
||||
|
{ |
||||
|
// arrange
|
||||
|
var tiffEncoder = new TiffEncoder(); |
||||
|
var testFile = TestFile.Create(imagePath); |
||||
|
using Image<Rgba32> input = testFile.CreateRgba32Image(); |
||||
|
using var memStream = new MemoryStream(); |
||||
|
|
||||
|
// act
|
||||
|
input.Save(memStream, tiffEncoder); |
||||
|
|
||||
|
// assert
|
||||
|
memStream.Position = 0; |
||||
|
using var output = Image.Load<Rgba32>(memStream); |
||||
|
TiffMetadata meta = output.Metadata.GetTiffMetadata(); |
||||
|
Assert.Equal(expectedBitsPerPixel, meta.BitsPerPixel); |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[WithFile(TestImages.Tiff.RgbUncompressed, PixelTypes.Rgba32)] |
||||
|
public void TiffEncoder_EncodeRgb_Works<TPixel>(TestImageProvider<TPixel> provider, TiffBitsPerPixel bitsPerPixel = TiffBitsPerPixel.Pixel24) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, bitsPerPixel); |
||||
|
|
||||
|
[Theory] |
||||
|
[WithFile(TestImages.Tiff.RgbUncompressed, PixelTypes.Rgba32)] |
||||
|
public void TiffEncoder_EncodeGray_Works<TPixel>(TestImageProvider<TPixel> provider, TiffBitsPerPixel bitsPerPixel = TiffBitsPerPixel.Pixel8) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, bitsPerPixel); |
||||
|
|
||||
|
private static void TestTiffEncoderCore<TPixel>( |
||||
|
TestImageProvider<TPixel> provider, |
||||
|
TiffBitsPerPixel bitsPerPixel, |
||||
|
TiffEncoderCompression compression = TiffEncoderCompression.None, |
||||
|
bool useExactComparer = true, |
||||
|
float compareTolerance = 0.01f) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
using Image<TPixel> image = provider.GetImage(); |
||||
|
var encoder = new TiffEncoder { BitsPerPixel = bitsPerPixel, Compression = compression }; |
||||
|
|
||||
|
using var memStream = new MemoryStream(); |
||||
|
image.Save(memStream, encoder); |
||||
|
memStream.Position = 0; |
||||
|
using var encodedImage = (Image<TPixel>)Image.Load(memStream); |
||||
|
TiffTestUtils.CompareWithReferenceDecoder(provider, encodedImage, useExactComparer, compareTolerance); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.IO; |
||||
|
using ImageMagick; |
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
||||
|
{ |
||||
|
public class TiffTestUtils |
||||
|
{ |
||||
|
public static void CompareWithReferenceDecoder<TPixel>( |
||||
|
TestImageProvider<TPixel> provider, |
||||
|
Image<TPixel> image, |
||||
|
bool useExactComparer = true, |
||||
|
float compareTolerance = 0.01f) |
||||
|
where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel<TPixel> |
||||
|
{ |
||||
|
string path = TestImageProvider<TPixel>.GetFilePathOrNull(provider); |
||||
|
if (path == null) |
||||
|
{ |
||||
|
throw new InvalidOperationException("CompareToOriginal() works only with file providers!"); |
||||
|
} |
||||
|
|
||||
|
var testFile = TestFile.Create(path); |
||||
|
Image<Rgba32> magickImage = DecodeWithMagick<Rgba32>(Configuration.Default, new FileInfo(testFile.FullPath)); |
||||
|
if (useExactComparer) |
||||
|
{ |
||||
|
ImageComparer.Exact.VerifySimilarity(magickImage, image); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ImageComparer.Tolerant(compareTolerance).VerifySimilarity(magickImage, image); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static Image<TPixel> DecodeWithMagick<TPixel>(Configuration configuration, FileInfo fileInfo) |
||||
|
where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel<TPixel> |
||||
|
{ |
||||
|
using var magickImage = new MagickImage(fileInfo); |
||||
|
magickImage.AutoOrient(); |
||||
|
var result = new Image<TPixel>(configuration, magickImage.Width, magickImage.Height); |
||||
|
|
||||
|
Assert.True(result.TryGetSinglePixelSpan(out Span<TPixel> resultPixels)); |
||||
|
|
||||
|
using IUnsafePixelCollection<ushort> pixels = magickImage.GetPixelsUnsafe(); |
||||
|
byte[] data = pixels.ToByteArray(PixelMapping.RGBA); |
||||
|
|
||||
|
PixelOperations<TPixel>.Instance.FromRgba32Bytes( |
||||
|
configuration, |
||||
|
data, |
||||
|
resultPixels, |
||||
|
resultPixels.Length); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue