mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-11-12 23:32:42 -05:00
Use System.Half
This commit is contained in:
@ -1413,7 +1413,7 @@ namespace AssetStudio
|
||||
result[i] = BitConverter.ToSingle(inputBytes, i * 4);
|
||||
break;
|
||||
case VertexFormat.Float16:
|
||||
result[i] = Half.ToHalf(inputBytes, i * 2);
|
||||
result[i] = (float)HalfHelper.ToHalf(inputBytes, i * 2);
|
||||
break;
|
||||
case VertexFormat.UNorm8:
|
||||
result[i] = inputBytes[i] / 255f;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
namespace AssetStudio
|
||||
{
|
||||
/// <summary>
|
||||
@ -35,27 +36,27 @@ namespace AssetStudio
|
||||
/// <summary>
|
||||
/// Represents the smallest positive System.Half value greater than zero. This field is constant.
|
||||
/// </summary>
|
||||
public static readonly Half Epsilon = Half.ToHalf(0x0001);
|
||||
public static readonly Half Epsilon = HalfHelper.ToHalf(0x0001);
|
||||
/// <summary>
|
||||
/// Represents the largest possible value of System.Half. This field is constant.
|
||||
/// </summary>
|
||||
public static readonly Half MaxValue = Half.ToHalf(0x7bff);
|
||||
public static readonly Half MaxValue = HalfHelper.ToHalf(0x7bff);
|
||||
/// <summary>
|
||||
/// Represents the smallest possible value of System.Half. This field is constant.
|
||||
/// </summary>
|
||||
public static readonly Half MinValue = Half.ToHalf(0xfbff);
|
||||
public static readonly Half MinValue = HalfHelper.ToHalf(0xfbff);
|
||||
/// <summary>
|
||||
/// Represents not a number (NaN). This field is constant.
|
||||
/// </summary>
|
||||
public static readonly Half NaN = Half.ToHalf(0xfe00);
|
||||
public static readonly Half NaN = HalfHelper.ToHalf(0xfe00);
|
||||
/// <summary>
|
||||
/// Represents negative infinity. This field is constant.
|
||||
/// </summary>
|
||||
public static readonly Half NegativeInfinity = Half.ToHalf(0xfc00);
|
||||
public static readonly Half NegativeInfinity = HalfHelper.ToHalf(0xfc00);
|
||||
/// <summary>
|
||||
/// Represents positive infinity. This field is constant.
|
||||
/// </summary>
|
||||
public static readonly Half PositiveInfinity = Half.ToHalf(0x7c00);
|
||||
public static readonly Half PositiveInfinity = HalfHelper.ToHalf(0x7c00);
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -63,7 +64,7 @@ namespace AssetStudio
|
||||
/// Initializes a new instance of System.Half to the value of the specified single-precision floating-point number.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to represent as a System.Half.</param>
|
||||
public Half(float value) { this = HalfHelper.SingleToHalf(value); }
|
||||
public Half(float value) { this = HalfHelper.ToHalf(value); }
|
||||
/// <summary>
|
||||
/// Initializes a new instance of System.Half to the value of the specified 32-bit signed integer.
|
||||
/// </summary>
|
||||
@ -314,7 +315,7 @@ namespace AssetStudio
|
||||
/// </summary>
|
||||
/// <param name="value">A System.Half to convert.</param>
|
||||
/// <returns>A single-precision floating-point number that represents the converted System.Half.</returns>
|
||||
public static implicit operator float(Half value) { return (float)HalfHelper.HalfToSingle(value); }
|
||||
public static implicit operator float(Half value) { return value.ToSingle(); }
|
||||
/// <summary>
|
||||
/// Converts a System.Half to a double-precision floating-point number.
|
||||
/// </summary>
|
||||
@ -508,32 +509,6 @@ namespace AssetStudio
|
||||
{
|
||||
return value.value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a half-precision floating point number converted from two bytes
|
||||
/// at a specified position in a byte array.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A half-precision floating point number formed by two bytes beginning at startIndex.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// startIndex is greater than or equal to the length of value minus 1, and is
|
||||
/// less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>
|
||||
public static Half ToHalf(byte[] value, int startIndex)
|
||||
{
|
||||
return Half.ToHalf((ushort)BitConverter.ToInt16(value, startIndex));
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a half-precision floating point number converted from its binary representation.
|
||||
/// </summary>
|
||||
/// <param name="bits">Binary representation of System.Half value</param>
|
||||
/// <returns>A half-precision floating point number formed by its binary representation.</returns>
|
||||
public static Half ToHalf(ushort bits)
|
||||
{
|
||||
return new Half { value = bits };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating the sign of a half-precision floating-point number.
|
||||
@ -886,3 +861,4 @@ namespace AssetStudio
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,18 +1,32 @@
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
#if NET
|
||||
public static class HalfHelper
|
||||
{
|
||||
public static Half ToHalf(ushort bits)
|
||||
{
|
||||
return (Half)bits;
|
||||
}
|
||||
|
||||
public static Half ToHalf(ReadOnlySpan<byte> bytes, int startIndex)
|
||||
{
|
||||
return BinaryPrimitives.ReadHalfLittleEndian(bytes[startIndex..]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/// <summary>
|
||||
/// Helper class for Half conversions and some low level operations.
|
||||
/// This class is internally used in the Half class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// References:
|
||||
/// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
||||
/// </remarks>
|
||||
[ComVisible(false)]
|
||||
internal static class HalfHelper
|
||||
public static class HalfHelper
|
||||
{
|
||||
private static uint[] mantissaTable = GenerateMantissaTable();
|
||||
private static uint[] exponentTable = GenerateExponentTable();
|
||||
@ -169,27 +183,54 @@ namespace AssetStudio
|
||||
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
|
||||
return Half.ToHalf(result);
|
||||
}*/
|
||||
public static float HalfToSingle(Half half)
|
||||
|
||||
/// <summary>
|
||||
/// Returns a half-precision floating point number converted from two bytes
|
||||
/// at a specified position in a byte array.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A half-precision floating point number formed by two bytes beginning at startIndex.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// startIndex is greater than or equal to the length of value minus 1, and is
|
||||
/// less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>
|
||||
public static Half ToHalf(ReadOnlySpan<byte> value, int startIndex)
|
||||
{
|
||||
return ToHalf((ushort)BinaryPrimitives.ReadInt16LittleEndian(value.Slice(startIndex)));
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a half-precision floating point number converted from its binary representation.
|
||||
/// </summary>
|
||||
/// <param name="bits">Binary representation of System.Half value</param>
|
||||
/// <returns>A half-precision floating point number formed by its binary representation.</returns>
|
||||
public static Half ToHalf(ushort bits)
|
||||
{
|
||||
return new Half { value = bits };
|
||||
}
|
||||
public static Half ToHalf(float single)
|
||||
{
|
||||
byte[] singleBytes = BitConverter.GetBytes(single);
|
||||
uint value = BitConverter.ToUInt32(singleBytes, 0);
|
||||
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
|
||||
return ToHalf(result);
|
||||
}
|
||||
public static float ToSingle(this Half half)
|
||||
{
|
||||
uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10];
|
||||
byte[] uintBytes = BitConverter.GetBytes(result);
|
||||
return BitConverter.ToSingle(uintBytes, 0);
|
||||
}
|
||||
public static Half SingleToHalf(float single)
|
||||
{
|
||||
byte[] singleBytes = BitConverter.GetBytes(single);
|
||||
uint value = BitConverter.ToUInt32(singleBytes, 0);
|
||||
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
|
||||
return Half.ToHalf(result);
|
||||
}
|
||||
|
||||
public static Half Negate(Half half)
|
||||
{
|
||||
return Half.ToHalf((ushort)(half.value ^ 0x8000));
|
||||
return ToHalf((ushort)(half.value ^ 0x8000));
|
||||
}
|
||||
public static Half Abs(Half half)
|
||||
{
|
||||
return Half.ToHalf((ushort)(half.value & 0x7fff));
|
||||
return ToHalf((ushort)(half.value & 0x7fff));
|
||||
}
|
||||
|
||||
public static bool IsNaN(Half half)
|
||||
@ -209,4 +250,5 @@ namespace AssetStudio
|
||||
return (half.value == 0xfc00);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ namespace AssetStudio
|
||||
{
|
||||
buff[i] = 0;
|
||||
buff[i + 1] = 0;
|
||||
buff[i + 2] = (byte)MathF.Round(Half.ToHalf(image_data, i / 2) * 255f);
|
||||
buff[i + 2] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i / 2) * 255f);
|
||||
buff[i + 3] = 255;
|
||||
}
|
||||
return true;
|
||||
@ -451,8 +451,8 @@ namespace AssetStudio
|
||||
for (var i = 0; i < outPutDataSize; i += 4)
|
||||
{
|
||||
buff[i] = 0;
|
||||
buff[i + 1] = (byte)MathF.Round(Half.ToHalf(image_data, i + 2) * 255f);
|
||||
buff[i + 2] = (byte)MathF.Round(Half.ToHalf(image_data, i) * 255f);
|
||||
buff[i + 1] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i + 2) * 255f);
|
||||
buff[i + 2] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i) * 255f);
|
||||
buff[i + 3] = 255;
|
||||
}
|
||||
return true;
|
||||
@ -462,10 +462,10 @@ namespace AssetStudio
|
||||
{
|
||||
for (var i = 0; i < outPutDataSize; i += 4)
|
||||
{
|
||||
buff[i] = (byte)MathF.Round(Half.ToHalf(image_data, i * 2 + 4) * 255f);
|
||||
buff[i + 1] = (byte)MathF.Round(Half.ToHalf(image_data, i * 2 + 2) * 255f);
|
||||
buff[i + 2] = (byte)MathF.Round(Half.ToHalf(image_data, i * 2) * 255f);
|
||||
buff[i + 3] = (byte)MathF.Round(Half.ToHalf(image_data, i * 2 + 6) * 255f);
|
||||
buff[i] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i * 2 + 4) * 255f);
|
||||
buff[i + 1] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i * 2 + 2) * 255f);
|
||||
buff[i + 2] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i * 2) * 255f);
|
||||
buff[i + 3] = (byte)MathF.Round((float)HalfHelper.ToHalf(image_data, i * 2 + 6) * 255f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user