1- // Copyright (c) Six Labors.
1+ // Copyright (c) Six Labors.
22// Licensed under the Six Labors Split License.
33
44using System . Runtime . CompilerServices ;
5- using System . Runtime . InteropServices ;
65
76namespace 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