Skip to content

Commit

Permalink
Tests: Add TestImageWriter
Browse files Browse the repository at this point in the history
For now, it tests that webps roundtrip, but it's easy to add basic
roundtrip testing for other image formats.
  • Loading branch information
nico committed May 5, 2024
1 parent 2f7f776 commit 1c3dcd9
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions Tests/LibGfx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(TEST_SOURCES
TestGfxBitmap.cpp
TestICCProfile.cpp
TestImageDecoder.cpp
TestImageWriter.cpp
TestPainter.cpp
TestParseISOBMFF.cpp
TestRect.cpp
Expand Down
81 changes: 81 additions & 0 deletions Tests/LibGfx/TestImageWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2024, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <AK/MemoryStream.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/ImageFormats/WebPLoader.h>
#include <LibGfx/ImageFormats/WebPWriter.h>
#include <LibTest/TestCase.h>

static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> 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<NonnullRefPtr<Gfx::Bitmap>> 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<class Writer, class Loader>
static ErrorOr<void> 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<AK::NonnullRefPtr<Gfx::Bitmap>> 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<AK::NonnullRefPtr<Gfx::Bitmap>> 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<Gfx::WebPWriter, Gfx::WebPImageDecoderPlugin>(TRY_OR_FAIL(create_test_rgb_bitmap()));
TRY_OR_FAIL(err);
err = test_roundtrip<Gfx::WebPWriter, Gfx::WebPImageDecoderPlugin>(TRY_OR_FAIL(create_test_rgba_bitmap()));
TRY_OR_FAIL(err);
}

0 comments on commit 1c3dcd9

Please sign in to comment.