mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
59 changed files with 318 additions and 5127 deletions
@ -1,176 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils |
|||
{ |
|||
/// <summary>
|
|||
/// Utility class to encapsulate a sub-portion of another <see cref="Stream"/>.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Note that disposing of the <see cref="SubStream"/> does not dispose the underlying
|
|||
/// <see cref="Stream"/>.
|
|||
/// </remarks>
|
|||
internal class SubStream : Stream |
|||
{ |
|||
private Stream innerStream; |
|||
private long offset; |
|||
private long endOffset; |
|||
private long length; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SubStream"/> class.
|
|||
/// </summary>
|
|||
/// <param name="innerStream">The underlying <see cref="Stream"/> to wrap.</param>
|
|||
/// <param name="length">The length of the sub-stream.</param>
|
|||
/// <remarks>
|
|||
/// Note that calling the sub-stream with start from the current offset of the
|
|||
/// underlying <see cref="Stream"/>
|
|||
/// </remarks>
|
|||
public SubStream(Stream innerStream, long length) |
|||
{ |
|||
this.innerStream = innerStream; |
|||
this.offset = this.innerStream.Position; |
|||
this.endOffset = this.offset + length; |
|||
this.length = length; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SubStream"/> class.
|
|||
/// </summary>
|
|||
/// <param name="innerStream">The underlying <see cref="Stream"/> to wrap.</param>
|
|||
/// <param name="offset">The offset of the sub-stream within the underlying <see cref="Stream"/>.</param>
|
|||
/// <param name="length">The length of the sub-stream.</param>
|
|||
/// <remarks>
|
|||
/// Note that calling the constructor will immediately move the underlying
|
|||
/// <see cref="Stream"/> to the specified offset.
|
|||
/// </remarks>
|
|||
public SubStream(Stream innerStream, long offset, long length) |
|||
{ |
|||
this.innerStream = innerStream; |
|||
this.offset = offset; |
|||
this.endOffset = offset + length; |
|||
this.length = length; |
|||
|
|||
innerStream.Seek(offset, SeekOrigin.Begin); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool CanRead |
|||
{ |
|||
get |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool CanWrite |
|||
{ |
|||
get |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool CanSeek |
|||
{ |
|||
get |
|||
{ |
|||
return this.innerStream.CanSeek; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override long Length |
|||
{ |
|||
get |
|||
{ |
|||
return this.length; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override long Position |
|||
{ |
|||
get |
|||
{ |
|||
return this.innerStream.Position - this.offset; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.Seek(value, SeekOrigin.Begin); |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override void Flush() |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int Read(byte[] buffer, int offset, int count) |
|||
{ |
|||
long bytesRemaining = this.endOffset - this.innerStream.Position; |
|||
|
|||
if (bytesRemaining < count) |
|||
{ |
|||
count = (int)bytesRemaining; |
|||
} |
|||
|
|||
return this.innerStream.Read(buffer, offset, count); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int ReadByte() |
|||
{ |
|||
if (this.innerStream.Position < this.endOffset) |
|||
{ |
|||
return this.innerStream.ReadByte(); |
|||
} |
|||
else |
|||
{ |
|||
return -1; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override void Write(byte[] array, int offset, int count) |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override void WriteByte(byte value) |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override long Seek(long offset, SeekOrigin origin) |
|||
{ |
|||
switch (origin) |
|||
{ |
|||
case SeekOrigin.Current: |
|||
return this.innerStream.Seek(offset, SeekOrigin.Current) - this.offset; |
|||
case SeekOrigin.Begin: |
|||
return this.innerStream.Seek(this.offset + offset, SeekOrigin.Begin) - this.offset; |
|||
case SeekOrigin.End: |
|||
return this.innerStream.Seek(this.endOffset - offset, SeekOrigin.Begin) - this.offset; |
|||
default: |
|||
throw new ArgumentException("Invalid seek origin."); |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override void SetLength(long value) |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,352 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Tiff |
|||
{ |
|||
/// <summary>
|
|||
/// Utility class for generating TIFF IFD entries.
|
|||
/// </summary>
|
|||
internal static class TiffIfdEntryCreator |
|||
{ |
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Byte' from a unsigned integer.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedByte(this List<TiffIfdEntry> entries, ushort tag, uint value) |
|||
{ |
|||
TiffIfdEntryCreator.AddUnsignedByte(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Byte' from an array of unsigned integers.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedByte(this List<TiffIfdEntry> entries, ushort tag, uint[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
bytes[i] = (byte)value[i]; |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Byte, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Short' from a unsigned integer.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedShort(this List<TiffIfdEntry> entries, ushort tag, uint value) |
|||
{ |
|||
TiffIfdEntryCreator.AddUnsignedShort(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Short' from an array of unsigned integers.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedShort(this List<TiffIfdEntry> entries, ushort tag, uint[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfShort]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
ToBytes((ushort)value[i], bytes, i * TiffConstants.SizeOfShort); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Short, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Long' from a unsigned integer.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedLong(this List<TiffIfdEntry> entries, ushort tag, uint value) |
|||
{ |
|||
TiffIfdEntryCreator.AddUnsignedLong(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Long' from an array of unsigned integers.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedLong(this List<TiffIfdEntry> entries, ushort tag, uint[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfLong]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
ToBytes(value[i], bytes, i * TiffConstants.SizeOfLong); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Long, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SByte' from a signed integer.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedByte(this List<TiffIfdEntry> entries, ushort tag, int value) |
|||
{ |
|||
TiffIfdEntryCreator.AddSignedByte(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SByte' from an array of signed integers.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedByte(this List<TiffIfdEntry> entries, ushort tag, int[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
bytes[i] = (byte)((sbyte)value[i]); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.SByte, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SShort' from a signed integer.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedShort(this List<TiffIfdEntry> entries, ushort tag, int value) |
|||
{ |
|||
TiffIfdEntryCreator.AddSignedShort(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SShort' from an array of signed integers.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedShort(this List<TiffIfdEntry> entries, ushort tag, int[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfShort]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
ToBytes((short)value[i], bytes, i * TiffConstants.SizeOfShort); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.SShort, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SLong' from a signed integer.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedLong(this List<TiffIfdEntry> entries, ushort tag, int value) |
|||
{ |
|||
TiffIfdEntryCreator.AddSignedLong(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SLong' from an array of signed integers.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedLong(this List<TiffIfdEntry> entries, ushort tag, int[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfLong]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
ToBytes(value[i], bytes, i * TiffConstants.SizeOfLong); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.SLong, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Ascii' from a string.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddAscii(this List<TiffIfdEntry> entries, ushort tag, string value) |
|||
{ |
|||
byte[] bytes = Encoding.UTF8.GetBytes(value + "\0"); |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Ascii, (uint)bytes.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Rational' from a <see cref="Rational"/>.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedRational(this List<TiffIfdEntry> entries, ushort tag, Rational value) |
|||
{ |
|||
TiffIfdEntryCreator.AddUnsignedRational(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Rational' from an array of <see cref="Rational"/> values.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddUnsignedRational(this List<TiffIfdEntry> entries, ushort tag, Rational[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfRational]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
int offset = i * TiffConstants.SizeOfRational; |
|||
ToBytes(value[i].Numerator, bytes, offset); |
|||
ToBytes(value[i].Denominator, bytes, offset + TiffConstants.SizeOfLong); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Rational, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SRational' from a <see cref="SignedRational"/>.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedRational(this List<TiffIfdEntry> entries, ushort tag, SignedRational value) |
|||
{ |
|||
TiffIfdEntryCreator.AddSignedRational(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'SRational' from an array of <see cref="SignedRational"/> values.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddSignedRational(this List<TiffIfdEntry> entries, ushort tag, SignedRational[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfRational]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
int offset = i * TiffConstants.SizeOfRational; |
|||
ToBytes(value[i].Numerator, bytes, offset); |
|||
ToBytes(value[i].Denominator, bytes, offset + TiffConstants.SizeOfLong); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.SRational, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Float' from a floating-point value.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddFloat(this List<TiffIfdEntry> entries, ushort tag, float value) |
|||
{ |
|||
TiffIfdEntryCreator.AddFloat(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Float' from an array of floating-point values.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddFloat(this List<TiffIfdEntry> entries, ushort tag, float[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfFloat]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
byte[] itemBytes = BitConverter.GetBytes(value[i]); |
|||
Array.Copy(itemBytes, 0, bytes, i * TiffConstants.SizeOfFloat, TiffConstants.SizeOfFloat); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Float, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Double' from a floating-point value.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddDouble(this List<TiffIfdEntry> entries, ushort tag, double value) |
|||
{ |
|||
TiffIfdEntryCreator.AddDouble(entries, tag, new[] { value }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a new <see cref="TiffIfdEntry"/> of type 'Double' from an array of floating-point values.
|
|||
/// </summary>
|
|||
/// <param name="entries">The list of <see cref="TiffIfdEntry"/> to add the new entry to.</param>
|
|||
/// <param name="tag">The tag for the resulting entry.</param>
|
|||
/// <param name="value">The value for the resulting entry.</param>
|
|||
public static void AddDouble(this List<TiffIfdEntry> entries, ushort tag, double[] value) |
|||
{ |
|||
byte[] bytes = new byte[value.Length * TiffConstants.SizeOfDouble]; |
|||
|
|||
for (int i = 0; i < value.Length; i++) |
|||
{ |
|||
byte[] itemBytes = BitConverter.GetBytes(value[i]); |
|||
Array.Copy(itemBytes, 0, bytes, i * TiffConstants.SizeOfDouble, TiffConstants.SizeOfDouble); |
|||
} |
|||
|
|||
entries.Add(new TiffIfdEntry(tag, TiffType.Double, (uint)value.Length, bytes)); |
|||
} |
|||
|
|||
private static void ToBytes(ushort value, byte[] bytes, int offset) |
|||
{ |
|||
bytes[offset + 0] = (byte)value; |
|||
bytes[offset + 1] = (byte)(value >> 8); |
|||
} |
|||
|
|||
private static void ToBytes(uint value, byte[] bytes, int offset) |
|||
{ |
|||
bytes[offset + 0] = (byte)value; |
|||
bytes[offset + 1] = (byte)(value >> 8); |
|||
bytes[offset + 2] = (byte)(value >> 16); |
|||
bytes[offset + 3] = (byte)(value >> 24); |
|||
} |
|||
|
|||
private static void ToBytes(short value, byte[] bytes, int offset) |
|||
{ |
|||
bytes[offset + 0] = (byte)value; |
|||
bytes[offset + 1] = (byte)(value >> 8); |
|||
} |
|||
|
|||
private static void ToBytes(int value, byte[] bytes, int offset) |
|||
{ |
|||
bytes[offset + 0] = (byte)value; |
|||
bytes[offset + 1] = (byte)(value >> 8); |
|||
bytes[offset + 2] = (byte)(value >> 16); |
|||
bytes[offset + 3] = (byte)(value >> 24); |
|||
} |
|||
} |
|||
} |
|||
@ -1,51 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Tiff |
|||
{ |
|||
/// <summary>
|
|||
/// Defines constants for each of the supported TIFF metadata types.
|
|||
/// </summary>
|
|||
public static class TiffMetadataNames |
|||
{ |
|||
/// <summary>
|
|||
/// Person who created the image.
|
|||
/// </summary>
|
|||
public const string Artist = "Artist"; |
|||
|
|||
/// <summary>
|
|||
/// Copyright notice.
|
|||
/// </summary>
|
|||
public const string Copyright = "Copyright"; |
|||
|
|||
/// <summary>
|
|||
/// Date and time of image creation.
|
|||
/// </summary>
|
|||
public const string DateTime = "DateTime"; |
|||
|
|||
/// <summary>
|
|||
/// The computer and/or operating system in use at the time of image creation.
|
|||
/// </summary>
|
|||
public const string HostComputer = "HostComputer"; |
|||
|
|||
/// <summary>
|
|||
/// A string that describes the subject of the image.
|
|||
/// </summary>
|
|||
public const string ImageDescription = "ImageDescription"; |
|||
|
|||
/// <summary>
|
|||
/// The scanner/camera manufacturer.
|
|||
/// </summary>
|
|||
public const string Make = "Make"; |
|||
|
|||
/// <summary>
|
|||
/// The scanner/camera model name or number.
|
|||
/// </summary>
|
|||
public const string Model = "Model"; |
|||
|
|||
/// <summary>
|
|||
/// Name and version number of the software package(s) used to create the image.
|
|||
/// </summary>
|
|||
public const string Software = "Software"; |
|||
} |
|||
} |
|||
@ -1,716 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Tiff |
|||
{ |
|||
/// <summary>
|
|||
/// Constants representing tag IDs in the Tiff file-format.
|
|||
/// </summary>
|
|||
internal class TiffTags |
|||
{ |
|||
/// <summary>
|
|||
/// Artist (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Artist = 315; |
|||
|
|||
/// <summary>
|
|||
/// BitsPerSample (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int BitsPerSample = 258; |
|||
|
|||
/// <summary>
|
|||
/// CellLength (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int CellLength = 265; |
|||
|
|||
/// <summary>
|
|||
/// CellWidth (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int CellWidth = 264; |
|||
|
|||
/// <summary>
|
|||
/// ColorMap (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int ColorMap = 320; |
|||
|
|||
/// <summary>
|
|||
/// Compression (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Compression = 259; |
|||
|
|||
/// <summary>
|
|||
/// Copyright (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Copyright = 33432; |
|||
|
|||
/// <summary>
|
|||
/// DateTime (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int DateTime = 306; |
|||
|
|||
/// <summary>
|
|||
/// ExtraSamples (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int ExtraSamples = 338; |
|||
|
|||
/// <summary>
|
|||
/// FillOrder (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int FillOrder = 266; |
|||
|
|||
/// <summary>
|
|||
/// FreeByteCounts (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int FreeByteCounts = 289; |
|||
|
|||
/// <summary>
|
|||
/// FreeOffsets (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int FreeOffsets = 288; |
|||
|
|||
/// <summary>
|
|||
/// GrayResponseCurve (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int GrayResponseCurve = 291; |
|||
|
|||
/// <summary>
|
|||
/// GrayResponseUnit (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int GrayResponseUnit = 290; |
|||
|
|||
/// <summary>
|
|||
/// HostComputer (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int HostComputer = 316; |
|||
|
|||
/// <summary>
|
|||
/// ImageDescription (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int ImageDescription = 270; |
|||
|
|||
/// <summary>
|
|||
/// ImageLength (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int ImageLength = 257; |
|||
|
|||
/// <summary>
|
|||
/// ImageWidth (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int ImageWidth = 256; |
|||
|
|||
/// <summary>
|
|||
/// Make (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Make = 271; |
|||
|
|||
/// <summary>
|
|||
/// MaxSampleValue (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int MaxSampleValue = 281; |
|||
|
|||
/// <summary>
|
|||
/// MinSampleValue (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int MinSampleValue = 280; |
|||
|
|||
/// <summary>
|
|||
/// Model (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Model = 272; |
|||
|
|||
/// <summary>
|
|||
/// NewSubfileType (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int NewSubfileType = 254; |
|||
|
|||
/// <summary>
|
|||
/// Orientation (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Orientation = 274; |
|||
|
|||
/// <summary>
|
|||
/// PhotometricInterpretation (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int PhotometricInterpretation = 262; |
|||
|
|||
/// <summary>
|
|||
/// PlanarConfiguration (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int PlanarConfiguration = 284; |
|||
|
|||
/// <summary>
|
|||
/// ResolutionUnit (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int ResolutionUnit = 296; |
|||
|
|||
/// <summary>
|
|||
/// RowsPerStrip (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int RowsPerStrip = 278; |
|||
|
|||
/// <summary>
|
|||
/// SamplesPerPixel (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int SamplesPerPixel = 277; |
|||
|
|||
/// <summary>
|
|||
/// Software (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Software = 305; |
|||
|
|||
/// <summary>
|
|||
/// StripByteCounts (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int StripByteCounts = 279; |
|||
|
|||
/// <summary>
|
|||
/// StripOffsets (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int StripOffsets = 273; |
|||
|
|||
/// <summary>
|
|||
/// SubfileType (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int SubfileType = 255; |
|||
|
|||
/// <summary>
|
|||
/// Threshholding (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int Threshholding = 263; |
|||
|
|||
/// <summary>
|
|||
/// XResolution (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int XResolution = 282; |
|||
|
|||
/// <summary>
|
|||
/// YResolution (see Section 8: Baseline Fields).
|
|||
/// </summary>
|
|||
public const int YResolution = 283; |
|||
|
|||
/// <summary>
|
|||
/// T4Options (see Section 11: CCITT Bilevel Encodings).
|
|||
/// </summary>
|
|||
public const int T4Options = 292; |
|||
|
|||
/// <summary>
|
|||
/// T6Options (see Section 11: CCITT Bilevel Encodings).
|
|||
/// </summary>
|
|||
public const int T6Options = 293; |
|||
|
|||
/// <summary>
|
|||
/// DocumentName (see Section 12: Document Storage and Retrieval).
|
|||
/// </summary>
|
|||
public const int DocumentName = 269; |
|||
|
|||
/// <summary>
|
|||
/// PageName (see Section 12: Document Storage and Retrieval).
|
|||
/// </summary>
|
|||
public const int PageName = 285; |
|||
|
|||
/// <summary>
|
|||
/// PageNumber (see Section 12: Document Storage and Retrieval).
|
|||
/// </summary>
|
|||
public const int PageNumber = 297; |
|||
|
|||
/// <summary>
|
|||
/// XPosition (see Section 12: Document Storage and Retrieval).
|
|||
/// </summary>
|
|||
public const int XPosition = 286; |
|||
|
|||
/// <summary>
|
|||
/// YPosition (see Section 12: Document Storage and Retrieval).
|
|||
/// </summary>
|
|||
public const int YPosition = 287; |
|||
|
|||
/// <summary>
|
|||
/// Predictor (see Section 14: Differencing Predictor).
|
|||
/// </summary>
|
|||
public const int Predictor = 317; |
|||
|
|||
/// <summary>
|
|||
/// TileWidth (see Section 15: Tiled Images).
|
|||
/// </summary>
|
|||
public const int TileWidth = 322; |
|||
|
|||
/// <summary>
|
|||
/// TileLength (see Section 15: Tiled Images).
|
|||
/// </summary>
|
|||
public const int TileLength = 323; |
|||
|
|||
/// <summary>
|
|||
/// TileOffsets (see Section 15: Tiled Images).
|
|||
/// </summary>
|
|||
public const int TileOffsets = 324; |
|||
|
|||
/// <summary>
|
|||
/// TileByteCounts (see Section 15: Tiled Images).
|
|||
/// </summary>
|
|||
public const int TileByteCounts = 325; |
|||
|
|||
/// <summary>
|
|||
/// InkSet (see Section 16: CMYK Images).
|
|||
/// </summary>
|
|||
public const int InkSet = 332; |
|||
|
|||
/// <summary>
|
|||
/// NumberOfInks (see Section 16: CMYK Images).
|
|||
/// </summary>
|
|||
public const int NumberOfInks = 334; |
|||
|
|||
/// <summary>
|
|||
/// InkNames (see Section 16: CMYK Images).
|
|||
/// </summary>
|
|||
public const int InkNames = 333; |
|||
|
|||
/// <summary>
|
|||
/// DotRange (see Section 16: CMYK Images).
|
|||
/// </summary>
|
|||
public const int DotRange = 336; |
|||
|
|||
/// <summary>
|
|||
/// TargetPrinter (see Section 16: CMYK Images).
|
|||
/// </summary>
|
|||
public const int TargetPrinter = 337; |
|||
|
|||
/// <summary>
|
|||
/// HalftoneHints (see Section 17: Halftone Hints).
|
|||
/// </summary>
|
|||
public const int HalftoneHints = 321; |
|||
|
|||
/// <summary>
|
|||
/// SampleFormat (see Section 19: Data Sample Format).
|
|||
/// </summary>
|
|||
public const int SampleFormat = 339; |
|||
|
|||
/// <summary>
|
|||
/// SMinSampleValue (see Section 19: Data Sample Format).
|
|||
/// </summary>
|
|||
public const int SMinSampleValue = 340; |
|||
|
|||
/// <summary>
|
|||
/// SMaxSampleValue (see Section 19: Data Sample Format).
|
|||
/// </summary>
|
|||
public const int SMaxSampleValue = 341; |
|||
|
|||
/// <summary>
|
|||
/// WhitePoint (see Section 20: RGB Image Colorimetry).
|
|||
/// </summary>
|
|||
public const int WhitePoint = 318; |
|||
|
|||
/// <summary>
|
|||
/// PrimaryChromaticities (see Section 20: RGB Image Colorimetry).
|
|||
/// </summary>
|
|||
public const int PrimaryChromaticities = 319; |
|||
|
|||
/// <summary>
|
|||
/// TransferFunction (see Section 20: RGB Image Colorimetry).
|
|||
/// </summary>
|
|||
public const int TransferFunction = 301; |
|||
|
|||
/// <summary>
|
|||
/// TransferRange (see Section 20: RGB Image Colorimetry).
|
|||
/// </summary>
|
|||
public const int TransferRange = 342; |
|||
|
|||
/// <summary>
|
|||
/// ReferenceBlackWhite (see Section 20: RGB Image Colorimetry).
|
|||
/// </summary>
|
|||
public const int ReferenceBlackWhite = 532; |
|||
|
|||
/// <summary>
|
|||
/// YCbCrCoefficients (see Section 21: YCbCr Images).
|
|||
/// </summary>
|
|||
public const int YCbCrCoefficients = 529; |
|||
|
|||
/// <summary>
|
|||
/// YCbCrSubSampling (see Section 21: YCbCr Images).
|
|||
/// </summary>
|
|||
public const int YCbCrSubSampling = 530; |
|||
|
|||
/// <summary>
|
|||
/// YCbCrPositioning (see Section 21: YCbCr Images).
|
|||
/// </summary>
|
|||
public const int YCbCrPositioning = 531; |
|||
|
|||
/// <summary>
|
|||
/// JpegProc (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegProc = 512; |
|||
|
|||
/// <summary>
|
|||
/// JpegInterchangeFormat (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegInterchangeFormat = 513; |
|||
|
|||
/// <summary>
|
|||
/// JpegInterchangeFormatLength (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegInterchangeFormatLength = 514; |
|||
|
|||
/// <summary>
|
|||
/// JpegRestartInterval (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegRestartInterval = 515; |
|||
|
|||
/// <summary>
|
|||
/// JpegLosslessPredictors (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegLosslessPredictors = 517; |
|||
|
|||
/// <summary>
|
|||
/// JpegPointTransforms (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegPointTransforms = 518; |
|||
|
|||
/// <summary>
|
|||
/// JpegQTables (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegQTables = 519; |
|||
|
|||
/// <summary>
|
|||
/// JpegDCTables (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegDCTables = 520; |
|||
|
|||
/// <summary>
|
|||
/// JpegACTables (see Section 22: JPEG Compression).
|
|||
/// </summary>
|
|||
public const int JpegACTables = 521; |
|||
|
|||
/// <summary>
|
|||
/// SubIFDs (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int SubIFDs = 330; |
|||
|
|||
/// <summary>
|
|||
/// ClipPath (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int ClipPath = 343; |
|||
|
|||
/// <summary>
|
|||
/// XClipPathUnits (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int XClipPathUnits = 344; |
|||
|
|||
/// <summary>
|
|||
/// YClipPathUnits (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int YClipPathUnits = 345; |
|||
|
|||
/// <summary>
|
|||
/// Indexed (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int Indexed = 346; |
|||
|
|||
/// <summary>
|
|||
/// ImageID (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int ImageID = 32781; |
|||
|
|||
/// <summary>
|
|||
/// OpiProxy (see TIFF Supplement 1: Adobe Pagemaker 6.0).
|
|||
/// </summary>
|
|||
public const int OpiProxy = 351; |
|||
|
|||
/// <summary>
|
|||
/// ImageSourceData (see TIFF Supplement 2: Adobe Photoshop).
|
|||
/// </summary>
|
|||
public const int ImageSourceData = 37724; |
|||
|
|||
/// <summary>
|
|||
/// JPEGTables (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int JPEGTables = 0x015B; |
|||
|
|||
/// <summary>
|
|||
/// CFARepeatPatternDim (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int CFARepeatPatternDim = 0x828D; |
|||
|
|||
/// <summary>
|
|||
/// BatteryLevel (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int BatteryLevel = 0x828F; |
|||
|
|||
/// <summary>
|
|||
/// Interlace (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int Interlace = 0x8829; |
|||
|
|||
/// <summary>
|
|||
/// TimeZoneOffset (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int TimeZoneOffset = 0x882A; |
|||
|
|||
/// <summary>
|
|||
/// SelfTimerMode (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int SelfTimerMode = 0x882B; |
|||
|
|||
/// <summary>
|
|||
/// Noise (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int Noise = 0x920D; |
|||
|
|||
/// <summary>
|
|||
/// ImageNumber (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int ImageNumber = 0x9211; |
|||
|
|||
/// <summary>
|
|||
/// SecurityClassification (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int SecurityClassification = 0x9212; |
|||
|
|||
/// <summary>
|
|||
/// ImageHistory (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int ImageHistory = 0x9213; |
|||
|
|||
/// <summary>
|
|||
/// TiffEPStandardID (see TIFF/EP Specification: Additional Tags).
|
|||
/// </summary>
|
|||
public const int TiffEPStandardID = 0x9216; |
|||
|
|||
/// <summary>
|
|||
/// BadFaxLines (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int BadFaxLines = 326; |
|||
|
|||
/// <summary>
|
|||
/// CleanFaxData (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int CleanFaxData = 327; |
|||
|
|||
/// <summary>
|
|||
/// ConsecutiveBadFaxLines (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int ConsecutiveBadFaxLines = 328; |
|||
|
|||
/// <summary>
|
|||
/// GlobalParametersIFD (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int GlobalParametersIFD = 400; |
|||
|
|||
/// <summary>
|
|||
/// ProfileType (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int ProfileType = 401; |
|||
|
|||
/// <summary>
|
|||
/// FaxProfile (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int FaxProfile = 402; |
|||
|
|||
/// <summary>
|
|||
/// CodingMethod (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int CodingMethod = 403; |
|||
|
|||
/// <summary>
|
|||
/// VersionYear (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int VersionYear = 404; |
|||
|
|||
/// <summary>
|
|||
/// ModeNumber (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int ModeNumber = 405; |
|||
|
|||
/// <summary>
|
|||
/// Decode (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int Decode = 433; |
|||
|
|||
/// <summary>
|
|||
/// DefaultImageColor (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int DefaultImageColor = 434; |
|||
|
|||
/// <summary>
|
|||
/// StripRowCounts (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int StripRowCounts = 559; |
|||
|
|||
/// <summary>
|
|||
/// ImageLayer (see RFC2301: TIFF-F/FX Specification).
|
|||
/// </summary>
|
|||
public const int ImageLayer = 34732; |
|||
|
|||
/// <summary>
|
|||
/// Xmp (Embedded Metadata).
|
|||
/// </summary>
|
|||
public const int Xmp = 700; |
|||
|
|||
/// <summary>
|
|||
/// Iptc (Embedded Metadata).
|
|||
/// </summary>
|
|||
public const int Iptc = 33723; |
|||
|
|||
/// <summary>
|
|||
/// Photoshop (Embedded Metadata).
|
|||
/// </summary>
|
|||
public const int Photoshop = 34377; |
|||
|
|||
/// <summary>
|
|||
/// ExifIFD (Embedded Metadata).
|
|||
/// </summary>
|
|||
public const int ExifIFD = 34665; |
|||
|
|||
/// <summary>
|
|||
/// GpsIFD (Embedded Metadata).
|
|||
/// </summary>
|
|||
public const int GpsIFD = 34853; |
|||
|
|||
/// <summary>
|
|||
/// InteroperabilityIFD (Embedded Metadata).
|
|||
/// </summary>
|
|||
public const int InteroperabilityIFD = 40965; |
|||
|
|||
/// <summary>
|
|||
/// WangAnnotation (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int WangAnnotation = 32932; |
|||
|
|||
/// <summary>
|
|||
/// MDFileTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDFileTag = 33445; |
|||
|
|||
/// <summary>
|
|||
/// MDScalePixel (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDScalePixel = 33446; |
|||
|
|||
/// <summary>
|
|||
/// MDColorTable (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDColorTable = 33447; |
|||
|
|||
/// <summary>
|
|||
/// MDLabName (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDLabName = 33448; |
|||
|
|||
/// <summary>
|
|||
/// MDSampleInfo (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDSampleInfo = 33449; |
|||
|
|||
/// <summary>
|
|||
/// MDPrepDate (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDPrepDate = 33450; |
|||
|
|||
/// <summary>
|
|||
/// MDPrepTime (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDPrepTime = 33451; |
|||
|
|||
/// <summary>
|
|||
/// MDFileUnits (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int MDFileUnits = 33452; |
|||
|
|||
/// <summary>
|
|||
/// ModelPixelScaleTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int ModelPixelScaleTag = 33550; |
|||
|
|||
/// <summary>
|
|||
/// IngrPacketDataTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int IngrPacketDataTag = 33918; |
|||
|
|||
/// <summary>
|
|||
/// IngrFlagRegisters (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int IngrFlagRegisters = 33919; |
|||
|
|||
/// <summary>
|
|||
/// IrasBTransformationMatrix (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int IrasBTransformationMatrix = 33920; |
|||
|
|||
/// <summary>
|
|||
/// ModelTiePointTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int ModelTiePointTag = 33922; |
|||
|
|||
/// <summary>
|
|||
/// ModelTransformationTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int ModelTransformationTag = 34264; |
|||
|
|||
/// <summary>
|
|||
/// IccProfile (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int IccProfile = 34675; |
|||
|
|||
/// <summary>
|
|||
/// GeoKeyDirectoryTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int GeoKeyDirectoryTag = 34735; |
|||
|
|||
/// <summary>
|
|||
/// GeoDoubleParamsTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int GeoDoubleParamsTag = 34736; |
|||
|
|||
/// <summary>
|
|||
/// GeoAsciiParamsTag (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int GeoAsciiParamsTag = 34737; |
|||
|
|||
/// <summary>
|
|||
/// HylaFAXFaxRecvParams (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int HylaFAXFaxRecvParams = 34908; |
|||
|
|||
/// <summary>
|
|||
/// HylaFAXFaxSubAddress (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int HylaFAXFaxSubAddress = 34909; |
|||
|
|||
/// <summary>
|
|||
/// HylaFAXFaxRecvTime (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int HylaFAXFaxRecvTime = 34910; |
|||
|
|||
/// <summary>
|
|||
/// GdalMetadata (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int GdalMetadata = 42112; |
|||
|
|||
/// <summary>
|
|||
/// GdalNodata (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int GdalNodata = 42113; |
|||
|
|||
/// <summary>
|
|||
/// OceScanjobDescription (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int OceScanjobDescription = 50215; |
|||
|
|||
/// <summary>
|
|||
/// OceApplicationSelector (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int OceApplicationSelector = 50216; |
|||
|
|||
/// <summary>
|
|||
/// OceIdentificationNumber (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int OceIdentificationNumber = 50217; |
|||
|
|||
/// <summary>
|
|||
/// OceImageLogicCharacteristics (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int OceImageLogicCharacteristics = 50218; |
|||
|
|||
/// <summary>
|
|||
/// AliasLayerMetadata (Other Private TIFF tags : see http://www.awaresystems.be/imaging/tiff/tifftags/private.html).
|
|||
/// </summary>
|
|||
public const int AliasLayerMetadata = 50784; |
|||
} |
|||
} |
|||
@ -1,76 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Tiff |
|||
{ |
|||
/// <summary>
|
|||
/// Enumeration representing the data types understood by the Tiff file-format.
|
|||
/// </summary>
|
|||
internal enum TiffType |
|||
{ |
|||
/// <summary>
|
|||
/// Unsigned 8-bit integer.
|
|||
/// </summary>
|
|||
Byte = 1, |
|||
|
|||
/// <summary>
|
|||
/// ASCII formatted text.
|
|||
/// </summary>
|
|||
Ascii = 2, |
|||
|
|||
/// <summary>
|
|||
/// Unsigned 16-bit integer.
|
|||
/// </summary>
|
|||
Short = 3, |
|||
|
|||
/// <summary>
|
|||
/// Unsigned 32-bit integer.
|
|||
/// </summary>
|
|||
Long = 4, |
|||
|
|||
/// <summary>
|
|||
/// Unsigned rational number.
|
|||
/// </summary>
|
|||
Rational = 5, |
|||
|
|||
/// <summary>
|
|||
/// Signed 8-bit integer.
|
|||
/// </summary>
|
|||
SByte = 6, |
|||
|
|||
/// <summary>
|
|||
/// Undefined data type.
|
|||
/// </summary>
|
|||
Undefined = 7, |
|||
|
|||
/// <summary>
|
|||
/// Signed 16-bit integer.
|
|||
/// </summary>
|
|||
SShort = 8, |
|||
|
|||
/// <summary>
|
|||
/// Signed 32-bit integer.
|
|||
/// </summary>
|
|||
SLong = 9, |
|||
|
|||
/// <summary>
|
|||
/// Signed rational number.
|
|||
/// </summary>
|
|||
SRational = 10, |
|||
|
|||
/// <summary>
|
|||
/// Single precision (4-byte) IEEE format.
|
|||
/// </summary>
|
|||
Float = 11, |
|||
|
|||
/// <summary>
|
|||
/// Double precision (8-byte) IEEE format.
|
|||
/// </summary>
|
|||
Double = 12, |
|||
|
|||
/// <summary>
|
|||
/// Reference to an IFD.
|
|||
/// </summary>
|
|||
Ifd = 13 |
|||
} |
|||
} |
|||
@ -1,328 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
|
|||
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; |
|||
|
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Format", "Tiff")] |
|||
public class SubStreamTests |
|||
{ |
|||
[Fact] |
|||
public void Constructor_PositionsStreamCorrectly_WithSpecifiedOffset() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
innerStream.Position = 2; |
|||
|
|||
SubStream stream = new SubStream(innerStream, 4, 6); |
|||
|
|||
Assert.Equal(0, stream.Position); |
|||
Assert.Equal(6, stream.Length); |
|||
Assert.Equal(4, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Constructor_PositionsStreamCorrectly_WithCurrentOffset() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
innerStream.Position = 2; |
|||
|
|||
SubStream stream = new SubStream(innerStream, 6); |
|||
|
|||
Assert.Equal(0, stream.Position); |
|||
Assert.Equal(6, stream.Length); |
|||
Assert.Equal(2, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanRead_ReturnsTrue() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.True(stream.CanRead); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanWrite_ReturnsFalse() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.False(stream.CanWrite); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanSeek_ReturnsTrue() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.True(stream.CanSeek); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Length_ReturnsTheConstrainedLength() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.Equal(6, stream.Length); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Position_ReturnsZeroBeforeReading() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.Equal(0, stream.Position); |
|||
Assert.Equal(2, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Position_ReturnsPositionAfterReading() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Read(new byte[2], 0, 2); |
|||
|
|||
Assert.Equal(2, stream.Position); |
|||
Assert.Equal(4, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Position_ReturnsPositionAfterReadingTwice() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Read(new byte[2], 0, 2); |
|||
stream.Read(new byte[2], 0, 2); |
|||
|
|||
Assert.Equal(4, stream.Position); |
|||
Assert.Equal(6, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Position_SettingPropertySeeksToNewPosition() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 3; |
|||
|
|||
Assert.Equal(3, stream.Position); |
|||
Assert.Equal(5, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Flush_ThrowsNotSupportedException() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.Throws<NotSupportedException>(() => stream.Flush()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Read_Reads_FromStartOfSubStream() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
byte[] buffer = new byte[3]; |
|||
var result = stream.Read(buffer, 0, 3); |
|||
|
|||
Assert.Equal(new byte[] { 3, 4, 5 }, buffer); |
|||
Assert.Equal(3, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(2, SeekOrigin.Begin)] |
|||
[InlineData(1, SeekOrigin.Current)] |
|||
[InlineData(4, SeekOrigin.End)] |
|||
public void Read_Reads_FromMiddleOfSubStream(long offset, SeekOrigin origin) |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 1; |
|||
stream.Seek(offset, origin); |
|||
byte[] buffer = new byte[3]; |
|||
var result = stream.Read(buffer, 0, 3); |
|||
|
|||
Assert.Equal(new byte[] { 5, 6, 7 }, buffer); |
|||
Assert.Equal(3, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(3, SeekOrigin.Begin)] |
|||
[InlineData(2, SeekOrigin.Current)] |
|||
[InlineData(3, SeekOrigin.End)] |
|||
public void Read_Reads_FromEndOfSubStream(long offset, SeekOrigin origin) |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 1; |
|||
stream.Seek(offset, origin); |
|||
byte[] buffer = new byte[3]; |
|||
var result = stream.Read(buffer, 0, 3); |
|||
|
|||
Assert.Equal(new byte[] { 6, 7, 8 }, buffer); |
|||
Assert.Equal(3, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(4, SeekOrigin.Begin)] |
|||
[InlineData(3, SeekOrigin.Current)] |
|||
[InlineData(2, SeekOrigin.End)] |
|||
public void Read_Reads_FromBeyondEndOfSubStream(long offset, SeekOrigin origin) |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 1; |
|||
stream.Seek(offset, origin); |
|||
byte[] buffer = new byte[3]; |
|||
var result = stream.Read(buffer, 0, 3); |
|||
|
|||
Assert.Equal(new byte[] { 7, 8, 0 }, buffer); |
|||
Assert.Equal(2, result); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ReadByte_Reads_FromStartOfSubStream() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
var result = stream.ReadByte(); |
|||
|
|||
Assert.Equal(3, result); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ReadByte_Reads_FromMiddleOfSubStream() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 3; |
|||
var result = stream.ReadByte(); |
|||
|
|||
Assert.Equal(6, result); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ReadByte_Reads_FromEndOfSubStream() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 5; |
|||
var result = stream.ReadByte(); |
|||
|
|||
Assert.Equal(8, result); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ReadByte_Reads_FromBeyondEndOfSubStream() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 5; |
|||
stream.ReadByte(); |
|||
var result = stream.ReadByte(); |
|||
|
|||
Assert.Equal(-1, result); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Write_ThrowsNotSupportedException() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.Throws<NotSupportedException>(() => stream.Write(new byte[] { 1, 2 }, 0, 2)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteByte_ThrowsNotSupportedException() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.Throws<NotSupportedException>(() => stream.WriteByte(42)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Seek_MovesToNewPosition_FromBegin() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 1; |
|||
long result = stream.Seek(2, SeekOrigin.Begin); |
|||
|
|||
Assert.Equal(2, result); |
|||
Assert.Equal(2, stream.Position); |
|||
Assert.Equal(4, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Seek_MovesToNewPosition_FromCurrent() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 1; |
|||
long result = stream.Seek(2, SeekOrigin.Current); |
|||
|
|||
Assert.Equal(3, result); |
|||
Assert.Equal(3, stream.Position); |
|||
Assert.Equal(5, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Seek_MovesToNewPosition_FromEnd() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
stream.Position = 1; |
|||
long result = stream.Seek(2, SeekOrigin.End); |
|||
|
|||
Assert.Equal(4, result); |
|||
Assert.Equal(4, stream.Position); |
|||
Assert.Equal(6, innerStream.Position); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Seek_ThrowsException_WithInvalidOrigin() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
var e = Assert.Throws<ArgumentException>(() => stream.Seek(2, (SeekOrigin)99)); |
|||
Assert.Equal("Invalid seek origin.", e.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SetLength_ThrowsNotSupportedException() |
|||
{ |
|||
Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); |
|||
SubStream stream = new SubStream(innerStream, 2, 6); |
|||
|
|||
Assert.Throws<NotSupportedException>(() => stream.SetLength(5)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System.Collections.Generic; |
|||
|
|||
/// <summary>
|
|||
/// An interface for any class within the Tiff generator that produces data to be included in the file.
|
|||
/// </summary>
|
|||
internal interface ITiffGenDataSource |
|||
{ |
|||
IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian); |
|||
} |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System.Collections.Generic; |
|||
|
|||
/// <summary>
|
|||
/// A utility data structure to represent an independent block of data in a Tiff file.
|
|||
/// These may be located in any order within a Tiff file.
|
|||
/// </summary>
|
|||
internal class TiffGenDataBlock |
|||
{ |
|||
public TiffGenDataBlock(byte[] bytes) |
|||
{ |
|||
this.Bytes = bytes; |
|||
this.References = new List<TiffGenDataReference>(); |
|||
} |
|||
|
|||
public byte[] Bytes { get; } |
|||
public IList<TiffGenDataReference> References { get; } |
|||
|
|||
public void AddReference(byte[] bytes, int offset) |
|||
{ |
|||
References.Add(new TiffGenDataReference(bytes, offset)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
/// <summary>
|
|||
/// A utility data structure to represent a reference from one block of data to another in a Tiff file.
|
|||
/// </summary>
|
|||
internal class TiffGenDataReference |
|||
{ |
|||
public TiffGenDataReference(byte[] bytes, int offset) |
|||
{ |
|||
this.Bytes = bytes; |
|||
this.Offset = offset; |
|||
} |
|||
|
|||
public byte[] Bytes { get; } |
|||
public int Offset { get; } |
|||
} |
|||
} |
|||
@ -1,204 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using ImageSharp.Formats.Tiff; |
|||
|
|||
/// <summary>
|
|||
/// A utility data structure to represent Tiff IFD entries in unit tests.
|
|||
/// </summary>
|
|||
internal abstract class TiffGenEntry : ITiffGenDataSource |
|||
{ |
|||
private TiffGenEntry(ushort tag, TiffType type, uint count) |
|||
{ |
|||
this.Tag = tag; |
|||
this.Type = type; |
|||
this.Count = count; |
|||
} |
|||
|
|||
public uint Count { get; } |
|||
public ushort Tag { get; } |
|||
public TiffType Type { get; } |
|||
|
|||
public abstract IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian); |
|||
|
|||
public static TiffGenEntry Ascii(ushort tag, string value) |
|||
{ |
|||
return new TiffGenEntryAscii(tag, value); |
|||
} |
|||
|
|||
public static TiffGenEntry Bytes(ushort tag, TiffType type, uint count, byte[] value) |
|||
{ |
|||
return new TiffGenEntryBytes(tag, type, count, value); |
|||
} |
|||
|
|||
public static TiffGenEntry Integer(ushort tag, TiffType type, int value) |
|||
{ |
|||
return TiffGenEntry.Integer(tag, type, new int[] { value }); |
|||
} |
|||
|
|||
public static TiffGenEntry Integer(ushort tag, TiffType type, int[] value) |
|||
{ |
|||
if (type != TiffType.Byte && type != TiffType.Short && type != TiffType.Long && |
|||
type != TiffType.SByte && type != TiffType.SShort && type != TiffType.SLong) |
|||
throw new ArgumentException(nameof(type), "The specified type is not an integer type."); |
|||
|
|||
return new TiffGenEntryInteger(tag, type, value); |
|||
} |
|||
|
|||
public static TiffGenEntry Integer(ushort tag, TiffType type, uint value) |
|||
{ |
|||
return TiffGenEntry.Integer(tag, type, new uint[] { value }); |
|||
} |
|||
|
|||
public static TiffGenEntry Integer(ushort tag, TiffType type, uint[] value) |
|||
{ |
|||
if (type != TiffType.Byte && type != TiffType.Short && type != TiffType.Long && |
|||
type != TiffType.SByte && type != TiffType.SShort && type != TiffType.SLong) |
|||
throw new ArgumentException(nameof(type), "The specified type is not an integer type."); |
|||
|
|||
return new TiffGenEntryUnsignedInteger(tag, type, value); |
|||
} |
|||
|
|||
public static TiffGenEntry Rational(ushort tag, uint numerator, uint denominator) |
|||
{ |
|||
return new TiffGenEntryRational(tag, numerator, denominator); |
|||
} |
|||
|
|||
private class TiffGenEntryAscii : TiffGenEntry |
|||
{ |
|||
public TiffGenEntryAscii(ushort tag, string value) : base(tag, TiffType.Ascii, (uint)GetBytes(value).Length) |
|||
{ |
|||
this.Value = value; |
|||
} |
|||
|
|||
public string Value { get; } |
|||
|
|||
public override IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = GetBytes(Value); |
|||
return new[] { new TiffGenDataBlock(bytes) }; |
|||
} |
|||
|
|||
private static byte[] GetBytes(string value) |
|||
{ |
|||
return Encoding.ASCII.GetBytes($"{value}\0"); |
|||
} |
|||
} |
|||
|
|||
private class TiffGenEntryBytes : TiffGenEntry |
|||
{ |
|||
public TiffGenEntryBytes(ushort tag, TiffType type, uint count, byte[] value) : base(tag, type, count) |
|||
{ |
|||
this.Value = value; |
|||
} |
|||
|
|||
public byte[] Value { get; } |
|||
|
|||
public override IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
return new[] { new TiffGenDataBlock(Value) }; |
|||
} |
|||
} |
|||
|
|||
private class TiffGenEntryInteger : TiffGenEntry |
|||
{ |
|||
public TiffGenEntryInteger(ushort tag, TiffType type, int[] value) : base(tag, type, (uint)value.Length) |
|||
{ |
|||
this.Value = value; |
|||
} |
|||
|
|||
public int[] Value { get; } |
|||
|
|||
public override IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = GetBytes().SelectMany(b => b.WithByteOrder(isLittleEndian)).ToArray(); |
|||
return new[] { new TiffGenDataBlock(bytes) }; |
|||
} |
|||
|
|||
private IEnumerable<byte[]> GetBytes() |
|||
{ |
|||
switch (Type) |
|||
{ |
|||
case TiffType.Byte: |
|||
return Value.Select(i => new byte[] { (byte)i }); |
|||
case TiffType.Short: |
|||
return Value.Select(i => BitConverter.GetBytes((ushort)i)); |
|||
case TiffType.Long: |
|||
return Value.Select(i => BitConverter.GetBytes((uint)i)); |
|||
case TiffType.SByte: |
|||
return Value.Select(i => BitConverter.GetBytes((sbyte)i)); |
|||
case TiffType.SShort: |
|||
return Value.Select(i => BitConverter.GetBytes((short)i)); |
|||
case TiffType.SLong: |
|||
return Value.Select(i => BitConverter.GetBytes((int)i)); |
|||
default: |
|||
throw new InvalidOperationException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private class TiffGenEntryUnsignedInteger : TiffGenEntry |
|||
{ |
|||
public TiffGenEntryUnsignedInteger(ushort tag, TiffType type, uint[] value) : base(tag, type, (uint)value.Length) |
|||
{ |
|||
this.Value = value; |
|||
} |
|||
|
|||
public uint[] Value { get; } |
|||
|
|||
public override IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = GetBytes().SelectMany(b => b.WithByteOrder(isLittleEndian)).ToArray(); |
|||
return new[] { new TiffGenDataBlock(bytes) }; |
|||
} |
|||
|
|||
private IEnumerable<byte[]> GetBytes() |
|||
{ |
|||
switch (Type) |
|||
{ |
|||
case TiffType.Byte: |
|||
return Value.Select(i => new byte[] { (byte)i }); |
|||
case TiffType.Short: |
|||
return Value.Select(i => BitConverter.GetBytes((ushort)i)); |
|||
case TiffType.Long: |
|||
return Value.Select(i => BitConverter.GetBytes((uint)i)); |
|||
case TiffType.SByte: |
|||
return Value.Select(i => BitConverter.GetBytes((sbyte)i)); |
|||
case TiffType.SShort: |
|||
return Value.Select(i => BitConverter.GetBytes((short)i)); |
|||
case TiffType.SLong: |
|||
return Value.Select(i => BitConverter.GetBytes((int)i)); |
|||
default: |
|||
throw new InvalidOperationException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private class TiffGenEntryRational : TiffGenEntry |
|||
{ |
|||
public TiffGenEntryRational(ushort tag, uint numerator, uint denominator) : base(tag, TiffType.Rational, 1u) |
|||
{ |
|||
this.Numerator = numerator; |
|||
this.Denominator = denominator; |
|||
} |
|||
|
|||
public uint Numerator { get; } |
|||
|
|||
public uint Denominator { get; } |
|||
|
|||
public override IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
byte[] numeratorBytes = BitConverter.GetBytes(Numerator).WithByteOrder(isLittleEndian); |
|||
byte[] denominatorBytes = BitConverter.GetBytes(Denominator).WithByteOrder(isLittleEndian); |
|||
byte[] bytes = Enumerable.Concat(numeratorBytes, denominatorBytes).ToArray(); |
|||
return new[] { new TiffGenDataBlock(bytes) }; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A utility class for generating in-memory Tiff files for use in unit tests.
|
|||
/// </summary>
|
|||
internal static class TiffGenExtensions |
|||
{ |
|||
public static byte[] ToBytes(this ITiffGenDataSource dataSource, bool isLittleEndian) |
|||
{ |
|||
var dataBlocks = dataSource.GetData(isLittleEndian); |
|||
|
|||
int offset = 0; |
|||
|
|||
foreach (var dataBlock in dataBlocks) |
|||
{ |
|||
byte[] offsetBytes = BitConverter.GetBytes(offset).WithByteOrder(isLittleEndian); |
|||
|
|||
foreach (var reference in dataBlock.References) |
|||
{ |
|||
reference.Bytes[reference.Offset + 0] = offsetBytes[0]; |
|||
reference.Bytes[reference.Offset + 1] = offsetBytes[1]; |
|||
reference.Bytes[reference.Offset + 2] = offsetBytes[2]; |
|||
reference.Bytes[reference.Offset + 3] = offsetBytes[3]; |
|||
} |
|||
|
|||
offset += dataBlock.Bytes.Length; |
|||
} |
|||
|
|||
return dataBlocks.SelectMany(b => b.Bytes).ToArray(); |
|||
} |
|||
|
|||
public static Stream ToStream(this ITiffGenDataSource dataSource, bool isLittleEndian) |
|||
{ |
|||
var bytes = dataSource.ToBytes(isLittleEndian); |
|||
return new MemoryStream(bytes); |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A utility data structure to represent a Tiff file-header.
|
|||
/// </summary>
|
|||
internal class TiffGenHeader : ITiffGenDataSource |
|||
{ |
|||
public TiffGenHeader() |
|||
{ |
|||
this.MagicNumber = 42; |
|||
} |
|||
|
|||
public ushort? ByteOrderMarker { get; set; } |
|||
public ushort MagicNumber { get; set; } |
|||
public TiffGenIfd FirstIfd { get; set; } |
|||
|
|||
public IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
ByteBuffer bytes = new ByteBuffer(isLittleEndian); |
|||
|
|||
bytes.AddUInt16(ByteOrderMarker ?? (isLittleEndian ? (ushort)0x4949 : (ushort)0x4D4D)); |
|||
bytes.AddUInt16(MagicNumber); |
|||
bytes.AddUInt32(0); |
|||
|
|||
var headerData = new TiffGenDataBlock(bytes.ToArray()); |
|||
|
|||
if (FirstIfd != null) |
|||
{ |
|||
var firstIfdData = FirstIfd.GetData(isLittleEndian); |
|||
firstIfdData.First().AddReference(headerData.Bytes, 4); |
|||
return new[] { headerData }.Concat(firstIfdData); |
|||
} |
|||
else |
|||
{ |
|||
return new[] { headerData }; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,88 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A utility data structure to represent Tiff IFDs in unit tests.
|
|||
/// </summary>
|
|||
internal class TiffGenIfd : ITiffGenDataSource |
|||
{ |
|||
public TiffGenIfd() |
|||
{ |
|||
this.Entries = new List<TiffGenEntry>(); |
|||
} |
|||
|
|||
public List<TiffGenEntry> Entries { get; } |
|||
public TiffGenIfd NextIfd { get; set; } |
|||
|
|||
public IEnumerable<TiffGenDataBlock> GetData(bool isLittleEndian) |
|||
{ |
|||
ByteBuffer bytes = new ByteBuffer(isLittleEndian); |
|||
List<TiffGenDataBlock> dataBlocks = new List<TiffGenDataBlock>(); |
|||
List<Tuple<TiffGenDataBlock, int>> entryReferences = new List<Tuple<TiffGenDataBlock, int>>(); |
|||
|
|||
// Add the entry count
|
|||
|
|||
bytes.AddUInt16((ushort)Entries.Count); |
|||
|
|||
// Add all IFD entries
|
|||
|
|||
int entryOffset = 2; |
|||
|
|||
foreach (var entry in Entries) |
|||
{ |
|||
var entryData = entry.GetData(isLittleEndian); |
|||
var entryBytes = entryData.First().Bytes; |
|||
|
|||
bytes.AddUInt16(entry.Tag); |
|||
bytes.AddUInt16((ushort)entry.Type); |
|||
bytes.AddUInt32(entry.Count); |
|||
|
|||
if (entryBytes.Length <=4) |
|||
{ |
|||
bytes.AddByte(entryBytes.Length > 0 ? entryBytes[0] : (byte)0); |
|||
bytes.AddByte(entryBytes.Length > 1 ? entryBytes[1] : (byte)0); |
|||
bytes.AddByte(entryBytes.Length > 2 ? entryBytes[2] : (byte)0); |
|||
bytes.AddByte(entryBytes.Length > 3 ? entryBytes[3] : (byte)0); |
|||
|
|||
dataBlocks.AddRange(entryData.Skip(1)); |
|||
} |
|||
else |
|||
{ |
|||
bytes.AddUInt32(0); |
|||
dataBlocks.AddRange(entryData); |
|||
entryReferences.Add(Tuple.Create(entryData.First(), entryOffset + 8)); |
|||
} |
|||
|
|||
entryOffset += 12; |
|||
} |
|||
|
|||
// Add reference to next IFD
|
|||
|
|||
bytes.AddUInt32(0); |
|||
|
|||
// Build the data
|
|||
|
|||
var ifdData = new TiffGenDataBlock(bytes.ToArray()); |
|||
|
|||
foreach (var entryReference in entryReferences) |
|||
{ |
|||
entryReference.Item1.AddReference(ifdData.Bytes, entryReference.Item2); |
|||
} |
|||
|
|||
IEnumerable<TiffGenDataBlock> nextIfdData = new TiffGenDataBlock[0]; |
|||
if (NextIfd != null) |
|||
{ |
|||
nextIfdData = NextIfd.GetData(isLittleEndian); |
|||
nextIfdData.First().AddReference(ifdData.Bytes, ifdData.Bytes.Length - 4); |
|||
} |
|||
|
|||
return new [] { ifdData }.Concat(dataBlocks).Concat(nextIfdData); |
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A utility class for manipulating in-memory Tiff files for use in unit tests.
|
|||
/// </summary>
|
|||
internal static class TiffGenIfdExtensions |
|||
{ |
|||
public static TiffGenIfd WithoutEntry(this TiffGenIfd ifd, ushort tag) |
|||
{ |
|||
TiffGenEntry entry = ifd.Entries.FirstOrDefault(e => e.Tag == tag); |
|||
if (entry != null) |
|||
{ |
|||
ifd.Entries.Remove(entry); |
|||
} |
|||
return ifd; |
|||
} |
|||
|
|||
public static TiffGenIfd WithEntry(this TiffGenIfd ifd, TiffGenEntry entry) |
|||
{ |
|||
ifd.WithoutEntry(entry.Tag); |
|||
ifd.Entries.Add(entry); |
|||
|
|||
return ifd; |
|||
} |
|||
} |
|||
} |
|||
@ -1,77 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using ImageSharp.Formats.Tiff; |
|||
|
|||
using SixLabors.ImageSharp.Metadata.Profiles.Exif; |
|||
using Xunit; |
|||
|
|||
/// <summary>
|
|||
/// A utility data structure to decode Tiff IFD entries in unit tests.
|
|||
/// </summary>
|
|||
internal static class TiffIfdParser |
|||
{ |
|||
public static int? GetInteger(this List<TiffIfdEntry> entries, ushort tag) |
|||
{ |
|||
TiffIfdEntry entry = entries.FirstOrDefault(e => e.Tag == tag); |
|||
|
|||
if (entry.Tag == 0) |
|||
return null; |
|||
|
|||
Assert.Equal(1u, entry.Count); |
|||
|
|||
switch (entry.Type) |
|||
{ |
|||
case TiffType.Byte: |
|||
return entry.Value[0]; |
|||
case TiffType.SByte: |
|||
return (sbyte)entry.Value[0]; |
|||
case TiffType.Short: |
|||
return BitConverter.ToUInt16(entry.Value, 0); |
|||
case TiffType.SShort: |
|||
return BitConverter.ToInt16(entry.Value, 0); |
|||
case TiffType.Long: |
|||
return (int)BitConverter.ToUInt32(entry.Value, 0); |
|||
case TiffType.SLong: |
|||
return BitConverter.ToInt32(entry.Value, 0); |
|||
default: |
|||
Assert.True(1 == 1, "TIFF IFD entry is not convertable to an integer."); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
public static Rational? GetUnsignedRational(this List<TiffIfdEntry> entries, ushort tag) |
|||
{ |
|||
TiffIfdEntry entry = entries.FirstOrDefault(e => e.Tag == tag); |
|||
|
|||
if (entry.Tag == 0) |
|||
return null; |
|||
|
|||
Assert.Equal(TiffType.Rational, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
|
|||
uint numerator = BitConverter.ToUInt32(entry.Value, 0); |
|||
uint denominator = BitConverter.ToUInt32(entry.Value, 4); |
|||
|
|||
return new Rational(numerator, denominator); |
|||
} |
|||
|
|||
public static string GetAscii(this List<TiffIfdEntry> entries, ushort tag) |
|||
{ |
|||
TiffIfdEntry entry = entries.FirstOrDefault(e => e.Tag == tag); |
|||
|
|||
if (entry.Tag == 0) |
|||
return null; |
|||
|
|||
Assert.Equal(TiffType.Ascii, entry.Type); |
|||
|
|||
return Encoding.UTF8.GetString(entry.Value, 0, (int)entry.Count); |
|||
} |
|||
} |
|||
} |
|||
@ -1,110 +0,0 @@ |
|||
// 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 |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffDecoderHeaderTests |
|||
{ |
|||
public static object[][] IsLittleEndianValues = new[] { new object[] { false }, |
|||
new object[] { true } }; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadHeader_ReadsEndianness(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd() |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, false, null, null); |
|||
|
|||
decoder.ReadHeader(); |
|||
|
|||
Assert.Equal(isLittleEndian, decoder.IsLittleEndian); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadHeader_ReadsFirstIfdOffset(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd() |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, false, null, null); |
|||
|
|||
uint firstIfdOffset = decoder.ReadHeader(); |
|||
|
|||
Assert.Equal(8u, firstIfdOffset); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0x1234)] |
|||
[InlineData(0x4912)] |
|||
[InlineData(0x1249)] |
|||
[InlineData(0x4D12)] |
|||
[InlineData(0x124D)] |
|||
[InlineData(0x494D)] |
|||
[InlineData(0x4D49)] |
|||
public void Decode_ThrowsException_WithInvalidByteOrderMarkers(ushort byteOrderMarker) |
|||
{ |
|||
Stream stream = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd(), |
|||
ByteOrderMarker = byteOrderMarker |
|||
} |
|||
.ToStream(true); |
|||
|
|||
TiffDecoder decoder = new TiffDecoder(); |
|||
|
|||
ImageFormatException e = Assert.Throws<ImageFormatException>(() => { decoder.Decode<Rgba32>(Configuration.Default, stream); }); |
|||
|
|||
Assert.Equal("Invalid TIFF file header.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void Decode_ThrowsException_WithIncorrectMagicNumber(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd(), |
|||
MagicNumber = 32 |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoder decoder = new TiffDecoder(); |
|||
|
|||
ImageFormatException e = Assert.Throws<ImageFormatException>(() => { decoder.Decode<Rgba32>(Configuration.Default, stream); }); |
|||
|
|||
Assert.Equal("Invalid TIFF file header.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void Decode_ThrowsException_WithNoIfdZero(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = null |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoder decoder = new TiffDecoder(); |
|||
|
|||
ImageFormatException e = Assert.Throws<ImageFormatException>(() => { decoder.Decode<Rgba32>(Configuration.Default, stream); }); |
|||
|
|||
Assert.Equal("Invalid TIFF file header.", e.Message); |
|||
} |
|||
} |
|||
} |
|||
@ -1,842 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffDecoderIfdEntryTests |
|||
{ |
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 1u, 1u)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii, 1u, 1u)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 1u, 2u)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 1u, 4u)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational, 1u, 8u)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 1u, 1u)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined, 1u, 1u)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 1u, 2u)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, 1u, 4u)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational, 1u, 8u)] |
|||
[InlineDataAttribute((ushort)TiffType.Float, 1u, 4u)] |
|||
[InlineDataAttribute((ushort)TiffType.Double, 1u, 8u)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd, 1u, 4u)] |
|||
[InlineDataAttribute((ushort)999, 1u, 0u)] |
|||
public void GetSizeOfData_SingleItem_ReturnsCorrectSize(ushort type, uint count, uint expectedSize) |
|||
{ |
|||
TiffIfdEntry entry = new TiffIfdEntry(TiffTags.ImageWidth, (TiffType)type, count, new byte[4]); |
|||
uint size = TiffDecoderCore.GetSizeOfData(entry); |
|||
Assert.Equal(expectedSize, size); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 15u, 15u)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii, 20u, 20u)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 18u, 36u)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 4u, 16u)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational, 9u, 72u)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 5u, 5u)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined, 136u, 136u)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 12u, 24u)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, 15u, 60u)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational, 10u, 80u)] |
|||
[InlineDataAttribute((ushort)TiffType.Float, 2u, 8u)] |
|||
[InlineDataAttribute((ushort)TiffType.Double, 2u, 16u)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd, 10u, 40u)] |
|||
[InlineDataAttribute((ushort)999, 1050u, 0u)] |
|||
public void GetSizeOfData_Array_ReturnsCorrectSize(ushort type, uint count, uint expectedSize) |
|||
{ |
|||
TiffIfdEntry entry = new TiffIfdEntry(TiffTags.ImageWidth, (TiffType)type, count, new byte[4]); |
|||
uint size = TiffDecoderCore.GetSizeOfData(entry); |
|||
Assert.Equal(expectedSize, size); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 1u, new byte[] { 17 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 1u, new byte[] { 17 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 2u, new byte[] { 17, 28 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 2u, new byte[] { 17, 28 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 4u, new byte[] { 17, 28, 2, 9 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 4u, new byte[] { 17, 28, 2, 9 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 5u, new byte[] { 17, 28, 2, 9, 13 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 5u, new byte[] { 17, 28, 2, 9, 13 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 10u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2, 127, 86 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 10u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2, 127, 86 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 1u, new byte[] { 17, 28 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 1u, new byte[] { 17, 28 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 2u, new byte[] { 17, 28, 2, 9 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 2u, new byte[] { 17, 28, 2, 9 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 3u, new byte[] { 17, 28, 2, 9, 13, 37 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 3u, new byte[] { 17, 28, 2, 9, 13, 37 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 1u, new byte[] { 17, 28, 2, 9 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 1u, new byte[] { 17, 28, 2, 9 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 2u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 2u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational, 1u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational, 1u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, true)] |
|||
public void ReadBytes_ReturnsExpectedData(ushort type, uint count, byte[] bytes, bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, count, bytes), isLittleEndian); |
|||
|
|||
byte[] result = decoder.ReadBytes(ref entry); |
|||
|
|||
if (bytes.Length < 4) |
|||
result = result.Take(bytes.Length).ToArray(); |
|||
|
|||
Assert.Equal(bytes, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 5u, new byte[] { 17, 28, 2, 9, 13 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 5u, new byte[] { 17, 28, 2, 9, 13 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 10u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2, 127, 86 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 10u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2, 127, 86 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 3u, new byte[] { 17, 28, 2, 9, 13, 37 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 3u, new byte[] { 17, 28, 2, 9, 13, 37 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 2u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 2u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational, 1u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational, 1u, new byte[] { 17, 28, 2, 9, 13, 37, 18, 2 }, true)] |
|||
public void ReadBytes_CachesDataLongerThanFourBytes(ushort type, uint count, byte[] bytes, bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, count, bytes), isLittleEndian); |
|||
|
|||
Assert.Equal(4, entry.Value.Length); |
|||
|
|||
byte[] result = decoder.ReadBytes(ref entry); |
|||
|
|||
Assert.Equal(bytes.Length, entry.Value.Length); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, true, new byte[] { 0, 1, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, true, new byte[] { 1, 2, 3, 4 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, true, new byte[] { 255, 2, 3, 4 }, 255)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, false, new byte[] { 0, 1, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, false, new byte[] { 1, 2, 3, 4 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, false, new byte[] { 255, 2, 3, 4 }, 255)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, true, new byte[] { 0, 0, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, true, new byte[] { 1, 0, 2, 3 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, true, new byte[] { 0, 1, 2, 3 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, true, new byte[] { 2, 1, 2, 3 }, 258)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, true, new byte[] { 255, 255, 2, 3 }, UInt16.MaxValue)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, false, new byte[] { 0, 0, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, false, new byte[] { 0, 1, 2, 3 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, false, new byte[] { 1, 0, 2, 3 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, false, new byte[] { 1, 2, 2, 3 }, 258)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, false, new byte[] { 255, 255, 2, 3 }, UInt16.MaxValue)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 0, 0, 0, 0 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 1, 0, 0, 0 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 0, 1, 0, 0 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 0, 0, 1, 0 }, 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 0, 0, 0, 1 }, 256 * 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 1, 2, 3, 4 }, 67305985)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true, new byte[] { 255, 255, 255, 255 }, UInt32.MaxValue)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 0, 0, 0, 0 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 0, 0, 0, 1 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 0, 0, 1, 0 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 0, 1, 0, 0 }, 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 1, 0, 0, 0 }, 256 * 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 4, 3, 2, 1 }, 67305985)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false, new byte[] { 255, 255, 255, 255 }, UInt32.MaxValue)] |
|||
public void ReadUnsignedInteger_ReturnsValue(ushort type, bool isLittleEndian, byte[] bytes, uint expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, bytes), isLittleEndian); |
|||
|
|||
uint result = decoder.ReadUnsignedInteger(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadUnsignedInteger_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadUnsignedInteger(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to an unsigned integer.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, true)] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Short, false)] |
|||
[InlineDataAttribute((ushort)TiffType.Long, false)] |
|||
public void ReadUnsignedInteger_ThrowsExceptionIfCountIsNotOne(ushort type, bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 2, new byte[4]), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadUnsignedInteger(ref entry)); |
|||
|
|||
Assert.Equal($"Cannot read a single value from an array of multiple items.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, true, new byte[] { 0, 1, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, true, new byte[] { 1, 2, 3, 4 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, true, new byte[] { 255, 2, 3, 4 }, -1)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, false, new byte[] { 0, 1, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, false, new byte[] { 1, 2, 3, 4 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, false, new byte[] { 255, 2, 3, 4 }, -1)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, true, new byte[] { 0, 0, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, true, new byte[] { 1, 0, 2, 3 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, true, new byte[] { 0, 1, 2, 3 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, true, new byte[] { 2, 1, 2, 3 }, 258)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, true, new byte[] { 255, 255, 2, 3 }, -1)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, false, new byte[] { 0, 0, 2, 3 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, false, new byte[] { 0, 1, 2, 3 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, false, new byte[] { 1, 0, 2, 3 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, false, new byte[] { 1, 2, 2, 3 }, 258)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, false, new byte[] { 255, 255, 2, 3 }, -1)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 0, 0, 0, 0 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 1, 0, 0, 0 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 0, 1, 0, 0 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 0, 0, 1, 0 }, 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 0, 0, 0, 1 }, 256 * 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 1, 2, 3, 4 }, 67305985)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true, new byte[] { 255, 255, 255, 255 }, -1)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 0, 0, 0, 0 }, 0)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 0, 0, 0, 1 }, 1)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 0, 0, 1, 0 }, 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 0, 1, 0, 0 }, 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 1, 0, 0, 0 }, 256 * 256 * 256)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 4, 3, 2, 1 }, 67305985)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false, new byte[] { 255, 255, 255, 255 }, -1)] |
|||
public void ReadSignedInteger_ReturnsValue(ushort type, bool isLittleEndian, byte[] bytes, int expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, bytes), isLittleEndian); |
|||
|
|||
int result = decoder.ReadSignedInteger(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadSignedInteger_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadSignedInteger(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a signed integer.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, true)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, true)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, true)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, false)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, false)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, false)] |
|||
public void ReadSignedInteger_ThrowsExceptionIfCountIsNotOne(ushort type, bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 2, new byte[4]), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadSignedInteger(ref entry)); |
|||
|
|||
Assert.Equal($"Cannot read a single value from an array of multiple items.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 1, true, new byte[] { 0, 1, 2, 3 }, new uint[] { 0 })] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 3, true, new byte[] { 0, 1, 2, 3 }, new uint[] { 0, 1, 2 })] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 7, true, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, new uint[] { 0, 1, 2, 3, 4, 5, 6 })] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 1, false, new byte[] { 0, 1, 2, 3 }, new uint[] { 0 })] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 3, false, new byte[] { 0, 1, 2, 3 }, new uint[] { 0, 1, 2 })] |
|||
[InlineDataAttribute((ushort)TiffType.Byte, 7, false, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, new uint[] { 0, 1, 2, 3, 4, 5, 6 })] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 1, true, new byte[] { 1, 0, 3, 2 }, new uint[] { 1 })] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 2, true, new byte[] { 1, 0, 3, 2 }, new uint[] { 1, 515 })] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 3, true, new byte[] { 1, 0, 3, 2, 5, 4, 6, 7, 8 }, new uint[] { 1, 515, 1029 })] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 1, false, new byte[] { 0, 1, 2, 3 }, new uint[] { 1 })] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 2, false, new byte[] { 0, 1, 2, 3 }, new uint[] { 1, 515 })] |
|||
[InlineDataAttribute((ushort)TiffType.Short, 3, false, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, new uint[] { 1, 515, 1029 })] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 1, true, new byte[] { 4, 3, 2, 1 }, new uint[] { 0x01020304 })] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 2, true, new byte[] { 4, 3, 2, 1, 6, 5, 4, 3, 99, 99 }, new uint[] { 0x01020304, 0x03040506 })] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 1, false, new byte[] { 1, 2, 3, 4 }, new uint[] { 0x01020304 })] |
|||
[InlineDataAttribute((ushort)TiffType.Long, 2, false, new byte[] { 1, 2, 3, 4, 3, 4, 5, 6, 99, 99 }, new uint[] { 0x01020304, 0x03040506 })] |
|||
public void ReadUnsignedIntegerArray_ReturnsValue(ushort type, int count, bool isLittleEndian, byte[] bytes, uint[] expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, (uint)expectedValue.Length, bytes), isLittleEndian); |
|||
|
|||
uint[] result = decoder.ReadUnsignedIntegerArray(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadUnsignedIntegerArray_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadUnsignedIntegerArray(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to an unsigned integer.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 1, true, new byte[] { 0, 1, 2, 3 }, new int[] { 0 })] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 3, true, new byte[] { 0, 255, 2, 3 }, new int[] { 0, -1, 2 })] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 7, true, new byte[] { 0, 255, 2, 3, 4, 5, 6, 7, 8 }, new int[] { 0, -1, 2, 3, 4, 5, 6 })] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 1, false, new byte[] { 0, 1, 2, 3 }, new int[] { 0 })] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 3, false, new byte[] { 0, 255, 2, 3 }, new int[] { 0, -1, 2 })] |
|||
[InlineDataAttribute((ushort)TiffType.SByte, 7, false, new byte[] { 0, 255, 2, 3, 4, 5, 6, 7, 8 }, new int[] { 0, -1, 2, 3, 4, 5, 6 })] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 1, true, new byte[] { 1, 0, 3, 2 }, new int[] { 1 })] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 2, true, new byte[] { 1, 0, 255, 255 }, new int[] { 1, -1 })] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 3, true, new byte[] { 1, 0, 255, 255, 5, 4, 6, 7, 8 }, new int[] { 1, -1, 1029 })] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 1, false, new byte[] { 0, 1, 2, 3 }, new int[] { 1 })] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 2, false, new byte[] { 0, 1, 255, 255 }, new int[] { 1, -1 })] |
|||
[InlineDataAttribute((ushort)TiffType.SShort, 3, false, new byte[] { 0, 1, 255, 255, 4, 5, 6, 7, 8 }, new int[] { 1, -1, 1029 })] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, 1, true, new byte[] { 4, 3, 2, 1 }, new int[] { 0x01020304 })] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, 2, true, new byte[] { 4, 3, 2, 1, 255, 255, 255, 255, 99, 99 }, new int[] { 0x01020304, -1 })] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, 1, false, new byte[] { 1, 2, 3, 4 }, new int[] { 0x01020304 })] |
|||
[InlineDataAttribute((ushort)TiffType.SLong, 2, false, new byte[] { 1, 2, 3, 4, 255, 255, 255, 255, 99, 99 }, new int[] { 0x01020304, -1 })] |
|||
public void ReadSignedIntegerArray_ReturnsValue(ushort type, int count, bool isLittleEndian, byte[] bytes, int[] expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, (uint)expectedValue.Length, bytes), isLittleEndian); |
|||
|
|||
int[] result = decoder.ReadSignedIntegerArray(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadSignedIntegerArray_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadSignedIntegerArray(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a signed integer.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(true, new byte[] { 0 }, "")] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A', (byte)'B', (byte)'C', 0 }, "ABC")] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', 0 }, "ABCDEF")] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0, (byte)'E', (byte)'F', (byte)'G', (byte)'H', 0 }, "ABCD\0EFGH")] |
|||
[InlineDataAttribute(false, new byte[] { 0 }, "")] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A', (byte)'B', (byte)'C', 0 }, "ABC")] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', 0 }, "ABCDEF")] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0, (byte)'E', (byte)'F', (byte)'G', (byte)'H', 0 }, "ABCD\0EFGH")] |
|||
public void ReadString_ReturnsValue(bool isLittleEndian, byte[] bytes, string expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Ascii, (uint)bytes.Length, bytes), isLittleEndian); |
|||
|
|||
string result = decoder.ReadString(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadString_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadString(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a string.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A' })] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A', (byte)'B', (byte)'C' })] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F' })] |
|||
[InlineDataAttribute(true, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0, (byte)'E', (byte)'F', (byte)'G', (byte)'H' })] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A' })] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A', (byte)'B', (byte)'C' })] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F' })] |
|||
[InlineDataAttribute(false, new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0, (byte)'E', (byte)'F', (byte)'G', (byte)'H' })] |
|||
public void ReadString_ThrowsExceptionIfStringIsNotNullTerminated(bool isLittleEndian, byte[] bytes) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Ascii, (uint)bytes.Length, bytes), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadString(ref entry)); |
|||
|
|||
Assert.Equal($"The retrieved string is not null terminated.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(true, new byte[] { 0, 0, 0, 0, 2, 0, 0, 0 }, 0, 2)] |
|||
[InlineDataAttribute(true, new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, 1, 2)] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 0, 0, 0, 0, 2 }, 0, 2)] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 1, 0, 0, 0, 2 }, 1, 2)] |
|||
public void ReadUnsignedRational_ReturnsValue(bool isLittleEndian, byte[] bytes, uint expectedNumerator, uint expectedDenominator) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Rational, 1, bytes), isLittleEndian); |
|||
|
|||
Rational result = decoder.ReadUnsignedRational(ref entry); |
|||
Rational expectedValue = new Rational(expectedNumerator, expectedDenominator); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(true, new byte[] { 0, 0, 0, 0, 2, 0, 0, 0 }, 0, 2)] |
|||
[InlineDataAttribute(true, new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, 1, 2)] |
|||
[InlineDataAttribute(true, new byte[] { 255, 255, 255, 255, 2, 0, 0, 0 }, -1, 2)] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 0, 0, 0, 0, 2 }, 0, 2)] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 1, 0, 0, 0, 2 }, 1, 2)] |
|||
[InlineDataAttribute(false, new byte[] { 255, 255, 255, 255, 0, 0, 0, 2 }, -1, 2)] |
|||
public void ReadSignedRational_ReturnsValue(bool isLittleEndian, byte[] bytes, int expectedNumerator, int expectedDenominator) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.SRational, 1, bytes), isLittleEndian); |
|||
|
|||
SignedRational result = decoder.ReadSignedRational(ref entry); |
|||
SignedRational expectedValue = new SignedRational(expectedNumerator, expectedDenominator); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(true, new byte[] { 0, 0, 0, 0, 2, 0, 0, 0 }, new uint[] { 0 }, new uint[] { 2 })] |
|||
[InlineDataAttribute(true, new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, new uint[] { 1 }, new uint[] { 2 })] |
|||
[InlineDataAttribute(true, new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }, new uint[] { 1, 2 }, new uint[] { 2, 3 })] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 0, 0, 0, 0, 2 }, new uint[] { 0 }, new uint[] { 2 })] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 1, 0, 0, 0, 2 }, new uint[] { 1 }, new uint[] { 2 })] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3 }, new uint[] { 1, 2 }, new uint[] { 2, 3 })] |
|||
public void ReadUnsignedRationalArray_ReturnsValue(bool isLittleEndian, byte[] bytes, uint[] expectedNumerators, uint[] expectedDenominators) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Rational, (uint)expectedNumerators.Length, bytes), isLittleEndian); |
|||
|
|||
Rational[] result = decoder.ReadUnsignedRationalArray(ref entry); |
|||
Rational[] expectedValue = Enumerable.Range(0, expectedNumerators.Length).Select(i => new Rational(expectedNumerators[i], expectedDenominators[i])).ToArray(); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(true, new byte[] { 0, 0, 0, 0, 2, 0, 0, 0 }, new int[] { 0 }, new int[] { 2 })] |
|||
[InlineDataAttribute(true, new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, new int[] { 1 }, new int[] { 2 })] |
|||
[InlineDataAttribute(true, new byte[] { 255, 255, 255, 255, 2, 0, 0, 0 }, new int[] { -1 }, new int[] { 2 })] |
|||
[InlineDataAttribute(true, new byte[] { 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }, new int[] { -1, 2 }, new int[] { 2, 3 })] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 0, 0, 0, 0, 2 }, new int[] { 0 }, new int[] { 2 })] |
|||
[InlineDataAttribute(false, new byte[] { 0, 0, 0, 1, 0, 0, 0, 2 }, new int[] { 1 }, new int[] { 2 })] |
|||
[InlineDataAttribute(false, new byte[] { 255, 255, 255, 255, 0, 0, 0, 2 }, new int[] { -1 }, new int[] { 2 })] |
|||
[InlineDataAttribute(false, new byte[] { 255, 255, 255, 255, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3 }, new int[] { -1, 2 }, new int[] { 2, 3 })] |
|||
public void ReadSignedRationalArray_ReturnsValue(bool isLittleEndian, byte[] bytes, int[] expectedNumerators, int[] expectedDenominators) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.SRational, (uint)expectedNumerators.Length, bytes), isLittleEndian); |
|||
|
|||
SignedRational[] result = decoder.ReadSignedRationalArray(ref entry); |
|||
SignedRational[] expectedValue = Enumerable.Range(0, expectedNumerators.Length).Select(i => new SignedRational(expectedNumerators[i], expectedDenominators[i])).ToArray(); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadUnsignedRational_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadUnsignedRational(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a Rational.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadSignedRational_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadSignedRational(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a SignedRational.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadUnsignedRationalArray_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadUnsignedRationalArray(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a Rational.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadSignedRationalArray_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadSignedRationalArray(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a SignedRational.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false)] |
|||
[InlineDataAttribute(true)] |
|||
public void ReadUnsignedRational_ThrowsExceptionIfCountIsNotOne(bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Rational, 2, new byte[4]), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadUnsignedRational(ref entry)); |
|||
|
|||
Assert.Equal($"Cannot read a single value from an array of multiple items.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false)] |
|||
[InlineDataAttribute(true)] |
|||
public void ReadSignedRational_ThrowsExceptionIfCountIsNotOne(bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.SRational, 2, new byte[4]), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadSignedRational(ref entry)); |
|||
|
|||
Assert.Equal($"Cannot read a single value from an array of multiple items.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false, new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0.0F)] |
|||
[InlineDataAttribute(false, new byte[] { 0x3F, 0x80, 0x00, 0x00 }, 1.0F)] |
|||
[InlineDataAttribute(false, new byte[] { 0xC0, 0x00, 0x00, 0x00 }, -2.0F)] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0x7F, 0xFF, 0xFF }, float.MaxValue)] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0x80, 0x00, 0x00 }, float.PositiveInfinity)] |
|||
[InlineDataAttribute(false, new byte[] { 0xFF, 0x80, 0x00, 0x00 }, float.NegativeInfinity)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0.0F)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x80, 0x3F }, 1.0F)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0xC0 }, -2.0F)] |
|||
[InlineDataAttribute(true, new byte[] { 0xFF, 0xFF, 0x7F, 0x7F }, float.MaxValue)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x80, 0x7F }, float.PositiveInfinity)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x80, 0xFF }, float.NegativeInfinity)] |
|||
public void ReadFloat_ReturnsValue(bool isLittleEndian, byte[] bytes, float expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Float, 1, bytes), isLittleEndian); |
|||
|
|||
float result = decoder.ReadFloat(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadFloat_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadFloat(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a float.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false)] |
|||
[InlineDataAttribute(true)] |
|||
public void ReadFloat_ThrowsExceptionIfCountIsNotOne(bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Float, 2, new byte[4]), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadFloat(ref entry)); |
|||
|
|||
Assert.Equal($"Cannot read a single value from an array of multiple items.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false, new byte[] { 0x00, 0x00, 0x00, 0x00 }, new float[] { 0.0F })] |
|||
[InlineDataAttribute(false, new byte[] { 0x3F, 0x80, 0x00, 0x00 }, new float[] { 1.0F })] |
|||
[InlineDataAttribute(false, new byte[] { 0xC0, 0x00, 0x00, 0x00 }, new float[] { -2.0F })] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0x7F, 0xFF, 0xFF }, new float[] { float.MaxValue })] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0x80, 0x00, 0x00 }, new float[] { float.PositiveInfinity })] |
|||
[InlineDataAttribute(false, new byte[] { 0xFF, 0x80, 0x00, 0x00 }, new float[] { float.NegativeInfinity })] |
|||
[InlineDataAttribute(false, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00 }, new float[] { 0.0F, 1.0F, -2.0F })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00 }, new float[] { 0.0F })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x80, 0x3F }, new float[] { 1.0F })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0xC0 }, new float[] { -2.0F })] |
|||
[InlineDataAttribute(true, new byte[] { 0xFF, 0xFF, 0x7F, 0x7F }, new float[] { float.MaxValue })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x80, 0x7F }, new float[] { float.PositiveInfinity })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x80, 0xFF }, new float[] { float.NegativeInfinity })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xC0 }, new float[] { 0.0F, 1.0F, -2.0F })] |
|||
|
|||
public void ReadFloatArray_ReturnsValue(bool isLittleEndian, byte[] bytes, float[] expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Float, (uint)expectedValue.Length, bytes), isLittleEndian); |
|||
|
|||
float[] result = decoder.ReadFloatArray(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Double)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadFloatArray_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadFloatArray(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a float.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0.0)] |
|||
[InlineDataAttribute(false, new byte[] { 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 1.0)] |
|||
[InlineDataAttribute(false, new byte[] { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 2.0)] |
|||
[InlineDataAttribute(false, new byte[] { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -2.0)] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, double.MaxValue)] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, double.PositiveInfinity)] |
|||
[InlineDataAttribute(false, new byte[] { 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, double.NegativeInfinity)] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, double.NaN)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0.0)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F }, 1.0)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 }, 2.0)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }, -2.0)] |
|||
[InlineDataAttribute(true, new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F }, double.MaxValue)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F }, double.PositiveInfinity)] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF }, double.NegativeInfinity)] |
|||
[InlineDataAttribute(true, new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }, double.NaN)] |
|||
public void ReadDouble_ReturnsValue(bool isLittleEndian, byte[] bytes, double expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Double, 1, bytes), isLittleEndian); |
|||
|
|||
double result = decoder.ReadDouble(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadDouble_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadDouble(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a double.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false)] |
|||
[InlineDataAttribute(true)] |
|||
public void ReadDouble_ThrowsExceptionIfCountIsNotOne(bool isLittleEndian) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Double, 2, new byte[4]), isLittleEndian); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadDouble(ref entry)); |
|||
|
|||
Assert.Equal($"Cannot read a single value from an array of multiple items.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(false, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { 0.0 })] |
|||
[InlineDataAttribute(false, new byte[] { 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { 1.0 })] |
|||
[InlineDataAttribute(false, new byte[] { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { 2.0 })] |
|||
[InlineDataAttribute(false, new byte[] { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { -2.0 })] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, new double[] { double.MaxValue })] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { double.PositiveInfinity })] |
|||
[InlineDataAttribute(false, new byte[] { 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { double.NegativeInfinity })] |
|||
[InlineDataAttribute(false, new byte[] { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, new double[] { double.NaN })] |
|||
[InlineDataAttribute(false, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { 0.0, 1.0, -2.0 })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { 0.0 })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F }, new double[] { 1.0 })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 }, new double[] { 2.0 })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }, new double[] { -2.0 })] |
|||
[InlineDataAttribute(true, new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F }, new double[] { double.MaxValue })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F }, new double[] { double.PositiveInfinity })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF }, new double[] { double.NegativeInfinity })] |
|||
[InlineDataAttribute(true, new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }, new double[] { double.NaN })] |
|||
[InlineDataAttribute(true, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }, new double[] { 0.0, 1.0, -2.0 })] |
|||
public void ReadDoubleArray_ReturnsValue(bool isLittleEndian, byte[] bytes, double[] expectedValue) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, TiffType.Double, (uint)expectedValue.Length, bytes), isLittleEndian); |
|||
|
|||
double[] result = decoder.ReadDoubleArray(ref entry); |
|||
|
|||
Assert.Equal(expectedValue, result); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute((ushort)TiffType.Byte)] |
|||
[InlineDataAttribute((ushort)TiffType.Ascii)] |
|||
[InlineDataAttribute((ushort)TiffType.Short)] |
|||
[InlineDataAttribute((ushort)TiffType.Long)] |
|||
[InlineDataAttribute((ushort)TiffType.Rational)] |
|||
[InlineDataAttribute((ushort)TiffType.SByte)] |
|||
[InlineDataAttribute((ushort)TiffType.Undefined)] |
|||
[InlineDataAttribute((ushort)TiffType.SShort)] |
|||
[InlineDataAttribute((ushort)TiffType.SLong)] |
|||
[InlineDataAttribute((ushort)TiffType.SRational)] |
|||
[InlineDataAttribute((ushort)TiffType.Float)] |
|||
[InlineDataAttribute((ushort)TiffType.Ifd)] |
|||
[InlineDataAttribute((ushort)99)] |
|||
public void ReadDoubleArray_ThrowsExceptionIfInvalidType(ushort type) |
|||
{ |
|||
(TiffDecoderCore decoder, TiffIfdEntry entry) = GenerateTestIfdEntry(TiffGenEntry.Bytes(TiffTags.ImageWidth, (TiffType)type, 1, new byte[4]), true); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadDoubleArray(ref entry)); |
|||
|
|||
Assert.Equal($"A value of type '{(TiffType)type}' cannot be converted to a double.", e.Message); |
|||
} |
|||
|
|||
private (TiffDecoderCore, TiffIfdEntry) GenerateTestIfdEntry(TiffGenEntry entry, bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
entry |
|||
} |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfdEntry ifdEntry = decoder.ReadIfd(0).Entries[0]; |
|||
|
|||
return (decoder, ifdEntry); |
|||
} |
|||
} |
|||
} |
|||
@ -1,108 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.IO; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffDecoderIfdTests |
|||
{ |
|||
public static object[][] IsLittleEndianValues = new[] { new object[] { false }, |
|||
new object[] { true } }; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadIfd_ReadsNextIfdOffset_IfPresent(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, 150) |
|||
}, |
|||
NextIfd = new TiffGenIfd() |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
Assert.Equal(18u, ifd.NextIfdOffset); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadIfd_ReadsNextIfdOffset_ZeroIfLastIfd(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, 150) |
|||
} |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
Assert.Equal(0u, ifd.NextIfdOffset); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadIfd_ReturnsCorrectNumberOfEntries(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, 150), |
|||
TiffGenEntry.Integer(TiffTags.ImageLength, TiffType.Long, 210), |
|||
TiffGenEntry.Integer(TiffTags.Orientation, TiffType.Short, 1), |
|||
TiffGenEntry.Ascii(TiffTags.Artist, "Image Artist Name"), |
|||
TiffGenEntry.Ascii(TiffTags.HostComputer, "Host Computer Name") |
|||
}, |
|||
NextIfd = new TiffGenIfd() |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
Assert.NotNull(ifd.Entries); |
|||
Assert.Equal(5, ifd.Entries.Length); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadIfd_ReadsRawTiffEntryData(bool isLittleEndian) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, 150), |
|||
TiffGenEntry.Integer(TiffTags.ImageLength, TiffType.Long, 210), |
|||
TiffGenEntry.Integer(TiffTags.Orientation, TiffType.Short, 1) |
|||
}, |
|||
NextIfd = new TiffGenIfd() |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
TiffIfdEntry entry = ifd.Entries[1]; |
|||
|
|||
byte[] expectedData = isLittleEndian ? new byte[] { 210, 0, 0, 0 } : new byte[] { 0, 0, 0, 210 }; |
|||
|
|||
Assert.Equal(TiffTags.ImageLength, entry.Tag); |
|||
Assert.Equal(TiffType.Long, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(expectedData, entry.Value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,510 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffDecoderImageTests |
|||
{ |
|||
public const int ImageWidth = 200; |
|||
public const int ImageHeight = 150; |
|||
|
|||
public static object[][] IsLittleEndianValues = new[] { new object[] { false }, |
|||
new object[] { true } }; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DecodeImage_SetsImageDimensions(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
Image<Rgba32> image = decoder.DecodeImage<Rgba32>(ifd); |
|||
|
|||
Assert.Equal(ImageWidth, image.Width); |
|||
Assert.Equal(ImageHeight, image.Height); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DecodeImage_ThrowsException_WithMissingImageWidth(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithoutEntry(TiffTags.ImageWidth) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.DecodeImage<Rgba32>(ifd)); |
|||
|
|||
Assert.Equal("The TIFF IFD does not specify the image dimensions.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DecodeImage_ThrowsException_WithMissingImageLength(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithoutEntry(TiffTags.ImageLength) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.DecodeImage<Rgba32>(ifd)); |
|||
|
|||
Assert.Equal("The TIFF IFD does not specify the image dimensions.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffCompression.None, (int)TiffCompressionType.None)] |
|||
[InlineData(true, (ushort)TiffCompression.None, (int)TiffCompressionType.None)] |
|||
[InlineData(false, (ushort)TiffCompression.PackBits, (int)TiffCompressionType.PackBits)] |
|||
[InlineData(true, (ushort)TiffCompression.PackBits, (int)TiffCompressionType.PackBits)] |
|||
[InlineData(false, (ushort)TiffCompression.Deflate, (int)TiffCompressionType.Deflate)] |
|||
[InlineData(true, (ushort)TiffCompression.Deflate, (int)TiffCompressionType.Deflate)] |
|||
[InlineData(false, (ushort)TiffCompression.OldDeflate, (int)TiffCompressionType.Deflate)] |
|||
[InlineData(true, (ushort)TiffCompression.OldDeflate, (int)TiffCompressionType.Deflate)] |
|||
[InlineData(false, (ushort)TiffCompression.Lzw, (int)TiffCompressionType.Lzw)] |
|||
[InlineData(true, (ushort)TiffCompression.Lzw, (int)TiffCompressionType.Lzw)] |
|||
public void ReadImageFormat_DeterminesCorrectCompressionImplementation(bool isLittleEndian, ushort compression, int compressionType) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.Compression, TiffType.Short, compression)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal((TiffCompressionType)compressionType, decoder.CompressionType); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffCompression.Ccitt1D)] |
|||
[InlineData(false, (ushort)TiffCompression.CcittGroup3Fax)] |
|||
[InlineData(false, (ushort)TiffCompression.CcittGroup4Fax)] |
|||
[InlineData(false, (ushort)TiffCompression.ItuTRecT43)] |
|||
[InlineData(false, (ushort)TiffCompression.ItuTRecT82)] |
|||
[InlineData(false, (ushort)TiffCompression.Jpeg)] |
|||
[InlineData(false, (ushort)TiffCompression.OldJpeg)] |
|||
[InlineData(false, 999)] |
|||
[InlineData(true, (ushort)TiffCompression.Ccitt1D)] |
|||
[InlineData(true, (ushort)TiffCompression.CcittGroup3Fax)] |
|||
[InlineData(true, (ushort)TiffCompression.CcittGroup4Fax)] |
|||
[InlineData(true, (ushort)TiffCompression.ItuTRecT43)] |
|||
[InlineData(true, (ushort)TiffCompression.ItuTRecT82)] |
|||
[InlineData(true, (ushort)TiffCompression.Jpeg)] |
|||
[InlineData(true, (ushort)TiffCompression.OldJpeg)] |
|||
[InlineData(true, 999)] |
|||
public void ReadImageFormat_ThrowsExceptionForUnsupportedCompression(bool isLittleEndian, ushort compression) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.Compression, TiffType.Short, compression)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<NotSupportedException>(() => decoder.ReadImageFormat(ifd)); |
|||
|
|||
Assert.Equal("The specified TIFF compression format is not supported.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 3 }, (int)TiffColorType.WhiteIsZero)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 3 }, (int)TiffColorType.WhiteIsZero)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 8 }, (int)TiffColorType.WhiteIsZero8)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 8 }, (int)TiffColorType.WhiteIsZero8)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 4 }, (int)TiffColorType.WhiteIsZero4)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 4 }, (int)TiffColorType.WhiteIsZero4)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 1 }, (int)TiffColorType.WhiteIsZero1)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 1 }, (int)TiffColorType.WhiteIsZero1)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 3 }, (int)TiffColorType.BlackIsZero)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 3 }, (int)TiffColorType.BlackIsZero)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 8 }, (int)TiffColorType.BlackIsZero8)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 8 }, (int)TiffColorType.BlackIsZero8)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 4 }, (int)TiffColorType.BlackIsZero4)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 4 }, (int)TiffColorType.BlackIsZero4)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 1 }, (int)TiffColorType.BlackIsZero1)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 1 }, (int)TiffColorType.BlackIsZero1)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 3 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 3 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 8 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 8 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 4 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 4 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 1 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 1 }, (int)TiffColorType.PaletteColor)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 4, 4, 4 }, (int)TiffColorType.Rgb)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 4, 4, 4 }, (int)TiffColorType.Rgb)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8, 8, 8 }, (int)TiffColorType.Rgb888)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8, 8, 8 }, (int)TiffColorType.Rgb888)] |
|||
public void ReadImageFormat_DeterminesCorrectColorImplementation_Chunky(bool isLittleEndian, ushort photometricInterpretation, int[] bitsPerSample, int colorType) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, photometricInterpretation)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PlanarConfiguration, TiffType.Short, (int)TiffPlanarConfiguration.Chunky)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, bitsPerSample)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal((TiffColorType)colorType, decoder.ColorType); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 4, 4, 4 }, (int)TiffColorType.RgbPlanar)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 4, 4, 4 }, (int)TiffColorType.RgbPlanar)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8, 8, 8 }, (int)TiffColorType.RgbPlanar)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8, 8, 8 }, (int)TiffColorType.RgbPlanar)] |
|||
public void ReadImageFormat_DeterminesCorrectColorImplementation_Planar(bool isLittleEndian, ushort photometricInterpretation, int[] bitsPerSample, int colorType) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, photometricInterpretation)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PlanarConfiguration, TiffType.Short, (int)TiffPlanarConfiguration.Planar)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, bitsPerSample)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal((TiffColorType)colorType, decoder.ColorType); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, (int)TiffColorType.WhiteIsZero1)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, (int)TiffColorType.WhiteIsZero1)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, (int)TiffColorType.BlackIsZero1)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, (int)TiffColorType.BlackIsZero1)] |
|||
public void ReadImageFormat_DeterminesCorrectColorImplementation_DefaultsToBilevel(bool isLittleEndian, ushort photometricInterpretation, int colorType) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, photometricInterpretation)) |
|||
.WithoutEntry(TiffTags.BitsPerSample) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal((TiffColorType)colorType, decoder.ColorType); |
|||
} |
|||
|
|||
// [Theory]
|
|||
// [InlineData(false, new[] { 8 }, (int)TiffColorType.WhiteIsZero8)]
|
|||
// [InlineData(true, new[] { 8 }, (int)TiffColorType.WhiteIsZero8)]
|
|||
// public void ReadImageFormat_UsesDefaultColorImplementationForCcitt1D(bool isLittleEndian, int[] bitsPerSample, int colorType)
|
|||
// {
|
|||
// Stream stream = CreateTiffGenIfd()
|
|||
// .WithEntry(TiffGenEntry.Integer(TiffTags.Compression, TiffType.Short, (int)TiffCompression.Ccitt1D))
|
|||
// .WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, bitsPerSample))
|
|||
// .WithoutEntry(TiffTags.PhotometricInterpretation)
|
|||
// .ToStream(isLittleEndian);
|
|||
|
|||
// TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null);
|
|||
// TiffIfd ifd = decoder.ReadIfd(0);
|
|||
// decoder.ReadImageFormat(ifd);
|
|||
|
|||
// Assert.Equal((TiffColorType)colorType, decoder.ColorType);
|
|||
// }
|
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadImageFormat_ThrowsExceptionForMissingPhotometricInterpretation(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithoutEntry(TiffTags.PhotometricInterpretation) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadImageFormat(ifd)); |
|||
|
|||
Assert.Equal("The TIFF photometric interpretation entry is missing.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.CieLab)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.ColorFilterArray)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.IccLab)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.ItuLab)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.LinearRaw)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Separated)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.TransparencyMask)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.YCbCr)] |
|||
[InlineData(false, 999)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.CieLab)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.ColorFilterArray)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.IccLab)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.ItuLab)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.LinearRaw)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Separated)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.TransparencyMask)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.YCbCr)] |
|||
[InlineData(true, 999)] |
|||
public void ReadImageFormat_ThrowsExceptionForUnsupportedPhotometricInterpretation(bool isLittleEndian, ushort photometricInterpretation) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, photometricInterpretation)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<NotSupportedException>(() => decoder.ReadImageFormat(ifd)); |
|||
|
|||
Assert.Equal("The specified TIFF photometric interpretation is not supported.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, new[] { 8u })] |
|||
[InlineData(true, new[] { 8u })] |
|||
[InlineData(false, new[] { 4u })] |
|||
[InlineData(true, new[] { 4u })] |
|||
[InlineData(false, new[] { 1u })] |
|||
[InlineData(true, new[] { 1u })] |
|||
// [InlineData(false, new[] { 1u, 2u, 3u })]
|
|||
// [InlineData(true, new[] { 1u, 2u, 3u })]
|
|||
// [InlineData(false, new[] { 8u, 8u, 8u })]
|
|||
// [InlineData(true, new[] { 8u, 8u, 8u })]
|
|||
public void ReadImageFormat_ReadsBitsPerSample(bool isLittleEndian, uint[] bitsPerSample) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, bitsPerSample)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal(bitsPerSample, decoder.BitsPerSample); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero)] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero)] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero)] |
|||
public void ReadImageFormat_ReadsBitsPerSample_DefaultsToBilevel(bool isLittleEndian, ushort photometricInterpretation) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, photometricInterpretation)) |
|||
.WithoutEntry(TiffTags.BitsPerSample) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal(new[] { 1u }, decoder.BitsPerSample); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadImageFormat_ThrowsExceptionForMissingBitsPerSample(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, (int)TiffPhotometricInterpretation.PaletteColor)) |
|||
.WithoutEntry(TiffTags.BitsPerSample) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadImageFormat(ifd)); |
|||
|
|||
Assert.Equal("The TIFF BitsPerSample entry is missing.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new int[] { })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new int[] { })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, new int[] { })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, new int[] { })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.PaletteColor, new int[] { })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.PaletteColor, new int[] { })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new int[] { })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new int[] { })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 8, 8 })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.WhiteIsZero, new[] { 8, 8 })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 8, 8 })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.BlackIsZero, new[] { 8, 8 })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 8, 8 })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.PaletteColor, new[] { 8, 8 })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8 })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8 })] |
|||
[InlineData(false, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8, 8 })] |
|||
[InlineData(true, (ushort)TiffPhotometricInterpretation.Rgb, new[] { 8, 8 })] |
|||
public void ReadImageFormat_ThrowsExceptionForUnsupportedNumberOfSamples(bool isLittleEndian, ushort photometricInterpretation, int[] bitsPerSample) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, photometricInterpretation)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, bitsPerSample)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<NotSupportedException>(() => decoder.ReadImageFormat(ifd)); |
|||
|
|||
Assert.Equal("The number of samples in the TIFF BitsPerSample entry is not supported.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadImageFormat_ReadsColorMap(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, (int)TiffPhotometricInterpretation.PaletteColor)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.ColorMap, TiffType.Short, new int[] { 10, 20, 30, 40, 50, 60 })) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal(new uint[] { 10, 20, 30, 40, 50, 60 }, decoder.ColorMap); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadImageFormat_ThrowsExceptionForMissingColorMap(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, (int)TiffPhotometricInterpretation.PaletteColor)) |
|||
.WithoutEntry(TiffTags.ColorMap) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
|
|||
var e = Assert.Throws<ImageFormatException>(() => decoder.ReadImageFormat(ifd)); |
|||
|
|||
Assert.Equal("The TIFF ColorMap entry is missing for a pallete color image.", e.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(false, (ushort)TiffPlanarConfiguration.Chunky)] |
|||
[InlineData(true, (ushort)TiffPlanarConfiguration.Chunky)] |
|||
[InlineData(false, (ushort)TiffPlanarConfiguration.Planar)] |
|||
[InlineData(true, (ushort)TiffPlanarConfiguration.Planar)] |
|||
public void ReadImageFormat_ReadsPlanarConfiguration(bool isLittleEndian, int planarConfiguration) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, (int)TiffPhotometricInterpretation.Rgb)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, new int[] { 8, 8, 8 })) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PlanarConfiguration, TiffType.Short, (int)planarConfiguration)) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal((TiffPlanarConfiguration)planarConfiguration, decoder.PlanarConfiguration); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void ReadImageFormat_DefaultsPlanarConfigurationToChunky(bool isLittleEndian) |
|||
{ |
|||
Stream stream = CreateTiffGenIfd() |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, (int)TiffPhotometricInterpretation.Rgb)) |
|||
.WithEntry(TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, new int[] { 8, 8, 8 })) |
|||
.WithoutEntry(TiffTags.PlanarConfiguration) |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
decoder.ReadImageFormat(ifd); |
|||
|
|||
Assert.Equal(TiffPlanarConfiguration.Chunky, decoder.PlanarConfiguration); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData((ushort)TiffColorType.WhiteIsZero, new uint[] { 1 }, 160, 80, 20 * 80)] |
|||
[InlineData((ushort)TiffColorType.WhiteIsZero, new uint[] { 1 }, 153, 80, 20 * 80)] |
|||
[InlineData((ushort)TiffColorType.WhiteIsZero, new uint[] { 3 }, 100, 80, 38 * 80)] |
|||
[InlineData((ushort)TiffColorType.WhiteIsZero, new uint[] { 4 }, 100, 80, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.WhiteIsZero, new uint[] { 4 }, 99, 80, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.WhiteIsZero, new uint[] { 8 }, 100, 80, 100 * 80)] |
|||
[InlineData((ushort)TiffColorType.PaletteColor, new uint[] { 1 }, 160, 80, 20 * 80)] |
|||
[InlineData((ushort)TiffColorType.PaletteColor, new uint[] { 1 }, 153, 80, 20 * 80)] |
|||
[InlineData((ushort)TiffColorType.PaletteColor, new uint[] { 3 }, 100, 80, 38 * 80)] |
|||
[InlineData((ushort)TiffColorType.PaletteColor, new uint[] { 4 }, 100, 80, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.PaletteColor, new uint[] { 4 }, 99, 80, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.PaletteColor, new uint[] { 8 }, 100, 80, 100 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 8, 8, 8 }, 100, 80, 300 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 4, 4 }, 100, 80, 150 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 100, 80, 200 * 80)] |
|||
public void CalculateImageBufferSize_ReturnsCorrectSize_Chunky(ushort colorType, uint[] bitsPerSample, int width, int height, int expectedResult) |
|||
{ |
|||
TiffDecoderCore decoder = new TiffDecoderCore(null, null); |
|||
decoder.ColorType = (TiffColorType)colorType; |
|||
decoder.PlanarConfiguration = TiffPlanarConfiguration.Chunky; |
|||
decoder.BitsPerSample = bitsPerSample; |
|||
|
|||
int bufferSize = decoder.CalculateImageBufferSize(width, height, 0); |
|||
|
|||
Assert.Equal(expectedResult, bufferSize); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 8, 8, 8 }, 100, 80, 0, 100 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 8, 8, 8 }, 100, 80, 1, 100 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 8, 8, 8 }, 100, 80, 2, 100 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 4, 4 }, 100, 80, 0, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 4, 4 }, 100, 80, 1, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 4, 4 }, 100, 80, 2, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 100, 80, 0, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 100, 80, 1, 100 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 100, 80, 2, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 99, 80, 0, 50 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 99, 80, 1, 99 * 80)] |
|||
[InlineData((ushort)TiffColorType.Rgb, new uint[] { 4, 8, 4 }, 99, 80, 2, 50 * 80)] |
|||
|
|||
public void CalculateImageBufferSize_ReturnsCorrectSize_Planar(ushort colorType, uint[] bitsPerSample, int width, int height, int plane, int expectedResult) |
|||
{ |
|||
TiffDecoderCore decoder = new TiffDecoderCore(null, null); |
|||
decoder.ColorType = (TiffColorType)colorType; |
|||
decoder.PlanarConfiguration = TiffPlanarConfiguration.Planar; |
|||
decoder.BitsPerSample = bitsPerSample; |
|||
|
|||
int bufferSize = decoder.CalculateImageBufferSize(width, height, plane); |
|||
|
|||
Assert.Equal(expectedResult, bufferSize); |
|||
} |
|||
|
|||
private TiffGenIfd CreateTiffGenIfd() |
|||
{ |
|||
return new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, ImageWidth), |
|||
TiffGenEntry.Integer(TiffTags.ImageLength, TiffType.Long, ImageHeight), |
|||
TiffGenEntry.Rational(TiffTags.XResolution, 100, 1), |
|||
TiffGenEntry.Rational(TiffTags.YResolution, 200, 1), |
|||
TiffGenEntry.Integer(TiffTags.ResolutionUnit, TiffType.Short, 2), |
|||
TiffGenEntry.Integer(TiffTags.PhotometricInterpretation, TiffType.Short, (int)TiffPhotometricInterpretation.WhiteIsZero), |
|||
TiffGenEntry.Integer(TiffTags.BitsPerSample, TiffType.Short, new int[] { 8 }), |
|||
TiffGenEntry.Integer(TiffTags.Compression, TiffType.Short, (int)TiffCompression.None), |
|||
TiffGenEntry.Integer(TiffTags.ColorMap, TiffType.Short, new int[256]) |
|||
} |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -1,134 +0,0 @@ |
|||
// 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 |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffDecoderMetadataTests |
|||
{ |
|||
public static object[][] BaselineMetadataValues = new[] { new object[] { false, TiffTags.Artist, TiffMetadataNames.Artist, "My Artist Name" }, |
|||
new object[] { false, TiffTags.Copyright, TiffMetadataNames.Copyright, "My Copyright Statement" }, |
|||
new object[] { false, TiffTags.DateTime, TiffMetadataNames.DateTime, "My DateTime Value" }, |
|||
new object[] { false, TiffTags.HostComputer, TiffMetadataNames.HostComputer, "My Host Computer Name" }, |
|||
new object[] { false, TiffTags.ImageDescription, TiffMetadataNames.ImageDescription, "My Image Description" }, |
|||
new object[] { false, TiffTags.Make, TiffMetadataNames.Make, "My Camera Make" }, |
|||
new object[] { false, TiffTags.Model, TiffMetadataNames.Model, "My Camera Model" }, |
|||
new object[] { false, TiffTags.Software, TiffMetadataNames.Software, "My Imaging Software" }, |
|||
new object[] { true, TiffTags.Artist, TiffMetadataNames.Artist, "My Artist Name" }, |
|||
new object[] { true, TiffTags.Copyright, TiffMetadataNames.Copyright, "My Copyright Statement" }, |
|||
new object[] { true, TiffTags.DateTime, TiffMetadataNames.DateTime, "My DateTime Value" }, |
|||
new object[] { true, TiffTags.HostComputer, TiffMetadataNames.HostComputer, "My Host Computer Name" }, |
|||
new object[] { true, TiffTags.ImageDescription, TiffMetadataNames.ImageDescription, "My Image Description" }, |
|||
new object[] { true, TiffTags.Make, TiffMetadataNames.Make, "My Camera Make" }, |
|||
new object[] { true, TiffTags.Model, TiffMetadataNames.Model, "My Camera Model" }, |
|||
new object[] { true, TiffTags.Software, TiffMetadataNames.Software, "My Imaging Software" }}; |
|||
|
|||
[Theory] |
|||
[InlineData(false, 150u, 1u, 200u, 1u, 2u /* Inch */, 150.0, 200.0)] |
|||
[InlineData(false, 150u, 1u, 200u, 1u, 3u /* Cm */, 150.0 * 2.54, 200.0 * 2.54)] |
|||
[InlineData(false, 150u, 1u, 200u, 1u, 1u /* None */, 96.0, 96.0)] |
|||
[InlineData(false, 150u, 1u, 200u, 1u, null /* Inch */, 150.0, 200.0)] |
|||
[InlineData(false, 5u, 2u, 9u, 4u, 2u /* Inch */, 2.5, 2.25)] |
|||
[InlineData(false, null, null, null, null, null /* Inch */, 96.0, 96.0)] |
|||
[InlineData(false, 150u, 1u, null, null, 2u /* Inch */, 150.0, 96.0)] |
|||
[InlineData(false, null, null, 200u, 1u, 2u /* Inch */, 96.0, 200.0)] |
|||
[InlineData(true, 150u, 1u, 200u, 1u, 2u /* Inch */, 150.0, 200.0)] |
|||
[InlineData(true, 150u, 1u, 200u, 1u, 3u /* Cm */, 150.0 * 2.54, 200.0 * 2.54)] |
|||
[InlineData(true, 150u, 1u, 200u, 1u, 1u /* None */, 96.0, 96.0)] |
|||
[InlineData(true, 5u, 2u, 9u, 4u, 2u /* Inch */, 2.5, 2.25)] |
|||
[InlineData(true, 150u, 1u, 200u, 1u, null /* Inch */, 150.0, 200.0)] |
|||
[InlineData(true, null, null, null, null, null /* Inch */, 96.0, 96.0)] |
|||
[InlineData(true, 150u, 1u, null, null, 2u /* Inch */, 150.0, 96.0)] |
|||
[InlineData(true, null, null, 200u, 1u, 2u /* Inch */, 96.0, 200.0)] |
|||
public void ReadMetadata_SetsImageResolution(bool isLittleEndian, uint? xResolutionNumerator, uint? xResolutionDenominator, |
|||
uint? yResolutionNumerator, uint? yResolutionDenominator, uint? resolutionUnit, |
|||
double expectedHorizonalResolution, double expectedVerticalResolution) |
|||
{ |
|||
TiffGenIfd ifdGen = new TiffGenIfd(); |
|||
|
|||
if (xResolutionNumerator != null) |
|||
{ |
|||
ifdGen.WithEntry(TiffGenEntry.Rational(TiffTags.XResolution, xResolutionNumerator.Value, xResolutionDenominator.Value)); |
|||
} |
|||
|
|||
if (yResolutionNumerator != null) |
|||
{ |
|||
ifdGen.WithEntry(TiffGenEntry.Rational(TiffTags.YResolution, yResolutionNumerator.Value, yResolutionDenominator.Value)); |
|||
} |
|||
|
|||
if (resolutionUnit != null) |
|||
{ |
|||
ifdGen.WithEntry(TiffGenEntry.Integer(TiffTags.ResolutionUnit, TiffType.Short, resolutionUnit.Value)); |
|||
} |
|||
|
|||
Stream stream = ifdGen.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
Image<Rgba32> image = new Image<Rgba32>(null, 20, 20); |
|||
|
|||
decoder.ReadMetadata<Rgba32>(ifd, image); |
|||
|
|||
Assert.Equal(expectedHorizonalResolution, image.Metadata.HorizontalResolution, 10); |
|||
Assert.Equal(expectedVerticalResolution, image.Metadata.VerticalResolution, 10); |
|||
} |
|||
/* |
|||
[Theory] |
|||
[MemberData(nameof(BaselineMetadataValues))] |
|||
public void ReadMetadata_SetsAsciiMetadata(bool isLittleEndian, ushort tag, string metadataName, string metadataValue) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, 150), |
|||
TiffGenEntry.Integer(TiffTags.ImageLength, TiffType.Long, 210), |
|||
TiffGenEntry.Ascii(tag, metadataValue), |
|||
TiffGenEntry.Integer(TiffTags.Orientation, TiffType.Short, 1) |
|||
} |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, null); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
Image<Rgba32> image = new Image<Rgba32>(null, 20, 20); |
|||
|
|||
decoder.ReadMetadata<Rgba32>(ifd, image); |
|||
var metadata = image.Metadata.Properties.FirstOrDefault(m => m.Name == metadataName).Value; |
|||
|
|||
Assert.Equal(metadataValue, metadata); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(BaselineMetadataValues))] |
|||
public void ReadMetadata_DoesntSetMetadataIfIgnoring(bool isLittleEndian, ushort tag, string metadataName, string metadataValue) |
|||
{ |
|||
Stream stream = new TiffGenIfd() |
|||
{ |
|||
Entries = |
|||
{ |
|||
TiffGenEntry.Integer(TiffTags.ImageWidth, TiffType.Long, 150), |
|||
TiffGenEntry.Integer(TiffTags.ImageLength, TiffType.Long, 210), |
|||
TiffGenEntry.Ascii(tag, metadataValue), |
|||
TiffGenEntry.Integer(TiffTags.Orientation, TiffType.Short, 1) |
|||
} |
|||
} |
|||
.ToStream(isLittleEndian); |
|||
|
|||
TiffDecoder options = new TiffDecoder() { IgnoreMetadata = true }; |
|||
TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, options); |
|||
TiffIfd ifd = decoder.ReadIfd(0); |
|||
Image<Rgba32> image = new Image<Rgba32>(null, 20, 20); |
|||
|
|||
decoder.ReadMetadata<Rgba32>(ifd, image); |
|||
var metadata = image.Metadata.Properties.FirstOrDefault(m => m.Name == metadataName).Value; |
|||
|
|||
Assert.Null(metadata); |
|||
} */ |
|||
} |
|||
} |
|||
@ -1,295 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffEncoderIfdTests |
|||
{ |
|||
[Fact] |
|||
public void WriteIfd_DataIsCorrectLength() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Long, 1, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Long, 1, new byte[] { 9, 10, 11, 12 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
Assert.Equal(2 + 12 * 3 + 4, stream.Length); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesNumberOfEntries() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Long, 1, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Long, 1, new byte[] { 9, 10, 11, 12 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntryBytes = stream.ToArray().Take(2).ToArray(); |
|||
Assert.Equal(new byte[] { 3, 0 }, ifdEntryBytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_ReturnsNextIfdMarker() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Long, 1, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Long, 1, new byte[] { 9, 10, 11, 12 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
Assert.Equal(2 + 12 * 3, nextIfdMarker); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesTagIdForEachEntry() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(10, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(20, TiffType.Long, 1, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(30, TiffType.Long, 1, new byte[] { 9, 10, 11, 12 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(2 + 12 * 0).Take(2).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(2 + 12 * 1).Take(2).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(2 + 12 * 2).Take(2).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 10, 0 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 20, 0 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { 30, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesTypeForEachEntry() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Short, 2, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Ascii, 4, new byte[] { (byte)'A', (byte)'B', (byte)'C', 0 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(4 + 12 * 0).Take(2).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(4 + 12 * 1).Take(2).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(4 + 12 * 2).Take(2).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 4, 0 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 3, 0 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { 2, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesCountForEachEntry() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Short, 2, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Ascii, 4, new byte[] { (byte)'A', (byte)'B', (byte)'C', 0 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(6 + 12 * 0).Take(4).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(6 + 12 * 1).Take(4).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(6 + 12 * 2).Take(4).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 1, 0, 0, 0 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 2, 0, 0, 0 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { 4, 0, 0, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesDataInline() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Short, 2, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Ascii, 3, new byte[] { (byte)'A', (byte)'B', 0 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(10 + 12 * 0).Take(4).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(10 + 12 * 1).Take(4).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(10 + 12 * 2).Take(4).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 1, 2, 3, 4 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 5, 6, 7, 8 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { (byte)'A', (byte)'B', 0, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesDataByReference() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Byte, 8, new byte[] { 1, 2, 3, 4, 4, 3, 2, 1 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Short, 4, new byte[] { 5, 6, 7, 8, 9, 10, 11, 12 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Ascii, 3, new byte[] { (byte)'A', (byte)'B', 0 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
writer.Write(new byte[] { 1, 2, 3, 4 }); |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(14 + 12 * 0).Take(4).ToArray(); |
|||
var ifdEntry1Data = stream.ToArray().Skip(46).Take(8).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(14 + 12 * 1).Take(4).ToArray(); |
|||
var ifdEntry2Data = stream.ToArray().Skip(54).Take(8).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(14 + 12 * 2).Take(4).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 46, 0, 0, 0 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 1, 2, 3, 4, 4, 3, 2, 1 }, ifdEntry1Data); |
|||
Assert.Equal(new byte[] { 54, 0, 0, 0 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { 5, 6, 7, 8, 9, 10, 11, 12 }, ifdEntry2Data); |
|||
Assert.Equal(new byte[] { (byte)'A', (byte)'B', 0, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesDataByReferenceOnWordBoundary() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(TiffTags.ImageWidth, TiffType.Byte, 8, new byte[] { 1, 2, 3, 4, 5 }), |
|||
new TiffIfdEntry(TiffTags.ImageLength, TiffType.Short, 4, new byte[] { 5, 6, 7, 8, 9, 10, 11, 12 }), |
|||
new TiffIfdEntry(TiffTags.Compression, TiffType.Ascii, 3, new byte[] { (byte)'A', (byte)'B', 0 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
writer.Write(new byte[] { 1, 2, 3, 4 }); |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(14 + 12 * 0).Take(4).ToArray(); |
|||
var ifdEntry1Data = stream.ToArray().Skip(46).Take(5).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(14 + 12 * 1).Take(4).ToArray(); |
|||
var ifdEntry2Data = stream.ToArray().Skip(52).Take(8).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(14 + 12 * 2).Take(4).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 46, 0, 0, 0 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 1, 2, 3, 4, 5 }, ifdEntry1Data); |
|||
Assert.Equal(new byte[] { 52, 0, 0, 0 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { 5, 6, 7, 8, 9, 10, 11, 12 }, ifdEntry2Data); |
|||
Assert.Equal(new byte[] { (byte)'A', (byte)'B', 0, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_WritesEntriesInCorrectOrder() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>() |
|||
{ |
|||
new TiffIfdEntry(10, TiffType.Long, 1, new byte[] { 1, 2, 3, 4 }), |
|||
new TiffIfdEntry(30, TiffType.Long, 1, new byte[] { 5, 6, 7, 8 }), |
|||
new TiffIfdEntry(20, TiffType.Long, 1, new byte[] { 9, 10, 11, 12 }) |
|||
}; |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
long nextIfdMarker = encoder.WriteIfd(writer, entries); |
|||
} |
|||
|
|||
var ifdEntry1Bytes = stream.ToArray().Skip(2 + 12 * 0).Take(2).ToArray(); |
|||
var ifdEntry2Bytes = stream.ToArray().Skip(2 + 12 * 1).Take(2).ToArray(); |
|||
var ifdEntry3Bytes = stream.ToArray().Skip(2 + 12 * 2).Take(2).ToArray(); |
|||
|
|||
Assert.Equal(new byte[] { 10, 0 }, ifdEntry1Bytes); |
|||
Assert.Equal(new byte[] { 20, 0 }, ifdEntry2Bytes); |
|||
Assert.Equal(new byte[] { 30, 0 }, ifdEntry3Bytes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WriteIfd_ThrowsException_IfNoEntriesArePresent() |
|||
{ |
|||
MemoryStream stream = new MemoryStream(); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> entries = new List<TiffIfdEntry>(); |
|||
|
|||
using (TiffWriter writer = new TiffWriter(stream)) |
|||
{ |
|||
ArgumentException e = Assert.Throws<ArgumentException>(() => { encoder.WriteIfd(writer, entries); }); |
|||
|
|||
Assert.Equal($"There must be at least one entry per IFD.{Environment.NewLine}Parameter name: entries", e.Message); |
|||
Assert.Equal("entries", e.ParamName); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Collections.Generic; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffEncoderMetadataTests |
|||
{ |
|||
public static object[][] BaselineMetadataValues = new[] { new object[] { TiffTags.Artist, TiffMetadataNames.Artist, "My Artist Name" }, |
|||
new object[] { TiffTags.Copyright, TiffMetadataNames.Copyright, "My Copyright Statement" }, |
|||
new object[] { TiffTags.DateTime, TiffMetadataNames.DateTime, "My DateTime Value" }, |
|||
new object[] { TiffTags.HostComputer, TiffMetadataNames.HostComputer, "My Host Computer Name" }, |
|||
new object[] { TiffTags.ImageDescription, TiffMetadataNames.ImageDescription, "My Image Description" }, |
|||
new object[] { TiffTags.Make, TiffMetadataNames.Make, "My Camera Make" }, |
|||
new object[] { TiffTags.Model, TiffMetadataNames.Model, "My Camera Model" }, |
|||
new object[] { TiffTags.Software, TiffMetadataNames.Software, "My Imaging Software" }}; |
|||
|
|||
[Fact] |
|||
public void AddMetadata_SetsImageResolution() |
|||
{ |
|||
Image<Rgba32> image = new Image<Rgba32>(100, 100); |
|||
image.Metadata.HorizontalResolution = 40.0; |
|||
image.Metadata.VerticalResolution = 50.5; |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> ifdEntries = new List<TiffIfdEntry>(); |
|||
encoder.AddMetadata(image, ifdEntries); |
|||
|
|||
Assert.Equal(new Rational(40, 1), ifdEntries.GetUnsignedRational(TiffTags.XResolution)); |
|||
Assert.Equal(new Rational(101, 2), ifdEntries.GetUnsignedRational(TiffTags.YResolution)); |
|||
Assert.Equal(TiffResolutionUnit.Inch, (TiffResolutionUnit?)ifdEntries.GetInteger(TiffTags.ResolutionUnit)); |
|||
} |
|||
|
|||
/* |
|||
[Theory] |
|||
[MemberData(nameof(BaselineMetadataValues))] |
|||
public void AddMetadata_SetsAsciiMetadata(ushort tag, string metadataName, string metadataValue) |
|||
{ |
|||
Image<Rgba32> image = new Image<Rgba32>(100, 100); |
|||
image.Metadata.Properties.Add(new ImageProperty(metadataName, metadataValue)); |
|||
TiffEncoderCore encoder = new TiffEncoderCore(null); |
|||
|
|||
List<TiffIfdEntry> ifdEntries = new List<TiffIfdEntry>(); |
|||
encoder.AddMetadata(image, ifdEntries); |
|||
|
|||
Assert.Equal(metadataValue + "\0", ifdEntries.GetAscii(tag)); |
|||
} */ |
|||
} |
|||
} |
|||
@ -1,406 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffIfdEntryCreatorTests |
|||
{ |
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0 }, 0)] |
|||
[InlineDataAttribute(new byte[] { 1 }, 1)] |
|||
[InlineDataAttribute(new byte[] { 255 }, 255)] |
|||
public void AddUnsignedByte_AddsSingleValue(byte[] bytes, uint value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedByte(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Byte, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0 }, new uint[] { 0 })] |
|||
[InlineDataAttribute(new byte[] { 0, 1, 2 }, new uint[] { 0, 1, 2 })] |
|||
[InlineDataAttribute(new byte[] { 0, 1, 2, 3, 4, 5, 6 }, new uint[] { 0, 1, 2, 3, 4, 5, 6 })] |
|||
public void AddUnsignedByte_AddsArray(byte[] bytes, uint[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedByte(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Byte, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0 }, 0)] |
|||
[InlineDataAttribute(new byte[] { 1, 0 }, 1)] |
|||
[InlineDataAttribute(new byte[] { 0, 1 }, 256)] |
|||
[InlineDataAttribute(new byte[] { 2, 1 }, 258)] |
|||
[InlineDataAttribute(new byte[] { 255, 255 }, UInt16.MaxValue)] |
|||
public void AddUnsignedShort_AddsSingleValue(byte[] bytes, uint value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedShort(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Short, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 1, 0 }, new uint[] { 1 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 3, 2 }, new uint[] { 1, 515 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 3, 2, 5, 4 }, new uint[] { 1, 515, 1029 })] |
|||
public void AddUnsignedShort_AddsArray(byte[] bytes, uint[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedShort(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Short, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 0 }, 0)] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0 }, 1)] |
|||
[InlineDataAttribute(new byte[] { 0, 1, 0, 0 }, 256)] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 1, 0 }, 256 * 256)] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 1 }, 256 * 256 * 256)] |
|||
[InlineDataAttribute(new byte[] { 1, 2, 3, 4 }, 67305985)] |
|||
[InlineDataAttribute(new byte[] { 255, 255, 255, 255 }, UInt32.MaxValue)] |
|||
public void AddUnsignedLong_AddsSingleValue(byte[] bytes, uint value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedLong(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Long, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 4, 3, 2, 1 }, new uint[] { 0x01020304 })] |
|||
[InlineDataAttribute(new byte[] { 4, 3, 2, 1, 6, 5, 4, 3 }, new uint[] { 0x01020304, 0x03040506 })] |
|||
public void AddUnsignedLong_AddsArray(byte[] bytes, uint[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedLong(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Long, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0 }, 0)] |
|||
[InlineDataAttribute(new byte[] { 1 }, 1)] |
|||
[InlineDataAttribute(new byte[] { 255 }, -1)] |
|||
public void AddSignedByte_AddsSingleValue(byte[] bytes, int value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedByte(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SByte, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0 }, new int[] { 0 })] |
|||
[InlineDataAttribute(new byte[] { 0, 255, 2 }, new int[] { 0, -1, 2 })] |
|||
[InlineDataAttribute(new byte[] { 0, 255, 2, 3, 4, 5, 6 }, new int[] { 0, -1, 2, 3, 4, 5, 6 })] |
|||
public void AddSignedByte_AddsArray(byte[] bytes, int[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedByte(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SByte, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0 }, 0)] |
|||
[InlineDataAttribute(new byte[] { 1, 0 }, 1)] |
|||
[InlineDataAttribute(new byte[] { 0, 1 }, 256)] |
|||
[InlineDataAttribute(new byte[] { 2, 1 }, 258)] |
|||
[InlineDataAttribute(new byte[] { 255, 255 }, -1)] |
|||
public void AddSignedShort_AddsSingleValue(byte[] bytes, int value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedShort(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SShort, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 1, 0 }, new int[] { 1 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 255, 255 }, new int[] { 1, -1 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 255, 255, 5, 4 }, new int[] { 1, -1, 1029 })] |
|||
public void AddSignedShort_AddsArray(byte[] bytes, int[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedShort(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SShort, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 0 }, 0)] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0 }, 1)] |
|||
[InlineDataAttribute(new byte[] { 0, 1, 0, 0 }, 256)] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 1, 0 }, 256 * 256)] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 1 }, 256 * 256 * 256)] |
|||
[InlineDataAttribute(new byte[] { 1, 2, 3, 4 }, 67305985)] |
|||
[InlineDataAttribute(new byte[] { 255, 255, 255, 255 }, -1)] |
|||
public void AddSignedLong_AddsSingleValue(byte[] bytes, int value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedLong(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SLong, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 4, 3, 2, 1 }, new int[] { 0x01020304 })] |
|||
[InlineDataAttribute(new byte[] { 4, 3, 2, 1, 255, 255, 255, 255 }, new int[] { 0x01020304, -1 })] |
|||
public void AddSignedLong_AddsArray(byte[] bytes, int[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedLong(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SLong, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0 }, "")] |
|||
[InlineDataAttribute(new byte[] { (byte)'A', (byte)'B', (byte)'C', 0 }, "ABC")] |
|||
[InlineDataAttribute(new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', 0 }, "ABCDEF")] |
|||
[InlineDataAttribute(new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0, (byte)'E', (byte)'F', (byte)'G', (byte)'H', 0 }, "ABCD\0EFGH")] |
|||
public void AddAscii_AddsEntry(byte[] bytes, string value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddAscii(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Ascii, entry.Type); |
|||
Assert.Equal((uint)bytes.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 0)] |
|||
[InlineDataAttribute(new byte[] { 2, 0, 0, 0, 1, 0, 0, 0 }, 2, 1)] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, 1, 2)] |
|||
public void AddUnsignedRational_AddsSingleValue(byte[] bytes, uint numerator, uint denominator) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddUnsignedRational(TiffTags.ImageWidth, new Rational(numerator, denominator)); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Rational, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new uint[] { 0 }, new uint[] { 0 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, new uint[] { 1 }, new uint[] { 2 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }, new uint[] { 1, 2 }, new uint[] { 2, 3 })] |
|||
public void AddUnsignedRational_AddsArray(byte[] bytes, uint[] numerators, uint[] denominators) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
Rational[] value = Enumerable.Range(0, numerators.Length).Select(i => new Rational(numerators[i], denominators[i])).ToArray(); |
|||
|
|||
entries.AddUnsignedRational(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Rational, entry.Type); |
|||
Assert.Equal((uint)numerators.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 0)] |
|||
[InlineDataAttribute(new byte[] { 2, 0, 0, 0, 1, 0, 0, 0 }, 2, 1)] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, 1, 2)] |
|||
[InlineDataAttribute(new byte[] { 255, 255, 255, 255, 2, 0, 0, 0 }, -1, 2)] |
|||
public void AddSignedRational_AddsSingleValue(byte[] bytes, int numerator, int denominator) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddSignedRational(TiffTags.ImageWidth, new SignedRational(numerator, denominator)); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SRational, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 0 }, new int[] { 0 })] |
|||
[InlineDataAttribute(new byte[] { 2, 0, 0, 0, 1, 0, 0, 0 }, new int[] { 2 }, new int[] { 1 })] |
|||
[InlineDataAttribute(new byte[] { 1, 0, 0, 0, 2, 0, 0, 0 }, new int[] { 1 }, new int[] { 2 })] |
|||
[InlineDataAttribute(new byte[] { 255, 255, 255, 255, 2, 0, 0, 0 }, new int[] { -1 }, new int[] { 2 })] |
|||
[InlineDataAttribute(new byte[] { 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }, new int[] { -1, 2 }, new int[] { 2, 3 })] |
|||
public void AddSignedRational_AddsArray(byte[] bytes, int[] numerators, int[] denominators) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
SignedRational[] value = Enumerable.Range(0, numerators.Length).Select(i => new SignedRational(numerators[i], denominators[i])).ToArray(); |
|||
|
|||
entries.AddSignedRational(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.SRational, entry.Type); |
|||
Assert.Equal((uint)numerators.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0.0F)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x80, 0x3F }, 1.0F)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0xC0 }, -2.0F)] |
|||
[InlineDataAttribute(new byte[] { 0xFF, 0xFF, 0x7F, 0x7F }, float.MaxValue)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x80, 0x7F }, float.PositiveInfinity)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x80, 0xFF }, float.NegativeInfinity)] |
|||
public void AddFloat_AddsSingleValue(byte[] bytes, float value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddFloat(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Float, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00 }, new float[] { 0.0F })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x80, 0x3F }, new float[] { 1.0F })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0xC0 }, new float[] { -2.0F })] |
|||
[InlineDataAttribute(new byte[] { 0xFF, 0xFF, 0x7F, 0x7F }, new float[] { float.MaxValue })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x80, 0x7F }, new float[] { float.PositiveInfinity })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x80, 0xFF }, new float[] { float.NegativeInfinity })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xC0 }, new float[] { 0.0F, 1.0F, -2.0F })] |
|||
public void AddFloat_AddsArray(byte[] bytes, float[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddFloat(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Float, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0.0)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F }, 1.0)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 }, 2.0)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }, -2.0)] |
|||
[InlineDataAttribute(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F }, double.MaxValue)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F }, double.PositiveInfinity)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF }, double.NegativeInfinity)] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF }, double.NaN)] |
|||
public void AddDouble_AddsSingleValue(byte[] bytes, double value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddDouble(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Double, entry.Type); |
|||
Assert.Equal(1u, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new double[] { 0.0 })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F }, new double[] { 1.0 })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 }, new double[] { 2.0 })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }, new double[] { -2.0 })] |
|||
[InlineDataAttribute(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F }, new double[] { double.MaxValue })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F }, new double[] { double.PositiveInfinity })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF }, new double[] { double.NegativeInfinity })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF }, new double[] { double.NaN })] |
|||
[InlineDataAttribute(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }, new double[] { 0.0, 1.0, -2.0 })] |
|||
public void AddDouble_AddsArray(byte[] bytes, double[] value) |
|||
{ |
|||
var entries = new List<TiffIfdEntry>(); |
|||
|
|||
entries.AddDouble(TiffTags.ImageWidth, value); |
|||
|
|||
var entry = entries[0]; |
|||
Assert.Equal(TiffTags.ImageWidth, entry.Tag); |
|||
Assert.Equal(TiffType.Double, entry.Type); |
|||
Assert.Equal((uint)value.Length, entry.Count); |
|||
Assert.Equal(bytes, entry.Value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffIfdEntryTests |
|||
{ |
|||
[Fact] |
|||
public void Constructor_SetsProperties() |
|||
{ |
|||
var entry = new TiffIfdEntry((ushort)10u, TiffType.Short, 20u, new byte[] { 2, 4, 6, 8 }); |
|||
|
|||
Assert.Equal(10u, entry.Tag); |
|||
Assert.Equal(TiffType.Short, entry.Type); |
|||
Assert.Equal(20u, entry.Count); |
|||
Assert.Equal(new byte[] { 2, 4, 6, 8 }, entry.Value); |
|||
} |
|||
} |
|||
} |
|||
@ -1,93 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffIfdTests |
|||
{ |
|||
[Fact] |
|||
public void Constructor_SetsProperties() |
|||
{ |
|||
var entries = new TiffIfdEntry[10]; |
|||
var ifd = new TiffIfd(entries, 1234u); |
|||
|
|||
Assert.Equal(entries, ifd.Entries); |
|||
Assert.Equal(1234u, ifd.NextIfdOffset); |
|||
} |
|||
|
|||
[Fact] |
|||
public void GetIfdEntry_ReturnsIfdIfExists() |
|||
{ |
|||
var entries = new[] |
|||
{ |
|||
new TiffIfdEntry(10, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(20, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(30, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(40, TiffType.Short, 20, new byte[4]) |
|||
}; |
|||
var ifd = new TiffIfd(entries, 1234u); |
|||
|
|||
TiffIfdEntry? entry = ifd.GetIfdEntry(30); |
|||
|
|||
Assert.True(entry.HasValue); |
|||
Assert.Equal(30, entry.Value.Tag); |
|||
} |
|||
|
|||
[Fact] |
|||
public void GetIfdEntry_ReturnsNullOtherwise() |
|||
{ |
|||
var entries = new[] |
|||
{ |
|||
new TiffIfdEntry(10, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(20, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(30, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(40, TiffType.Short, 20, new byte[4]) |
|||
}; |
|||
var ifd = new TiffIfd(entries, 1234u); |
|||
|
|||
TiffIfdEntry? entry = ifd.GetIfdEntry(25); |
|||
|
|||
Assert.False(entry.HasValue); |
|||
} |
|||
|
|||
[Fact] |
|||
public void TryGetIfdEntry_ReturnsIfdIfExists() |
|||
{ |
|||
var entries = new[] |
|||
{ |
|||
new TiffIfdEntry(10, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(20, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(30, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(40, TiffType.Short, 20, new byte[4]) |
|||
}; |
|||
var ifd = new TiffIfd(entries, 1234u); |
|||
|
|||
bool success = ifd.TryGetIfdEntry(30, out var entry); |
|||
|
|||
Assert.True(success); |
|||
Assert.Equal(30, entry.Tag); |
|||
} |
|||
|
|||
[Fact] |
|||
public void TryGetIfdEntry_ReturnsFalseOtherwise() |
|||
{ |
|||
var entries = new[] |
|||
{ |
|||
new TiffIfdEntry(10, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(20, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(30, TiffType.Short, 20, new byte[4]), |
|||
new TiffIfdEntry(40, TiffType.Short, 20, new byte[4]) |
|||
}; |
|||
var ifd = new TiffIfd(entries, 1234u); |
|||
|
|||
bool success = ifd.TryGetIfdEntry(25, out var entry); |
|||
|
|||
Assert.False(success); |
|||
Assert.Equal(0, entry.Tag); |
|||
} |
|||
} |
|||
} |
|||
@ -1,87 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Linq; |
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Formats.Tiff |
|||
{ |
|||
[Trait("Category", "Tiff")] |
|||
public class TiffImageFormatDetectorTests |
|||
{ |
|||
public static object[][] IsLittleEndianValues = new[] { new object[] { false }, |
|||
new object[] { true } }; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DetectFormat_ReturnsTiffFormat_ForValidFile(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd() |
|||
} |
|||
.ToBytes(isLittleEndian); |
|||
|
|||
TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); |
|||
byte[] headerBytes = bytes.Take(formatDetector.HeaderSize).ToArray(); |
|||
var format = formatDetector.DetectFormat(headerBytes); |
|||
|
|||
Assert.NotNull(format); |
|||
Assert.IsType<TiffFormat>(format); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DetectFormat_ReturnsNull_WithInvalidByteOrderMarkers(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd(), |
|||
ByteOrderMarker = 0x1234 |
|||
} |
|||
.ToBytes(isLittleEndian); |
|||
|
|||
TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); |
|||
byte[] headerBytes = bytes.Take(formatDetector.HeaderSize).ToArray(); |
|||
var format = formatDetector.DetectFormat(headerBytes); |
|||
|
|||
Assert.Null(format); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DetectFormat_ReturnsNull_WithIncorrectMagicNumber(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd(), |
|||
MagicNumber = 32 |
|||
} |
|||
.ToBytes(isLittleEndian); |
|||
|
|||
TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); |
|||
byte[] headerBytes = bytes.Take(formatDetector.HeaderSize).ToArray(); |
|||
var format = formatDetector.DetectFormat(headerBytes); |
|||
|
|||
Assert.Null(format); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(IsLittleEndianValues))] |
|||
public void DetectFormat_ReturnsNull_WithShortHeader(bool isLittleEndian) |
|||
{ |
|||
byte[] bytes = new TiffGenHeader() |
|||
{ |
|||
FirstIfd = new TiffGenIfd() |
|||
} |
|||
.ToBytes(isLittleEndian); |
|||
|
|||
TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); |
|||
byte[] headerBytes = bytes.Take(formatDetector.HeaderSize - 1).ToArray(); |
|||
var format = formatDetector.DetectFormat(headerBytes); |
|||
|
|||
Assert.Null(format); |
|||
} |
|||
} |
|||
} |
|||
@ -1,69 +1,87 @@ |
|||
``` ini |
|||
|
|||
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.450 (2004/?/20H1) |
|||
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 |
|||
Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores |
|||
.NET Core SDK=3.1.401 |
|||
[Host] : .NET Core 3.1.7 (CoreCLR 4.700.20.36602, CoreFX 4.700.20.37001), X64 RyuJIT |
|||
Job-MTZTUC : .NET Framework 4.8 (4.8.4200.0), X64 RyuJIT |
|||
Job-BGVYTJ : .NET Core 2.1.21 (CoreCLR 4.6.29130.01, CoreFX 4.6.29130.02), X64 RyuJIT |
|||
Job-ZDUDFU : .NET Core 3.1.7 (CoreCLR 4.700.20.36602, CoreFX 4.700.20.37001), X64 RyuJIT |
|||
.NET Core SDK=5.0.100 |
|||
[Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT |
|||
Job-KSIANY : .NET Framework 4.8 (4.8.4250.0), X64 RyuJIT |
|||
Job-VMCLSF : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT |
|||
Job-UHENIY : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT |
|||
|
|||
InvocationCount=1 IterationCount=5 LaunchCount=1 |
|||
UnrollFactor=1 WarmupCount=3 |
|||
|
|||
``` |
|||
| Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | |
|||
|---------------------- |----------- |-------------- |-------------------------------------------------------- |------------:|------------:|------------:|-------:|--------:|------------:|----------:|----------:|-------------:| |
|||
| **'System.Drawing Tiff'** | **Job-MTZTUC** | **.NET 4.7.2** | **Tiff/Benchmarks/jpeg444_big_grayscale_uncompressed.tiff** | **180.2 ms** | **15.21 ms** | **2.35 ms** | **1.00** | **0.00** | **85000.0000** | **-** | **-** | **269221840 B** | |
|||
| 'ImageSharp Tiff' | Job-MTZTUC | .NET 4.7.2 | Tiff/Benchmarks/jpeg444_big_grayscale_uncompressed.tiff | 31,527.8 ms | 4,371.70 ms | 1,135.32 ms | 176.11 | 8.81 | 1000.0000 | 1000.0000 | 1000.0000 | 1342029912 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_grayscale_uncompressed.tiff | 185.5 ms | 15.88 ms | 2.46 ms | 1.00 | 0.00 | 85000.0000 | - | - | 268813936 B | |
|||
| 'ImageSharp Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_grayscale_uncompressed.tiff | 17,768.7 ms | 116.03 ms | 30.13 ms | 95.84 | 1.13 | 1000.0000 | 1000.0000 | 1000.0000 | 1342016464 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_grayscale_uncompressed.tiff | 149.9 ms | 8.23 ms | 1.27 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_grayscale_uncompressed.tiff | 16,782.2 ms | 718.14 ms | 111.13 ms | 111.94 | 0.80 | 1000.0000 | 1000.0000 | 1000.0000 | 1342016440 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-MTZTUC** | **.NET 4.7.2** | **Tiff/Benchmarks/jpeg444_big_palette_uncompressed.tiff** | **178.0 ms** | **7.07 ms** | **1.83 ms** | **1.00** | **0.00** | **85000.0000** | **-** | **-** | **269221840 B** | |
|||
| 'ImageSharp Tiff' | Job-MTZTUC | .NET 4.7.2 | Tiff/Benchmarks/jpeg444_big_palette_uncompressed.tiff | 33,721.9 ms | 78.03 ms | 12.08 ms | 188.96 | 1.80 | 1000.0000 | 1000.0000 | 1000.0000 | 1342023280 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_palette_uncompressed.tiff | 180.1 ms | 8.81 ms | 2.29 ms | 1.00 | 0.00 | 85000.0000 | - | - | 268815616 B | |
|||
| 'ImageSharp Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_palette_uncompressed.tiff | 22,941.4 ms | 728.12 ms | 189.09 ms | 127.37 | 1.07 | 1000.0000 | 1000.0000 | 1000.0000 | 1342022368 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_palette_uncompressed.tiff | 145.5 ms | 3.20 ms | 0.50 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_palette_uncompressed.tiff | 21,485.0 ms | 711.10 ms | 184.67 ms | 148.04 | 0.66 | 1000.0000 | 1000.0000 | 1000.0000 | 1342025632 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-MTZTUC** | **.NET 4.7.2** | **Tiff/Benchmarks/jpeg444_big_rgb_deflate.tiff** | **2,518.2 ms** | **76.22 ms** | **19.79 ms** | **1.00** | **0.00** | **6000.0000** | **-** | **-** | **29598616 B** | |
|||
| 'ImageSharp Tiff' | Job-MTZTUC | .NET 4.7.2 | Tiff/Benchmarks/jpeg444_big_rgb_deflate.tiff | 29,327.2 ms | 102.72 ms | 26.68 ms | 11.65 | 0.10 | 1000.0000 | 1000.0000 | 1000.0000 | 1124088224 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_deflate.tiff | 2,500.3 ms | 67.24 ms | 10.41 ms | 1.00 | 0.00 | 6000.0000 | - | - | 29528752 B | |
|||
| 'ImageSharp Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_deflate.tiff | 18,974.7 ms | 199.58 ms | 30.89 ms | 7.59 | 0.04 | 1000.0000 | 1000.0000 | 1000.0000 | 1123947608 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_deflate.tiff | 2,541.1 ms | 21.36 ms | 5.55 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_deflate.tiff | 17,974.8 ms | 751.73 ms | 116.33 ms | 7.07 | 0.04 | 1000.0000 | 1000.0000 | 1000.0000 | 1123949960 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-MTZTUC** | **.NET 4.7.2** | **Tiff/Benchmarks/jpeg444_big_rgb_lzw.tiff** | **3,368.4 ms** | **40.71 ms** | **6.30 ms** | **1.00** | **0.00** | **4000.0000** | **-** | **-** | **22835824 B** | |
|||
| 'ImageSharp Tiff' | Job-MTZTUC | .NET 4.7.2 | Tiff/Benchmarks/jpeg444_big_rgb_lzw.tiff | 28,919.9 ms | 705.58 ms | 183.24 ms | 8.57 | 0.04 | 1000.0000 | 1000.0000 | 1000.0000 | 1123956384 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_lzw.tiff | 3,365.1 ms | 36.93 ms | 5.72 ms | 1.00 | 0.00 | 4000.0000 | - | - | 22789840 B | |
|||
| 'ImageSharp Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_lzw.tiff | 17,905.1 ms | 40.08 ms | 10.41 ms | 5.32 | 0.01 | 1000.0000 | 1000.0000 | 1000.0000 | 1123949072 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_lzw.tiff | 3,377.6 ms | 125.36 ms | 32.56 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_lzw.tiff | 16,998.0 ms | 460.59 ms | 119.61 ms | 5.03 | 0.07 | 1000.0000 | 1000.0000 | 1000.0000 | 1123952144 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-MTZTUC** | **.NET 4.7.2** | **Tiff/Benchmarks/jpeg444_big_rgb_packbits.tiff** | **1,849.3 ms** | **43.52 ms** | **11.30 ms** | **1.00** | **0.00** | **255000.0000** | **-** | **-** | **812350880 B** | |
|||
| 'ImageSharp Tiff' | Job-MTZTUC | .NET 4.7.2 | Tiff/Benchmarks/jpeg444_big_rgb_packbits.tiff | 29,360.0 ms | 157.78 ms | 40.98 ms | 15.88 | 0.12 | - | - | - | 2690323752 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_packbits.tiff | 1,882.7 ms | 64.85 ms | 16.84 ms | 1.00 | 0.00 | 255000.0000 | - | - | 811943568 B | |
|||
| 'ImageSharp Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_packbits.tiff | 18,967.7 ms | 445.86 ms | 115.79 ms | 10.08 | 0.09 | - | - | - | 2690318648 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_packbits.tiff | 1,743.2 ms | 78.50 ms | 20.39 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_packbits.tiff | 17,379.6 ms | 243.53 ms | 63.24 ms | 9.97 | 0.10 | - | - | - | 2690321912 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-MTZTUC** | **.NET 4.7.2** | **Tiff/Benchmarks/jpeg444_big_rgb_uncompressed.tiff** | **758.5 ms** | **9.75 ms** | **2.53 ms** | **1.00** | **0.00** | **255000.0000** | **-** | **-** | **806059984 B** | |
|||
| 'ImageSharp Tiff' | Job-MTZTUC | .NET 4.7.2 | Tiff/Benchmarks/jpeg444_big_rgb_uncompressed.tiff | 29,198.2 ms | 677.81 ms | 176.03 ms | 38.50 | 0.19 | - | - | - | 1878827096 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_uncompressed.tiff | 760.1 ms | 15.95 ms | 2.47 ms | 1.00 | 0.00 | 255000.0000 | - | - | 805652192 B | |
|||
| 'ImageSharp Tiff' | Job-BGVYTJ | .NET Core 2.1 | Tiff/Benchmarks/jpeg444_big_rgb_uncompressed.tiff | 18,457.2 ms | 35.60 ms | 5.51 ms | 24.28 | 0.08 | - | - | - | 1878821992 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_uncompressed.tiff | 629.5 ms | 11.40 ms | 2.96 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-ZDUDFU | .NET Core 3.1 | Tiff/Benchmarks/jpeg444_big_rgb_uncompressed.tiff | 17,579.8 ms | 371.72 ms | 96.54 ms | 27.93 | 0.11 | - | - | - | 1878825256 B | |
|||
| Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | |
|||
|---------------------- |----------- |-------------- |----------------------------------- |-----------:|----------:|----------:|------:|--------:|-----------:|----------:|----------:|------------:| |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_bw_Fax3.tiff** | **491.6 ms** | **20.40 ms** | **5.30 ms** | **1.00** | **0.00** | **1000.0000** | **-** | **-** | **5768128 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_bw_Fax3.tiff | 6,970.2 ms | 70.64 ms | 10.93 ms | 14.23 | 0.12 | 1000.0000 | 1000.0000 | 1000.0000 | 241518600 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Fax3.tiff | 486.2 ms | 23.15 ms | 3.58 ms | 1.00 | 0.00 | 1000.0000 | - | - | 5751016 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Fax3.tiff | 4,150.2 ms | 322.16 ms | 83.66 ms | 8.47 | 0.16 | - | - | - | 235961088 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Fax3.tiff | 490.1 ms | 12.76 ms | 3.31 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Fax3.tiff | 3,582.9 ms | 61.89 ms | 16.07 ms | 7.31 | 0.06 | - | - | - | 235961496 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_bw_Rle.tiff** | **499.1 ms** | **26.71 ms** | **6.94 ms** | **1.00** | **0.00** | **1000.0000** | **-** | **-** | **8494472 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_bw_Rle.tiff | 7,290.4 ms | 938.28 ms | 243.67 ms | 14.61 | 0.33 | 1000.0000 | 1000.0000 | 1000.0000 | 237020384 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Rle.tiff | 490.6 ms | 30.19 ms | 4.67 ms | 1.00 | 0.00 | 1000.0000 | - | - | 8475688 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Rle.tiff | 4,230.2 ms | 35.59 ms | 5.51 ms | 8.62 | 0.08 | - | - | - | 235961944 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Rle.tiff | 487.6 ms | 12.07 ms | 1.87 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Rle.tiff | 3,647.4 ms | 42.62 ms | 11.07 ms | 7.48 | 0.04 | - | - | - | 235962184 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_grayscale_uncompressed.tiff** | **606.7 ms** | **20.45 ms** | **5.31 ms** | **1.00** | **0.00** | **18000.0000** | **-** | **-** | **90301696 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_grayscale_uncompressed.tiff | 1,852.9 ms | 6.74 ms | 1.75 ms | 3.05 | 0.03 | - | - | - | 235970584 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_grayscale_uncompressed.tiff | 606.6 ms | 36.58 ms | 9.50 ms | 1.00 | 0.00 | 18000.0000 | - | - | 90104048 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_grayscale_uncompressed.tiff | 764.3 ms | 15.69 ms | 4.08 ms | 1.26 | 0.02 | - | - | - | 235965376 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_grayscale_uncompressed.tiff | 569.6 ms | 17.44 ms | 4.53 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_grayscale_uncompressed.tiff | 655.2 ms | 17.48 ms | 4.54 ms | 1.15 | 0.01 | - | - | - | 235965488 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_palette_uncompressed.tiff** | **578.0 ms** | **22.32 ms** | **5.80 ms** | **1.00** | **0.00** | **18000.0000** | **-** | **-** | **90301696 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_palette_uncompressed.tiff | 3,336.9 ms | 21.42 ms | 5.56 ms | 5.77 | 0.07 | - | - | - | 236003608 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_palette_uncompressed.tiff | 601.9 ms | 40.85 ms | 6.32 ms | 1.00 | 0.00 | 18000.0000 | - | - | 90107368 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_palette_uncompressed.tiff | 1,971.9 ms | 15.69 ms | 4.07 ms | 3.28 | 0.04 | - | - | - | 235996096 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_palette_uncompressed.tiff | 566.1 ms | 28.06 ms | 4.34 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_palette_uncompressed.tiff | 1,664.1 ms | 11.59 ms | 1.79 ms | 2.94 | 0.02 | - | - | - | 235996208 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_deflate.tiff** | **357.4 ms** | **15.54 ms** | **2.40 ms** | **1.00** | **0.00** | **3000.0000** | **-** | **-** | **9662560 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_deflate.tiff | 776.1 ms | 14.51 ms | 3.77 ms | 2.17 | 0.01 | 22000.0000 | 1000.0000 | 1000.0000 | 303476856 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_deflate.tiff | 359.7 ms | 12.29 ms | 3.19 ms | 1.00 | 0.00 | 3000.0000 | - | - | 9629400 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_deflate.tiff | 554.5 ms | 16.78 ms | 4.36 ms | 1.54 | 0.02 | 2000.0000 | 1000.0000 | 1000.0000 | 239716144 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_deflate.tiff | 353.2 ms | 7.22 ms | 1.12 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_deflate.tiff | 557.1 ms | 10.79 ms | 2.80 ms | 1.58 | 0.00 | 2000.0000 | 1000.0000 | 1000.0000 | 239470552 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_lzw.tiff** | **511.0 ms** | **6.43 ms** | **1.67 ms** | **1.00** | **0.00** | **3000.0000** | **-** | **-** | **11600840 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_lzw.tiff | 2,691.6 ms | 16.81 ms | 2.60 ms | 5.27 | 0.02 | - | - | - | 236044312 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_lzw.tiff | 511.4 ms | 11.44 ms | 1.77 ms | 1.00 | 0.00 | 3000.0000 | - | - | 11569776 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_lzw.tiff | 1,654.1 ms | 12.42 ms | 1.92 ms | 3.23 | 0.01 | - | - | - | 236041592 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_lzw.tiff | 507.7 ms | 8.89 ms | 2.31 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_lzw.tiff | 1,689.5 ms | 40.41 ms | 6.25 ms | 3.33 | 0.03 | - | - | - | 236041656 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_packbits.tiff** | **776.8 ms** | **31.69 ms** | **8.23 ms** | **1.00** | **0.00** | **56000.0000** | **-** | **-** | **304057016 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_packbits.tiff | 531.2 ms | 23.17 ms | 6.02 ms | 0.68 | 0.01 | - | - | - | 236003352 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_packbits.tiff | 764.2 ms | 41.43 ms | 6.41 ms | 1.00 | 0.00 | 56000.0000 | - | - | 303861120 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_packbits.tiff | 300.0 ms | 4.39 ms | 0.68 ms | 0.39 | 0.00 | - | - | - | 235998408 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_packbits.tiff | 659.1 ms | 34.59 ms | 8.98 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_packbits.tiff | 297.5 ms | 21.13 ms | 5.49 ms | 0.45 | 0.00 | - | - | - | 235998520 B | |
|||
| | | | | | | | | | | | | | |
|||
| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_uncompressed.tiff** | **742.5 ms** | **50.45 ms** | **13.10 ms** | **1.00** | **0.00** | **55000.0000** | **-** | **-** | **302644272 B** | |
|||
| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_uncompressed.tiff | 414.3 ms | 15.37 ms | 3.99 ms | 0.56 | 0.01 | - | - | - | 235986968 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_uncompressed.tiff | 750.2 ms | 74.13 ms | 19.25 ms | 1.00 | 0.00 | 55000.0000 | - | - | 302448096 B | |
|||
| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_uncompressed.tiff | 283.6 ms | 21.56 ms | 5.60 ms | 0.38 | 0.01 | - | - | - | 235981128 B | |
|||
| | | | | | | | | | | | | | |
|||
| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_uncompressed.tiff | 662.6 ms | 49.79 ms | 12.93 ms | 1.00 | 0.00 | - | - | - | 176 B | |
|||
| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_uncompressed.tiff | 278.6 ms | 9.48 ms | 2.46 ms | 0.42 | 0.01 | - | - | - | 235981352 B | |
|||
|
|||
@ -1,12 +1,14 @@ |
|||
$Gm_Exe = "C:\Program Files\ImageMagick-7.0.8-Q16\magick.exe" |
|||
$Gm_Exe = "C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\magick.exe" |
|||
$Source_Image = ".\jpeg444_big.jpg" |
|||
$Output_Prefix = ".\jpeg444_big" |
|||
$Output_Prefix = ".\big" |
|||
|
|||
& $Gm_Exe convert $Source_Image -compress None -type TrueColor $Output_Prefix"_rgb_uncompressed.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress LZW -type TrueColor $Output_Prefix"_rgb_lzw.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress RLE -type TrueColor $Output_Prefix"_rgb_packbits.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress JPEG -type TrueColor $Output_Prefix"_rgb_jpeg.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress Zip -type TrueColor $Output_Prefix"_rgb_deflate.tiff" |
|||
# & $Gm_Exe convert $Source_Image -compress Group4 -type Bilevel $Output_Prefix"_bw_Group4.tiff" |
|||
# & $Gm_Exe convert $Source_Image -compress Fax -type Bilevel $Output_Prefix"_bw_Fax.tiff" |
|||
|
|||
& $Gm_Exe convert $Source_Image -compress None -type Grayscale $Output_Prefix"_grayscale_uncompressed.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress None -colors 256 $Output_Prefix"_palette_uncompressed.tiff" |
|||
@ -1,12 +1,14 @@ |
|||
$Gm_Exe = "C:\Program Files\ImageMagick-7.0.8-Q16\magick.exe" |
|||
$Gm_Exe = "C:\Program Files\ImageMagick-7.0.10-Q16-HDRI\magick.exe" |
|||
$Source_Image = ".\jpeg444_medium.jpg" |
|||
$Output_Prefix = ".\jpeg444_medium" |
|||
$Output_Prefix = ".\medium" |
|||
|
|||
& $Gm_Exe convert $Source_Image -compress None -type TrueColor $Output_Prefix"_rgb_uncompressed.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress LZW -type TrueColor $Output_Prefix"_rgb_lzw.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress RLE -type TrueColor $Output_Prefix"_rgb_packbits.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress JPEG -type TrueColor $Output_Prefix"_rgb_jpeg.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress Zip -type TrueColor $Output_Prefix"_rgb_deflate.tiff" |
|||
# & $Gm_Exe convert $Source_Image -compress Group4 -type Bilevel $Output_Prefix"_bw_Group4.tiff" |
|||
# & $Gm_Exe convert $Source_Image -compress Fax -type Bilevel $Output_Prefix"_bw_Fax.tiff" |
|||
|
|||
& $Gm_Exe convert $Source_Image -compress None -type Grayscale $Output_Prefix"_grayscale_uncompressed.tiff" |
|||
& $Gm_Exe convert $Source_Image -compress None -colors 256 $Output_Prefix"_palette_uncompressed.tiff" |
|||
Loading…
Reference in new issue