|
|
|
@ -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 |
|
|
|
/// <summary>
|
|
|
|
/// A flag indicating if the file is encoded in little-endian or big-endian format.
|
|
|
|
/// </summary>
|
|
|
|
public bool IsLittleEndian; |
|
|
|
public bool IsLittleEndian { get; private set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Decodes the image from the specified <see cref="Stream"/> 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); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -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<entryCount; i++) |
|
|
|
for (int i = 0; i < entryCount; i++) |
|
|
|
{ |
|
|
|
ReadBytes(buffer, TiffConstants.SizeOfIfdEntry); |
|
|
|
this.ReadBytes(buffer, TiffConstants.SizeOfIfdEntry); |
|
|
|
|
|
|
|
ushort tag = ToUInt16(buffer, 0); |
|
|
|
TiffType type = (TiffType)ToUInt16(buffer, 2); |
|
|
|
uint count = ToUInt32(buffer, 4); |
|
|
|
ushort tag = this.ToUInt16(buffer, 0); |
|
|
|
TiffType type = (TiffType)this.ToUInt16(buffer, 2); |
|
|
|
uint count = this.ToUInt32(buffer, 4); |
|
|
|
byte[] value = new byte[] { buffer[8], buffer[9], buffer[10], buffer[11] }; |
|
|
|
|
|
|
|
entries[i] = new TiffIfdEntry(tag, type, count, value); |
|
|
|
} |
|
|
|
|
|
|
|
ReadBytes(buffer, 4); |
|
|
|
uint nextIfdOffset = ToUInt32(buffer, 0); |
|
|
|
this.ReadBytes(buffer, 4); |
|
|
|
uint nextIfdOffset = this.ToUInt32(buffer, 0); |
|
|
|
|
|
|
|
return new TiffIfd(entries, nextIfdOffset); |
|
|
|
} |
|
|
|
@ -122,10 +131,12 @@ namespace ImageSharp.Formats |
|
|
|
|
|
|
|
while (count > 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); |
|
|
|
} |
|
|
|
|