1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:04:59 +00:00
serenity/Userland/Utilities/test-jpeg-roundtrip.cpp
Nico Weber 5a47e71604 Utilities: Add test-jpeg-roundtrip
This creates a bitmap filled with a fixed color, then (in memory)
saves it as jpeg and loads it again, and repeats that until the
color of the bitmap no longer changes. It then reports how many
iterations that took, and what the final color was.

It does this for a couple of colors.

This is for quality assessment of the jpeg codec. Ideally, it should
converge quickly (in one iteration), and on a color not very far from
the original input color.
2024-01-14 11:35:40 +00:00

66 lines
1.8 KiB
C++

/*
* Copyright (c) 2024, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/ImageFormats/JPEGLoader.h>
#include <LibGfx/ImageFormats/JPEGWriter.h>
#include <LibMain/Main.h>
struct Fixpoint {
Gfx::Color fixpoint;
int number_of_iterations {};
};
static ErrorOr<Fixpoint> 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<void> 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<int> 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;
}