sharkdp / pastel

A command-line tool to generate, analyze, convert and manipulate colors
Apache License 2.0
5.04k stars 97 forks source link

Improve speed of 8bit ANSI mode #55

Closed sharkdp closed 5 years ago

sharkdp commented 5 years ago

8-bit ANSI mode is extremely slow (like, 3-4 orders of magnitude slower) due to the inefficient to_ansi_8bit implementation.

sharkdp commented 5 years ago

There is the approximate version which we have used in bat in the past:

    fn to_ansi_8bit(&self) -> u8 {
        let rgb = self.to_rgba();
        let r = rgb.r;
        let g = rgb.g;
        let b = rgb.b;

        const BLACK: u8 = 16;
        const WHITE: u8 = 231;

        if r == g && g == b {
            if r < 8 {
                BLACK
            } else if r > 248 {
                WHITE
            } else {
                ((r - 8) as u16 * 24 / 247) as u8 + 232
            }
        } else {
            36 * (r / 51) + 6 * (g / 51) + (b / 51) + 16
        }
    }

This is extremely fast (3 ms for pastel pick), but only approximate.

Since I want the ANSI approximation to be as good as it can possibly be (via Delta-E), I now optimized the code a bit (bringing the time down from 3 s to around 90 ms). This should be fast enough for now.