mirror of https://github.com/SixLabors/ImageSharp
3 changed files with 145 additions and 99 deletions
@ -0,0 +1,114 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.IO; |
||||
|
|
||||
|
using SixLabors.ImageSharp.Formats; |
||||
|
using SixLabors.ImageSharp.Formats.Tiff; |
||||
|
using SixLabors.ImageSharp.Formats.Tiff.Constants; |
||||
|
using SixLabors.ImageSharp.Metadata.Profiles.Exif; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
||||
|
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
||||
|
{ |
||||
|
[Trait("Format", "Tiff")] |
||||
|
public abstract class TiffEncoderBaseTester |
||||
|
{ |
||||
|
private static readonly IImageDecoder ReferenceDecoder = new MagickReferenceDecoder(); |
||||
|
|
||||
|
protected static void TestStripLength<TPixel>( |
||||
|
TestImageProvider<TPixel> provider, |
||||
|
TiffPhotometricInterpretation photometricInterpretation, |
||||
|
TiffCompression compression, |
||||
|
bool useExactComparer = true, |
||||
|
float compareTolerance = 0.01f) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
// arrange
|
||||
|
var tiffEncoder = new TiffEncoder() { PhotometricInterpretation = photometricInterpretation, Compression = compression }; |
||||
|
using Image<TPixel> input = provider.GetImage(); |
||||
|
using var memStream = new MemoryStream(); |
||||
|
TiffFrameMetadata inputMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata(); |
||||
|
TiffCompression inputCompression = inputMeta.Compression ?? TiffCompression.None; |
||||
|
|
||||
|
// act
|
||||
|
input.Save(memStream, tiffEncoder); |
||||
|
|
||||
|
// assert
|
||||
|
memStream.Position = 0; |
||||
|
using var output = Image.Load<Rgba32>(memStream); |
||||
|
ExifProfile exifProfileOutput = output.Frames.RootFrame.Metadata.ExifProfile; |
||||
|
TiffFrameMetadata outputMeta = output.Frames.RootFrame.Metadata.GetTiffMetadata(); |
||||
|
ImageFrame<Rgba32> rootFrame = output.Frames.RootFrame; |
||||
|
|
||||
|
Number rowsPerStrip = exifProfileOutput.GetValue(ExifTag.RowsPerStrip) != null ? exifProfileOutput.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity; |
||||
|
Assert.True(output.Height > (int)rowsPerStrip); |
||||
|
Assert.True(exifProfileOutput.GetValue(ExifTag.StripOffsets)?.Value.Length > 1); |
||||
|
Number[] stripByteCounts = exifProfileOutput.GetValue(ExifTag.StripByteCounts)?.Value; |
||||
|
Assert.NotNull(stripByteCounts); |
||||
|
Assert.True(stripByteCounts.Length > 1); |
||||
|
Assert.NotNull(outputMeta.BitsPerPixel); |
||||
|
|
||||
|
foreach (Number sz in stripByteCounts) |
||||
|
{ |
||||
|
Assert.True((uint)sz <= TiffConstants.DefaultStripSize); |
||||
|
} |
||||
|
|
||||
|
// For uncompressed more accurate test.
|
||||
|
if (compression == TiffCompression.None) |
||||
|
{ |
||||
|
for (int i = 0; i < stripByteCounts.Length - 1; i++) |
||||
|
{ |
||||
|
// The difference must be less than one row.
|
||||
|
int stripBytes = (int)stripByteCounts[i]; |
||||
|
int widthBytes = ((int)outputMeta.BitsPerPixel + 7) / 8 * rootFrame.Width; |
||||
|
|
||||
|
Assert.True((TiffConstants.DefaultStripSize - stripBytes) < widthBytes); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Compare with reference.
|
||||
|
TestTiffEncoderCore( |
||||
|
provider, |
||||
|
inputMeta.BitsPerPixel, |
||||
|
photometricInterpretation, |
||||
|
inputCompression, |
||||
|
useExactComparer: useExactComparer, |
||||
|
compareTolerance: compareTolerance); |
||||
|
} |
||||
|
|
||||
|
protected static void TestTiffEncoderCore<TPixel>( |
||||
|
TestImageProvider<TPixel> provider, |
||||
|
TiffBitsPerPixel? bitsPerPixel, |
||||
|
TiffPhotometricInterpretation photometricInterpretation, |
||||
|
TiffCompression compression = TiffCompression.None, |
||||
|
TiffPredictor predictor = TiffPredictor.None, |
||||
|
bool useExactComparer = true, |
||||
|
float compareTolerance = 0.001f, |
||||
|
IImageDecoder imageDecoder = null) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
using Image<TPixel> image = provider.GetImage(); |
||||
|
var encoder = new TiffEncoder |
||||
|
{ |
||||
|
PhotometricInterpretation = photometricInterpretation, |
||||
|
BitsPerPixel = bitsPerPixel, |
||||
|
Compression = compression, |
||||
|
HorizontalPredictor = predictor |
||||
|
}; |
||||
|
|
||||
|
// Does DebugSave & load reference CompareToReferenceInput():
|
||||
|
image.VerifyEncoder( |
||||
|
provider, |
||||
|
"tiff", |
||||
|
bitsPerPixel, |
||||
|
encoder, |
||||
|
useExactComparer ? ImageComparer.Exact : ImageComparer.Tolerant(compareTolerance), |
||||
|
referenceDecoder: imageDecoder ?? ReferenceDecoder); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using SixLabors.ImageSharp.Formats.Tiff; |
||||
|
using SixLabors.ImageSharp.Formats.Tiff.Constants; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
using static SixLabors.ImageSharp.Tests.TestImages.Tiff; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
||||
|
{ |
||||
|
[Trait("Format", "Tiff")] |
||||
|
public class TiffEncoderMultiframeTests : TiffEncoderBaseTester |
||||
|
{ |
||||
|
[Theory] |
||||
|
[WithFile(MultiframeLzwPredictor, PixelTypes.Rgba32)] |
||||
|
public void TiffEncoder_EncodeMultiframe_Works<TPixel>(TestImageProvider<TPixel> provider) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb); |
||||
|
|
||||
|
[Theory] |
||||
|
[WithFile(MultiframeDeflateWithPreview, PixelTypes.Rgba32)] |
||||
|
[WithFile(MultiframeDifferentSize, PixelTypes.Rgba32)] |
||||
|
[WithFile(MultiframeDifferentVariants, PixelTypes.Rgba32)] |
||||
|
public void TiffEncoder_EncodeMultiframe_NotSupport<TPixel>(TestImageProvider<TPixel> provider) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> => Assert.Throws<NotSupportedException>(() => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb)); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue