From 7fc5fd453ec3eca0c6a290b8e873f23ca6751749 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sat, 4 May 2024 20:44:07 -0400 Subject: [PATCH] Tests: Add TestImageWriter For now, it tests that webps roundtrip, but it's easy to add basic roundtrip testing for other image formats. --- Tests/LibGfx/CMakeLists.txt | 1 + Tests/LibGfx/TestImageWriter.cpp | 81 ++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 Tests/LibGfx/TestImageWriter.cpp diff --git a/Tests/LibGfx/CMakeLists.txt b/Tests/LibGfx/CMakeLists.txt index 8afe85836c6..f9582f16f0f 100644 --- a/Tests/LibGfx/CMakeLists.txt +++ b/Tests/LibGfx/CMakeLists.txt @@ -6,6 +6,7 @@ set(TEST_SOURCES TestGfxBitmap.cpp TestICCProfile.cpp TestImageDecoder.cpp + TestImageWriter.cpp TestPainter.cpp TestParseISOBMFF.cpp TestRect.cpp diff --git a/Tests/LibGfx/TestImageWriter.cpp b/Tests/LibGfx/TestImageWriter.cpp new file mode 100644 index 00000000000..6ed6843d8d2 --- /dev/null +++ b/Tests/LibGfx/TestImageWriter.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +static ErrorOr> expect_single_frame(Gfx::ImageDecoderPlugin& plugin_decoder) +{ + EXPECT_EQ(plugin_decoder.frame_count(), 1u); + EXPECT(!plugin_decoder.is_animated()); + EXPECT(!plugin_decoder.loop_count()); + + auto frame_descriptor = TRY(plugin_decoder.frame(0)); + EXPECT_EQ(frame_descriptor.duration, 0); + return *frame_descriptor.image; +} + +static ErrorOr> expect_single_frame_of_size(Gfx::ImageDecoderPlugin& plugin_decoder, Gfx::IntSize size) +{ + EXPECT_EQ(plugin_decoder.size(), size); + auto frame = TRY(expect_single_frame(plugin_decoder)); + EXPECT_EQ(frame->size(), size); + return frame; +} + +template +static ErrorOr test_roundtrip(Gfx::Bitmap const& bitmap) +{ + AllocatingMemoryStream stream; + TRY(Writer::encode(stream, bitmap)); + auto encoded_data = TRY(stream.read_until_eof()); + + auto plugin = TRY(Loader::create(encoded_data)); + auto decoded = TRY(expect_single_frame_of_size(*plugin, bitmap.size())); + + for (int y = 0; y < bitmap.height(); ++y) + for (int x = 0; x < bitmap.width(); ++x) + EXPECT_EQ(decoded->get_pixel(x, y), bitmap.get_pixel(x, y)); + + return {}; +} + +static ErrorOr> create_test_rgb_bitmap() +{ + auto bitmap = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { 47, 33 })); + + for (int y = 0; y < bitmap->height(); ++y) + for (int x = 0; x < bitmap->width(); ++x) + bitmap->set_pixel(x, y, Gfx::Color((x * 255) / bitmap->width(), (y * 255) / bitmap->height(), x + y)); + + return bitmap; +} + +static ErrorOr> create_test_rgba_bitmap() +{ + auto bitmap = TRY(create_test_rgb_bitmap()); + + for (int y = 0; y < bitmap->height(); ++y) { + for (int x = 0; x < bitmap->width(); ++x) { + Color pixel = bitmap->get_pixel(x, y); + pixel.set_alpha(255 - x); + bitmap->set_pixel(x, y, pixel); + } + } + + return bitmap; +} + +TEST_CASE(test_webp) +{ + auto err = test_roundtrip(TRY_OR_FAIL(create_test_rgb_bitmap())); + TRY_OR_FAIL(err); + err = test_roundtrip(TRY_OR_FAIL(create_test_rgba_bitmap())); + TRY_OR_FAIL(err); +}