diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffNewSubfileType.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffNewSubfileType.cs index cf66d6d584..9a6fa497e5 100644 --- a/src/ImageSharp/Formats/Tiff/Constants/TiffNewSubfileType.cs +++ b/src/ImageSharp/Formats/Tiff/Constants/TiffNewSubfileType.cs @@ -25,7 +25,7 @@ namespace ImageSharp.Formats AlternativePreview = 0x10000, // TIFF-F/FX Specification subfile types - + MixedRasterContent = 0x0008 } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffOrientation.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffOrientation.cs index 4938a3f7f9..6dbdec4842 100644 --- a/src/ImageSharp/Formats/Tiff/Constants/TiffOrientation.cs +++ b/src/ImageSharp/Formats/Tiff/Constants/TiffOrientation.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Formats /// internal enum TiffOrientation { - /// TIFF baseline Orientation values + // TIFF baseline Orientation values TopLeft = 1, TopRight = 2, diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffThreshholding.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffThreshholding.cs index 237b8419bd..72efa92225 100644 --- a/src/ImageSharp/Formats/Tiff/Constants/TiffThreshholding.cs +++ b/src/ImageSharp/Formats/Tiff/Constants/TiffThreshholding.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Formats /// internal enum TiffThreshholding { - /// TIFF baseline Threshholding values + // TIFF baseline Threshholding values None = 1, Ordered = 2, diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 08d42b973f..8e0a42515b 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -28,7 +28,8 @@ namespace ImageSharp.Formats this.options = options ?? new DecoderOptions(); } - public TiffDecoderCore(Stream stream, bool isLittleEndian, IDecoderOptions options) : this(options) + public TiffDecoderCore(Stream stream, bool isLittleEndian, IDecoderOptions options) + : this(options) { this.InputStream = stream; this.IsLittleEndian = isLittleEndian; @@ -42,7 +43,7 @@ namespace ImageSharp.Formats /// /// A flag indicating if the file is encoded in little-endian or big-endian format. /// - public bool IsLittleEndian; + public bool IsLittleEndian { get; private set; } /// /// Decodes the image from the specified and sets @@ -57,8 +58,8 @@ namespace ImageSharp.Formats { this.InputStream = stream; - uint firstIfdOffset = ReadHeader(); - TiffIfd firstIfd = ReadIfd(firstIfdOffset); + uint firstIfdOffset = this.ReadHeader(); + TiffIfd firstIfd = this.ReadIfd(firstIfdOffset); } /// @@ -71,47 +72,55 @@ namespace ImageSharp.Formats public uint ReadHeader() { byte[] headerBytes = new byte[TiffConstants.SizeOfTiffHeader]; - ReadBytes(headerBytes, TiffConstants.SizeOfTiffHeader); + this.ReadBytes(headerBytes, TiffConstants.SizeOfTiffHeader); if (headerBytes[0] == TiffConstants.ByteOrderLittleEndian && headerBytes[1] == TiffConstants.ByteOrderLittleEndian) - IsLittleEndian = true; + { + this.IsLittleEndian = true; + } else if (headerBytes[0] != TiffConstants.ByteOrderBigEndian && headerBytes[1] != TiffConstants.ByteOrderBigEndian) + { throw new ImageFormatException("Invalid TIFF file header."); + } - if (ToUInt16(headerBytes, 2) != TiffConstants.HeaderMagicNumber) + if (this.ToUInt16(headerBytes, 2) != TiffConstants.HeaderMagicNumber) + { throw new ImageFormatException("Invalid TIFF file header."); + } - uint firstIfdOffset = ToUInt32(headerBytes, 4); + uint firstIfdOffset = this.ToUInt32(headerBytes, 4); if (firstIfdOffset == 0) + { throw new ImageFormatException("Invalid TIFF file header."); + } return firstIfdOffset; } public TiffIfd ReadIfd(uint offset) { - InputStream.Seek(offset, SeekOrigin.Begin); - + this.InputStream.Seek(offset, SeekOrigin.Begin); + byte[] buffer = new byte[TiffConstants.SizeOfIfdEntry]; - ReadBytes(buffer, 2); - ushort entryCount = ToUInt16(buffer, 0); + this.ReadBytes(buffer, 2); + ushort entryCount = this.ToUInt16(buffer, 0); TiffIfdEntry[] entries = new TiffIfdEntry[entryCount]; - for (int i = 0 ; i 0) { - int bytesRead = InputStream.Read(buffer, offset, count); + int bytesRead = this.InputStream.Read(buffer, offset, count); if (bytesRead == 0) + { break; + } offset += bytesRead; count -= bytesRead; @@ -138,11 +149,11 @@ namespace ImageSharp.Formats if (entry.Value.Length < byteLength) { - uint offset = ToUInt32(entry.Value, 0); - InputStream.Seek(offset, SeekOrigin.Begin); + uint offset = this.ToUInt32(entry.Value, 0); + this.InputStream.Seek(offset, SeekOrigin.Begin); byte[] data = new byte[byteLength]; - ReadBytes(data, (int)byteLength); + this.ReadBytes(data, (int)byteLength); entry.Value = data; } @@ -152,16 +163,18 @@ namespace ImageSharp.Formats public uint ReadUnsignedInteger(ref TiffIfdEntry entry) { if (entry.Count != 1) + { throw new ImageFormatException($"Cannot read a single value from an array of multiple items."); + } switch (entry.Type) { case TiffType.Byte: - return (uint)ToByte(entry.Value, 0); + return (uint)this.ToByte(entry.Value, 0); case TiffType.Short: - return (uint)ToUInt16(entry.Value, 0); + return (uint)this.ToUInt16(entry.Value, 0); case TiffType.Long: - return ToUInt32(entry.Value, 0); + return this.ToUInt32(entry.Value, 0); default: throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to an unsigned integer."); } @@ -170,16 +183,18 @@ namespace ImageSharp.Formats public int ReadSignedInteger(ref TiffIfdEntry entry) { if (entry.Count != 1) + { throw new ImageFormatException($"Cannot read a single value from an array of multiple items."); + } switch (entry.Type) { case TiffType.SByte: - return (int)ToSByte(entry.Value, 0); + return (int)this.ToSByte(entry.Value, 0); case TiffType.SShort: - return (int)ToInt16(entry.Value, 0); + return (int)this.ToInt16(entry.Value, 0); case TiffType.SLong: - return ToInt32(entry.Value, 0); + return this.ToInt32(entry.Value, 0); default: throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a signed integer."); } @@ -187,29 +202,41 @@ namespace ImageSharp.Formats public uint[] ReadUnsignedIntegerArray(ref TiffIfdEntry entry) { - byte[] bytes = ReadBytes(ref entry); + byte[] bytes = this.ReadBytes(ref entry); uint[] result = new uint[entry.Count]; switch (entry.Type) { case TiffType.Byte: - { - for (int i = 0 ; i < result.Length ; i++) - result[i] = (uint)ToByte(bytes, i); - break; - } + { + for (int i = 0; i < result.Length; i++) + { + result[i] = (uint)this.ToByte(bytes, i); + } + + break; + } + case TiffType.Short: - { - for (int i = 0 ; i < result.Length ; i++) - result[i] = (uint)ToUInt16(bytes, i * TiffConstants.SizeOfShort); - break; - } + { + for (int i = 0; i < result.Length; i++) + { + result[i] = (uint)this.ToUInt16(bytes, i * TiffConstants.SizeOfShort); + } + + break; + } + case TiffType.Long: - { - for (int i = 0 ; i < result.Length ; i++) - result[i] = ToUInt32(bytes, i * TiffConstants.SizeOfLong); - break; - } + { + for (int i = 0; i < result.Length; i++) + { + result[i] = this.ToUInt32(bytes, i * TiffConstants.SizeOfLong); + } + + break; + } + default: throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to an unsigned integer."); } @@ -219,29 +246,41 @@ namespace ImageSharp.Formats public int[] ReadSignedIntegerArray(ref TiffIfdEntry entry) { - byte[] bytes = ReadBytes(ref entry); + byte[] bytes = this.ReadBytes(ref entry); int[] result = new int[entry.Count]; switch (entry.Type) { case TiffType.SByte: - { - for (int i = 0 ; i < result.Length ; i++) - result[i] = (int)ToSByte(bytes, i); - break; - } + { + for (int i = 0; i < result.Length; i++) + { + result[i] = (int)this.ToSByte(bytes, i); + } + + break; + } + case TiffType.SShort: - { - for (int i = 0 ; i < result.Length ; i++) - result[i] = (int)ToInt16(bytes, i * TiffConstants.SizeOfShort); - break; - } + { + for (int i = 0; i < result.Length; i++) + { + result[i] = (int)this.ToInt16(bytes, i * TiffConstants.SizeOfShort); + } + + break; + } + case TiffType.SLong: - { - for (int i = 0 ; i < result.Length ; i++) - result[i] = ToInt32(bytes, i * TiffConstants.SizeOfLong); - break; - } + { + for (int i = 0; i < result.Length; i++) + { + result[i] = this.ToInt32(bytes, i * TiffConstants.SizeOfLong); + } + + break; + } + default: throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a signed integer."); } @@ -252,12 +291,16 @@ namespace ImageSharp.Formats public string ReadString(ref TiffIfdEntry entry) { if (entry.Type != TiffType.Ascii) + { throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a string."); + } + + byte[] bytes = this.ReadBytes(ref entry); - byte[] bytes = ReadBytes(ref entry); - if (bytes[entry.Count - 1] != 0) + { throw new ImageFormatException("The retrieved string is not null terminated."); + } return Encoding.UTF8.GetString(bytes, 0, (int)entry.Count - 1); } @@ -265,31 +308,37 @@ namespace ImageSharp.Formats public Rational ReadUnsignedRational(ref TiffIfdEntry entry) { if (entry.Count != 1) + { throw new ImageFormatException($"Cannot read a single value from an array of multiple items."); + } - return ReadUnsignedRationalArray(ref entry)[0]; + return this.ReadUnsignedRationalArray(ref entry)[0]; } public SignedRational ReadSignedRational(ref TiffIfdEntry entry) { if (entry.Count != 1) + { throw new ImageFormatException($"Cannot read a single value from an array of multiple items."); + } - return ReadSignedRationalArray(ref entry)[0]; + return this.ReadSignedRationalArray(ref entry)[0]; } public Rational[] ReadUnsignedRationalArray(ref TiffIfdEntry entry) { if (entry.Type != TiffType.Rational) + { throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a Rational."); + } - byte[] bytes = ReadBytes(ref entry); + byte[] bytes = this.ReadBytes(ref entry); Rational[] result = new Rational[entry.Count]; - for (int i = 0 ; i < result.Length ; i++) + for (int i = 0; i < result.Length; i++) { - uint numerator = ToUInt32(bytes, i * TiffConstants.SizeOfRational); - uint denominator = ToUInt32(bytes, i * TiffConstants.SizeOfRational + TiffConstants.SizeOfLong); + uint numerator = this.ToUInt32(bytes, i * TiffConstants.SizeOfRational); + uint denominator = this.ToUInt32(bytes, i * TiffConstants.SizeOfRational + TiffConstants.SizeOfLong); result[i] = new Rational(numerator, denominator); } @@ -299,15 +348,17 @@ namespace ImageSharp.Formats public SignedRational[] ReadSignedRationalArray(ref TiffIfdEntry entry) { if (entry.Type != TiffType.SRational) + { throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a SignedRational."); + } - byte[] bytes = ReadBytes(ref entry); + byte[] bytes = this.ReadBytes(ref entry); SignedRational[] result = new SignedRational[entry.Count]; - for (int i = 0 ; i < result.Length ; i++) + for (int i = 0; i < result.Length; i++) { - int numerator = ToInt32(bytes, i * TiffConstants.SizeOfRational); - int denominator = ToInt32(bytes, i * TiffConstants.SizeOfRational + TiffConstants.SizeOfLong); + int numerator = this.ToInt32(bytes, i * TiffConstants.SizeOfRational); + int denominator = this.ToInt32(bytes, i * TiffConstants.SizeOfRational + TiffConstants.SizeOfLong); result[i] = new SignedRational(numerator, denominator); } @@ -317,32 +368,42 @@ namespace ImageSharp.Formats public float ReadFloat(ref TiffIfdEntry entry) { if (entry.Count != 1) + { throw new ImageFormatException($"Cannot read a single value from an array of multiple items."); + } if (entry.Type != TiffType.Float) + { throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a float."); + } - return ToSingle(entry.Value, 0); + return this.ToSingle(entry.Value, 0); } public double ReadDouble(ref TiffIfdEntry entry) { if (entry.Count != 1) + { throw new ImageFormatException($"Cannot read a single value from an array of multiple items."); + } - return ReadDoubleArray(ref entry)[0]; + return this.ReadDoubleArray(ref entry)[0]; } public float[] ReadFloatArray(ref TiffIfdEntry entry) { if (entry.Type != TiffType.Float) + { throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a float."); + } - byte[] bytes = ReadBytes(ref entry); + byte[] bytes = this.ReadBytes(ref entry); float[] result = new float[entry.Count]; - for (int i = 0 ; i < result.Length ; i++) - result[i] = ToSingle(bytes, i * TiffConstants.SizeOfFloat); + for (int i = 0; i < result.Length; i++) + { + result[i] = this.ToSingle(bytes, i * TiffConstants.SizeOfFloat); + } return result; } @@ -350,71 +411,87 @@ namespace ImageSharp.Formats public double[] ReadDoubleArray(ref TiffIfdEntry entry) { if (entry.Type != TiffType.Double) + { throw new ImageFormatException($"A value of type '{entry.Type}' cannot be converted to a double."); + } - byte[] bytes = ReadBytes(ref entry); + byte[] bytes = this.ReadBytes(ref entry); double[] result = new double[entry.Count]; - for (int i = 0 ; i < result.Length ; i++) - result[i] = ToDouble(bytes, i * TiffConstants.SizeOfDouble); + for (int i = 0; i < result.Length; i++) + { + result[i] = this.ToDouble(bytes, i * TiffConstants.SizeOfDouble); + } return result; } - private SByte ToSByte(byte[] bytes, int offset) + private sbyte ToSByte(byte[] bytes, int offset) { return (sbyte)bytes[offset]; } - private Int16 ToInt16(byte[] bytes, int offset) + private short ToInt16(byte[] bytes, int offset) { - if (IsLittleEndian) + if (this.IsLittleEndian) + { return (short)(bytes[offset + 0] | (bytes[offset + 1] << 8)); + } else + { return (short)((bytes[offset + 0] << 8) | bytes[offset + 1]); + } } - private Int32 ToInt32(byte[] bytes, int offset) + private int ToInt32(byte[] bytes, int offset) { - if (IsLittleEndian) + if (this.IsLittleEndian) + { return bytes[offset + 0] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24); + } else + { return (bytes[offset + 0] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]; + } } - private Byte ToByte(byte[] bytes, int offset) + private byte ToByte(byte[] bytes, int offset) { return bytes[offset]; } - private UInt32 ToUInt32(byte[] bytes, int offset) + private uint ToUInt32(byte[] bytes, int offset) { - return (uint)ToInt32(bytes, offset); + return (uint)this.ToInt32(bytes, offset); } - private UInt16 ToUInt16(byte[] bytes, int offset) + private ushort ToUInt16(byte[] bytes, int offset) { - return (ushort)ToInt16(bytes, offset); + return (ushort)this.ToInt16(bytes, offset); } - private Single ToSingle(byte[] bytes, int offset) + private float ToSingle(byte[] bytes, int offset) { byte[] buffer = new byte[4]; Array.Copy(bytes, offset, buffer, 0, 4); - if (BitConverter.IsLittleEndian != IsLittleEndian) + if (this.IsLittleEndian != BitConverter.IsLittleEndian) + { Array.Reverse(buffer); + } return BitConverter.ToSingle(buffer, 0); } - private Double ToDouble(byte[] bytes, int offset) + private double ToDouble(byte[] bytes, int offset) { byte[] buffer = new byte[8]; Array.Copy(bytes, offset, buffer, 0, 8); - if (BitConverter.IsLittleEndian != IsLittleEndian) + if (this.IsLittleEndian != BitConverter.IsLittleEndian) + { Array.Reverse(buffer); + } return BitConverter.ToDouble(buffer, 0); } diff --git a/src/ImageSharp/Formats/Tiff/TiffFormat.cs b/src/ImageSharp/Formats/Tiff/TiffFormat.cs index 6f09d49099..20090a2892 100644 --- a/src/ImageSharp/Formats/Tiff/TiffFormat.cs +++ b/src/ImageSharp/Formats/Tiff/TiffFormat.cs @@ -34,8 +34,8 @@ namespace ImageSharp.Formats public bool IsSupportedFileFormat(byte[] header) { return header.Length >= this.HeaderSize && - ((header[0] == 0x49 && header[1] == 0x49 && header[2] == 0x2A && header[3] == 0x00) || // Little-endian - (header[0] == 0x4D && header[1] == 0x4D && header[2] == 0x00 && header[3] == 0x2A)); // Big-endian + ((header[0] == 0x49 && header[1] == 0x49 && header[2] == 0x2A && header[3] == 0x00) || // Little-endian + (header[0] == 0x4D && header[1] == 0x4D && header[2] == 0x00 && header[3] == 0x2A)); // Big-endian } } }