diff --git a/TextureDecoder/Rgb/RgbConverter.cs b/TextureDecoder/Rgb/RgbConverter.cs
index e152172..64916b3 100644
--- a/TextureDecoder/Rgb/RgbConverter.cs
+++ b/TextureDecoder/Rgb/RgbConverter.cs
@@ -1,8 +1,6 @@
using System;
-using System.Runtime.CompilerServices;
-#if NET5_0_OR_GREATER
using System.Buffers.Binary;
-#endif
+using System.Runtime.CompilerServices;
namespace AssetRipper.TextureDecoder.Rgb
{
@@ -18,7 +16,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] A8ToBGRA32(byte[] input, int width, int height)
+ public static byte[] A8ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
A8ToBGRA32(input, width, height, output);
@@ -32,7 +30,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void A8ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void A8ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -57,7 +55,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] ARGB16ToBGRA32(byte[] input, int width, int height)
+ public static byte[] ARGB16ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
ARGB16ToBGRA32(input, width, height, output);
@@ -71,7 +69,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void ARGB16ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void ARGB16ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -96,7 +94,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGB24ToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGB24ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGB24ToBGRA32(input, width, height, output);
@@ -110,7 +108,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGB24ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGB24ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -135,7 +133,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGBA32ToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGBA32ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGBA32ToBGRA32(input, width, height, output);
@@ -149,7 +147,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGBA32ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGBA32ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -174,7 +172,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] ARGB32ToBGRA32(byte[] input, int width, int height)
+ public static byte[] ARGB32ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
ARGB32ToBGRA32(input, width, height, output);
@@ -188,7 +186,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void ARGB32ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void ARGB32ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -213,7 +211,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGB16ToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGB16ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGB16ToBGRA32(input, width, height, output);
@@ -227,7 +225,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGB16ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGB16ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -255,7 +253,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] R16ToBGRA32(byte[] input, int width, int height)
+ public static byte[] R16ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
R16ToBGRA32(input, width, height, output);
@@ -269,7 +267,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void R16ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void R16ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -294,7 +292,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGBA16ToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGBA16ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGBA16ToBGRA32(input, width, height, output);
@@ -308,7 +306,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGBA16ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGBA16ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -333,7 +331,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RG16ToBGRA32(byte[] input, int width, int height)
+ public static byte[] RG16ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RG16ToBGRA32(input, width, height, output);
@@ -347,7 +345,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RG16ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RG16ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -372,7 +370,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] R8ToBGRA32(byte[] input, int width, int height)
+ public static byte[] R8ToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
R8ToBGRA32(input, width, height, output);
@@ -386,7 +384,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void R8ToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void R8ToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -411,7 +409,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RHalfToBGRA32(byte[] input, int width, int height)
+ public static byte[] RHalfToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RHalfToBGRA32(input, width, height, output);
@@ -425,7 +423,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RHalfToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RHalfToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -451,7 +449,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGHalfToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGHalfToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGHalfToBGRA32(input, width, height, output);
@@ -465,7 +463,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGHalfToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGHalfToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -492,7 +490,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGBAHalfToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGBAHalfToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGBAHalfToBGRA32(input, width, height, output);
@@ -506,7 +504,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGBAHalfToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGBAHalfToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -535,7 +533,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RFloatToBGRA32(byte[] input, int width, int height)
+ public static byte[] RFloatToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RFloatToBGRA32(input, width, height, output);
@@ -549,7 +547,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RFloatToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RFloatToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -575,7 +573,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGFloatToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGFloatToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGFloatToBGRA32(input, width, height, output);
@@ -589,7 +587,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGFloatToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGFloatToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -616,7 +614,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGBAFloatToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGBAFloatToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGBAFloatToBGRA32(input, width, height, output);
@@ -630,7 +628,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGBAFloatToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGBAFloatToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -659,7 +657,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static byte[] RGB9e5FloatToBGRA32(byte[] input, int width, int height)
+ public static byte[] RGB9e5FloatToBGRA32(ReadOnlySpan input, int width, int height)
{
byte[] output = new byte[width * height * 4];
RGB9e5FloatToBGRA32(input, width, height, output);
@@ -673,7 +671,7 @@ namespace AssetRipper.TextureDecoder.Rgb
///
///
///
- public static void RGB9e5FloatToBGRA32(byte[] input, int width, int height, byte[] output)
+ public static void RGB9e5FloatToBGRA32(ReadOnlySpan input, int width, int height, Span output)
{
int io = 0;
int oo = 0;
@@ -681,7 +679,7 @@ namespace AssetRipper.TextureDecoder.Rgb
{
for (int j = 0; j < height; j++)
{
- uint value = BitConverter.ToUInt32(input, io);
+ uint value = BinaryPrimitives.ReadUInt32LittleEndian(input.Slice(io, 4));
double scale = Math.Pow(2, unchecked((int)(value >> 27) - 24));
byte r = ClampByte((value >> 0 & 0x1FF) * scale * 255.0);
byte g = ClampByte((value >> 9 & 0x1FF) * scale * 255.0);
@@ -696,34 +694,23 @@ namespace AssetRipper.TextureDecoder.Rgb
}
}
- private static float ToHalf(byte[] input, int offset)
+ private static float ToHalf(ReadOnlySpan input, int offset)
{
#if NET6_0_OR_GREATER
- return (float)BinaryPrimitives.ReadHalfLittleEndian(input.AsSpan(offset, 2));
-#elif NET5_0
- return (float)ToHalf(BinaryPrimitives.ReadUInt16LittleEndian(input.AsSpan(offset, 2)));
+ return (float)BinaryPrimitives.ReadHalfLittleEndian(input.Slice(offset, 2));
#else
- return (float)Half.ToHalf(input, offset);
+ ushort bits = BinaryPrimitives.ReadUInt16LittleEndian(input.Slice(offset, 2));
+ return (float)Unsafe.As(ref bits);
#endif
}
-#if NET5_0
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static unsafe Half ToHalf(ushort bits)
- {
- return *((Half*)&bits);
- }
-#endif
-
- private static float ToSingle(byte[] input, int offset)
+ private static float ToSingle(ReadOnlySpan input, int offset)
{
#if NET5_0_OR_GREATER
- return BinaryPrimitives.ReadSingleLittleEndian(input.AsSpan(offset, 4));
+ return BinaryPrimitives.ReadSingleLittleEndian(input.Slice(offset, 4));
#else
- if (BitConverter.IsLittleEndian)
- return BitConverter.ToSingle(input, offset);
- else
- return BitConverter.ToSingle(new byte[] { input[offset + 3], input[offset + 2], input[offset + 1], input[offset] }, 0);
+ uint bits = BinaryPrimitives.ReadUInt32LittleEndian(input.Slice(offset, 4));
+ return Unsafe.As(ref bits);
#endif
}
@@ -738,6 +725,5 @@ namespace AssetRipper.TextureDecoder.Rgb
{
return byte.MaxValue < x ? byte.MaxValue : (x > byte.MinValue ? (byte)x : byte.MinValue);
}
-
}
}
diff --git a/TextureDecoder/TextureDecoder.csproj b/TextureDecoder/TextureDecoder.csproj
index 09e10f4..b5f5cc2 100644
--- a/TextureDecoder/TextureDecoder.csproj
+++ b/TextureDecoder/TextureDecoder.csproj
@@ -21,18 +21,13 @@
Copyright (c) 2022 ds5678
Managed library for decoding textures in multiple formats.
true
+ true
+ bin\TextureDecoder.xml
+
-
- true
-
-
-
- bin\TextureDecoder.xml
-
-