Skip to content

Commit 93ad0ee

Browse files
committed
Generic methods for Bc decoding
1 parent b5b6b5a commit 93ad0ee

File tree

10 files changed

+174
-100
lines changed

10 files changed

+174
-100
lines changed

AssetRipper.TextureDecoder.ConsoleApp/Program.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,25 +143,25 @@ private static void DecodeBc(ReadOnlySpan<byte> input, int width, int height, st
143143
switch (mode)
144144
{
145145
case 1:
146-
Bc1.Decompress(input, width, height, output);
146+
Bc1.Decompress<ColorBGRA32, byte>(input, width, height, output);
147147
break;
148148
case 2:
149-
Bc2.Decompress(input, width, height, output);
149+
Bc2.Decompress<ColorBGRA32, byte>(input, width, height, output);
150150
break;
151151
case 3:
152-
Bc3.Decompress(input, width, height, output);
152+
Bc3.Decompress<ColorBGRA32, byte>(input, width, height, output);
153153
break;
154154
case 4:
155-
Bc4.Decompress(input, width, height, output);
155+
Bc4.Decompress<ColorBGRA32, byte>(input, width, height, output);
156156
break;
157157
case 5:
158-
Bc5.Decompress(input, width, height, output);
158+
Bc5.Decompress<ColorBGRA32, byte>(input, width, height, output);
159159
break;
160160
case 6:
161-
Bc6h.Decompress(input, width, height, bool.Parse(isSignedString), output);
161+
Bc6h.Decompress<ColorBGRA32, byte>(input, width, height, bool.Parse(isSignedString), output);
162162
break;
163163
case 7:
164-
Bc7.Decompress(input, width, height, output);
164+
Bc7.Decompress<ColorBGRA32, byte>(input, width, height, output);
165165
break;
166166

167167
default:

AssetRipper.TextureDecoder.Tests/BcTests.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void Decompress_BC1()
2727
int totalBytesRead = 0;
2828
foreach (int size in new int[] { 256, 128, 64, 32, 16, 8, 4 }) //mipmaps 2 and 1 cause a buffer overrun for the output
2929
{
30-
int bytesRead = Bc1.Decompress(data.Slice(totalBytesRead), size, size, out byte[] bcDecodedData);
30+
int bytesRead = Bc1.Decompress<ColorBGRA32, byte>(data.Slice(totalBytesRead), size, size, out byte[] bcDecodedData);
3131
DxtDecoder.DecompressDXT1<ColorBGRA32, byte>(data.Slice(totalBytesRead), size, size, out byte[] dxtDecodedData);
3232
totalBytesRead += bytesRead;
3333
AssertAlmostEqual(dxtDecodedData, bcDecodedData);
@@ -42,7 +42,7 @@ public void Decompress_BC2()
4242
int totalBytesRead = 0;
4343
foreach (int size in new int[] { 256, 128, 64, 32, 16, 8, 4 }) //mipmaps 2 and 1 cause a buffer overrun for the output
4444
{
45-
int bytesRead = Bc2.Decompress(data.Slice(totalBytesRead), size, size, out byte[] bcDecodedData);
45+
int bytesRead = Bc2.Decompress<ColorBGRA32, byte>(data.Slice(totalBytesRead), size, size, out byte[] bcDecodedData);
4646
DxtDecoder.DecompressDXT3<ColorBGRA32, byte>(data.Slice(totalBytesRead), size, size, out byte[] dxtDecodedData);
4747
totalBytesRead += bytesRead;
4848
AssertAlmostEqual(dxtDecodedData, bcDecodedData);
@@ -57,7 +57,7 @@ public void Decompress_BC3()
5757
int totalBytesRead = 0;
5858
foreach (int size in new int[] { 256, 128, 64, 32, 16, 8, 4 }) //mipmaps 2 and 1 cause a buffer overrun for the output
5959
{
60-
int bytesRead = Bc3.Decompress(data.Slice(totalBytesRead), size, size, out byte[] bcDecodedData);
60+
int bytesRead = Bc3.Decompress<ColorBGRA32, byte>(data.Slice(totalBytesRead), size, size, out byte[] bcDecodedData);
6161
DxtDecoder.DecompressDXT5<ColorBGRA32, byte>(data.Slice(totalBytesRead), size, size, out byte[] dxtDecodedData);
6262
totalBytesRead += bytesRead;
6363
AssertAlmostEqual(dxtDecodedData, bcDecodedData);
@@ -69,15 +69,15 @@ public void Decompress_BC3()
6969
public void Decompress_BC4()
7070
{
7171
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.BcTestFiles + "test.bc4");
72-
int bytesRead = Bc4.Decompress(data, 512, 512, out _);
72+
int bytesRead = Bc4.Decompress<ColorBGRA32, byte>(data, 512, 512, out _);
7373
Assert.That(bytesRead, Is.EqualTo(data.Length));
7474
}
7575

7676
[Test]
7777
public void Decompress_BC5()
7878
{
7979
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.BcTestFiles + "test.bc5");
80-
int bytesRead = Bc5.Decompress(data, 512, 512, out _);
80+
int bytesRead = Bc5.Decompress<ColorBGRA32, byte>(data, 512, 512, out _);
8181
Assert.That(bytesRead, Is.EqualTo(data.Length));
8282
}
8383

@@ -103,7 +103,7 @@ public void PartialBlock_BC1([Range(1, 4)] int width, [Range(1, 4)] int height)
103103
Assert.Multiple(() =>
104104
{
105105
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.DxtTestFiles + "test.dxt1").AsSpan()[..Bc1.BlockSize];
106-
int bytesRead = Bc1.Decompress(data, width, height, out byte[] decodedData);
106+
int bytesRead = Bc1.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
107107
Assert.That(bytesRead, Is.EqualTo(data.Length));
108108
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
109109
});
@@ -115,7 +115,7 @@ public void PartialBlock_BC2([Range(1, 4)] int width, [Range(1, 4)] int height)
115115
Assert.Multiple(() =>
116116
{
117117
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.DxtTestFiles + "test.dxt3").AsSpan()[..Bc2.BlockSize];
118-
int bytesRead = Bc2.Decompress(data, width, height, out byte[] decodedData);
118+
int bytesRead = Bc2.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
119119
Assert.That(bytesRead, Is.EqualTo(data.Length));
120120
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
121121
});
@@ -127,7 +127,7 @@ public void PartialBlock_BC3([Range(1, 4)] int width, [Range(1, 4)] int height)
127127
Assert.Multiple(() =>
128128
{
129129
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.DxtTestFiles + "test.dxt5").AsSpan()[..Bc3.BlockSize];
130-
int bytesRead = Bc3.Decompress(data, width, height, out byte[] decodedData);
130+
int bytesRead = Bc3.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
131131
Assert.That(bytesRead, Is.EqualTo(data.Length));
132132
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
133133
});
@@ -139,7 +139,7 @@ public void PartialBlock_BC4([Range(1, 4)] int width, [Range(1, 4)] int height)
139139
Assert.Multiple(() =>
140140
{
141141
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.BcTestFiles + "test.bc4").AsSpan()[..Bc4.BlockSize];
142-
int bytesRead = Bc4.Decompress(data, width, height, out byte[] decodedData);
142+
int bytesRead = Bc4.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
143143
Assert.That(bytesRead, Is.EqualTo(data.Length));
144144
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
145145
});
@@ -151,7 +151,7 @@ public void PartialBlock_BC5([Range(1, 4)] int width, [Range(1, 4)] int height)
151151
Assert.Multiple(() =>
152152
{
153153
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.BcTestFiles + "test.bc5").AsSpan()[..Bc5.BlockSize];
154-
int bytesRead = Bc5.Decompress(data, width, height, out byte[] decodedData);
154+
int bytesRead = Bc5.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
155155
Assert.That(bytesRead, Is.EqualTo(data.Length));
156156
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
157157
});
@@ -163,7 +163,7 @@ public void PartialBlock_BC6H([Range(1, 4)] int width, [Range(1, 4)] int height)
163163
Assert.Multiple(() =>
164164
{
165165
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.BcTestFiles + "test.bc6h_best").AsSpan()[..Bc6h.BlockSize];
166-
int bytesRead = Bc6h.Decompress(data, width, height, false, out byte[] decodedData);
166+
int bytesRead = Bc6h.Decompress<ColorBGRA32, byte>(data, width, height, false, out byte[] decodedData);
167167
Assert.That(bytesRead, Is.EqualTo(data.Length));
168168
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
169169
});
@@ -175,7 +175,7 @@ public void PartialBlock_BC7([Range(1, 4)] int width, [Range(1, 4)] int height)
175175
Assert.Multiple(() =>
176176
{
177177
ReadOnlySpan<byte> data = File.ReadAllBytes(TestFileFolders.BcTestFiles + "test.bc7_best").AsSpan()[..Bc7.BlockSize];
178-
int bytesRead = Bc7.Decompress(data, width, height, out byte[] decodedData);
178+
int bytesRead = Bc7.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
179179
Assert.That(bytesRead, Is.EqualTo(data.Length));
180180
Assert.That(decodedData, Has.Length.EqualTo(width * height * Unsafe.SizeOf<ColorBGRA32>()));
181181
});
@@ -184,15 +184,15 @@ public void PartialBlock_BC7([Range(1, 4)] int width, [Range(1, 4)] int height)
184184
private static void AssertCorrectBC6HDecompression(string path, int width, int height, bool isSigned)
185185
{
186186
ReadOnlySpan<byte> data = File.ReadAllBytes(path);
187-
int bytesRead = Bc6h.Decompress(data, width, height, isSigned, out byte[] decodedData);
187+
int bytesRead = Bc6h.Decompress<ColorBGRA32, byte>(data, width, height, isSigned, out byte[] decodedData);
188188
Assert.That(bytesRead, Is.EqualTo(data.Length));
189189
ByteArrayDeviation.AssertMinimalDeviation(decodedData, originalBgra32LogoData, MaxMeanDeviationBc6h, MaxStandardDeviationBc6h);
190190
}
191191

192192
private static void AssertCorrectBC7Decompression(string path, int width, int height)
193193
{
194194
ReadOnlySpan<byte> data = File.ReadAllBytes(path);
195-
int bytesRead = Bc7.Decompress(data, width, height, out byte[] decodedData);
195+
int bytesRead = Bc7.Decompress<ColorBGRA32, byte>(data, width, height, out byte[] decodedData);
196196
Assert.That(bytesRead, Is.EqualTo(data.Length));
197197
ByteArrayDeviation.AssertMinimalDeviation(decodedData, originalBgra32LogoData, MaxMeanDeviationBc7, MaxStandardDeviationBc7);
198198
}

AssetRipper.TextureDecoder/Bc/Bc1.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,39 @@ public static class Bc1
2626
/// </summary>
2727
internal static int DecodedBlockSize => BlockWidth * BlockHeight * PixelSize;
2828

29-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
29+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
30+
where TOutputChannelValue : unmanaged
31+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3032
{
31-
output = new byte[width * height * Unsafe.SizeOf<ColorBGRA32>()];
32-
return Decompress(input, width, height, output);
33+
output = new byte[width * height * Unsafe.SizeOf<TOutputColor>()];
34+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, output);
3335
}
3436

35-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
37+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
38+
where TOutputChannelValue : unmanaged
39+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3640
{
41+
ThrowHelper.ThrowIfNotLittleEndian();
42+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, MemoryMarshal.Cast<byte, TOutputColor>(output));
43+
}
44+
45+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<TOutputColor> output)
46+
where TOutputChannelValue : unmanaged
47+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
48+
{
49+
ThrowHelper.ThrowIfNotLittleEndian();
50+
ThrowHelper.ThrowIfNotEnoughSpace(output.Length, width * height);
3751
Span<byte> buffer = stackalloc byte[DecodedBlockSize];
3852
int inputOffset = 0;
3953
for (int i = 0; i < height; i += BlockHeight)
4054
{
4155
for (int j = 0; j < width; j += BlockWidth)
4256
{
4357
BcHelpers.DecompressBc1(input.Slice(inputOffset, BlockSize), buffer);
44-
BcHelpers.CopyBufferToOutput(buffer, output, width, height, j, i, BlockWidth, BlockHeight, PixelSize);
58+
BcHelpers.CopyBufferToOutput<ColorRGBA<byte>, byte, TOutputColor, TOutputChannelValue>(MemoryMarshal.Cast<byte, ColorRGBA<byte>>(buffer), output, width, height, j, i, BlockWidth, BlockHeight);
4559
inputOffset += BlockSize;
4660
}
4761
}
48-
RgbConverter.Convert<ColorRGBA<byte>, byte, ColorBGRA32, byte>(output, width, height, output);
4962
return inputOffset;
5063
}
5164

AssetRipper.TextureDecoder/Bc/Bc2.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,39 @@ public static class Bc2
2626
/// </summary>
2727
internal static int DecodedBlockSize => BlockWidth * BlockHeight * PixelSize;
2828

29-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
29+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
30+
where TOutputChannelValue : unmanaged
31+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3032
{
31-
output = new byte[width * height * Unsafe.SizeOf<ColorBGRA32>()];
32-
return Decompress(input, width, height, output);
33+
output = new byte[width * height * Unsafe.SizeOf<TOutputColor>()];
34+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, output);
3335
}
3436

35-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
37+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
38+
where TOutputChannelValue : unmanaged
39+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3640
{
41+
ThrowHelper.ThrowIfNotLittleEndian();
42+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, MemoryMarshal.Cast<byte, TOutputColor>(output));
43+
}
44+
45+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<TOutputColor> output)
46+
where TOutputChannelValue : unmanaged
47+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
48+
{
49+
ThrowHelper.ThrowIfNotLittleEndian();
50+
ThrowHelper.ThrowIfNotEnoughSpace(output.Length, width * height);
3751
Span<byte> buffer = stackalloc byte[DecodedBlockSize];
3852
int inputOffset = 0;
3953
for (int i = 0; i < height; i += BlockHeight)
4054
{
4155
for (int j = 0; j < width; j += BlockWidth)
4256
{
43-
BcHelpers.DecompressBc2(input.Slice(inputOffset), buffer);
44-
BcHelpers.CopyBufferToOutput(buffer, output, width, height, j, i, BlockWidth, BlockHeight, PixelSize);
57+
BcHelpers.DecompressBc2(input.Slice(inputOffset, BlockSize), buffer);
58+
BcHelpers.CopyBufferToOutput<ColorRGBA<byte>, byte, TOutputColor, TOutputChannelValue>(MemoryMarshal.Cast<byte, ColorRGBA<byte>>(buffer), output, width, height, j, i, BlockWidth, BlockHeight);
4559
inputOffset += BlockSize;
4660
}
4761
}
48-
RgbConverter.Convert<ColorRGBA<byte>, byte, ColorBGRA32, byte>(output, width, height, output);
4962
return inputOffset;
5063
}
5164

AssetRipper.TextureDecoder/Bc/Bc3.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,39 @@ public static class Bc3
2626
/// </summary>
2727
internal static int DecodedBlockSize => BlockWidth * BlockHeight * PixelSize;
2828

29-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
29+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
30+
where TOutputChannelValue : unmanaged
31+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3032
{
31-
output = new byte[width * height * Unsafe.SizeOf<ColorBGRA32>()];
32-
return Decompress(input, width, height, output);
33+
output = new byte[width * height * Unsafe.SizeOf<TOutputColor>()];
34+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, output);
3335
}
3436

35-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
37+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
38+
where TOutputChannelValue : unmanaged
39+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3640
{
41+
ThrowHelper.ThrowIfNotLittleEndian();
42+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, MemoryMarshal.Cast<byte, TOutputColor>(output));
43+
}
44+
45+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<TOutputColor> output)
46+
where TOutputChannelValue : unmanaged
47+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
48+
{
49+
ThrowHelper.ThrowIfNotLittleEndian();
50+
ThrowHelper.ThrowIfNotEnoughSpace(output.Length, width * height);
3751
Span<byte> buffer = stackalloc byte[DecodedBlockSize];
3852
int inputOffset = 0;
3953
for (int i = 0; i < height; i += BlockHeight)
4054
{
4155
for (int j = 0; j < width; j += BlockWidth)
4256
{
43-
BcHelpers.DecompressBc3(input.Slice(inputOffset), buffer);
44-
BcHelpers.CopyBufferToOutput(buffer, output, width, height, j, i, BlockWidth, BlockHeight, PixelSize);
57+
BcHelpers.DecompressBc3(input.Slice(inputOffset, BlockSize), buffer);
58+
BcHelpers.CopyBufferToOutput<ColorRGBA<byte>, byte, TOutputColor, TOutputChannelValue>(MemoryMarshal.Cast<byte, ColorRGBA<byte>>(buffer), output, width, height, j, i, BlockWidth, BlockHeight);
4559
inputOffset += BlockSize;
4660
}
4761
}
48-
RgbConverter.Convert<ColorRGBA<byte>, byte, ColorBGRA32, byte>(output, width, height, output);
4962
return inputOffset;
5063
}
5164

AssetRipper.TextureDecoder/Bc/Bc4.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,39 @@ public static class Bc4
2727
/// </summary>
2828
internal static int DecodedBlockSize => BlockWidth * BlockHeight * PixelSize;
2929

30-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
30+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, out byte[] output)
31+
where TOutputChannelValue : unmanaged
32+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3133
{
32-
output = new byte[width * height * Unsafe.SizeOf<ColorBGRA32>()];
33-
return Decompress(input, width, height, output);
34+
output = new byte[width * height * Unsafe.SizeOf<TOutputColor>()];
35+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, output);
3436
}
3537

36-
public static int Decompress(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
38+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<byte> output)
39+
where TOutputChannelValue : unmanaged
40+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
3741
{
38-
int naturalSize = width * height * PixelSize;
39-
byte[] rentedArray = ArrayPool<byte>.Shared.Rent(naturalSize);
40-
Span<byte> naturalPixels = new Span<byte>(rentedArray, 0, naturalSize);
42+
ThrowHelper.ThrowIfNotLittleEndian();
43+
return Decompress<TOutputColor, TOutputChannelValue>(input, width, height, MemoryMarshal.Cast<byte, TOutputColor>(output));
44+
}
45+
46+
public static int Decompress<TOutputColor, TOutputChannelValue>(ReadOnlySpan<byte> input, int width, int height, Span<TOutputColor> output)
47+
where TOutputChannelValue : unmanaged
48+
where TOutputColor : unmanaged, IColor<TOutputChannelValue>
49+
{
50+
ThrowHelper.ThrowIfNotLittleEndian();
51+
ThrowHelper.ThrowIfNotEnoughSpace(output.Length, width * height);
4152
Span<byte> buffer = stackalloc byte[DecodedBlockSize];
4253
int inputOffset = 0;
4354
for (int i = 0; i < height; i += BlockHeight)
4455
{
4556
for (int j = 0; j < width; j += BlockWidth)
4657
{
47-
BcHelpers.DecompressBc4(input.Slice(inputOffset), buffer);
48-
BcHelpers.CopyBufferToOutput(buffer, naturalPixels, width, height, j, i, BlockWidth, BlockHeight, PixelSize);
58+
BcHelpers.DecompressBc4(input.Slice(inputOffset, BlockSize), buffer);
59+
BcHelpers.CopyBufferToOutput<ColorR<byte>, byte, TOutputColor, TOutputChannelValue>(MemoryMarshal.Cast<byte, ColorR<byte>>(buffer), output, width, height, j, i, BlockWidth, BlockHeight);
4960
inputOffset += BlockSize;
5061
}
5162
}
52-
RgbConverter.Convert<ColorR<byte>, byte, ColorBGRA32, byte>(naturalPixels, width, height, output);
53-
ArrayPool<byte>.Shared.Return(rentedArray);
5463
return inputOffset;
5564
}
5665

0 commit comments

Comments
 (0)