diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs
index ba5c588ca..885443e86 100644
--- a/src/ImageSharp/Common/Helpers/Numerics.cs
+++ b/src/ImageSharp/Common/Helpers/Numerics.cs
@@ -226,6 +226,38 @@ namespace SixLabors.ImageSharp
return value;
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong Clamp(ulong value, ulong min, ulong max)
+ {
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long Clamp(long value, long min, long max)
+ {
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
///
/// Returns the value clamped to the inclusive range of min and max.
///
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs
index 733eb4a79..0185afb50 100644
--- a/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs
+++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs
@@ -80,6 +80,21 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
///
/// Reference to an IFD (32-bit (4-byte) unsigned integer).
///
- Ifd = 13
+ Ifd = 13,
+
+ ///
+ /// A 64-bit (8-byte) unsigned integer.
+ ///
+ Long8 = 16,
+
+ ///
+ /// A 64-bit (8-byte) signed integer (2's complement notation).
+ ///
+ SignedLong8 = 17,
+
+ ///
+ /// Reference to an IFD (64-bit (8-byte) unsigned integer).
+ ///
+ Ifd8 = 18,
}
}
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifDataTypes.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifDataTypes.cs
index 4f75999bb..ee30c6b08 100644
--- a/src/ImageSharp/Metadata/Profiles/Exif/ExifDataTypes.cs
+++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifDataTypes.cs
@@ -32,10 +32,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
case ExifDataType.Long:
case ExifDataType.SignedLong:
case ExifDataType.SingleFloat:
+ case ExifDataType.Ifd:
return 4;
case ExifDataType.DoubleFloat:
case ExifDataType.Rational:
- case ExifDataType.SignedRational:
+ case ExifDataType.Long8:
+ case ExifDataType.SignedLong8:
+ case ExifDataType.Ifd8:
return 8;
default:
throw new NotSupportedException(dataType.ToString());
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
index 6e671b3ec..5c26fde7b 100644
--- a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
+++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
@@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return values;
}
- protected override void RegisterExtLoader(uint offset, Action loader) => this.loaders.Add(loader);
+ protected override void RegisterExtLoader(ulong offset, Action loader) => this.loaders.Add(loader);
private void GetThumbnail(uint offset)
{
@@ -87,6 +87,8 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
internal abstract class BaseExifReader
{
private readonly byte[] offsetBuffer = new byte[4];
+ private readonly byte[] offsetBuffer8 = new byte[8];
+ private readonly byte[] buf8 = new byte[8];
private readonly byte[] buf4 = new byte[4];
private readonly byte[] buf2 = new byte[2];
@@ -119,7 +121,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
public bool IsBigEndian { get; protected set; }
- protected abstract void RegisterExtLoader(uint offset, Action loader);
+ protected abstract void RegisterExtLoader(ulong offset, Action loader);
///
/// Reads the values to the values collection.
@@ -155,6 +157,35 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
}
}
+ protected void ReadValues64(List values, ulong offset)
+ {
+ if (offset > (ulong)this.data.Length)
+ {
+ return;
+ }
+
+ this.Seek(offset);
+ ulong count = this.ReadUInt64();
+
+ for (ulong i = 0; i < count; i++)
+ {
+ this.ReadValue64(values);
+ }
+ }
+
+ protected void ReadSubIfd64(List values)
+ {
+ if (this.exifOffset != 0)
+ {
+ this.ReadValues64(values, this.exifOffset);
+ }
+
+ if (this.gpsOffset != 0)
+ {
+ this.ReadValues64(values, this.gpsOffset);
+ }
+ }
+
private static TDataType[] ToArray(ExifDataType dataType, ReadOnlySpan data, ConverterMethod converter)
{
int dataTypeSize = (int)ExifDataTypes.GetSize(dataType);
@@ -186,7 +217,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return Encoding.UTF8.GetString(buffer);
}
- private object ConvertValue(ExifDataType dataType, ReadOnlySpan buffer, uint numberOfComponents)
+ private object ConvertValue(ExifDataType dataType, ReadOnlySpan buffer, ulong numberOfComponents)
{
if (buffer.Length == 0)
{
@@ -269,6 +300,20 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
}
return ToArray(dataType, buffer, this.ConvertToSingle);
+ case ExifDataType.Long8:
+ if (numberOfComponents == 1)
+ {
+ return this.ConvertToUInt64(buffer);
+ }
+
+ return ToArray(dataType, buffer, this.ConvertToUInt64);
+ case ExifDataType.SignedLong8:
+ if (numberOfComponents == 1)
+ {
+ return this.ConvertToInt64(buffer);
+ }
+
+ return ToArray(dataType, buffer, this.ConvertToUInt64);
case ExifDataType.Undefined:
if (numberOfComponents == 1)
{
@@ -349,6 +394,69 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
}
}
+ private void ReadValue64(List values)
+ {
+ if ((this.data.Length - this.data.Position) < 20)
+ {
+ return;
+ }
+
+ var tag = (ExifTagValue)this.ReadUInt16();
+ ExifDataType dataType = EnumUtils.Parse(this.ReadUInt16(), ExifDataType.Unknown);
+
+ ulong numberOfComponents = this.ReadUInt64();
+
+ this.TryReadSpan(this.offsetBuffer8);
+
+ if (dataType == ExifDataType.Unknown)
+ {
+ return;
+ }
+
+ if (dataType == ExifDataType.Undefined && numberOfComponents == 0)
+ {
+ numberOfComponents = 8;
+ }
+
+ // The StripOffsets, StripByteCounts, TileOffsets, and TileByteCounts tags are allowed to have the datatype TIFF_LONG8 in BigTIFF.
+ // Old datatypes TIFF_LONG, and TIFF_SHORT where allowed in the TIFF 6.0 specification, are still valid in BigTIFF, too.
+ // https://www.awaresystems.be/imaging/tiff/bigtiff.html
+ ExifValue exifValue = exifValue = ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents);
+
+ if (exifValue is null)
+ {
+ this.AddInvalidTag(new UnkownExifTag(tag));
+ return;
+ }
+
+ ulong size = numberOfComponents * ExifDataTypes.GetSize(dataType);
+ if (size > 8)
+ {
+ ulong newOffset = this.ConvertToUInt64(this.offsetBuffer8);
+ if (newOffset > ulong.MaxValue || (newOffset + size) > (ulong)this.data.Length)
+ {
+ this.AddInvalidTag(new UnkownExifTag(tag));
+ return;
+ }
+
+ this.RegisterExtLoader(newOffset, () =>
+ {
+ byte[] dataBuffer = new byte[size];
+ this.Seek(newOffset);
+ if (this.TryReadSpan(dataBuffer))
+ {
+ object value = this.ConvertValue(dataType, dataBuffer, numberOfComponents);
+ this.Add(values, exifValue, value);
+ }
+ });
+ }
+ else
+ {
+ object value = this.ConvertValue(dataType, ((Span)this.offsetBuffer8).Slice(0, (int)size), numberOfComponents);
+ this.Add(values, exifValue, value);
+ }
+ }
+
private void Add(IList values, IExifValue exif, object value)
{
if (!exif.TrySetValue(value))
@@ -383,8 +491,8 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
private void AddInvalidTag(ExifTag tag)
=> (this.invalidTags ??= new List()).Add(tag);
- private void Seek(long pos)
- => this.data.Seek(pos, SeekOrigin.Begin);
+ private void Seek(ulong pos)
+ => this.data.Seek((long)pos, SeekOrigin.Begin);
private bool TryReadSpan(Span span)
{
@@ -398,6 +506,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return read == length;
}
+ protected ulong ReadUInt64() =>
+ this.TryReadSpan(this.buf8)
+ ? this.ConvertToUInt64(this.buf8)
+ : default;
+
// Known as Long in Exif Specification.
protected uint ReadUInt32() =>
this.TryReadSpan(this.buf4)
@@ -408,6 +521,30 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
? this.ConvertToShort(this.buf2)
: default;
+ private long ConvertToInt64(ReadOnlySpan buffer)
+ {
+ if (buffer.Length < 8)
+ {
+ return default;
+ }
+
+ return this.IsBigEndian
+ ? BinaryPrimitives.ReadInt64BigEndian(buffer)
+ : BinaryPrimitives.ReadInt64LittleEndian(buffer);
+ }
+
+ private ulong ConvertToUInt64(ReadOnlySpan buffer)
+ {
+ if (buffer.Length < 8)
+ {
+ return default;
+ }
+
+ return this.IsBigEndian
+ ? BinaryPrimitives.ReadUInt64BigEndian(buffer)
+ : BinaryPrimitives.ReadUInt64LittleEndian(buffer);
+ }
+
private double ConvertToDouble(ReadOnlySpan buffer)
{
if (buffer.Length < 8)
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8.cs
new file mode 100644
index 000000000..47da962f3
--- /dev/null
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Globalization;
+
+namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
+{
+ internal sealed class ExifLong8 : ExifValue
+ {
+ public ExifLong8(ExifTag tag)
+ : base(tag)
+ {
+ }
+
+ public ExifLong8(ExifTagValue tag)
+ : base(tag)
+ {
+ }
+
+ private ExifLong8(ExifLong8 value)
+ : base(value)
+ {
+ }
+
+ public override ExifDataType DataType => ExifDataType.Long8;
+
+ protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
+
+ public override bool TrySetValue(object value)
+ {
+ if (base.TrySetValue(value))
+ {
+ return true;
+ }
+
+ switch (value)
+ {
+ case long intValue:
+ if (intValue >= 0)
+ {
+ this.Value = (ulong)intValue;
+ return true;
+ }
+
+ return false;
+ default:
+ return false;
+ }
+ }
+
+ public override IExifValue DeepClone() => new ExifLong8(this);
+ }
+}
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs
new file mode 100644
index 000000000..3cf59adac
--- /dev/null
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
+{
+ internal sealed class ExifLong8Array : ExifArrayValue
+ {
+ public ExifLong8Array(ExifTag tag)
+ : base(tag)
+ {
+ }
+
+ public ExifLong8Array(ExifTagValue tag)
+ : base(tag)
+ {
+ }
+
+ private ExifLong8Array(ExifLong8Array value)
+ : base(value)
+ {
+ }
+
+ public override ExifDataType DataType => ExifDataType.Long8;
+
+ public override IExifValue DeepClone() => new ExifLong8Array(this);
+ }
+}
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumber.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumber.cs
index 9e206b23d..d16de4d22 100644
--- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumber.cs
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumber.cs
@@ -21,6 +21,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
get
{
+ if (this.Value > uint.MaxValue)
+ {
+ return ExifDataType.Long8;
+ }
+
if (this.Value > ushort.MaxValue)
{
return ExifDataType.Long;
@@ -41,6 +46,18 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
switch (value)
{
+ case long longValue:
+ if (longValue >= 0)
+ {
+ this.Value = (ulong)longValue;
+ return true;
+ }
+
+ return false;
+ case ulong ulongValue:
+ this.Value = ulongValue;
+
+ return true;
case int intValue:
if (intValue >= uint.MinValue)
{
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs
index 2d3a93aed..15b29dcec 100644
--- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs
@@ -26,6 +26,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
for (int i = 0; i < this.Value.Length; i++)
{
+ if (this.Value[i] > uint.MaxValue)
+ {
+ return ExifDataType.Long8;
+ }
+
if (this.Value[i] > ushort.MaxValue)
{
return ExifDataType.Long;
@@ -45,6 +50,10 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
switch (value)
{
+ case long val:
+ return this.SetSingle(val);
+ case ulong val:
+ return this.SetSingle(val);
case int val:
return this.SetSingle(val);
case uint val:
@@ -53,6 +62,10 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return this.SetSingle(val);
case ushort val:
return this.SetSingle(val);
+ case long[] array:
+ return this.SetArray(array);
+ case ulong[] array:
+ return this.SetArray(array);
case int[] array:
return this.SetArray(array);
case uint[] array:
@@ -74,6 +87,30 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return true;
}
+ private bool SetArray(long[] values)
+ {
+ var numbers = new Number[values.Length];
+ for (int i = 0; i < values.Length; i++)
+ {
+ numbers[i] = values[i];
+ }
+
+ this.Value = numbers;
+ return true;
+ }
+
+ private bool SetArray(ulong[] values)
+ {
+ var numbers = new Number[values.Length];
+ for (int i = 0; i < values.Length; i++)
+ {
+ numbers[i] = values[i];
+ }
+
+ this.Value = numbers;
+ return true;
+ }
+
private bool SetArray(int[] values)
{
var numbers = new Number[values.Length];
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedLong8.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedLong8.cs
new file mode 100644
index 000000000..8362dcf2c
--- /dev/null
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedLong8.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Globalization;
+
+namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
+{
+ internal sealed class ExifSignedLong8 : ExifValue
+ {
+ public ExifSignedLong8(ExifTagValue tag)
+ : base(tag)
+ {
+ }
+
+ private ExifSignedLong8(ExifSignedLong8 value)
+ : base(value)
+ {
+ }
+
+ public override ExifDataType DataType => ExifDataType.SignedLong8;
+
+ protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
+
+ public override IExifValue DeepClone() => new ExifSignedLong8(this);
+ }
+}
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedLong8Array.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedLong8Array.cs
new file mode 100644
index 000000000..34ce20c8f
--- /dev/null
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedLong8Array.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
+{
+ internal sealed class ExifSignedLong8Array : ExifArrayValue
+ {
+ public ExifSignedLong8Array(ExifTagValue tag)
+ : base(tag)
+ {
+ }
+
+ private ExifSignedLong8Array(ExifSignedLong8Array value)
+ : base(value)
+ {
+ }
+
+ public override ExifDataType DataType => ExifDataType.SignedLong8;
+
+ public override IExifValue DeepClone() => new ExifSignedLong8Array(this);
+ }
+}
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs
index af1eee2dc..7e5b35f49 100644
--- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs
+++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs
@@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
public static ExifValue Create(ExifTag tag) => (ExifValue)CreateValue((ExifTagValue)(ushort)tag);
- public static ExifValue Create(ExifTagValue tag, ExifDataType dataType, uint numberOfComponents) => Create(tag, dataType, numberOfComponents != 1);
+ public static ExifValue Create(ExifTagValue tag, ExifDataType dataType, ulong numberOfComponents) => Create(tag, dataType, numberOfComponents != 1);
public static ExifValue Create(ExifTagValue tag, ExifDataType dataType, bool isArray)
{
@@ -19,10 +19,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
case ExifDataType.DoubleFloat: return isArray ? (ExifValue)new ExifDoubleArray(tag) : new ExifDouble(tag);
case ExifDataType.SingleFloat: return isArray ? (ExifValue)new ExifFloatArray(tag) : new ExifFloat(tag);
case ExifDataType.Long: return isArray ? (ExifValue)new ExifLongArray(tag) : new ExifLong(tag);
+ case ExifDataType.Long8: return isArray ? (ExifValue)new ExifLong8Array(tag) : new ExifLong8(tag);
case ExifDataType.Rational: return isArray ? (ExifValue)new ExifRationalArray(tag) : new ExifRational(tag);
case ExifDataType.Short: return isArray ? (ExifValue)new ExifShortArray(tag) : new ExifShort(tag);
case ExifDataType.SignedByte: return isArray ? (ExifValue)new ExifSignedByteArray(tag) : new ExifSignedByte(tag);
case ExifDataType.SignedLong: return isArray ? (ExifValue)new ExifSignedLongArray(tag) : new ExifSignedLong(tag);
+ case ExifDataType.SignedLong8: return isArray ? (ExifValue)new ExifSignedLong8Array(tag) : new ExifSignedLong8(tag);
case ExifDataType.SignedRational: return isArray ? (ExifValue)new ExifSignedRationalArray(tag) : new ExifSignedRational(tag);
case ExifDataType.SignedShort: return isArray ? (ExifValue)new ExifSignedShortArray(tag) : new ExifSignedShort(tag);
case ExifDataType.Ascii: return new ExifString(tag);
diff --git a/src/ImageSharp/Primitives/Number.cs b/src/ImageSharp/Primitives/Number.cs
index e33d2344a..690b72d79 100644
--- a/src/ImageSharp/Primitives/Number.cs
+++ b/src/ImageSharp/Primitives/Number.cs
@@ -14,19 +14,19 @@ namespace SixLabors.ImageSharp
public struct Number : IEquatable, IComparable
{
[FieldOffset(0)]
- private readonly int signedValue;
+ private readonly long signedValue;
[FieldOffset(0)]
- private readonly uint unsignedValue;
+ private readonly ulong unsignedValue;
- [FieldOffset(4)]
+ [FieldOffset(8)]
private readonly bool isSigned;
///
/// Initializes a new instance of the struct.
///
/// The value of the number.
- public Number(int value)
+ public Number(long value)
: this()
{
this.signedValue = value;
@@ -37,30 +37,70 @@ namespace SixLabors.ImageSharp
/// Initializes a new instance of the struct.
///
/// The value of the number.
- public Number(uint value)
+ public Number(ulong value)
: this()
{
this.unsignedValue = value;
this.isSigned = false;
}
+ ///
+ /// Converts the specified to an instance of this type.
+ ///
+ /// The value.
+ public static implicit operator Number(long value) => new Number(value);
+
+ ///
+ /// Converts the specified to an instance of this type.
+ ///
+ /// The value.
+ public static implicit operator Number(ulong value) => new Number(value);
+
///
/// Converts the specified to an instance of this type.
///
/// The value.
- public static implicit operator Number(int value) => new Number(value);
+ public static implicit operator Number(int value) => new Number((long)value);
///
/// Converts the specified to an instance of this type.
///
/// The value.
- public static implicit operator Number(uint value) => new Number(value);
+ public static implicit operator Number(uint value) => new Number((ulong)value);
+
+ ///
+ /// Converts the specified to an instance of this type.
+ ///
+ /// The value.
+ public static implicit operator Number(short value) => new Number((long)value);
///
/// Converts the specified to an instance of this type.
///
/// The value.
- public static implicit operator Number(ushort value) => new Number((uint)value);
+ public static implicit operator Number(ushort value) => new Number((ulong)value);
+
+ ///
+ /// Converts the specified to an instance of this type.
+ ///
+ /// The to convert.
+ public static explicit operator long(Number number)
+ {
+ return number.isSigned
+ ? number.signedValue
+ : (long)Numerics.Clamp(number.unsignedValue, 0, long.MaxValue);
+ }
+
+ ///
+ /// Converts the specified to an instance of this type.
+ ///
+ /// The to convert.
+ public static explicit operator ulong(Number number)
+ {
+ return number.isSigned
+ ? (ulong)Numerics.Clamp(number.signedValue, 0, long.MaxValue)
+ : number.unsignedValue;
+ }
///
/// Converts the specified to a .
@@ -69,8 +109,8 @@ namespace SixLabors.ImageSharp
public static explicit operator int(Number number)
{
return number.isSigned
- ? number.signedValue
- : (int)Numerics.Clamp(number.unsignedValue, 0, int.MaxValue);
+ ? (int)Numerics.Clamp(number.signedValue, int.MinValue, int.MaxValue)
+ : (int)Numerics.Clamp(number.unsignedValue, 0, (uint)int.MaxValue);
}
///
@@ -80,8 +120,19 @@ namespace SixLabors.ImageSharp
public static explicit operator uint(Number number)
{
return number.isSigned
- ? (uint)Numerics.Clamp(number.signedValue, 0, int.MaxValue)
- : number.unsignedValue;
+ ? (uint)Numerics.Clamp(number.signedValue, uint.MinValue, uint.MaxValue)
+ : (uint)Numerics.Clamp(number.unsignedValue, uint.MinValue, uint.MaxValue);
+ }
+
+ ///
+ /// Converts the specified to a .
+ ///
+ /// The to convert.
+ public static explicit operator short(Number number)
+ {
+ return number.isSigned
+ ? (short)Numerics.Clamp(number.signedValue, short.MinValue, short.MaxValue)
+ : (short)Numerics.Clamp(number.unsignedValue, 0, (ushort)short.MaxValue);
}
///