This file, usually found in /usr/X11R6/lib/X11/rgb.txt, contains the abstract color names for the X server. These names allow the user to refer to colors in a more user friendly way: for example, you can say

xsetroot -solid red

instead of

xsetroot -solid rgb:f/0/0 (this is canonical)
xsetroot -solid "#ff0000" (this is considered an obsolete but still legal syntax)

It is Xlib that does the matching. You will notice that these are RGB triples, which means that the actual color you see on the screen depends on your video card, on your monitor and possibly also on the phase of the moon.
Being the observant and acute reader you are, you will also notice that the "#F3AC91" notation was borrowed by the HTML color notation.
The values you see in the file (example follows) mean Red, Green and Blue in a scale from 0 to 255: for example, BlueViolet is 138 43 226, that's to say: some red, a tiny touch of green and quite a lot of blue. This results in quite a nasty violet that will drive you insane if you use it a background in your root window.

Of course, one could use device independent color, in various colorspaces: for more on that man X. But I can't resist mentioning that xsetroot -solid "TekHVC:100/80/50" will give you a rather tasty pea green.

What follows is the beginning of rgb.txt in my Linux system:

255 250 250 snow
248 248 255 ghost white
248 248 255 GhostWhite
245 245 245 white smoke
245 245 245 WhiteSmoke
220 220 220 gainsboro
255 250 240 floral white
255 250 240 FloralWhite
253 245 230 old lace
253 245 230 OldLace
250 240 230 linen
250 235 215 antique white
250 235 215 AntiqueWhite
255 239 213 papaya whip
255 239 213 PapayaWhip
255 235 205 blanched almond
255 235 205 BlanchedAlmond
255 228 196 bisque
255 218 185 peach puff
255 218 185 PeachPuff
255 222 173 navajo white
255 222 173 NavajoWhite
255 228 181 moccasin
255 248 220 cornsilk
255 255 240 ivory
255 250 205 lemon chiffon
255 250 205 LemonChiffon
255 245 238 seashell
240 255 240 honeydew
245 255 250 mint cream
245 255 250 MintCream
240 255 255 azure
240 248 255 alice blue
240 248 255 AliceBlue
230 230 250 lavender
255 240 245 lavender blush
255 240 245 LavenderBlush
255 228 225 misty rose
255 228 225 MistyRose
255 255 255 white

You will notice that, even within this short sample, there are many synonims: "white", "grey100" and "gray100" all refer to the color that is written as "255 255 255", that's to say, the whitest white possible.
This is probably done to tolerate better differences in spelling and capitalization.

Some of the color names are very poetical: gaisboro, old lace, cornsilk, misty rose, peru, burlywood ...

On IRC someone suggested using rgb.txt in the reverse direction: when you have a color and want to know what it is called. The short C program below illustrates the idea.

As some experimentation will show, it does not work too well. I suspect this is due to two factors: that rgb.txt isn't the most suitable sample of names, and that the program measures distances in RGB-space. (the better alternative would be to convert to L*u*v*-space, using the xlib color management functions, and compare distances there). It did find the name turquoise, though, which was the original question. :)

 

/* colorname.c - find the closest color in rgb.txt, in the sense of
                 smallest sum of squares of differences of components.
                 (that is, shortest distance in the RGB cube). */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define RGBFILE "/usr/X11R6/lib/X11/rgb.txt"

int main (int argc, char *argv[]) {
        int R, G, B, r, g, b;
        FILE *f;
        unsigned dist, bestdist = -1;
        char name[42], bestname[42] = "none";
        char buf[100];

        if (argc!=4) {
                fprintf(stderr, "Usage: %s <R> <G> <B>\n", argv[0]);
                exit(1);
        }

        R = atoi(argv[1]); G = atoi(argv[2]); B = atoi(argv[3]);

        if (!(f = fopen(RGBFILE, "r"))) {
                perror(RGBFILE);
                exit(1);
        }

        while (fgets(buf, sizeof(buf), f)) {
                if (sscanf(buf, "%d %d %d %42[^\n]\n", &r, &g, &b, name) != 4)
                        continue;

                dist = (R-r)*(R-r) + (G-g)*(G-g) + (B-b)*(B-b);
                if (dist < bestdist) {
                        bestdist = dist;
                        strcpy(bestname, name);
                }
        }

        printf("Best match: %s (distance %.1f)\n", bestname, sqrt(bestdist));
        return 0;
}

Log in or register to write something here or to contact authors.