@@ -383,12 +383,10 @@ private static TTo ConvertUInt32<TTo>(uint value) where TTo : unmanaged
383383 else if ( typeof ( TTo ) == typeof ( byte ) )
384384 {
385385 // See https://github.com/AssetRipper/TextureDecoder/issues/19
386- // There are more accurate ways to map UInt32 onto Byte, but this is the simplest.
387- unchecked
388- {
389- byte converted = ( byte ) ( ( uint ) value >> 24 ) ;
390- return Unsafe . As < byte , TTo > ( ref converted ) ;
391- }
386+ double interpolated = ( double ) value / ( double ) uint . MaxValue ;
387+ double exact = interpolated * ( double ) byte . MaxValue ;
388+ byte converted = ( byte ) double . Round ( exact , MidpointRounding . AwayFromZero ) ;
389+ return Unsafe . As < byte , TTo > ( ref converted ) ;
392390 }
393391 else if ( typeof ( TTo ) == typeof ( short ) )
394392 {
@@ -398,12 +396,10 @@ private static TTo ConvertUInt32<TTo>(uint value) where TTo : unmanaged
398396 else if ( typeof ( TTo ) == typeof ( ushort ) )
399397 {
400398 // See https://github.com/AssetRipper/TextureDecoder/issues/19
401- // There are more accurate ways to map UInt32 onto UInt16, but this is the simplest.
402- unchecked
403- {
404- ushort converted = ( ushort ) ( ( uint ) value >> 16 ) ;
405- return Unsafe . As < ushort , TTo > ( ref converted ) ;
406- }
399+ double interpolated = ( double ) value / ( double ) uint . MaxValue ;
400+ double exact = interpolated * ( double ) ushort . MaxValue ;
401+ ushort converted = ( ushort ) double . Round ( exact , MidpointRounding . AwayFromZero ) ;
402+ return Unsafe . As < ushort , TTo > ( ref converted ) ;
407403 }
408404 else if ( typeof ( TTo ) == typeof ( int ) )
409405 {
0 commit comments