#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"};
	}
}