#include "stdafx.h" #include "doctest.h" #include "scripting/scriptscreenkernels.h" #include #include #include // the image filters the script screens call through the host give the pixels of the Python screens: led_util's // render_post() and Pillow's resize(..., Image.LANCZOS). the expected images were made by them (Pillow 12.2) from a // 5x3 image of (x*53 + y*97, x*31 + y*17 + 100, x*7 + y*151 + 40) mod 256 namespace { // RGB as Pillow gives it constexpr std::array source{ 0, 100, 40, 53, 131, 47, 106, 162, 54, 159, 193, 61, 212, 224, 68, 97, 117, 191, 150, 148, 198, 203, 179, 205, 0, 210, 212, 53, 241, 219, 194, 134, 86, 247, 165, 93, 44, 196, 100, 97, 227, 107, 150, 2, 114, }; constexpr std::array posted{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 144, 77, 28, 122, 65, 99, 194, 97, 84, 164, 82, 158, 236, 108, 134, 200, 91, 205, 255, 114, 174, 229, 96, 241, 255, 109, 204, 238, 92, 0, 0, 0, 0, 0, 0, 28, 122, 65, 23, 100, 53, 84, 164, 82, 69, 135, 67, 134, 200, 91, 110, 165, 75, 174, 229, 96, 143, 189, 79, 204, 238, 92, 168, 196, 76, 0, 0, 0, 0, 0, 0, 144, 173, 231, 122, 147, 196, 215, 229, 255, 182, 194, 219, 255, 255, 255, 219, 232, 230, 67, 255, 255, 56, 255, 235, 101, 255, 255, 85, 255, 225, 0, 0, 0, 0, 0, 0, 122, 147, 196, 100, 121, 161, 182, 194, 219, 150, 160, 180, 219, 232, 230, 180, 191, 189, 56, 255, 235, 46, 213, 193, 85, 255, 225, 70, 212, 185, 0, 0, 0, 0, 0, 0, 234, 178, 126, 198, 151, 107, 255, 231, 148, 251, 196, 125, 106, 255, 159, 90, 230, 135, 139, 255, 165, 118, 248, 140, 177, 65, 158, 150, 55, 134, 0, 0, 0, 0, 0, 0, 198, 151, 107, 163, 124, 88, 251, 196, 125, 207, 161, 103, 90, 230, 135, 74, 189, 111, 118, 248, 140, 97, 204, 115, 150, 55, 134, 123, 45, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; constexpr std::array enlarged{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 46, 26, 22, 90, 53, 18, 71, 41, 50, 102, 55, 58, 108, 58, 53, 98, 52, 88, 131, 65, 87, 128, 62, 84, 119, 58, 114, 144, 69, 102, 139, 63, 106, 133, 60, 136, 144, 67, 139, 144, 68, 56, 71, 29, 0, 0, 0, 0, 0, 0, 16, 85, 39, 25, 165, 76, 21, 130, 59, 80, 188, 84, 94, 198, 89, 86, 178, 78, 155, 246, 102, 150, 236, 97, 151, 221, 89, 232, 255, 112, 210, 255, 100, 213, 250, 94, 255, 255, 108, 255, 255, 107, 113, 129, 44, 0, 0, 0, 0, 0, 0, 19, 67, 38, 31, 130, 74, 25, 100, 57, 72, 148, 78, 83, 155, 82, 75, 137, 72, 128, 191, 92, 124, 181, 87, 119, 172, 81, 167, 225, 99, 146, 202, 89, 151, 197, 85, 200, 238, 97, 198, 235, 95, 79, 96, 39, 0, 0, 0, 0, 0, 0, 70, 90, 108, 135, 177, 217, 108, 140, 171, 172, 198, 208, 188, 211, 215, 167, 186, 192, 218, 235, 219, 227, 238, 214, 175, 222, 204, 95, 245, 222, 62, 245, 213, 89, 240, 209, 122, 244, 224, 123, 243, 224, 49, 124, 99, 0, 0, 0, 0, 0, 0, 74, 89, 130, 139, 174, 255, 110, 136, 201, 182, 194, 246, 197, 205, 253, 170, 182, 223, 244, 239, 255, 255, 234, 252, 186, 218, 236, 52, 255, 255, 15, 245, 249, 49, 244, 240, 72, 255, 255, 73, 255, 255, 29, 130, 113, 0, 0, 0, 0, 0, 0, 76, 82, 96, 147, 160, 188, 114, 123, 145, 166, 177, 183, 181, 187, 188, 163, 165, 163, 186, 224, 205, 188, 214, 191, 140, 200, 176, 80, 251, 215, 54, 228, 190, 75, 211, 179, 105, 219, 206, 106, 217, 204, 42, 87, 82, 0, 0, 0, 0, 0, 0, 124, 96, 69, 250, 189, 137, 195, 149, 108, 225, 207, 138, 250, 221, 143, 237, 195, 127, 134, 244, 156, 80, 245, 148, 103, 228, 139, 135, 248, 165, 120, 252, 150, 129, 193, 143, 175, 68, 160, 178, 59, 161, 72, 34, 66, 0, 0, 0, 0, 0, 0, 135, 101, 67, 255, 197, 133, 206, 153, 103, 255, 216, 134, 255, 228, 139, 247, 200, 122, 127, 255, 152, 67, 255, 144, 98, 237, 134, 147, 255, 162, 131, 255, 146, 138, 187, 138, 189, 48, 157, 190, 37, 156, 76, 26, 64, 0, 0, 0, 0, 0, 0, 57, 44, 32, 110, 85, 64, 84, 65, 48, 121, 94, 63, 140, 98, 65, 102, 86, 57, 60, 120, 72, 39, 112, 68, 46, 103, 62, 61, 134, 76, 52, 133, 68, 56, 82, 64, 78, 34, 74, 77, 29, 73, 31, 16, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; constexpr std::array reduced{ 2, 22, 10, 14, 58, 25, 35, 70, 30, 53, 83, 33, 74, 90, 34, 95, 99, 36, 37, 40, 13, 17, 60, 41, 63, 155, 101, 115, 186, 110, 157, 217, 117, 161, 234, 120, 207, 255, 127, 81, 103, 47, 52, 64, 91, 142, 165, 218, 186, 193, 220, 217, 219, 227, 58, 229, 227, 70, 251, 241, 32, 101, 90, 92, 72, 57, 230, 184, 137, 233, 214, 144, 110, 238, 155, 114, 255, 157, 158, 131, 166, 64, 23, 60, 32, 24, 16, 84, 60, 38, 82, 70, 41, 27, 79, 44, 40, 90, 45, 56, 29, 47, 22, 2, 17, }; constexpr std::array plain{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 40, 0, 85, 34, 53, 131, 47, 45, 111, 39, 106, 162, 54, 90, 137, 45, 159, 193, 61, 135, 164, 51, 212, 224, 68, 180, 190, 57, 0, 0, 0, 0, 0, 0, 0, 85, 34, 0, 70, 28, 45, 111, 39, 37, 91, 32, 90, 137, 45, 74, 113, 37, 135, 164, 51, 111, 135, 42, 180, 190, 57, 148, 156, 47, 0, 0, 0, 0, 0, 0, 97, 117, 191, 82, 99, 162, 150, 148, 198, 127, 125, 168, 203, 179, 205, 172, 152, 174, 0, 210, 212, 0, 178, 180, 53, 241, 219, 45, 204, 186, 0, 0, 0, 0, 0, 0, 82, 99, 162, 67, 81, 133, 127, 125, 168, 105, 103, 138, 172, 152, 174, 142, 125, 143, 0, 178, 180, 0, 147, 148, 45, 204, 186, 37, 168, 153, 0, 0, 0, 0, 0, 0, 194, 134, 86, 164, 113, 73, 247, 165, 93, 209, 140, 79, 44, 196, 100, 37, 166, 85, 97, 227, 107, 82, 192, 90, 150, 2, 114, 127, 1, 96, 0, 0, 0, 0, 0, 0, 164, 113, 73, 135, 93, 60, 209, 140, 79, 172, 115, 65, 37, 166, 85, 30, 137, 70, 82, 192, 90, 67, 158, 74, 127, 1, 96, 105, 1, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; std::vector rgba(std::span const Rgb) { std::vector result; for (std::size_t idx = 0; idx < Rgb.size(); idx += 3) { result.insert(result.end(), {Rgb[idx], Rgb[idx + 1], Rgb[idx + 2], 255}); } return result; } } // namespace TEST_CASE("script screen kernels: led_post gives the pixels of led_util.render_post") { auto const input{rgba(source)}; std::vector output(script_screens::image_size(12, 8), 7); REQUIRE(script_screens::led_post(input, 5, 3, output, true)); CHECK(output == rgba(posted)); REQUIRE(script_screens::led_post(input, 5, 3, output, false)); CHECK(output == rgba(plain)); } TEST_CASE("script screen kernels: resize_lanczos gives the pixels of Pillow's resize with LANCZOS") { auto const input{rgba(posted)}; std::vector larger(script_screens::image_size(17, 11)); REQUIRE(script_screens::resize_lanczos(input, 12, 8, larger, 17, 11)); CHECK(larger == rgba(enlarged)); std::vector smaller(script_screens::image_size(7, 5)); REQUIRE(script_screens::resize_lanczos(input, 12, 8, smaller, 7, 5)); CHECK(smaller == rgba(reduced)); } TEST_CASE("script screen kernels: images that don't fit their buffers are refused") { std::vector const input(script_screens::image_size(5, 3)); std::vector output(script_screens::image_size(12, 8) - 1); CHECK_FALSE(script_screens::led_post(input, 5, 3, output, true)); CHECK_FALSE(script_screens::led_post(input, 0, 3, output, true)); CHECK_FALSE(script_screens::resize_lanczos(input, 5, 3, output, 12, 8)); CHECK_FALSE(script_screens::resize_lanczos(input, 6, 3, output, 2, 2)); } TEST_CASE("script screen kernels: the post-processing steps of an image run one after another") { script_screens::post_step led; led.type = script_screens::post_step::kind::led; led.bloom = true; script_screens::post_step resize; resize.type = script_screens::post_step::kind::resize; resize.width = 17; resize.height = 11; std::array const steps{led, resize}; CHECK(script_screens::width_after(led, 5) == 12); CHECK(script_screens::height_after(led, 3) == 8); CHECK(script_screens::width_after(resize, 12) == 17); CHECK(script_screens::height_after(resize, 8) == 11); script_screens::post_image image{rgba(source), 5, 3}; REQUIRE(script_screens::apply_post(image, steps)); CHECK(image.width == 17); CHECK(image.height == 11); CHECK(image.pixels == rgba(enlarged)); // nothing to do, nothing done script_screens::post_image unchanged{rgba(source), 5, 3}; REQUIRE(script_screens::apply_post(unchanged, {})); CHECK(unchanged.pixels == rgba(source)); // a size the kernels refuse leaves the image as it was script_screens::post_image tooshort{std::vector(10), 5, 3}; CHECK_FALSE(script_screens::apply_post(tooshort, steps)); CHECK(tooshort.width == 5); CHECK(tooshort.pixels.size() == 10); }