#include #include namespace psemek::gfx { static std::uint8_t interleave_with_zeros(std::uint8_t input) { std::uint8_t word = input; word = (word ^ (word << 4 )) & 0x0f0f; word = (word ^ (word << 2 )) & 0x3333; word = (word ^ (word << 1 )) & 0x5555; return word; } static std::uint8_t bit_interleave(std::uint8_t a, std::uint8_t b) { return interleave_with_zeros(a) | (interleave_with_zeros(b) << 1); } static std::uint8_t bit_reverse(std::uint8_t b) { b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; } basic_pixmap ordered_dither(std::size_t size) { if (size > 16) throw util::exception("8-bit dither map cannot be larger than 16x16"); basic_pixmap result({size, size}); for (auto idx : result.indices()) { result(idx) = bit_reverse(bit_interleave(idx[0] ^ idx[1], idx[0])); } return result; } }