diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index e459853a65..417d7011bc 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -701,6 +701,11 @@ if (BUILD_LAGOM) # It is therefore not reasonable to run it on Lagom, and we only run the Regex test lagom_test(../../Tests/LibRegex/Regex.cpp LIBS LibRegex WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../Tests/LibRegex) + # test-jpeg-roundtrip + add_executable(test-jpeg-roundtrip + ../../Userland/Utilities/test-jpeg-roundtrip.cpp) + target_link_libraries(test-jpeg-roundtrip LibGfx LibMain) + # JavaScriptTestRunner + LibTest tests # test-js add_executable(test-js diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 947c8f8ca5..3a87027d80 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -146,6 +146,7 @@ target_link_libraries(ttfdisasm PRIVATE LibGfx) target_link_libraries(tar PRIVATE LibArchive LibCompress LibFileSystem) target_link_libraries(telws PRIVATE LibProtocol LibLine) target_link_libraries(test-imap PRIVATE LibIMAP) +target_link_libraries(test-jpeg-roundtrip PRIVATE LibGfx) target_link_libraries(test-pthread PRIVATE LibThreading) target_link_libraries(touch PRIVATE LibFileSystem) target_link_libraries(unzip PRIVATE LibArchive LibCompress LibCrypto LibFileSystem) diff --git a/Userland/Utilities/test-jpeg-roundtrip.cpp b/Userland/Utilities/test-jpeg-roundtrip.cpp new file mode 100644 index 0000000000..73b0df1e74 --- /dev/null +++ b/Userland/Utilities/test-jpeg-roundtrip.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +struct Fixpoint { + Gfx::Color fixpoint; + int number_of_iterations {}; +}; + +static ErrorOr compute_fixpoint(Gfx::Color start_color) +{ + auto bitmap = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { 8, 8 })); + bitmap->fill(start_color); + + int number_of_iterations = 1; + Color last_color = start_color; + while (true) { + AllocatingMemoryStream stream; + TRY(Gfx::JPEGWriter::encode(stream, *bitmap)); + auto data = TRY(stream.read_until_eof()); + auto plugin_decoder = TRY(Gfx::JPEGImageDecoderPlugin::create(data)); + auto frame = TRY(plugin_decoder->frame(0)); + + Color current_color = frame.image->get_pixel(4, 4); + if (current_color == last_color) + break; + + ++number_of_iterations; + last_color = current_color; + bitmap = *frame.image; + } + return Fixpoint { last_color, number_of_iterations }; +} + +static ErrorOr test(Gfx::Color color) +{ + auto fixpoint = TRY(compute_fixpoint(color)); + outln("color {} converges to {} after saving {} times", color, fixpoint.fixpoint, fixpoint.number_of_iterations); + return {}; +} + +ErrorOr serenity_main(Main::Arguments) +{ + TRY(test(Gfx::Color::Red)); + TRY(test(Gfx::Color::Green)); + TRY(test(Gfx::Color::Blue)); + + TRY(test(Gfx::Color::MidRed)); + TRY(test(Gfx::Color::MidGreen)); + TRY(test(Gfx::Color::MidBlue)); + + TRY(test(Gfx::Color::Cyan)); + TRY(test(Gfx::Color::Magenta)); + TRY(test(Gfx::Color::Yellow)); + + TRY(test(Gfx::Color::Black)); + TRY(test(Gfx::Color::White)); + + return 0; +}