6#include "Math/NumericLimits.h"
7#include "Math/UnrealMathUtility.h"
9#include "Templates/TypeCompatibleBytes.h"
12
13
14
43 IValue[0] = *(uint32*)&Src.R;
44 IValue[1] = *(uint32*)&Src.G;
45 IValue[2] = *(uint32*)&Src.B;
46 IValue[3] = *(uint32*)&Src.A;
51 for (uint32 j=0; j < 2; ++j)
53 uint32 Sign = IValue[j] & 0x80000000;
54 uint32 I = IValue[j] & 0x7FFFFFFF;
56 if ((I & 0x7F800000) == 0x7F800000)
60 if (( I & 0x7FFFFF ) != 0)
62 Result[j] = 0x7c0 | (((I>>17)|(I>>11)|(I>>6)|(I))&0x3f);
75 else if (I > 0x477E0000U)
86 uint32 Shift = 113U - (I >> 23U);
87 I = (0x800000U | (I & 0x7FFFFFU)) >> Shift;
95 Result[j] = ((I + 0xFFFFU + ((I >> 17U) & 1U)) >> 17U)&0x7ffU;
100 uint32 Sign = IValue[2] & 0x80000000;
101 uint32 I = IValue[2] & 0x7FFFFFFF;
103 if ((I & 0x7F800000) == 0x7F800000)
109 Result[2] = 0x3e0 | (((I>>18)|(I>>13)|(I>>3)|(I))&0x1f);
122 else if (I > 0x477C0000U)
133 uint32 Shift = 113U - (I >> 23U);
134 I = (0x800000U | (I & 0x7FFFFFU)) >> Shift;
142 Result[2] = ((I + 0x1FFFFU + ((I >> 18U) & 1U)) >> 18U)&0x3ffU;
146 v = (Result[0] & 0x7ff)
147 | ( (Result[1] & 0x7ff) << 11 )
148 | ( (Result[2] & 0x3ff) << 22 );
160 Mantissa = pSource->xm;
162 if ( pSource->xe == 0x1f )
164 Result[0] = 0x7f800000 | (pSource->xm << 17);
168 if ( pSource->xe != 0 )
170 Exponent = pSource->xe;
172 else if (Mantissa != 0)
181 }
while ((Mantissa & 0x40) == 0);
187 Exponent = (uint32)-112;
190 Result[0] = ((Exponent + 112) << 23) | (Mantissa << 17);
194 Mantissa = pSource->ym;
196 if ( pSource->ye == 0x1f )
198 Result[1] = 0x7f800000 | (pSource->ym << 17);
202 if ( pSource->ye != 0 )
204 Exponent = pSource->ye;
206 else if (Mantissa != 0)
215 }
while ((Mantissa & 0x40) == 0);
221 Exponent = (uint32)-112;
224 Result[1] = ((Exponent + 112) << 23) | (Mantissa << 17);
228 Mantissa = pSource->zm;
230 if ( pSource->ze == 0x1f )
232 Result[2] = 0x7f800000 | (pSource->zm << 17);
236 if ( pSource->ze != 0 )
238 Exponent = pSource->ze;
240 else if (Mantissa != 0)
249 }
while ((Mantissa & 0x20) == 0);
255 Exponent = (uint32)-112;
258 Result[2] = ((Exponent + 112) << 23) | (Mantissa << 18);
262 ResultColor.R = *(
float*)&Result[0];
263 ResultColor.G = *(
float*)&Result[1];
264 ResultColor.B = *(
float*)&Result[2];
270
271
272
298 R = (int8)FMath::Clamp<int32>(FMath::RoundToInt(Src.R * Scale),
MIN_int8,
MAX_int8);
299 G = (int8)FMath::Clamp<int32>(FMath::RoundToInt(Src.G * Scale),
MIN_int8,
MAX_int8);
300 B = (int8)FMath::Clamp<int32>(FMath::RoundToInt(Src.B * Scale),
MIN_int8,
MAX_int8);
301 A = (int8)FMath::Clamp<int32>(FMath::RoundToInt(Src.A * Scale),
MIN_int8,
MAX_int8);
306 const float Scale = 1.0f /
MAX_int8;
311
312
360 bool IsSubnormal() {
return (e == 0 && m != 0 ); }
361 uint32 Mantissa() {
return m + (IsSubnormal() ? 0 : (1 << 23) ); }
362 int32 Exponent() {
return e - 127; }
363 bool IsInfinity() {
return (e == 0xff) && (m == 0); }
364 bool IsNaN() {
return (e == 0xff) && (m != 0); }
367 PackedFloat RGBPacked[3];
368 RGBPacked[0] = BitCast<PackedFloat,
float>(Src.R);
369 RGBPacked[1] = BitCast<PackedFloat,
float>(Src.G);
370 RGBPacked[2] = BitCast<PackedFloat,
float>(Src.B);
375 for (uint32 i = 0; i < 3; ++i)
377 Mantissas[i] = RGBPacked[i].Mantissa();
378 Exponents[i] = RGBPacked[i].Exponent();
381 if (!RGBPacked[i].IsSubnormal())
387 if ( (Exponents[i] < -15 && RGBPacked[i].v != 0.0f) || (RGBPacked[i].v < 0.0f) || RGBPacked[i].IsNaN())
393 else if (Exponents[i] > 15)
396 Mantissas[i] = 0x7fffff;
401 int32 NewExponent = FMath::Max<int32>(Exponents[0], FMath::Max<int32>(Exponents[1], Exponents[2]));
403 for (uint32 i = 0; i < 3; ++i)
405 Mantissas[i] = (Mantissas[i] >> ((uint32)(NewExponent - Exponents[i])));
407 Mantissas[i] = Mantissas[i] >> (23 - 9);
410 check( Mantissas[0] < (1 << 23) && Mantissas[1] < (1 << 23) && Mantissas[2] < (1 << 23) );
412 EncodedValue = (((NewExponent + 15) & 0x01f) << (9 + 9 + 9)) |
413 ((Mantissas[2] & 0x1ff) << (0 + 9 + 9)) |
414 ((Mantissas[1] & 0x1ff) << (0 + 0 + 9)) |
415 ((Mantissas[0] & 0x1ff) << (0 + 0 + 0)) ;
421 int32 SharedExponent8Bits = 0x33800000 + (SharedExponent << 23);
422 float Scale = BitCast<
float, int32>(SharedExponent8Bits);
424 return FLinearColor( Scale *
float(RMantissa)
, Scale *
float(GMantissa)
, Scale *
float(BMantissa)
,1.0f
);
FFixedRGBASigned8(const FLinearColor &Src)
FLinearColor ToLinearColor() const
FFloat3Packed(const FLinearColor &Src)
FLinearColor ToLinearColor() const
FFloat3PackedSE(uint32 InEncodedValue)
FFloat3PackedSE(const FLinearColor &Src)
FLinearColor ToLinearColor() const
constexpr FORCEINLINE FLinearColor(float InR, float InG, float InB, float InA=1.0f)