mirror of
https://github.com/AssetRipper/AssetRipper.TextureDecoder.git
synced 2026-11-12 18:07:28 -10:00
Add support for sbyte and short in IColor<T>
This commit is contained in:
1 parent
89b76dafd3
commit
dc1ecc5d46
2 files changed
+132
-7
No files matched your search
@@ -11,10 +11,20 @@
|
||||
{
|
||||
return Unsafe.As<TFrom, TTo>(ref value);
|
||||
}
|
||||
else if (typeof(TFrom) == typeof(sbyte))
|
||||
{
|
||||
byte converted = ChangeSign(Unsafe.As<TFrom, sbyte>(ref value));
|
||||
return ConvertUInt8<TTo>(converted);
|
||||
}
|
||||
else if(typeof(TFrom) == typeof(byte))
|
||||
{
|
||||
return ConvertUInt8<TTo>(Unsafe.As<TFrom, byte>(ref value));
|
||||
}
|
||||
else if (typeof(TFrom) == typeof(short))
|
||||
{
|
||||
ushort converted = ChangeSign(Unsafe.As<TFrom, short>(ref value));
|
||||
return ConvertUInt16<TTo>(converted);
|
||||
}
|
||||
else if (typeof(TFrom) == typeof(ushort))
|
||||
{
|
||||
return ConvertUInt16<TTo>(Unsafe.As<TFrom, ushort>(ref value));
|
||||
@@ -40,13 +50,23 @@
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static TTo ConvertUInt8<TTo>(byte value) where TTo : unmanaged
|
||||
{
|
||||
if (typeof(TTo) == typeof(byte))
|
||||
if (typeof(TTo) == typeof(sbyte))
|
||||
{
|
||||
sbyte converted = ChangeSign(value);
|
||||
return Unsafe.As<sbyte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(byte))
|
||||
{
|
||||
return Unsafe.As<byte, TTo>(ref value);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(short))
|
||||
{
|
||||
short converted = ChangeSign(ConvertUInt8ToUInt16(value));
|
||||
return Unsafe.As<short, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(ushort))
|
||||
{
|
||||
ushort converted = unchecked((ushort)((uint)value << 8));
|
||||
ushort converted = ConvertUInt8ToUInt16(value);
|
||||
return Unsafe.As<ushort, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(Half))
|
||||
@@ -68,16 +88,29 @@
|
||||
{
|
||||
return ThrowOrReturnDefault<TTo>();
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
static ushort ConvertUInt8ToUInt16(byte value) => unchecked((ushort)((uint)value << 8));
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static TTo ConvertUInt16<TTo>(ushort value) where TTo : unmanaged
|
||||
{
|
||||
if (typeof(TTo) == typeof(byte))
|
||||
if (typeof(TTo) == typeof(sbyte))
|
||||
{
|
||||
byte converted = unchecked((byte)((uint)value >> 8));
|
||||
sbyte converted = ChangeSign(ConvertUInt16ToUInt8(value));
|
||||
return Unsafe.As<sbyte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(byte))
|
||||
{
|
||||
byte converted = ConvertUInt16ToUInt8(value);
|
||||
return Unsafe.As<byte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(short))
|
||||
{
|
||||
short converted = ChangeSign(value);
|
||||
return Unsafe.As<short, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(ushort))
|
||||
{
|
||||
return Unsafe.As<ushort, TTo>(ref value);
|
||||
@@ -101,16 +134,29 @@
|
||||
{
|
||||
return ThrowOrReturnDefault<TTo>();
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
static byte ConvertUInt16ToUInt8(ushort value) => unchecked((byte)((uint)value >> 8));
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static TTo ConvertHalf<TTo>(Half value) where TTo : unmanaged
|
||||
{
|
||||
if (typeof(TTo) == typeof(byte))
|
||||
if (typeof(TTo) == typeof(sbyte))
|
||||
{
|
||||
sbyte converted = ChangeSign(ClampUInt8((float)value * byte.MaxValue));
|
||||
return Unsafe.As<sbyte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(byte))
|
||||
{
|
||||
byte converted = ClampUInt8((float)value * byte.MaxValue);
|
||||
return Unsafe.As<byte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(short))
|
||||
{
|
||||
short converted = ChangeSign(ClampUInt16((float)value * ushort.MaxValue));
|
||||
return Unsafe.As<short, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(ushort))
|
||||
{
|
||||
ushort converted = ClampUInt16((float)value * ushort.MaxValue);
|
||||
@@ -139,11 +185,21 @@
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static TTo ConvertSingle<TTo>(float value) where TTo : unmanaged
|
||||
{
|
||||
if (typeof(TTo) == typeof(byte))
|
||||
if (typeof(TTo) == typeof(sbyte))
|
||||
{
|
||||
sbyte converted = ChangeSign(ClampUInt8(value * byte.MaxValue));
|
||||
return Unsafe.As<sbyte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(byte))
|
||||
{
|
||||
byte converted = ClampUInt8(value * byte.MaxValue);
|
||||
return Unsafe.As<byte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(short))
|
||||
{
|
||||
short converted = ChangeSign(ClampUInt16(value * ushort.MaxValue));
|
||||
return Unsafe.As<short, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(ushort))
|
||||
{
|
||||
ushort converted = ClampUInt16(value * ushort.MaxValue);
|
||||
@@ -172,11 +228,21 @@
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static TTo ConvertDouble<TTo>(double value) where TTo : unmanaged
|
||||
{
|
||||
if (typeof(TTo) == typeof(byte))
|
||||
if (typeof(TTo) == typeof(sbyte))
|
||||
{
|
||||
sbyte converted = ChangeSign(ClampUInt8(value * byte.MaxValue));
|
||||
return Unsafe.As<sbyte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(byte))
|
||||
{
|
||||
byte converted = ClampUInt8(value * byte.MaxValue);
|
||||
return Unsafe.As<byte, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(short))
|
||||
{
|
||||
short converted = ChangeSign(ClampUInt16(value * ushort.MaxValue));
|
||||
return Unsafe.As<short, TTo>(ref converted);
|
||||
}
|
||||
else if (typeof(TTo) == typeof(ushort))
|
||||
{
|
||||
ushort converted = ClampUInt16(value * ushort.MaxValue);
|
||||
@@ -235,5 +301,45 @@
|
||||
{
|
||||
return ushort.MaxValue < x ? ushort.MaxValue : (x > ushort.MinValue ? (ushort)x : ushort.MinValue);
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static byte ChangeSign(sbyte x)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
const uint SignBit = 0x80;
|
||||
return (byte)((uint)x ^ SignBit);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static sbyte ChangeSign(byte x)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
const uint SignBit = 0x80;
|
||||
return (sbyte)(x ^ SignBit);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static ushort ChangeSign(short x)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
const uint SignBit = 0x8000;
|
||||
return (ushort)((uint)x ^ SignBit);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(OptimizationConstants.AggressiveInliningAndOptimization)]
|
||||
private static short ChangeSign(ushort x)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
const uint SignBit = 0x8000;
|
||||
return (short)(x ^ SignBit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,24 @@
|
||||
namespace AssetRipper.TextureDecoder.Rgb
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see langword="interface"/> for handling color formats with up to 4 channels.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When used as a generic type constraint, the methods and properties get devirtualized by the JIT compiler.
|
||||
/// This prevents boxing when the implementing type is a <see langword="struct"/>.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">
|
||||
/// Supported types are:
|
||||
/// <list type="bullet">
|
||||
/// <item><see cref="sbyte"/></item>
|
||||
/// <item><see cref="byte"/></item>
|
||||
/// <item><see cref="short"/></item>
|
||||
/// <item><see cref="ushort"/></item>
|
||||
/// <item><see cref="Half"/></item>
|
||||
/// <item><see cref="float"/></item>
|
||||
/// <item><see cref="double"/></item>
|
||||
/// </list>
|
||||
/// </typeparam>
|
||||
public interface IColor<T> where T : unmanaged
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
Reference in new issue
Block a user