@@ -39,9 +39,9 @@ public static void DecompressBc6h(ReadOnlySpan<byte> compressedBlock, Span<byte>
3939 low = BinaryPrimitives . ReadUInt64LittleEndian ( compressedBlock ) ,
4040 high = BinaryPrimitives . ReadUInt64LittleEndian ( compressedBlock . Slice ( sizeof ( ulong ) ) )
4141 } ;
42- Span < int > r = stackalloc int [ 4 ] ; // wxyz
43- Span < int > g = stackalloc int [ 4 ] ;
44- Span < int > b = stackalloc int [ 4 ] ;
42+ Span < uint > r = stackalloc uint [ 4 ] ; // wxyz
43+ Span < uint > g = stackalloc uint [ 4 ] ;
44+ Span < uint > b = stackalloc uint [ 4 ] ;
4545
4646 int decompressedOffset = 0 ;
4747
@@ -52,7 +52,7 @@ public static void DecompressBc6h(ReadOnlySpan<byte> compressedBlock, Span<byte>
5252 int mode ;
5353
5454 //modes >= 11 (10 in my code) are using 0 one, others will read it from the bitstream
55- int partition ;
55+ uint partition ;
5656
5757 switch ( ReadBc6hModeBits ( ref bstream ) )
5858 {
@@ -520,7 +520,7 @@ public static void DecompressBc6h(ReadOnlySpan<byte> compressedBlock, Span<byte>
520520 }
521521 partitionSet &= 0x01 ;
522522
523- int index = bstream . ReadBits ( indexBits ) ;
523+ int index = bstream . ReadBits ( indexBits ) . ToSigned ( ) ;
524524
525525 int ep_i = ( partitionSet * 2 ) ;
526526
@@ -542,12 +542,12 @@ public static void DecompressBc6h(ReadOnlySpan<byte> compressedBlock, Span<byte>
542542 decompressedOffset += destinationPitch * sizeof ( ushort ) ;
543543 }
544544
545- static int ReadBc6hModeBits ( ref BitStream bstream )
545+ static uint ReadBc6hModeBits ( ref BitStream bstream )
546546 {
547- int twoBits = bstream . ReadBits ( 2 ) ;
547+ uint twoBits = bstream . ReadBits ( 2 ) ;
548548 if ( twoBits > 1 )
549549 {
550- int threeBits = bstream . ReadBits ( 3 ) ;
550+ uint threeBits = bstream . ReadBits ( 3 ) ;
551551 return ( threeBits << 2 ) | twoBits ;
552552 }
553553 else
@@ -564,7 +564,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
564564 low = BinaryPrimitives . ReadUInt64LittleEndian ( compressedBlock ) ,
565565 high = BinaryPrimitives . ReadUInt64LittleEndian ( compressedBlock . Slice ( sizeof ( ulong ) ) )
566566 } ;
567- Span2D < int > endpoints = new ( stackalloc int [ 6 * 4 ] , 6 , 4 ) ;
567+ Span2D < uint > endpoints = new ( stackalloc uint [ 6 * 4 ] , 6 , 4 ) ;
568568 Span2D < int > indices = new ( stackalloc int [ 4 * 4 ] , 4 , 4 ) ;
569569
570570 int decompressedOffset = 0 ;
@@ -589,15 +589,15 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
589589 return ;
590590 }
591591
592- int partition = 0 ;
592+ uint partition = 0 ;
593593 int numPartitions = 1 ;
594- int rotation = 0 ;
595- int indexSelectionBit = 0 ;
594+ uint rotation = 0 ;
595+ uint indexSelectionBit = 0 ;
596596
597597 if ( mode == 0 || mode == 1 || mode == 2 || mode == 3 || mode == 7 )
598598 {
599- numPartitions = ( mode == 0 || mode == 2 ) ? 3 : 2 ;
600- partition = bstream . ReadBits ( ( mode == 0 ) ? 4 : 6 ) ;
599+ numPartitions = ( mode is 0 or 2 ) ? 3 : 2 ;
600+ partition = bstream . ReadBits ( ( mode is 0 ) ? 4 : 6 ) ;
601601 }
602602
603603 int numEndpoints = numPartitions * 2 ;
@@ -646,8 +646,8 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
646646 // if P-bit is shared
647647 if ( mode == 1 )
648648 {
649- int i = bstream . ReadBit ( ) ;
650- int j = bstream . ReadBit ( ) ;
649+ uint i = bstream . ReadBit ( ) ;
650+ uint j = bstream . ReadBit ( ) ;
651651
652652 // rgb component-wise insert pbits
653653 for ( int k = 0 ; k < 3 ; ++ k )
@@ -663,7 +663,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
663663 // unique P-bit per endpoint
664664 for ( int i = 0 ; i < numEndpoints ; ++ i )
665665 {
666- int j = bstream . ReadBit ( ) ;
666+ uint j = bstream . ReadBit ( ) ;
667667 for ( int k = 0 ; k < 4 ; ++ k )
668668 {
669669 endpoints [ i , k ] |= j ;
@@ -726,7 +726,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
726726 indexBits -- ;
727727 }
728728
729- indices [ i , j ] = bstream . ReadBits ( indexBits ) ;
729+ indices [ i , j ] = bstream . ReadBits ( indexBits ) . ToSigned ( ) ;
730730 }
731731 }
732732
@@ -742,10 +742,10 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
742742
743743 int index = indices [ i , j ] ;
744744
745- int r ;
746- int g ;
747- int b ;
748- int a ;
745+ uint r ;
746+ uint g ;
747+ uint b ;
748+ uint a ;
749749
750750 if ( indexBits2 == 0 )
751751 {
@@ -756,7 +756,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
756756 }
757757 else
758758 {
759- int index2 = bstream . ReadBits ( ( i | j ) != 0 ? indexBits2 : ( indexBits2 - 1 ) ) ;
759+ int index2 = bstream . ReadBits ( ( i | j ) != 0 ? indexBits2 : ( indexBits2 - 1 ) ) . ToSigned ( ) ;
760760 // The index value for interpolating color comes from the secondary index bits for the texel
761761 // if the mode has an index selection bit and its value is one, and from the primary index bits otherwise.
762762 // The alpha index comes from the secondary index bits if the block has a secondary index
@@ -949,6 +949,11 @@ public static int ExtendSign(int val, int bits)
949949 return ( val << ( 32 - bits ) ) >> ( 32 - bits ) ;
950950 }
951951
952+ private static uint ExtendSign ( uint val , int bits )
953+ {
954+ return ExtendSign ( val . ToSigned ( ) , bits ) . ToUnsigned ( ) ;
955+ }
956+
952957 public static int TransformInverse ( int val , int a0 , int bits , bool isSigned )
953958 {
954959 // If the precision of A0 is "p" bits, then the transform algorithm is:
@@ -961,6 +966,11 @@ public static int TransformInverse(int val, int a0, int bits, bool isSigned)
961966 return val ;
962967 }
963968
969+ private static uint TransformInverse ( uint val , uint a0 , int bits , bool isSigned )
970+ {
971+ return TransformInverse ( val . ToSigned ( ) , a0 . ToSigned ( ) , bits , isSigned ) . ToUnsigned ( ) ;
972+ }
973+
964974 /// <summary>
965975 /// Essentially copy-paste from documentation
966976 /// </summary>
@@ -1028,11 +1038,21 @@ public static int Unquantize(int val, int bits, bool isSigned)
10281038 return unq ;
10291039 }
10301040
1041+ private static uint Unquantize ( uint val , int bits , bool isSigned )
1042+ {
1043+ return Unquantize ( val . ToSigned ( ) , bits , isSigned ) . ToUnsigned ( ) ;
1044+ }
1045+
10311046 public static int Interpolate ( int a , int b , ReadOnlySpan < int > weights , int index )
10321047 {
10331048 return ( ( a * ( 64 - weights [ index ] ) ) + ( b * weights [ index ] ) + 32 ) >> 6 ;
10341049 }
10351050
1051+ private static uint Interpolate ( uint a , uint b , ReadOnlySpan < int > weights , int index )
1052+ {
1053+ return Interpolate ( a . ToSigned ( ) , b . ToSigned ( ) , weights , index ) . ToUnsigned ( ) ;
1054+ }
1055+
10361056 public static ushort FinishUnquantize ( int val , bool isSigned )
10371057 {
10381058 if ( ! isSigned )
@@ -1041,7 +1061,7 @@ public static ushort FinishUnquantize(int val, bool isSigned)
10411061 }
10421062 else
10431063 {
1044- val = ( val < 0 ) ? - ( ( ( - val ) * 31 ) >> 5 ) : ( val * 31 ) >> 5 ; // scale the magnitude by 31 / 32
1064+ val = ( val < 0 ) ? ( ( ( - val ) * 31 ) >> 5 ) : ( val * 31 ) >> 5 ; // scale the magnitude by 31 / 32
10451065 int s = 0 ;
10461066 if ( val < 0 )
10471067 {
@@ -1052,8 +1072,23 @@ public static ushort FinishUnquantize(int val, bool isSigned)
10521072 }
10531073 }
10541074
1055- public static void SwapValues ( ref int a , ref int b )
1075+ private static ushort FinishUnquantize ( uint val , bool isSigned )
1076+ {
1077+ return FinishUnquantize ( val . ToSigned ( ) , isSigned ) ;
1078+ }
1079+
1080+ public static void SwapValues ( ref uint a , ref uint b )
10561081 {
10571082 ( a , b ) = ( b , a ) ;
10581083 }
1084+
1085+ private static uint ToUnsigned ( this int value )
1086+ {
1087+ return unchecked ( ( uint ) value ) ;
1088+ }
1089+
1090+ private static int ToSigned ( this uint value )
1091+ {
1092+ return unchecked ( ( int ) value ) ;
1093+ }
10591094}
0 commit comments