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

Code before:
                for (unsigned i = 0; i < sizeof(delta_r); ++i) {
                    auto lab2 = TRY(lab_from_rgb(r + delta_r[i], g + delta_g[i], b + delta_b[i]));
                    float delta = Gfx::DeltaE(lab, lab2);
                    if (delta > largest) {
                        largest = delta;
                        largest_color1 = Color(r, g, b);
                        largest_color2 = Color(r + delta_r[i], g + delta_g[i], b + delta_b[i]);
                    }
                    if (delta < smallest) {
                        smallest = delta;
                        smallest_color1 = Color(r, g, b);
                        smallest_color2 = Color(r + delta_r[i], g + delta_g[i], b + delta_b[i]);
                    }
                }
            }
        }
    }
    outln("\rlargest difference between neighboring colors: {}, between {} and {}", largest, largest_color1, largest_color2);
    outln("smallest difference between neighboring colors: {}, between {} and {}", smallest, smallest_color1, smallest_color2);
    return {};
}

static ErrorOr<void> convert_color(StringView color, Gfx::ICC::Profile const& profile)
{
    auto split = color.split_view(',');
    if (split.size() != 3 && split.size() != 4)
        return Error::from_string_literal("expected 3 or 4 channels for color convertion");

    if (number_of_components_in_color_space(profile.data_color_space()) != split.size())
        return Error::from_string_literal("unexpected number of color in color string");

    Vector<u8, 4> channels;
    channels.resize(split.size());
    for (auto [i, channel] : enumerate(split)) {
        auto maybe_number = channel.to_number<u8>();
        if (!maybe_number.has_value())
            return Error::from_string_literal("unable to parse color string");
        channels[i] = *maybe_number;
    }

    auto srgb_profile = TRY(Gfx::ICC::sRGB());
    auto pcs = TRY(profile.to_pcs(channels));
    Array<u8, 3> out_color_buffer {};
    TRY(srgb_profile->from_pcs(profile, pcs, out_color_buffer));
    auto out_color = Color { out_color_buffer[0], out_color_buffer[1], out_color_buffer[2] };
    if (channels.size() == 3)
        outln("({}, {}, {}) in sRGB is {}", channels[0], channels[1], channels[2], out_color);
    else
        outln("({}, {}, {}, {}) in sRGB is {}", channels[0], channels[1], channels[2], channels[3], out_color);
    return {};
}

Review comment (refactor):
I'd remove this check. There are profiles with other channel counts, and none of the code needs this. (For example, if you're on a mac, `/System/Library/ColorSync/Profiles/Generic\ Gray\ Profile.icc` is a 1-channel profile.)

The next check is all you need.

Code after:
                for (unsigned i = 0; i < sizeof(delta_r); ++i) {
                    auto lab2 = TRY(lab_from_rgb(r + delta_r[i], g + delta_g[i], b + delta_b[i]));
                    float delta = Gfx::DeltaE(lab, lab2);
                    if (delta > largest) {
                        largest = delta;
                        largest_color1 = Color(r, g, b);
                        largest_color2 = Color(r + delta_r[i], g + delta_g[i], b + delta_b[i]);
                    }
                    if (delta < smallest) {
                        smallest = delta;
                        smallest_color1 = Color(r, g, b);
                        smallest_color2 = Color(r + delta_r[i], g + delta_g[i], b + delta_b[i]);
                    }
                }
            }
        }
    }
    outln("\rlargest difference between neighboring colors: {}, between {} and {}", largest, largest_color1, largest_color2);
    outln("smallest difference between neighboring colors: {}, between {} and {}", smallest, smallest_color1, smallest_color2);
    return {};
}

static ErrorOr<void> print_color_as_sRGB(StringView color, Gfx::ICC::Profile const& profile)
{
    auto split = color.split_view(',');

    if (number_of_components_in_color_space(profile.data_color_space()) != split.size())
        return Error::from_string_literal("unexpected number of color in color string");

    Vector<u8, 4> channels;
    for (auto [i, channel] : enumerate(split)) {
        auto maybe_number = channel.to_number<u8>();
        if (!maybe_number.has_value())
            return Error::from_string_literal("unable to parse color string");
        channels.append(*maybe_number);
    }

    auto srgb_profile = TRY(Gfx::ICC::sRGB());
    auto pcs = TRY(profile.to_pcs(channels));
    Array<u8, 3> out_color_buffer {};
    TRY(srgb_profile->from_pcs(profile, pcs, out_color_buffer));
    auto out_color = Color { out_color_buffer[0], out_color_buffer[1], out_color_buffer[2] };
    outln("{} in sRGB is {}", channels, out_color);

    return {};
}

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