(defconst colour-triplet-regex
"\\([0-9A-Fa-f]{2}\\)\\([0-9A-Fa-f]{2}\\)\\([0-9A-Fa-f]{2}\\)")
(defun parse-colour (colour frame)
(cond ((and (stringp colour) (string-match colour-triplet-regex colour))
(mapcar
(lambda (x)
(* (string-to-int (match-string x colour) 16) 257)) '(1 2 3)))
((stringp colour)
(if (fboundp 'color-values)
(color-values colour frame)
(x-color-values colour frame)))
((consp colour) colour)
(t (error "colour (%S) is not a colour name, #xxxxxx or list"))) )
(defun colour-distance (colour-a colour-b &optional frame)
"Return an integer distance between COLOUR-A and COLOUR-B on FRAME.
COLOUR-A and COLOUR-B may be either strings containing the color name,
or lists of the form (RED GREEN BLUE).
If FRAME is unspecified or nil, the current frame is used."
(if frame nil (setq frame (selected-frame)))
(let* ((colour-a (parse-colour colour-a frame))
(colour-b (parse-colour colour-b frame))
(r (lsh (- (car colour-a) (car colour-b)) -8))
(g (lsh (- (cadr colour-a) (cadr colour-b)) -8))
(b (lsh (- (caddr colour-a) (caddr colour-b)) -8))
(rmu (lsh (+ (car colour-a) (car colour-b)) -9)))
(+ (lsh (* (+ 512 rmu) r r) -8) (* 4 g g) (lsh (* (- 767 rmu) b b) -8)) ))