Skip to content

Commit 699e437

Browse files
committed
Higher precision for ColorRGB9e5
1 parent 8b7644d commit 699e437

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed
Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
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

Comments
 (0)