Repository: SerenityOS/serenity
File: Userland/Utilities/imgcmp.cpp (C++)

Code before:
        return Error::from_string_view("can only save to .png and .webp files"sv);

    auto output_stream = TRY(Core::File::open(out_path, Core::File::OpenMode::Write));
    auto buffered_stream = TRY(Core::OutputBufferedFile::create(move(output_stream)));

    if (out_path.ends_with(".png"sv, CaseSensitivity::CaseInsensitive))
        return Gfx::PNGWriter::encode(*buffered_stream, *bitmap);

    VERIFY(out_path.ends_with(".webp"sv, CaseSensitivity::CaseInsensitive));
    return Gfx::WebPWriter::encode(*buffered_stream, *bitmap);
}

static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> make_diff_image(NonnullRefPtr<Gfx::Bitmap> first_image, NonnullRefPtr<Gfx::Bitmap> second_image)
{
    VERIFY(first_image->size() == second_image->size());

    auto diff_image = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, first_image->size()));

    for (int y = 0; y < first_image->height(); ++y) {
        for (int x = 0; x < first_image->width(); ++x) {
            auto first_pixel = first_image->get_pixel<Gfx::StorageFormat::BGRA8888>(x, y);
            auto second_pixel = second_image->get_pixel<Gfx::StorageFormat::BGRA8888>(x, y);
            if (first_pixel == second_pixel) {
                diff_image->set_pixel(x, y, first_pixel.interpolate(Gfx::Color::White, 0.5f));
            } else {
                diff_image->set_pixel(x, y, Gfx::Color::from_rgb(0xff0000));
            }
        }
    }

    return diff_image;
}

ErrorOr<int> serenity_main(Main::Arguments arguments)
{
    Core::ArgsParser args_parser;

    StringView write_diff_image_path;
    args_parser.add_option(write_diff_image_path, "Write image that highlights differing pixels", "write-diff-image", {}, "FILE");

    StringView first_image_path;
    args_parser.add_positional_argument(first_image_path, "Path to first input image", "FILE1");

    StringView second_image_path;
    args_parser.add_positional_argument(second_image_path, "Path to second input image", "FILE2");

    args_parser.parse(arguments);

    auto first_image = TRY(load_image(first_image_path));
    auto second_image = TRY(load_image(second_image_path));


Review comment (suggestion):
That should work: `diff_image->set_pixel(x, y, { Color::Red });`

Code after:
        return Error::from_string_view("can only save to .png and .webp files"sv);

    auto output_stream = TRY(Core::File::open(out_path, Core::File::OpenMode::Write));
    auto buffered_stream = TRY(Core::OutputBufferedFile::create(move(output_stream)));

    if (out_path.ends_with(".png"sv, CaseSensitivity::CaseInsensitive))
        return Gfx::PNGWriter::encode(*buffered_stream, *bitmap);

    VERIFY(out_path.ends_with(".webp"sv, CaseSensitivity::CaseInsensitive));
    return Gfx::WebPWriter::encode(*buffered_stream, *bitmap);
}

static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> make_diff_image(NonnullRefPtr<Gfx::Bitmap> first_image, NonnullRefPtr<Gfx::Bitmap> second_image)
{
    VERIFY(first_image->size() == second_image->size());

    auto diff_image = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, first_image->size()));

    for (int y = 0; y < first_image->height(); ++y) {
        for (int x = 0; x < first_image->width(); ++x) {
            auto first_pixel = first_image->get_pixel<Gfx::StorageFormat::BGRA8888>(x, y);
            auto second_pixel = second_image->get_pixel<Gfx::StorageFormat::BGRA8888>(x, y);
            if (first_pixel == second_pixel) {
                diff_image->set_pixel(x, y, first_pixel.interpolate(Gfx::Color::White, 0.5f));
            } else {
                diff_image->set_pixel(x, y, Gfx::Color::Red);
            }
        }
    }

    return diff_image;
}

ErrorOr<int> serenity_main(Main::Arguments arguments)
{
    Core::ArgsParser args_parser;

    StringView write_diff_image_path;
    args_parser.add_option(write_diff_image_path, "Write image that highlights differing pixels", "write-diff-image", {}, "FILE");

    StringView first_image_path;
    args_parser.add_positional_argument(first_image_path, "Path to first input image", "FILE1");

    StringView second_image_path;
    args_parser.add_positional_argument(second_image_path, "Path to second input image", "FILE2");

    args_parser.parse(arguments);

    auto first_image = TRY(load_image(first_image_path));
    auto second_image = TRY(load_image(second_image_path));