Curating Data – SGI Color names

Every once in a while I turn some low level bit of data into something useful for my programming.  I’ve done the ASCII table, and I’ve done mime types, and I’ve done http headers.  this time around, I’ve been playing with colors, pixels, graphics, and the like.  So, this time around, I found some useful color names that I wanted to use.

SGI X Windows Colors is a file that contains some information that is no doubt already available in many different forms.  Apparently, this is the source for names such as: azure, honeydew, navyblue, rosy brown, saddle brown, etc.  There’s about 660 of them.  The data in the original form looks like this:

255 250 250 snow
248 248 255 ghost white
248 248 255 GhostWhite

So on and so forth.  Of particular note, the names have a space in them in some cases, which is then rectified with a duplicate entry with the space removed, and Caml casing used.  Furthermore, gray/grey values look like this:

163 163 163 gray64
163 163 163 grey64
166 166 166 gray65
166 166 166 grey65
168 168 168 gray66
168 168 168 grey66

Some people like ‘grey’, some like ‘gray’, and so it goes.

When I look at the data, I want to do different things with it.  In some cases, I might like to use the values as direct pixel RGB representations.  I might want to do this:

ffi.cdef[[
struct RGB {
   uint8_t r,g,b;
}
]]
RGB = ffi.typeof("struct RGB");

red = RGB(255, 0,0);
green = RGB(0, 255, 0);

But, then again, I might prefer something like:

colors = {
  {name = "red", red=255, green=0, blue=0},
  {name = "green", red=0, green=255, blue=0},
}

These forms are very application specific, and either too verbose, or too special. Instead, I’ll pick a middle ground which is more like this:

local SGIColors = {
snow = {255, 250, 250},
ghostwhite = {248, 248, 255},
whitesmoke = {245, 245, 245},
gainsboro = {220, 220, 220},
.
.
.
}

When it’s in this form, I can fairly easily transform it into any other form, including those above, using some simple code that just traverses the table and does the needful.

But, how to get it in this form in the first place?

parseline = function(line)
	local starting, ending, n1, n2, n3, name = line:find("%s*(%d*)%s*(%d*)%s*(%d*)%s*([%a%d%s]*)")
	return tonumber(n1), tonumber(n2), tonumber(n3), name
end

convertFile = function(filename)
	for line in io.lines(filename) do
		local red,green,blue,name = parseline(line)
		name = name:lower()
		if name:find("%s") == nil then
			io.write(string.format("%s = {%d, %d, %d},\n",name, red, green, blue))
		end
	end
end

convertFile("SGIColors.txt")

The parse line() function takes a single line, and parses out the three component numbers, and the name. The io.write simply outputs it into the format that I expect (could be changed to anything). With this, I’m done.

So, there you have it. A web search, and about 10 minutes of coding, and suddenly I’ve got a little database of colors rather than simply a web page of stuff.

 



Leave a comment