Skip to content

Commit 0e6f308

Browse files
committed
Conversion between linear and sRGB
1 parent f8294ef commit 0e6f308

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

AssetRipper.TextureDecoder/Rgb/Color.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,30 @@ public static TTarget Convert<TThis, TThisChannelValue, TTarget, TTargetChannelV
9292
return destination;
9393
}
9494
}
95+
96+
internal static TColor SRgbToLinear<TColor, TChannel>(this TColor color)
97+
where TChannel : unmanaged
98+
where TColor : unmanaged, IColor<TChannel>
99+
{
100+
color.GetChannels(out TChannel r, out TChannel g, out TChannel b, out TChannel a);
101+
color.SetChannels(
102+
SRgb.ToLinear(r),
103+
SRgb.ToLinear(g),
104+
SRgb.ToLinear(b),
105+
a);
106+
return color;
107+
}
108+
109+
internal static TColor LinearToSRgb<TColor, TChannel>(this TColor color)
110+
where TChannel : unmanaged
111+
where TColor : unmanaged, IColor<TChannel>
112+
{
113+
color.GetChannels(out TChannel r, out TChannel g, out TChannel b, out TChannel a);
114+
color.SetChannels(
115+
SRgb.FromLinear(r),
116+
SRgb.FromLinear(g),
117+
SRgb.FromLinear(b),
118+
a);
119+
return color;
120+
}
95121
}

AssetRipper.TextureDecoder/Rgb/RgbConverter.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,25 @@ static void ThrowDestinationSpanNotLargeEnough()
6464
throw new ArgumentException("Destination span is not large enough to hold the converted data.", nameof(destinationSpan));
6565
}
6666
}
67+
68+
public static void SRgbToLinear<TColor, TChannel>(Span<TColor> span)
69+
where TChannel : unmanaged
70+
where TColor : unmanaged, IColor<TChannel>
71+
{
72+
for (int i = 0; i < span.Length; i++)
73+
{
74+
span[i] = span[i].SRgbToLinear<TColor, TChannel>();
75+
}
76+
}
77+
78+
public static void LinearToSRgb<TColor, TChannel>(Span<TColor> span)
79+
where TChannel : unmanaged
80+
where TColor : unmanaged, IColor<TChannel>
81+
{
82+
for (int i = 0; i < span.Length; i++)
83+
{
84+
span[i] = span[i].LinearToSRgb<TColor, TChannel>();
85+
}
86+
}
6787
}
6888
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace AssetRipper.TextureDecoder.Rgb;
2+
3+
internal static class SRgb
4+
{
5+
public static T ToLinear<T>(T value) where T : unmanaged
6+
{
7+
double d = NumericConversion.Convert<T, double>(value);
8+
d = SRgbToLinear(d);
9+
return NumericConversion.Convert<double, T>(d);
10+
}
11+
12+
public static T FromLinear<T>(T value) where T : unmanaged
13+
{
14+
double d = NumericConversion.Convert<T, double>(value);
15+
d = LinearToSRgb(d);
16+
return NumericConversion.Convert<double, T>(d);
17+
}
18+
19+
private static double SRgbToLinear(double value)
20+
{
21+
if (value <= 0.04045)
22+
{
23+
return value / 12.92;
24+
}
25+
else
26+
{
27+
return double.Pow((value + 0.055) / 1.055, 2.4);
28+
}
29+
}
30+
31+
private static double LinearToSRgb(double value)
32+
{
33+
if (value <= 0.0031308)
34+
{
35+
return value * 12.92;
36+
}
37+
else
38+
{
39+
return 1.055 * double.Pow(value, 1.0 / 2.4) - 0.055;
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)