Repository: SerenityOS/serenity
File: Tests/LibGfx/TestImageWriter.cpp (C++)

Code before:
    auto encoded_data = TRY(encode_bitmap<Writer>(bitmap));
    return expect_single_frame_of_size(*TRY(Loader::create(encoded_data)), bitmap.size());
}

template<class Writer, class Loader>
static ErrorOr<NonnullRefPtr<Gfx::CMYKBitmap>> get_roundtrip_bitmap(Gfx::CMYKBitmap const& bitmap)
{
    auto encoded_data = TRY(encode_bitmap<Writer>(bitmap));
    return expect_cmyk_frame_of_size(*TRY(Loader::create(encoded_data)), bitmap.size());
}

static void expect_bitmaps_equal(Gfx::Bitmap const& a, Gfx::Bitmap const& b)
{
    VERIFY(a.size() == b.size());
    for (int y = 0; y < a.height(); ++y)
        for (int x = 0; x < a.width(); ++x)
            EXPECT_EQ(a.get_pixel(x, y), b.get_pixel(x, y));
}

static void expect_bitmaps_equal(Gfx::CMYKBitmap const& a, Gfx::CMYKBitmap const& b)
{
    VERIFY(a.size() == b.size());
    for (int y = 0; y < a.size().height(); ++y)
        for (int x = 0; x < a.size().width(); ++x)
            EXPECT_EQ(a.scanline(y)[x], b.scanline(y)[x]);
}

template<class Writer, class Loader>
static ErrorOr<void> test_roundtrip(Gfx::Bitmap const& bitmap)
{
    auto decoded = TRY((get_roundtrip_bitmap<Writer, Loader>(bitmap)));
    expect_bitmaps_equal(*decoded, bitmap);
    return {};
}

template<class Writer, class Loader>
static ErrorOr<void> test_roundtrip(Gfx::CMYKBitmap const& bitmap)
{
    auto decoded = TRY((get_roundtrip_bitmap<Writer, Loader>(bitmap)));
    expect_bitmaps_equal(*decoded, bitmap);
    return {};
}

static void add_alpha_channel(Gfx::Bitmap& 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);
        }

Review comment (suggestion):
Same here, right?
AFAICT the API of `CMYKBitmap` that is used here is a subset of `Bitmap`.

Code after:
    return expect_cmyk_frame_of_size(*TRY(Loader::create(encoded_data)), bitmap.size());
}

template<OneOf<Gfx::Bitmap, Gfx::CMYKBitmap> BitmapType>
static void expect_bitmaps_equal(BitmapType const& a, BitmapType const& b)
{
    VERIFY(a.size() == b.size());
    for (int y = 0; y < a.size().height(); ++y)
        for (int x = 0; x < a.size().width(); ++x)
            EXPECT_EQ(a.scanline(y)[x], b.scanline(y)[x]);
}

template<class Writer, class Loader, OneOf<Gfx::Bitmap, Gfx::CMYKBitmap> BitmapType>
static ErrorOr<void> test_roundtrip(BitmapType const& bitmap)
{
    auto decoded = TRY((get_roundtrip_bitmap<Writer, Loader>(bitmap)));
    expect_bitmaps_equal(*decoded, bitmap);
    return {};
}

static void add_alpha_channel(Gfx::Bitmap& 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);
        }
    }
}

static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> create_test_grayscale_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) {
            auto gray = (x + y) * 255 / (bitmap->width() + bitmap->height());
            bitmap->set_pixel(x, y, Gfx::Color(gray, gray, gray));
        }
    }

    return bitmap;
}

static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> create_test_grayscale_alpha_bitmap()
{
    auto bitmap = TRY(create_test_grayscale_bitmap());
    add_alpha_channel(*bitmap);
    return bitmap;
}