1- using static System . Math ;
2-
3- namespace AssetRipper . TextureDecoder . Rgb . Formats
1+ namespace AssetRipper . TextureDecoder . Rgb . Formats
42{
53 /// <summary>
64 /// 9 bits each for RGB and 5 bits for an exponent
75 /// </summary>
86 public partial struct ColorRGB9e5 : IColor < double >
9- {
7+ {
108 private uint bits ;
119
1210 public double R
@@ -15,7 +13,7 @@ public double R
1513 set
1614 {
1715 GetChannels ( out _ , out double g , out double b , out _ ) ;
18- SetChannels ( value , g , b , default ) ;
16+ SetChannels ( value , g , b ) ;
1917 }
2018 }
2119
@@ -25,7 +23,7 @@ public double G
2523 set
2624 {
2725 GetChannels ( out double r , out _ , out double b , out _ ) ;
28- SetChannels ( r , value , b , default ) ;
26+ SetChannels ( r , value , b ) ;
2927 }
3028 }
3129
@@ -35,7 +33,7 @@ public double B
3533 set
3634 {
3735 GetChannels ( out double r , out double g , out _ , out _ ) ;
38- SetChannels ( r , g , value , default ) ;
36+ SetChannels ( r , g , value ) ;
3937 }
4038 }
4139
@@ -56,32 +54,44 @@ public readonly void GetChannels(out double r, out double g, out double b, out d
5654 }
5755
5856 [ MethodImpl ( OptimizationConstants . AggressiveInliningAndOptimization ) ]
59- public void SetChannels ( double r , double g , double b , double a )
57+ public void SetChannels ( double r , double g , double b , double a )
58+ {
59+ SetChannels ( r , g , b ) ;
60+ }
61+
62+ [ MethodImpl ( OptimizationConstants . AggressiveInliningAndOptimization ) ]
63+ public void SetChannels ( double r , double g , double b )
6064 {
6165 int exponent = CalculateExponent ( r , g , b ) ;
62- double scale = Pow ( 2 , exponent ) ;
63- uint rBits = ( uint ) ( r / scale ) & 0x1FF ;
64- uint gBits = ( uint ) ( g / scale ) & 0x1FF ;
65- uint bBits = ( uint ) ( b / scale ) & 0x1FF ;
66+ decimal scale = ( decimal ) double . Pow ( 2 , exponent ) ;
67+ uint rBits = ( uint ) ( ( decimal ) r / scale ) & ChannelBitMask ;
68+ uint gBits = ( uint ) ( ( decimal ) g / scale ) & ChannelBitMask ;
69+ uint bBits = ( uint ) ( ( decimal ) b / scale ) & ChannelBitMask ;
6670 uint exponentBits = unchecked ( ( uint ) ( exponent + 24 ) ) ;
67- bits = ( exponentBits << 27 ) | ( bBits << 18 ) | ( gBits << 9 ) | ( rBits << 0 ) ;
71+ bits = ( exponentBits << ExponentOffset ) | ( bBits << BlueOffset ) | ( gBits << GreenOffset ) | ( rBits << RedOffset ) ;
6872 }
6973
7074 /// <summary>
7175 /// Range: -24 to 7 inclusive
7276 /// </summary>
73- private readonly int Exponent => unchecked ( ( int ) ( bits >> 27 ) - 24 ) ;
74- private readonly double Scale => Pow ( 2 , Exponent ) ;
75- private readonly uint RBits => ( bits >> 0 ) & 0x1FF ;
76- private readonly uint GBits => ( bits >> 9 ) & 0x1FF ;
77- private readonly uint BBits => ( bits >> 18 ) & 0x1FF ;
77+ private readonly int Exponent => unchecked ( ( int ) ( bits >> ExponentOffset ) - 24 ) ;
78+ private readonly double Scale => double . Pow ( 2 , Exponent ) ;
79+ private readonly uint RBits => ( bits >> RedOffset ) & ChannelBitMask ;
80+ private readonly uint GBits => ( bits >> GreenOffset ) & ChannelBitMask ;
81+ private readonly uint BBits => ( bits >> BlueOffset ) & ChannelBitMask ;
7882
7983 [ MethodImpl ( OptimizationConstants . AggressiveInliningAndOptimization ) ]
8084 private static int CalculateExponent ( double r , double g , double b )
8185 {
82- double maxChannel = Max ( r , Max ( g , b ) ) ;
83- double minExponent = Log2 ( maxChannel / 0x1FF ) ;
84- return ( int ) Ceiling ( minExponent ) ;
85- }
86+ double maxChannel = double . Max ( r , double . Max ( g , b ) ) ;
87+ double minExponent = double . Log2 ( maxChannel / ChannelBitMask ) ;
88+ return ( int ) double . Ceiling ( minExponent ) ;
89+ }
90+
91+ private const int ChannelBitMask = 0x1FF ;
92+ private const int RedOffset = 0 ;
93+ private const int GreenOffset = 9 ;
94+ private const int BlueOffset = 18 ;
95+ private const int ExponentOffset = 27 ;
8696 }
8797}
0 commit comments