Loading libs/jpegrecoverymap/include/jpegrecoverymap/recoverymapmath.h +11 −5 Original line number Diff line number Diff line Loading @@ -116,11 +116,17 @@ inline Color operator/(const Color& lhs, const float rhs) { } inline uint16_t floatToHalf(float f) { uint32_t x = *((uint32_t*)&f); uint16_t h = ((x >> 16) & 0x8000) | ((((x & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | ((x >> 13) & 0x03ff); return h; // round-to-nearest-even: add last bit after truncated mantissa const uint32_t b = *((uint32_t*)&f) + 0x00001000; const uint32_t e = (b & 0x7F800000) >> 23; // exponent const uint32_t m = b & 0x007FFFFF; // mantissa // sign : normalized : denormalized : saturate return (b & 0x80000000) >> 16 | (e > 112) * ((((e - 112) << 10) & 0x7C00) | m >> 13) | ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | (e > 143) * 0x7FFF; } constexpr size_t kRecoveryFactorPrecision = 10; Loading libs/jpegrecoverymap/tests/recoverymapmath_test.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -952,6 +952,27 @@ TEST_F(RecoveryMapMathTest, ColorToRgba1010102) { | static_cast<uint32_t>(0.3f * static_cast<float>(0x3ff)) << 20); } TEST_F(RecoveryMapMathTest, ColorToRgbaF16) { EXPECT_EQ(colorToRgbaF16(RgbBlack()), ((uint64_t) 0x3C00) << 48); EXPECT_EQ(colorToRgbaF16(RgbWhite()), 0x3C003C003C003C00); EXPECT_EQ(colorToRgbaF16(RgbRed()), (((uint64_t) 0x3C00) << 48) | ((uint64_t) 0x3C00)); EXPECT_EQ(colorToRgbaF16(RgbGreen()), (((uint64_t) 0x3C00) << 48) | (((uint64_t) 0x3C00) << 16)); EXPECT_EQ(colorToRgbaF16(RgbBlue()), (((uint64_t) 0x3C00) << 48) | (((uint64_t) 0x3C00) << 32)); Color e_gamma = {{{ 0.1f, 0.2f, 0.3f }}}; EXPECT_EQ(colorToRgbaF16(e_gamma), 0x3C0034CD32662E66); } TEST_F(RecoveryMapMathTest, Float32ToFloat16) { EXPECT_EQ(floatToHalf(0.1f), 0x2E66); EXPECT_EQ(floatToHalf(0.0f), 0x0); EXPECT_EQ(floatToHalf(1.0f), 0x3C00); EXPECT_EQ(floatToHalf(-1.0f), 0xBC00); EXPECT_EQ(floatToHalf(0x1.fffffep127f), 0x7FFF); // float max EXPECT_EQ(floatToHalf(-0x1.fffffep127f), 0xFFFF); // float min EXPECT_EQ(floatToHalf(0x1.0p-126f), 0x0); // float zero } TEST_F(RecoveryMapMathTest, GenerateMapLuminanceSrgb) { EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvBlack(), srgbLuminance), 0.0f); Loading Loading
libs/jpegrecoverymap/include/jpegrecoverymap/recoverymapmath.h +11 −5 Original line number Diff line number Diff line Loading @@ -116,11 +116,17 @@ inline Color operator/(const Color& lhs, const float rhs) { } inline uint16_t floatToHalf(float f) { uint32_t x = *((uint32_t*)&f); uint16_t h = ((x >> 16) & 0x8000) | ((((x & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | ((x >> 13) & 0x03ff); return h; // round-to-nearest-even: add last bit after truncated mantissa const uint32_t b = *((uint32_t*)&f) + 0x00001000; const uint32_t e = (b & 0x7F800000) >> 23; // exponent const uint32_t m = b & 0x007FFFFF; // mantissa // sign : normalized : denormalized : saturate return (b & 0x80000000) >> 16 | (e > 112) * ((((e - 112) << 10) & 0x7C00) | m >> 13) | ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | (e > 143) * 0x7FFF; } constexpr size_t kRecoveryFactorPrecision = 10; Loading
libs/jpegrecoverymap/tests/recoverymapmath_test.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -952,6 +952,27 @@ TEST_F(RecoveryMapMathTest, ColorToRgba1010102) { | static_cast<uint32_t>(0.3f * static_cast<float>(0x3ff)) << 20); } TEST_F(RecoveryMapMathTest, ColorToRgbaF16) { EXPECT_EQ(colorToRgbaF16(RgbBlack()), ((uint64_t) 0x3C00) << 48); EXPECT_EQ(colorToRgbaF16(RgbWhite()), 0x3C003C003C003C00); EXPECT_EQ(colorToRgbaF16(RgbRed()), (((uint64_t) 0x3C00) << 48) | ((uint64_t) 0x3C00)); EXPECT_EQ(colorToRgbaF16(RgbGreen()), (((uint64_t) 0x3C00) << 48) | (((uint64_t) 0x3C00) << 16)); EXPECT_EQ(colorToRgbaF16(RgbBlue()), (((uint64_t) 0x3C00) << 48) | (((uint64_t) 0x3C00) << 32)); Color e_gamma = {{{ 0.1f, 0.2f, 0.3f }}}; EXPECT_EQ(colorToRgbaF16(e_gamma), 0x3C0034CD32662E66); } TEST_F(RecoveryMapMathTest, Float32ToFloat16) { EXPECT_EQ(floatToHalf(0.1f), 0x2E66); EXPECT_EQ(floatToHalf(0.0f), 0x0); EXPECT_EQ(floatToHalf(1.0f), 0x3C00); EXPECT_EQ(floatToHalf(-1.0f), 0xBC00); EXPECT_EQ(floatToHalf(0x1.fffffep127f), 0x7FFF); // float max EXPECT_EQ(floatToHalf(-0x1.fffffep127f), 0xFFFF); // float min EXPECT_EQ(floatToHalf(0x1.0p-126f), 0x0); // float zero } TEST_F(RecoveryMapMathTest, GenerateMapLuminanceSrgb) { EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvBlack(), srgbLuminance), 0.0f); Loading