#include <cmath>
#include <cstdint>
#include <stdexcept>
std::uint16_t SrgbToScrgb(std::uint8_t srgb)
{
auto x = static_cast<float>(srgb);
x /= 255.0f;
if (x <= 0.04045f) x /= 12.92f;
else x = std::pow((x + 0.055f) / 1.055f, 2.4f);
x *= 8192.0f;
x += 4096.0f;
return static_cast<std::uint16_t>(x + 0.5f);
}
std::uint8_t ScrgbToSrgb(std::uint16_t scrgb)
{
auto x = static_cast<float>(scrgb);
x -= 4096.0f;
x /= 8192.0f;
if (x <= 0.0031308f) x *= 12.92f;
else x = 1.055f * std::pow(x, 0.41666f) - 0.055f;
x *= 255.0f;
return static_cast<std::uint8_t>(x + 0.5f);
}
int main()
{
for (unsigned i = 0; i != 256; ++i)
{
auto scrgb = SrgbToScrgb(i);
auto srgb = ScrgbToSrgb(scrgb);
if (srgb != i) throw std::runtime_error{"Unable to perform lossless conversion"};
}
}
I2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPHN0ZGV4Y2VwdD4KCnN0ZDo6dWludDE2X3QgU3JnYlRvU2NyZ2Ioc3RkOjp1aW50OF90IHNyZ2IpCnsKCWF1dG8geCA9IHN0YXRpY19jYXN0PGZsb2F0PihzcmdiKTsKCgl4IC89IDI1NS4wZjsKCglpZiAoeCA8PSAwLjA0MDQ1ZikgeCAvPSAxMi45MmY7CgllbHNlIHggPSBzdGQ6OnBvdygoeCArIDAuMDU1ZikgLyAxLjA1NWYsIDIuNGYpOwoJCgl4ICo9IDgxOTIuMGY7Cgl4ICs9IDQwOTYuMGY7CgoJcmV0dXJuIHN0YXRpY19jYXN0PHN0ZDo6dWludDE2X3Q+KHggKyAwLjVmKTsKfQoKc3RkOjp1aW50OF90IFNjcmdiVG9TcmdiKHN0ZDo6dWludDE2X3Qgc2NyZ2IpCnsKCWF1dG8geCA9IHN0YXRpY19jYXN0PGZsb2F0PihzY3JnYik7CgoJeCAtPSA0MDk2LjBmOwkKCXggLz0gODE5Mi4wZjsKCglpZiAoeCA8PSAwLjAwMzEzMDhmKSB4ICo9IDEyLjkyZjsKCWVsc2UgeCA9IDEuMDU1ZiAqIHN0ZDo6cG93KHgsIDAuNDE2NjZmKSAtIDAuMDU1ZjsKCgl4ICo9IDI1NS4wZjsKCglyZXR1cm4gc3RhdGljX2Nhc3Q8c3RkOjp1aW50OF90Pih4ICsgMC41Zik7Cn0KCmludCBtYWluKCkKewoJZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSAyNTY7ICsraSkKCXsKCQlhdXRvIHNjcmdiID0gU3JnYlRvU2NyZ2IoaSk7CgkJYXV0byBzcmdiID0gU2NyZ2JUb1NyZ2Ioc2NyZ2IpOwoJCWlmIChzcmdiICE9IGkpIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcnsiVW5hYmxlIHRvIHBlcmZvcm0gbG9zc2xlc3MgY29udmVyc2lvbiJ9OwoJfQp9