Skip to content

Commit 12c6750

Browse files
committed
Make Astc use safe code
1 parent 5dacd48 commit 12c6750

7 files changed

Lines changed: 120 additions & 112 deletions
Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,35 @@
1-
namespace AssetRipper.TextureDecoder.Astc
1+
namespace AssetRipper.TextureDecoder.Astc;
2+
3+
public static partial class AstcDecoder
24
{
3-
public static partial class AstcDecoder
5+
private struct BlockData
46
{
5-
private unsafe struct BlockData
6-
{
7-
public int bw;
8-
public int bh;
9-
public int width;
10-
public int height;
11-
public int part_num;
12-
public int dual_plane;
13-
public int plane_selector;
14-
public int weight_range;
15-
/// <summary>
16-
/// max: 120
17-
/// </summary>
18-
public int weight_num;
19-
public fixed int cem[4];
20-
public int cem_range;
21-
/// <summary>
22-
/// max: 32
23-
/// </summary>
24-
public int endpoint_value_num;
25-
public fixed int endpoints[4 * 8];
26-
public fixed int weights[144 * 2];
27-
public fixed int partition[144];
28-
}
7+
public int bw;
8+
public int bh;
9+
public int width;
10+
public int height;
11+
public int part_num;
12+
public int dual_plane;
13+
public int plane_selector;
14+
public int weight_range;
15+
/// <summary>
16+
/// max: 120
17+
/// </summary>
18+
public int weight_num;
19+
public IntBuffer4 cem;
20+
public int cem_range;
21+
/// <summary>
22+
/// max: 32
23+
/// </summary>
24+
public int endpoint_value_num;
25+
/// <summary>
26+
/// 4 * 8
27+
/// </summary>
28+
public EndpointBuffer endpoints;
29+
/// <summary>
30+
/// 144 * 2
31+
/// </summary>
32+
public IntBuffer288 weights;
33+
public IntBuffer144 partition;
2934
}
3035
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace AssetRipper.TextureDecoder.Astc;
2+
3+
public static partial class AstcDecoder
4+
{
5+
[InlineArray(4)]
6+
private struct EndpointBuffer
7+
{
8+
private Endpoint _element0;
9+
10+
[InlineArray(8)]
11+
public struct Endpoint
12+
{
13+
private int _element0;
14+
}
15+
}
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace AssetRipper.TextureDecoder.Astc;
2+
3+
public static partial class AstcDecoder
4+
{
5+
[InlineArray(144)]
6+
private struct IntBuffer144
7+
{
8+
private int _element0;
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace AssetRipper.TextureDecoder.Astc;
2+
3+
public static partial class AstcDecoder
4+
{
5+
[InlineArray(288)]
6+
private struct IntBuffer288
7+
{
8+
private int _element0;
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace AssetRipper.TextureDecoder.Astc;
2+
3+
public static partial class AstcDecoder
4+
{
5+
[InlineArray(4)]
6+
private struct IntBuffer4
7+
{
8+
private int _element0;
9+
}
10+
}
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
namespace AssetRipper.TextureDecoder.Astc
1+
namespace AssetRipper.TextureDecoder.Astc;
2+
3+
public static partial class AstcDecoder
24
{
3-
public static partial class AstcDecoder
5+
private struct IntSeqData
46
{
5-
private struct IntSeqData
6-
{
7-
public int bits;
8-
public int nonbits;
9-
}
7+
public int bits;
8+
public int nonbits;
109
}
1110
}

AssetRipper.TextureDecoder/Astc/AstcDecoder.cs

Lines changed: 37 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static void WriteUInt32(Span<byte> buffer, int offsetUInt32, uint value)
5252
}
5353
}
5454

55-
private unsafe static void DecodeBlock(ReadOnlySpan<byte> input, int blockWidth, int blockHeight, Span<uint> output)
55+
private static void DecodeBlock(ReadOnlySpan<byte> input, int blockWidth, int blockHeight, Span<uint> output)
5656
{
5757
if (input[0] == 0xfc && (input[1] & 1) == 1)
5858
{
@@ -78,7 +78,7 @@ private unsafe static void DecodeBlock(ReadOnlySpan<byte> input, int blockWidth,
7878
}
7979
}
8080

81-
private unsafe static void DecodeBlockParameters(ReadOnlySpan<byte> input, ref BlockData pBlock)
81+
private static void DecodeBlockParameters(ReadOnlySpan<byte> input, ref BlockData pBlock)
8282
{
8383
pBlock.dual_plane = (input[1] & 4) >> 2;
8484
pBlock.weight_range = (input[0] >> 4 & 1) | (input[1] << 2 & 8);
@@ -231,7 +231,7 @@ private unsafe static void DecodeBlockParameters(ReadOnlySpan<byte> input, ref B
231231
}
232232
}
233233

234-
private unsafe static void DecodeEndpoints(ReadOnlySpan<byte> input, ref BlockData pBlock)
234+
private static void DecodeEndpoints(ReadOnlySpan<byte> input, ref BlockData pBlock)
235235
{
236236
Span<IntSeqData> epSeq = stackalloc IntSeqData[32];
237237
DecodeIntseq(input, pBlock.part_num == 1 ? 17 : 29, CemTableA[pBlock.cem_range], CemTableB[pBlock.cem_range], pBlock.endpoint_value_num, false, epSeq);
@@ -352,61 +352,40 @@ private unsafe static void DecodeEndpoints(ReadOnlySpan<byte> input, ref BlockDa
352352
}
353353

354354
Span<int> v = ev;
355-
for (int cem = 0, cemOff = 0; cem < pBlock.part_num; v = v.Slice((pBlock.cem[cem] / 4 + 1) * 2), cem++, cemOff += 8)
355+
for (int cem = 0; cem < pBlock.part_num; v = v.Slice((pBlock.cem[cem] / 4 + 1) * 2), cem++)
356356
{
357357
switch (pBlock.cem[cem])
358358
{
359359
case 0:
360-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
361-
{
362-
SetEndpoint(new Span<int>(endpoint, 8), v[0], v[0], v[0], 255, v[1], v[1], v[1], 255);
363-
}
360+
SetEndpoint(pBlock.endpoints[cem], v[0], v[0], v[0], 255, v[1], v[1], v[1], 255);
364361
break;
365362
case 1:
366363
{
367364
int l0 = (v[0] >> 2) | (v[1] & 0xc0);
368365
int l1 = Clamp(l0 + (v[1] & 0x3f));
369-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
370-
{
371-
SetEndpoint(new Span<int>(endpoint, 8), l0, l0, l0, 255, l1, l1, l1, 255);
372-
}
366+
SetEndpoint(pBlock.endpoints[cem], l0, l0, l0, 255, l1, l1, l1, 255);
373367
}
374368
break;
375369
case 4:
376-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
377-
{
378-
SetEndpoint(new Span<int>(endpoint, 8), v[0], v[0], v[0], v[2], v[1], v[1], v[1], v[3]);
379-
}
370+
SetEndpoint(pBlock.endpoints[cem], v[0], v[0], v[0], v[2], v[1], v[1], v[1], v[3]);
380371
break;
381372
case 5:
382373
BitTransferSigned(ref v[1], ref v[0]);
383374
BitTransferSigned(ref v[3], ref v[2]);
384375
v[1] += v[0];
385-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
386-
{
387-
SetEndpointClamp(new Span<int>(endpoint, 8), v[0], v[0], v[0], v[2], v[1], v[1], v[1], v[2] + v[3]);
388-
}
376+
SetEndpointClamp(pBlock.endpoints[cem], v[0], v[0], v[0], v[2], v[1], v[1], v[1], v[2] + v[3]);
389377
break;
390378
case 6:
391-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
392-
{
393-
SetEndpoint(new Span<int>(endpoint, 8), v[0] * v[3] >> 8, v[1] * v[3] >> 8, v[2] * v[3] >> 8, 255, v[0], v[1], v[2], 255);
394-
}
379+
SetEndpoint(pBlock.endpoints[cem], v[0] * v[3] >> 8, v[1] * v[3] >> 8, v[2] * v[3] >> 8, 255, v[0], v[1], v[2], 255);
395380
break;
396381
case 8:
397382
if (v[0] + v[2] + v[4] <= v[1] + v[3] + v[5])
398383
{
399-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
400-
{
401-
SetEndpoint(new Span<int>(endpoint, 8), v[0], v[2], v[4], 255, v[1], v[3], v[5], 255);
402-
}
384+
SetEndpoint(pBlock.endpoints[cem], v[0], v[2], v[4], 255, v[1], v[3], v[5], 255);
403385
}
404386
else
405387
{
406-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
407-
{
408-
SetEndpointBlue(new Span<int>(endpoint, 8), v[1], v[3], v[5], 255, v[0], v[2], v[4], 255);
409-
}
388+
SetEndpointBlue(pBlock.endpoints[cem], v[1], v[3], v[5], 255, v[0], v[2], v[4], 255);
410389
}
411390

412391
break;
@@ -416,40 +395,25 @@ private unsafe static void DecodeEndpoints(ReadOnlySpan<byte> input, ref BlockDa
416395
BitTransferSigned(ref v[5], ref v[4]);
417396
if (v[1] + v[3] + v[5] >= 0)
418397
{
419-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
420-
{
421-
SetEndpointClamp(new Span<int>(endpoint, 8), v[0], v[2], v[4], 255, v[0] + v[1], v[2] + v[3], v[4] + v[5], 255);
422-
}
398+
SetEndpointClamp(pBlock.endpoints[cem], v[0], v[2], v[4], 255, v[0] + v[1], v[2] + v[3], v[4] + v[5], 255);
423399
}
424400
else
425401
{
426-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
427-
{
428-
SetEndpointBlueClamp(new Span<int>(endpoint, 8), v[0] + v[1], v[2] + v[3], v[4] + v[5], 255, v[0], v[2], v[4], 255);
429-
}
402+
SetEndpointBlueClamp(pBlock.endpoints[cem], v[0] + v[1], v[2] + v[3], v[4] + v[5], 255, v[0], v[2], v[4], 255);
430403
}
431404

432405
break;
433406
case 10:
434-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
435-
{
436-
SetEndpoint(new Span<int>(endpoint, 8), v[0] * v[3] >> 8, v[1] * v[3] >> 8, v[2] * v[3] >> 8, v[4], v[0], v[1], v[2], v[5]);
437-
}
407+
SetEndpoint(pBlock.endpoints[cem], v[0] * v[3] >> 8, v[1] * v[3] >> 8, v[2] * v[3] >> 8, v[4], v[0], v[1], v[2], v[5]);
438408
break;
439409
case 12:
440410
if (v[0] + v[2] + v[4] <= v[1] + v[3] + v[5])
441411
{
442-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
443-
{
444-
SetEndpoint(new Span<int>(endpoint, 8), v[0], v[2], v[4], v[6], v[1], v[3], v[5], v[7]);
445-
}
412+
SetEndpoint(pBlock.endpoints[cem], v[0], v[2], v[4], v[6], v[1], v[3], v[5], v[7]);
446413
}
447414
else
448415
{
449-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
450-
{
451-
SetEndpointBlue(new Span<int>(endpoint, 8), v[1], v[3], v[5], v[7], v[0], v[2], v[4], v[6]);
452-
}
416+
SetEndpointBlue(pBlock.endpoints[cem], v[1], v[3], v[5], v[7], v[0], v[2], v[4], v[6]);
453417
}
454418

455419
break;
@@ -460,25 +424,19 @@ private unsafe static void DecodeEndpoints(ReadOnlySpan<byte> input, ref BlockDa
460424
BitTransferSigned(ref v[7], ref v[6]);
461425
if (v[1] + v[3] + v[5] >= 0)
462426
{
463-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
464-
{
465-
SetEndpointClamp(new Span<int>(endpoint, 8), v[0], v[2], v[4], v[6], v[0] + v[1], v[2] + v[3], v[4] + v[5], v[6] + v[7]);
466-
}
427+
SetEndpointClamp(pBlock.endpoints[cem], v[0], v[2], v[4], v[6], v[0] + v[1], v[2] + v[3], v[4] + v[5], v[6] + v[7]);
467428
}
468429
else
469430
{
470-
fixed (int* endpoint = &pBlock.endpoints[cemOff])
471-
{
472-
SetEndpointBlueClamp(new Span<int>(endpoint, 8), v[0] + v[1], v[2] + v[3], v[4] + v[5], v[6] + v[7], v[0], v[2], v[4], v[6]);
473-
}
431+
SetEndpointBlueClamp(pBlock.endpoints[cem], v[0] + v[1], v[2] + v[3], v[4] + v[5], v[6] + v[7], v[0], v[2], v[4], v[6]);
474432
}
475433

476434
break;
477435
}
478436
}
479437
}
480438

481-
private unsafe static void DecodeWeights(ReadOnlySpan<byte> input, ref BlockData block)
439+
private static void DecodeWeights(ReadOnlySpan<byte> input, ref BlockData block)
482440
{
483441
Span<IntSeqData> wSeq = stackalloc IntSeqData[128];
484442
DecodeIntseq(input, 128, WeightPrecTableA[block.weight_range], WeightPrecTableB[block.weight_range], block.weight_num, true, wSeq);
@@ -634,7 +592,7 @@ private unsafe static void DecodeWeights(ReadOnlySpan<byte> input, ref BlockData
634592
}
635593
}
636594

637-
private unsafe static void SelectPartition(ReadOnlySpan<byte> input, ref BlockData block)
595+
private static void SelectPartition(ReadOnlySpan<byte> input, ref BlockData block)
638596
{
639597
bool small_block = block.bw * block.bh < 31;
640598
int seed = (BinaryPrimitives.ReadInt32LittleEndian(input) >> 13 & 0x3ff) | (block.part_num - 1) << 10;
@@ -716,7 +674,7 @@ private unsafe static void SelectPartition(ReadOnlySpan<byte> input, ref BlockDa
716674
}
717675
}
718676

719-
private unsafe static void ApplicateColor(BlockData block, Span<uint> output)
677+
private static void ApplicateColor(BlockData block, Span<uint> output)
720678
{
721679
if (block.dual_plane != 0)
722680
{
@@ -727,21 +685,21 @@ private unsafe static void ApplicateColor(BlockData block, Span<uint> output)
727685
for (int i = 0; i < block.bw * block.bh; i++)
728686
{
729687
int p = block.partition[i];
730-
byte r = SelectColor(block.endpoints[p * 8 + 0], block.endpoints[p * 8 + 4], block.weights[i * 2 + ps[0]]);
731-
byte g = SelectColor(block.endpoints[p * 8 + 1], block.endpoints[p * 8 + 5], block.weights[i * 2 + ps[1]]);
732-
byte b = SelectColor(block.endpoints[p * 8 + 2], block.endpoints[p * 8 + 6], block.weights[i * 2 + ps[2]]);
733-
byte a = SelectColor(block.endpoints[p * 8 + 3], block.endpoints[p * 8 + 7], block.weights[i * 2 + ps[3]]);
688+
byte r = SelectColor(block.endpoints[p][0], block.endpoints[p][4], block.weights[i * 2 + ps[0]]);
689+
byte g = SelectColor(block.endpoints[p][1], block.endpoints[p][5], block.weights[i * 2 + ps[1]]);
690+
byte b = SelectColor(block.endpoints[p][2], block.endpoints[p][6], block.weights[i * 2 + ps[2]]);
691+
byte a = SelectColor(block.endpoints[p][3], block.endpoints[p][7], block.weights[i * 2 + ps[3]]);
734692
output[i] = Color(r, g, b, a);
735693
}
736694
}
737695
else
738696
{
739697
for (int i = 0; i < block.bw * block.bh; i++)
740698
{
741-
byte r = SelectColor(block.endpoints[0], block.endpoints[4], block.weights[i * 2 + ps[0]]);
742-
byte g = SelectColor(block.endpoints[1], block.endpoints[5], block.weights[i * 2 + ps[1]]);
743-
byte b = SelectColor(block.endpoints[2], block.endpoints[6], block.weights[i * 2 + ps[2]]);
744-
byte a = SelectColor(block.endpoints[3], block.endpoints[7], block.weights[i * 2 + ps[3]]);
699+
byte r = SelectColor(block.endpoints[0][0], block.endpoints[0][4], block.weights[i * 2 + ps[0]]);
700+
byte g = SelectColor(block.endpoints[0][1], block.endpoints[0][5], block.weights[i * 2 + ps[1]]);
701+
byte b = SelectColor(block.endpoints[0][2], block.endpoints[0][6], block.weights[i * 2 + ps[2]]);
702+
byte a = SelectColor(block.endpoints[0][3], block.endpoints[0][7], block.weights[i * 2 + ps[3]]);
745703
output[i] = Color(r, g, b, a);
746704
}
747705
}
@@ -751,21 +709,21 @@ private unsafe static void ApplicateColor(BlockData block, Span<uint> output)
751709
for (int i = 0; i < block.bw * block.bh; i++)
752710
{
753711
int p = block.partition[i];
754-
byte r = SelectColor(block.endpoints[p * 8 + 0], block.endpoints[p * 8 + 4], block.weights[i * 2]);
755-
byte g = SelectColor(block.endpoints[p * 8 + 1], block.endpoints[p * 8 + 5], block.weights[i * 2]);
756-
byte b = SelectColor(block.endpoints[p * 8 + 2], block.endpoints[p * 8 + 6], block.weights[i * 2]);
757-
byte a = SelectColor(block.endpoints[p * 8 + 3], block.endpoints[p * 8 + 7], block.weights[i * 2]);
712+
byte r = SelectColor(block.endpoints[p][0], block.endpoints[p][4], block.weights[i * 2]);
713+
byte g = SelectColor(block.endpoints[p][1], block.endpoints[p][5], block.weights[i * 2]);
714+
byte b = SelectColor(block.endpoints[p][2], block.endpoints[p][6], block.weights[i * 2]);
715+
byte a = SelectColor(block.endpoints[p][3], block.endpoints[p][7], block.weights[i * 2]);
758716
output[i] = Color(r, g, b, a);
759717
}
760718
}
761719
else
762720
{
763721
for (int i = 0; i < block.bw * block.bh; i++)
764722
{
765-
byte r = SelectColor(block.endpoints[0], block.endpoints[4], block.weights[i * 2]);
766-
byte g = SelectColor(block.endpoints[1], block.endpoints[5], block.weights[i * 2]);
767-
byte b = SelectColor(block.endpoints[2], block.endpoints[6], block.weights[i * 2]);
768-
byte a = SelectColor(block.endpoints[3], block.endpoints[7], block.weights[i * 2]);
723+
byte r = SelectColor(block.endpoints[0][0], block.endpoints[0][4], block.weights[i * 2]);
724+
byte g = SelectColor(block.endpoints[0][1], block.endpoints[0][5], block.weights[i * 2]);
725+
byte b = SelectColor(block.endpoints[0][2], block.endpoints[0][6], block.weights[i * 2]);
726+
byte a = SelectColor(block.endpoints[0][3], block.endpoints[0][7], block.weights[i * 2]);
769727
output[i] = Color(r, g, b, a);
770728
}
771729
}

0 commit comments

Comments
 (0)