Skip to content

Commit

Permalink
Add missing float and double types from TIFF spec
Browse files Browse the repository at this point in the history
  • Loading branch information
oozcitak committed May 15, 2019
1 parent a66844c commit 07e1ee3
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 0 deletions.
64 changes: 64 additions & 0 deletions ExifLibrary/ExifBitConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,40 @@ public static short[] ToSShortArray(byte[] data, int count, ByteOrder frombyteor
return numbers;
}

/// <summary>
/// Returns an array of 32-bit floating numbers converted from
/// the given byte array.
/// Numbers are converted from the given byte-order to platform byte-order.
/// </summary>
public static float[] ToSingleArray(byte[] data, int count, ByteOrder frombyteorder)
{
float[] numbers = new float[count];
for (int i = 0; i < count; i++)
{
byte[] num = new byte[4];
Array.Copy(data, i * 4, num, 0, 4);
numbers[i] = ToSingle(num, 0, frombyteorder, BitConverterEx.SystemByteOrder);
}
return numbers;
}

/// <summary>
/// Returns an array of 64-bit floating numbers converted from
/// the given byte array.
/// Numbers are converted from the given byte-order to platform byte-order.
/// </summary>
public static double[] ToDoubleArray(byte[] data, int count, ByteOrder frombyteorder)
{
double[] numbers = new double[count];
for (int i = 0; i < count; i++)
{
byte[] num = new byte[8];
Array.Copy(data, i * 8, num, 0, 8);
numbers[i] = ToDouble(num, 0, frombyteorder, BitConverterEx.SystemByteOrder);
}
return numbers;
}

/// <summary>
/// Converts the given ascii string to an array of bytes optionally adding a null terminator.
/// </summary>
Expand Down Expand Up @@ -385,6 +419,36 @@ public static byte[] GetBytes(short[] value, ByteOrder tobyteorder)
}
return data;
}

/// <summary>
/// Converts the given array of 32-bit floating numbers to an array of bytes.
/// Numbers are converted from the platform byte-order to the given byte-order.
/// </summary>
public static byte[] GetBytes(float[] value, ByteOrder tobyteorder)
{
byte[] data = new byte[4 * value.Length];
for (int i = 0; i < value.Length; i++)
{
byte[] num = GetBytes(value[i], BitConverterEx.SystemByteOrder, tobyteorder);
Array.Copy(num, 0, data, i * 4, 4);
}
return data;
}

/// <summary>
/// Converts the given array of 64-bit floating numbers to an array of bytes.
/// Numbers are converted from the platform byte-order to the given byte-order.
/// </summary>
public static byte[] GetBytes(double[] value, ByteOrder tobyteorder)
{
byte[] data = new byte[8 * value.Length];
for (int i = 0; i < value.Length; i++)
{
byte[] num = GetBytes(value[i], BitConverterEx.SystemByteOrder, tobyteorder);
Array.Copy(num, 0, data, i * 8, 8);
}
return data;
}
#endregion
}
}
208 changes: 208 additions & 0 deletions ExifLibrary/ExifProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,76 @@ public override ExifInterOperability Interoperability
}
}

/// <summary>
/// Represents an 8-bit signed integer. (EXIF Specification: SBYTE)
/// </summary>
public class ExifSByte : ExifProperty
{
protected sbyte mValue;
protected override object _Value { get { return Value; } set { Value = Convert.ToSByte(value); } }
public new sbyte Value { get { return mValue; } set { mValue = value; } }

static public implicit operator sbyte(ExifSByte obj) { return obj.mValue; }

public override string ToString() { return mValue.ToString(); }

public ExifSByte(ExifTag tag, sbyte value)
: base(tag)
{
mValue = value;
}

public override ExifInterOperability Interoperability
{
get
{
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), InterOpType.SBYTE, 1, new byte[] { (byte)mValue });
}
}
}

/// <summary>
/// Represents an array of 8-bit signed integers. (EXIF Specification: SBYTE with count > 1)
/// </summary>
public class ExifSByteArray : ExifProperty
{
protected sbyte[] mValue;
protected override object _Value { get { return Value; } set { Value = (sbyte[])value; } }
public new sbyte[] Value { get { return mValue; } set { mValue = value; } }

static public implicit operator sbyte[] (ExifSByteArray obj) { return obj.mValue; }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('[');
foreach (sbyte b in mValue)
{
sb.Append(b);
sb.Append(' ');
}
sb.Remove(sb.Length - 1, 1);
sb.Append(']');
return sb.ToString();
}

public ExifSByteArray(ExifTag tag, sbyte[] value)
: base(tag)
{
mValue = value;
}

public override ExifInterOperability Interoperability
{
get
{
byte[] data = new byte[mValue.Length];
Buffer.BlockCopy(mValue, 0, data, 0, mValue.Length);
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), InterOpType.SBYTE, data.Length, data);
}
}
}

/// <summary>
/// Represents an ASCII string. (EXIF Specification: ASCII)
/// </summary>
Expand Down Expand Up @@ -644,4 +714,142 @@ public override ExifInterOperability Interoperability
}
}
}

/// <summary>
/// Represents a 32-bit floating number. (EXIF Specification: FLOAT)
/// </summary>
public class ExifFloat : ExifProperty
{
protected float mValue;
protected override object _Value { get { return Value; } set { Value = Convert.ToSingle(value); } }
public new float Value { get { return mValue; } set { mValue = value; } }

static public implicit operator float(ExifFloat obj) { return obj.mValue; }

public override string ToString() { return mValue.ToString(); }

public ExifFloat(ExifTag tag, float value)
: base(tag)
{
mValue = value;
}

public override ExifInterOperability Interoperability
{
get
{
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), InterOpType.FLOAT, 1, ExifBitConverter.GetBytes(mValue, BitConverterEx.SystemByteOrder, BitConverterEx.SystemByteOrder));
}
}
}

/// <summary>
/// Represents an array of 32-bit floating numbers.
/// (EXIF Specification: FLOAT with count > 1)
/// </summary>
public class ExifFloatArray : ExifProperty
{
protected float[] mValue;
protected override object _Value { get { return Value; } set { Value = (float[])value; } }
public new float[] Value { get { return mValue; } set { mValue = value; } }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('[');
foreach (float b in mValue)
{
sb.Append(b);
sb.Append(' ');
}
sb.Remove(sb.Length - 1, 1);
sb.Append(']');
return sb.ToString();
}

static public implicit operator float[] (ExifFloatArray obj) { return obj.mValue; }

public ExifFloatArray(ExifTag tag, float[] value)
: base(tag)
{
mValue = value;
}

public override ExifInterOperability Interoperability
{
get
{
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), InterOpType.FLOAT, (uint)mValue.Length, ExifBitConverter.GetBytes(mValue, BitConverterEx.SystemByteOrder));
}
}
}

/// <summary>
/// Represents a 64-bit floating number. (EXIF Specification: DOUBLE)
/// </summary>
public class ExifDouble : ExifProperty
{
protected double mValue;
protected override object _Value { get { return Value; } set { Value = Convert.ToDouble(value); } }
public new double Value { get { return mValue; } set { mValue = value; } }

static public implicit operator double(ExifDouble obj) { return obj.mValue; }

public override string ToString() { return mValue.ToString(); }

public ExifDouble(ExifTag tag, double value)
: base(tag)
{
mValue = value;
}

public override ExifInterOperability Interoperability
{
get
{
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), InterOpType.DOUBLE, 1, ExifBitConverter.GetBytes(mValue, BitConverterEx.SystemByteOrder, BitConverterEx.SystemByteOrder));
}
}
}

/// <summary>
/// Represents an array of 64-bit floating numbers.
/// (EXIF Specification: DOUBLE with count > 1)
/// </summary>
public class ExifDoubleArray : ExifProperty
{
protected double[] mValue;
protected override object _Value { get { return Value; } set { Value = (double[])value; } }
public new double[] Value { get { return mValue; } set { mValue = value; } }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('[');
foreach (float b in mValue)
{
sb.Append(b);
sb.Append(' ');
}
sb.Remove(sb.Length - 1, 1);
sb.Append(']');
return sb.ToString();
}

static public implicit operator double[](ExifDoubleArray obj) { return obj.mValue; }

public ExifDoubleArray(ExifTag tag, double[] value)
: base(tag)
{
mValue = value;
}

public override ExifInterOperability Interoperability
{
get
{
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), InterOpType.DOUBLE, (uint)mValue.Length, ExifBitConverter.GetBytes(mValue, BitConverterEx.SystemByteOrder));
}
}
}
}
27 changes: 27 additions & 0 deletions ExifLibrary/ExifPropertyFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,19 @@ public static ExifProperty Get(ushort tag, ushort type, uint count, byte[] value
else
return new ExifURationalArray(etag, ExifBitConverter.ToURationalArray(value, (int)count, byteOrder));
}
else if (type == 6) // 1 = SBYTE An 8-bit signed integer.
{
if (count == 1)
{
return new ExifSByte(etag, (sbyte)value[0]);
}
else
{
sbyte[] data = new sbyte[count];
Buffer.BlockCopy(value, 0, data, 0, (int)count);
return new ExifSByteArray(etag, data);
}
}
else if (type == 7) // 7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition.
return new ExifUndefined(etag, value);
else if (type == 8) // 8 = SSHORT A 16-bit (2-byte) signed integer.
Expand All @@ -254,6 +267,20 @@ public static ExifProperty Get(ushort tag, ushort type, uint count, byte[] value
else
return new ExifSRationalArray(etag, ExifBitConverter.ToSRationalArray(value, (int)count, byteOrder));
}
else if (type == 11) // 11 = FLOAT Single precision (4-byte) IEEE format.
{
if (count == 1)
return new ExifFloat(etag, conv.ToSingle(value, 0));
else
return new ExifFloatArray(etag, ExifBitConverter.ToSingleArray(value, (int)count, byteOrder));
}
else if (type == 12) // 12 = DOUBLE Double precision (8-byte) IEEE format.
{
if (count == 1)
return new ExifDouble(etag, conv.ToDouble(value, 0));
else
return new ExifDoubleArray(etag, ExifBitConverter.ToDoubleArray(value, (int)count, byteOrder));
}
else
throw new ArgumentException("Unknown property type.");
}
Expand Down

0 comments on commit 07e1ee3

Please sign in to comment.