Skip to content

Commit 22a7cba

Browse files
Merge pull request #2233 from SixLabors/js/system-half
Use System.Half for HalfTypeHelper
2 parents 8af5d8a + eb864c5 commit 22a7cba

File tree

1 file changed

+4
-120
lines changed

1 file changed

+4
-120
lines changed
Lines changed: 4 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

44
using System.Runtime.CompilerServices;
5-
using System.Runtime.InteropServices;
65

76
namespace SixLabors.ImageSharp.PixelFormats;
87

@@ -17,128 +16,13 @@ internal static class HalfTypeHelper
1716
/// <param name="value">The float to pack</param>
1817
/// <returns>The <see cref="ushort"/></returns>
1918
[MethodImpl(MethodImplOptions.AggressiveInlining)]
20-
internal static ushort Pack(float value)
21-
{
22-
var uif = new Uif { F = value };
23-
return Pack(uif.I);
24-
}
25-
26-
/// <summary>
27-
/// Packs an <see cref="int"/> into a <see cref="ushort"/>
28-
/// </summary>
29-
/// <param name="value">The integer to pack.</param>
30-
/// <returns>The <see cref="ushort"/></returns>
31-
internal static ushort Pack(int value)
32-
{
33-
int s = (value >> 16) & 0x00008000;
34-
int e = ((value >> 23) & 0x000000ff) - (127 - 15);
35-
int m = value & 0x007fffff;
36-
37-
if (e <= 0)
38-
{
39-
if (e < -10)
40-
{
41-
return (ushort)s;
42-
}
43-
44-
m |= 0x00800000;
45-
46-
int t = 14 - e;
47-
int a = (1 << (t - 1)) - 1;
48-
int b = (m >> t) & 1;
49-
50-
m = (m + a + b) >> t;
51-
52-
return (ushort)(s | m);
53-
}
54-
55-
if (e == 0xff - (127 - 15))
56-
{
57-
if (m == 0)
58-
{
59-
return (ushort)(s | 0x7c00);
60-
}
61-
62-
m >>= 13;
63-
return (ushort)(s | 0x7c00 | m | ((m == 0) ? 1 : 0));
64-
}
65-
66-
m = m + 0x00000fff + ((m >> 13) & 1);
67-
68-
if ((m & 0x00800000) != 0)
69-
{
70-
m = 0;
71-
e++;
72-
}
73-
74-
if (e > 30)
75-
{
76-
return (ushort)(s | 0x7c00);
77-
}
78-
79-
return (ushort)(s | (e << 10) | (m >> 13));
80-
}
19+
internal static ushort Pack(float value) => BitConverter.HalfToUInt16Bits((Half)value);
8120

8221
/// <summary>
8322
/// Unpacks a <see cref="ushort"/> into a <see cref="float"/>.
8423
/// </summary>
8524
/// <param name="value">The value.</param>
8625
/// <returns>The <see cref="float"/>.</returns>
87-
internal static float Unpack(ushort value)
88-
{
89-
uint result;
90-
uint mantissa = (uint)(value & 1023);
91-
uint exponent = 0xfffffff2;
92-
93-
if ((value & -33792) == 0)
94-
{
95-
if (mantissa != 0)
96-
{
97-
while ((mantissa & 1024) == 0)
98-
{
99-
exponent--;
100-
mantissa <<= 1;
101-
}
102-
103-
mantissa &= 0xfffffbff;
104-
result = (((uint)value & 0x8000) << 16) | ((exponent + 127) << 23) | (mantissa << 13);
105-
}
106-
else
107-
{
108-
result = (uint)((value & 0x8000) << 16);
109-
}
110-
}
111-
else
112-
{
113-
result = (((uint)value & 0x8000) << 16) | ((((((uint)value >> 10) & 0x1f) - 15) + 127) << 23) | (mantissa << 13);
114-
}
115-
116-
var uif = new Uif { U = result };
117-
return uif.F;
118-
}
119-
120-
/// <summary>
121-
/// Maps the position of number types in memory
122-
/// </summary>
123-
[StructLayout(LayoutKind.Explicit)]
124-
private struct Uif
125-
{
126-
/// <summary>
127-
/// The float.
128-
/// </summary>
129-
[FieldOffset(0)]
130-
public float F;
131-
132-
/// <summary>
133-
/// The integer.
134-
/// </summary>
135-
[FieldOffset(0)]
136-
public int I;
137-
138-
/// <summary>
139-
/// The unsigned integer.
140-
/// </summary>
141-
[FieldOffset(0)]
142-
public uint U;
143-
}
26+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
27+
internal static float Unpack(ushort value) => (float)BitConverter.UInt16BitsToHalf(value);
14428
}

0 commit comments

Comments
 (0)