Skip to content

Commit 5dacd48

Browse files
committed
Use InlineArray for PvrtcDecoder
1 parent 509a567 commit 5dacd48

3 files changed

Lines changed: 33 additions & 69 deletions

File tree

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,11 @@
1-
//#define DISABLE_TWINDDLING_ROUTINE
2-
#define ASSUME_IMAGE_TILING
1+
namespace AssetRipper.TextureDecoder.Pvrtc;
32

4-
5-
namespace AssetRipper.TextureDecoder.Pvrtc
3+
public static partial class PvrtcDecoder
64
{
7-
public static partial class PvrtcDecoder
5+
/// <summary>
6+
/// 8 bytes (64 bits) per block
7+
/// </summary>
8+
private readonly record struct AmtcBlock(uint PackedData0, uint PackedData1)
89
{
9-
/// <summary>
10-
/// 8 bytes
11-
/// </summary>
12-
private struct AmtcBlock
13-
{
14-
public AmtcBlock(uint v0, uint v1)
15-
{
16-
PackedData0 = v0;
17-
PackedData1 = v1;
18-
}
19-
20-
// Uses 64 bits pre block
21-
public readonly uint PackedData0;
22-
public readonly uint PackedData1;
23-
}
2410
}
2511
}
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
//#define DISABLE_TWINDDLING_ROUTINE
2-
#define ASSUME_IMAGE_TILING
1+
namespace AssetRipper.TextureDecoder.Pvrtc;
32

4-
5-
namespace AssetRipper.TextureDecoder.Pvrtc
3+
public static partial class PvrtcDecoder
64
{
7-
public static partial class PvrtcDecoder
5+
/// <summary>
6+
/// Low precision colours extracted from the blocks
7+
/// </summary>
8+
/// <remarks>
9+
/// 2 * 4 integers
10+
/// </remarks>
11+
[InlineArray(8)]
12+
private struct Colours5554
813
{
9-
/// <summary>
10-
/// Low precision colours extracted from the blocks
11-
/// </summary>
12-
private unsafe struct Colours5554
13-
{
14-
public fixed int Reps[2 * 4];
15-
}
14+
private int _element0;
1615
}
1716
}

AssetRipper.TextureDecoder/Pvrtc/PvrtcDecoder.cs

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,16 @@ public static int DecompressPVRTC(ReadOnlySpan<byte> input, int xDim, int yDim,
8383
if (changed)
8484
{
8585
AmtcBlock block00 = blocks[(int)blocki00];
86-
Unpack5554Colour(block00, m_colors.GetIntSpanForColor(0));
86+
Unpack5554Colour(block00, m_colors[0]);
8787
UnpackModulations(block00, do2bitMode, modulationVals, modulationModes, 0, 0);
8888
AmtcBlock block01 = blocks[(int)blocki01];
89-
Unpack5554Colour(block01, m_colors.GetIntSpanForColor(1));
89+
Unpack5554Colour(block01, m_colors[1]);
9090
UnpackModulations(block01, do2bitMode, modulationVals, modulationModes, xBlockSize, 0);
9191
AmtcBlock block10 = blocks[(int)blocki10];
92-
Unpack5554Colour(block10, m_colors.GetIntSpanForColor(2));
92+
Unpack5554Colour(block10, m_colors[2]);
9393
UnpackModulations(block10, do2bitMode, modulationVals, modulationModes, 0, BlockYSize);
9494
AmtcBlock block11 = blocks[(int)blocki11];
95-
Unpack5554Colour(block11, m_colors.GetIntSpanForColor(3));
95+
Unpack5554Colour(block11, m_colors[3]);
9696
UnpackModulations(block11, do2bitMode, modulationVals, modulationModes, xBlockSize, BlockYSize);
9797

9898
pblocki00 = blocki00;
@@ -104,8 +104,8 @@ public static int DecompressPVRTC(ReadOnlySpan<byte> input, int xDim, int yDim,
104104
}
105105

106106
// decompress the pixel. First compute the interpolated A and B signals
107-
InterpolateColours(m_colors.GetIntSpanForColor(0), m_colors.GetIntSpanForColor(1), m_colors.GetIntSpanForColor(2), m_colors.GetIntSpanForColor(3), 0, do2bitMode, x, y, aSig);
108-
InterpolateColours(m_colors.GetIntSpanForColor(0), m_colors.GetIntSpanForColor(1), m_colors.GetIntSpanForColor(2), m_colors.GetIntSpanForColor(3), 1, do2bitMode, x, y, bSig);
107+
InterpolateColours(m_colors[0], m_colors[1], m_colors[2], m_colors[3], 0, do2bitMode, x, y, aSig);
108+
InterpolateColours(m_colors[0], m_colors[1], m_colors[2], m_colors[3], 1, do2bitMode, x, y, bSig);
109109
GetModulationValue(x, y, do2bitMode, modulationVals, modulationModes, out int mod, out bool doPT);
110110

111111
// compute the modulated color. Swap red and blue channel
@@ -141,11 +141,11 @@ private static uint TwiddleUV(uint ySize, uint xSize, uint yPos, uint xPos)
141141
{
142142
throw new Exception();
143143
}
144-
if (!IsPowerOf2((uint)ySize))
144+
if (!BitOperations.IsPow2(ySize))
145145
{
146146
throw new Exception();
147147
}
148-
if (!IsPowerOf2((uint)xSize))
148+
if (!BitOperations.IsPow2(xSize))
149149
{
150150
throw new Exception();
151151
}
@@ -396,12 +396,14 @@ private static void UnpackModulations(AmtcBlock block, bool do2bitMode, Span<int
396396
/// </summary>
397397
private static void Unpack5554Colour(AmtcBlock block, Span<int> abColors)
398398
{
399-
Span<uint> rawBits = stackalloc uint[2];
400-
// extract A and B
401-
// 15 bits (shifted up by one)
402-
rawBits[0] = block.PackedData1 & (0xFFFE);
403-
// 16 bits
404-
rawBits[1] = block.PackedData1 >> 16;
399+
ReadOnlySpan<uint> rawBits =
400+
[
401+
// extract A and B
402+
// 15 bits (shifted up by one)
403+
block.PackedData1 & (0xFFFE),
404+
// 16 bits
405+
block.PackedData1 >> 16,
406+
];
405407

406408
// step through both colours
407409
for (int i = 0; i < 2; i++)
@@ -453,29 +455,6 @@ private static void Unpack5554Colour(AmtcBlock block, Span<int> abColors)
453455
}
454456
}
455457

456-
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
457-
private static Span<int> GetIntSpanForColor(this Span<Colours5554> colorSpan, int index)
458-
{
459-
return MemoryMarshal.Cast<Colours5554, int>(colorSpan.Slice(index, 1));
460-
}
461-
462-
/// <summary>
463-
/// Check that a number is an integer power of two, i.e. 1, 2, 4, 8, ... etc. Returns false for zero
464-
/// </summary>
465-
/// <param name="input">A number</param>
466-
/// <returns>True if the number is an integer power of two, else false</returns>
467-
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
468-
private static bool IsPowerOf2(uint input)
469-
{
470-
if (input == 0)
471-
{
472-
return false;
473-
}
474-
475-
uint minus1 = input - 1;
476-
return ((input | minus1) == (input ^ minus1));
477-
}
478-
479458
/// <summary>
480459
/// Define an expression to either wrap or clamp large or small vals to the legal coordinate range
481460
/// </summary>

0 commit comments

Comments
 (0)