### 5.11 Color ¶

http://people.csail.mit.edu/jaffer/Color

The goals of this package are to provide methods to specify, compute, and transform colors in a core set of additive color spaces. The color spaces supported should be sufficient for working with the color data encountered in practice and the literature.

#### 5.11.1 Color Data-Type ¶

`(require 'color)`

Function: color? obj ¶

  Returns #t if obj is a color.

Function: color? obj typ ¶

  Returns #t if obj is a color of color-space typ. The symbol typ must be one of:

  - CIEXYZ
  - RGB709
  - L*a*b*
  - L*u*v*
  - sRGB
  - e-sRGB
  - L*C*h

Function: make-color space arg … ¶

  Returns a color of type space.

  - For space arguments `CIEXYZ`, `RGB709`, and `sRGB`, the sole arg is a list of three numbers.
  - For space arguments `L*a*b*`, `L*u*v*`, and `L*C*h`, arg is a list of three numbers optionally followed by a whitepoint.
  - For `xRGB`, arg is an integer.
  - For `e-sRGB`, the arguments are as for `e-sRGB->color`.

Function: color-space color ¶

  Returns the symbol for the color-space in which color is embedded.

Function: color-precision color ¶

  For colors in digital color-spaces, `color-precision` returns the number of bits used for each of the R, G, and B channels of the encoding. Otherwise, `color-precision` returns #f

Function: color-white-point color ¶

  Returns the white-point of color in all color-spaces except CIEXYZ.

Function: convert-color color space white-point ¶
Function: convert-color color space ¶
Function: convert-color color e-sRGB precision ¶

  Converts color into space at optional white-point.

#### 5.11.1.1 External Representation ¶

Each color encoding has an external, case-insensitive representation. To ensure portability, the white-point for all color strings is D65. 5

Color Space | External Representation
CIEXYZ | CIEXYZ:<X>/<Y>/<Z>
RGB709 | RGBi:<R>/<G>/<B>
L*a*b* | CIELAB:<L>/<a>/<b>
L*u*v* | CIELuv:<L>/<u>/<v>
L*C*h | CIELCh:<L>/<C>/<h>

The X, Y, Z, L, a, b, u, v, C, h, R, G, and B fields are (Scheme) real numbers within the appropriate ranges.

Color Space | External Representation
sRGB | sRGB:<R>/<G>/<B>
e-sRGB10 | e-sRGB10:<R>/<G>/<B>
e-sRGB12 | e-sRGB12:<R>/<G>/<B>
e-sRGB16 | e-sRGB16:<R>/<G>/<B>

The R, G, and B, fields are non-negative exact decimal integers within the appropriate ranges.

Several additional syntaxes are supported by `string->color`:

Color Space | External Representation
sRGB | sRGB:<RRGGBB>
sRGB | #<RRGGBB>
sRGB | 0x<RRGGBB>
sRGB | #x<RRGGBB>

Where RRGGBB is a non-negative six-digit hexadecimal number.

Function: color->string color ¶

  Returns a string representation of color.

Function: string->color string ¶

  Returns the color represented by string. If string is not a syntactically valid notation for a color, then `string->color` returns #f.

#### 5.11.1.2 White ¶

We experience color relative to the illumination around us. CIEXYZ coordinates, although subject to uniform scaling, are objective. Thus other color spaces are specified relative to a white point in CIEXYZ coordinates.

The white point for digital color spaces is set to D65. For the other spaces a white-point argument can be specified. The default if none is specified is the white-point with which the color was created or last converted; and D65 if none has been specified.

Constant: D65 ¶

  Is the color of 6500.K (blackbody) illumination. D65 is close to the average color of daylight.

Constant: D50 ¶

  Is the color of 5000.K (blackbody) illumination. D50 is the color of indoor lighting by incandescent bulbs, whose filaments have temperatures around 5000.K.

#### 5.11.2 Color Spaces ¶

#### Measurement-based Color Spaces ¶

The tristimulus color spaces are those whose component values are proportional measurements of light intensity. The CIEXYZ(1931) system provides 3 sets of spectra to dot-product with a spectrum of interest. The result of those dot-products is coordinates in CIEXYZ space. All tristimuls color spaces are related to CIEXYZ by linear transforms, namely matrix multiplication. Of the color spaces listed here, CIEXYZ and RGB709 are tristimulus spaces.

Color Space: CIEXYZ ¶

  The CIEXYZ color space covers the full gamut. It is the basis for color-space conversions.

  CIEXYZ is a list of three inexact numbers between 0.0 and 1.1. ’(0. 0. 0.) is black; ’(1. 1. 1.) is white.

Function: ciexyz->color xyz ¶

  xyz must be a list of 3 numbers. If xyz is valid CIEXYZ coordinates, then `ciexyz->color` returns the color specified by xyz; otherwise returns #f.

Function: color:ciexyz x y z ¶

  Returns the CIEXYZ color composed of x, y, z. If the coordinates do not encode a valid CIEXYZ color, then an error is signaled.

Function: color->ciexyz color ¶

  Returns the list of 3 numbers encoding color in CIEXYZ.

Color Space: RGB709 ¶

  BT.709-4 (03/00) Parameter values for the HDTV standards for production and international programme exchange specifies parameter values for chromaticity, sampling, signal format, frame rates, etc., of high definition television signals.

  An RGB709 color is represented by a list of three inexact numbers between 0.0 and 1.0. ’(0. 0. 0.) is black ’(1. 1. 1.) is white.

Function: rgb709->color rgb ¶

  rgb must be a list of 3 numbers. If rgb is valid RGB709 coordinates, then `rgb709->color` returns the color specified by rgb; otherwise returns #f.

Function: color:rgb709 r g b ¶

  Returns the RGB709 color composed of r, g, b. If the coordinates do not encode a valid RGB709 color, then an error is signaled.

Function: color->rgb709 color ¶

  Returns the list of 3 numbers encoding color in RGB709.

#### Perceptual Uniformity ¶

Although properly encoding the chromaticity, tristimulus spaces do not match the logarithmic response of human visual systems to intensity. Minimum detectable differences between colors correspond to a smaller range of distances (6:1) in the L*a*b* and L*u*v* spaces than in tristimulus spaces (80:1). For this reason, color distances are computed in L*a*b* (or L*C*h).

Color Space: L*a*b* ¶

  Is a CIE color space which better matches the human visual system’s perception of color. It is a list of three numbers:

  - 0 <= L* <= 100 (CIE Lightness)
  - -500 <= a* <= 500
  - -200 <= b* <= 200

Function: l*a*b*->color L*a*b* white-point ¶

  L*a*b* must be a list of 3 numbers. If L*a*b* is valid L*a*b* coordinates, then `l*a*b*->color` returns the color specified by L*a*b*; otherwise returns #f.

Function: color:l*a*b* L* a* b* white-point ¶

  Returns the L*a*b* color composed of L*, a*, b* with white-point.

Function: color:l*a*b* L* a* b* ¶

  Returns the L*a*b* color composed of L*, a*, b*. If the coordinates do not encode a valid L*a*b* color, then an error is signaled.

Function: color->l*a*b* color white-point ¶

  Returns the list of 3 numbers encoding color in L*a*b* with white-point.

Function: color->l*a*b* color ¶

  Returns the list of 3 numbers encoding color in L*a*b*.

Color Space: L*u*v* ¶

  Is another CIE encoding designed to better match the human visual system’s perception of color.

Function: l*u*v*->color L*u*v* white-point ¶

  L*u*v* must be a list of 3 numbers. If L*u*v* is valid L*u*v* coordinates, then `l*u*v*->color` returns the color specified by L*u*v*; otherwise returns #f.

Function: color:l*u*v* L* u* v* white-point ¶

  Returns the L*u*v* color composed of L*, u*, v* with white-point.

Function: color:l*u*v* L* u* v* ¶

  Returns the L*u*v* color composed of L*, u*, v*. If the coordinates do not encode a valid L*u*v* color, then an error is signaled.

Function: color->l*u*v* color white-point ¶

  Returns the list of 3 numbers encoding color in L*u*v* with white-point.

Function: color->l*u*v* color ¶

  Returns the list of 3 numbers encoding color in L*u*v*.

#### Cylindrical Coordinates ¶

HSL (Hue Saturation Lightness), HSV (Hue Saturation Value), HSI (Hue Saturation Intensity) and HCI (Hue Chroma Intensity) are cylindrical color spaces (with angle hue). But these spaces are all defined in terms device-dependent RGB spaces.

One might wonder if there is some fundamental reason why intuitive specification of color must be device-dependent. But take heart! A cylindrical system can be based on L*a*b* and is used for predicting how close colors seem to observers.

Color Space: L*C*h ¶

  Expresses the *a and b* of L*a*b* in polar coordinates. It is a list of three numbers:

  - 0 <= L* <= 100 (CIE Lightness)
  - C* (CIE Chroma) is the distance from the neutral (gray) axis.
  - 0 <= h <= 360 (CIE Hue) is the angle.

  The colors by quadrant of h are:

  0 | red, orange, yellow | 90
  90 | yellow, yellow-green, green | 180
  180 | green, cyan (blue-green), blue | 270
  270 | blue, purple, magenta | 360

Function: l*c*h->color L*C*h white-point ¶

  L*C*h must be a list of 3 numbers. If L*C*h is valid L*C*h coordinates, then `l*c*h->color` returns the color specified by L*C*h; otherwise returns #f.

Function: color:l*c*h L* C* h white-point ¶

  Returns the L*C*h color composed of L*, C*, h with white-point.

Function: color:l*c*h L* C* h ¶

  Returns the L*C*h color composed of L*, C*, h. If the coordinates do not encode a valid L*C*h color, then an error is signaled.

Function: color->l*c*h color white-point ¶

  Returns the list of 3 numbers encoding color in L*C*h with white-point.

Function: color->l*c*h color ¶

  Returns the list of 3 numbers encoding color in L*C*h.

#### Digital Color Spaces ¶

The color spaces discussed so far are impractical for image data because of numerical precision and computational requirements. In 1998 the IEC adopted A Standard Default Color Space for the Internet - sRGB (http://www.w3.org/Graphics/Color/sRGB). sRGB was cleverly designed to employ the 24-bit (256x256x256) color encoding already in widespread use; and the 2.2 gamma intrinsic to CRT monitors.

Conversion from CIEXYZ to digital (sRGB) color spaces is accomplished by conversion first to a RGB709 tristimulus space with D65 white-point; then each coordinate is individually subjected to the same non-linear mapping. Inverse operations in the reverse order create the inverse transform.

Color Space: sRGB ¶

  Is "A Standard Default Color Space for the Internet". Most display monitors will work fairly well with sRGB directly. Systems using ICC profiles 6 should work very well with sRGB.

Function: srgb->color rgb ¶

  rgb must be a list of 3 numbers. If rgb is valid sRGB coordinates, then `srgb->color` returns the color specified by rgb; otherwise returns #f.

Function: color:srgb r g b ¶

  Returns the sRGB color composed of r, g, b. If the coordinates do not encode a valid sRGB color, then an error is signaled.

Color Space: xRGB ¶

  Represents the equivalent sRGB color with a single 24-bit integer. The most significant 8 bits encode red, the middle 8 bits blue, and the least significant 8 bits green.

Function: color->srgb color ¶

  Returns the list of 3 integers encoding color in sRGB.

Function: color->xrgb color ¶

  Returns the 24-bit integer encoding color in sRGB.

Function: xrgb->color k ¶

  Returns the sRGB color composed of the 24-bit integer k.

Color Space: e-sRGB ¶

  Is "Photography - Electronic still picture imaging - Extended sRGB color encoding" (PIMA 7667:2001). It extends the gamut of sRGB; and its higher precision numbers provide a larger dynamic range.

  A triplet of integers represent e-sRGB colors. Three precisions are supported:

  e-sRGB10

    0 to 1023

  e-sRGB12

    0 to 4095

  e-sRGB16

    0 to 65535

Function: e-srgb->color precision rgb ¶

  precision must be the integer 10, 12, or 16. rgb must be a list of 3 numbers. If rgb is valid e-sRGB coordinates, then `e-srgb->color` returns the color specified by rgb; otherwise returns #f.

Function: color:e-srgb 10 r g b ¶

  Returns the e-sRGB10 color composed of integers r, g, b.

Function: color:e-srgb 12 r g b ¶

  Returns the e-sRGB12 color composed of integers r, g, b.

Function: color:e-srgb 16 r g b ¶

  Returns the e-sRGB16 color composed of integers r, g, b. If the coordinates do not encode a valid e-sRGB color, then an error is signaled.

Function: color->e-srgb precision color ¶

  precision must be the integer 10, 12, or 16. `color->e-srgb` returns the list of 3 integers encoding color in sRGB10, sRGB12, or sRGB16.

#### 5.11.3 Spectra ¶

The following functions compute colors from spectra, scale color luminance, and extract chromaticity. XYZ is used in the names of procedures for unnormalized colors; the coordinates of CIEXYZ colors are constrained as described in Color Spaces.

`(require 'color-space)`

A spectrum may be represented as:

- A procedure of one argument accepting real numbers from 380e-9 to 780e-9, the wavelength in meters; or
- A vector of real numbers representing intensity samples evenly spaced over some range of wavelengths overlapping the range 380e-9 to 780e-9.

CIEXYZ values are calculated as dot-product with the X, Y (Luminance), and Z Spectral Tristimulus Values. The files `cie1931.xyz` and `cie1964.xyz` in the distribution contain these CIE-defined values.

Feature: cie1964 ¶

  Loads the Spectral Tristimulus Values CIE 1964 Supplementary Standard Colorimetric Observer, defining cie:x-bar, cie:y-bar, and cie:z-bar.

Feature: cie1931 ¶

  Loads the Spectral Tristimulus Values CIE 1931 Supplementary Standard Colorimetric Observer, defining cie:x-bar, cie:y-bar, and cie:z-bar.

Feature: ciexyz ¶

  Requires Spectral Tristimulus Values, defaulting to cie1931, defining cie:x-bar, cie:y-bar, and cie:z-bar.

`(require 'cie1964)` or `(require 'cie1931)` will `load-ciexyz` specific values used by the following spectrum conversion procedures. The spectrum conversion procedures `(require 'ciexyz)` to assure that a set is loaded.

Function: read-cie-illuminant path ¶

  path must be a string naming a file consisting of 107 numbers for 5.nm intervals from 300.nm to 830.nm. `read-cie-illuminant` reads (using Scheme `read`) these numbers and returns a length 107 vector filled with them.

    (define CIE:SI-D65
      (read-CIE-illuminant (in-vicinity (library-vicinity) "ciesid65.dat")))
    (spectrum->XYZ CIE:SI-D65 300e-9 830e-9)
    ⇒ (25.108569422374994 26.418013465625001 28.764075683374993)

Function: read-normalized-illuminant path ¶

  path must be a string naming a file consisting of 107 numbers for 5.nm intervals from 300.nm to 830.nm. `read-normalized-illuminant` reads (using Scheme `read`) these numbers and returns a length 107 vector filled with them, normalized so that `spectrum->XYZ` of the illuminant returns its whitepoint.

CIE Standard Illuminants A and D65 are included with SLIB:

    (define CIE:SI-A
      (read-normalized-illuminant (in-vicinity (library-vicinity) "ciesia.dat")))
    (define CIE:SI-D65
      (read-normalized-illuminant (in-vicinity (library-vicinity) "ciesid65.dat")))
    (spectrum->XYZ CIE:SI-A 300e-9 830e-9)
    ⇒ (1.098499460820401 999.9999999999998e-3 355.8173930654951e-3)
    (CIEXYZ->sRGB (spectrum->XYZ CIE:SI-A 300e-9 830e-9))
    ⇒ (255 234 133)
    (spectrum->XYZ CIE:SI-D65 300e-9 830e-9)
    ⇒ (950.4336673552745e-3 1.0000000000000002 1.0888053986649182)
    (CIEXYZ->sRGB (spectrum->XYZ CIE:SI-D65 300e-9 830e-9))
    ⇒ (255 255 255)

Function: illuminant-map proc siv ¶

  siv must be a one-dimensional array or vector of 107 numbers. `illuminant-map` returns a vector of length 107 containing the result of applying proc to each element of siv.

Function: illuminant-map->XYZ proc siv ¶

  `(spectrum->XYZ (illuminant-map proc siv) 300e-9 830e-9)`

Function: spectrum->XYZ proc ¶

  proc must be a function of one argument. `spectrum->XYZ` computes the CIEXYZ(1931) values for the spectrum returned by proc when called with arguments from 380e-9 to 780e-9, the wavelength in meters.

Function: spectrum->XYZ spectrum x1 x2 ¶

  x1 and x2 must be positive real numbers specifying the wavelengths (in meters) corresponding to the zeroth and last elements of vector or list spectrum. `spectrum->XYZ` returns the CIEXYZ(1931) values for a light source with spectral values proportional to the elements of spectrum at evenly spaced wavelengths between x1 and x2.

  Compute the colors of 6500.K and 5000.K blackbody radiation:

      (require 'color-space)
      (define xyz (spectrum->XYZ (blackbody-spectrum 6500)))
      (define y_n (cadr xyz))
      (map (lambda (x) (/ x y_n)) xyz)
          ⇒ (0.9687111145512467 1.0 1.1210875945303613)

      (define xyz (spectrum->XYZ (blackbody-spectrum 5000)))
      (map (lambda (x) (/ x y_n)) xyz)
          ⇒ (0.2933441826889158 0.2988931825387761 0.25783646831201573)

Function: spectrum->chromaticity proc ¶
Function: spectrum->chromaticity spectrum x1 x2 ¶

  Computes the chromaticity for the given spectrum.

Function: wavelength->XYZ w ¶

  w must be a number between 380e-9 to 780e-9. `wavelength->XYZ` returns (unnormalized) XYZ values for a monochromatic light source with wavelength w.

Function: wavelength->chromaticity w ¶

  w must be a number between 380e-9 to 780e-9. `wavelength->chromaticity` returns the chromaticity for a monochromatic light source with wavelength w.

Function: blackbody-spectrum temp ¶
Function: blackbody-spectrum temp span ¶

  Returns a procedure of one argument (wavelength in meters), which returns the radiance of a black body at temp.

  The optional argument span is the wavelength analog of bandwidth. With the default span of 1.nm (1e-9.m), the values returned by the procedure correspond to the power of the photons with wavelengths w to w+1e-9.

Function: temperature->XYZ x ¶

  The positive number x is a temperature in degrees kelvin. `temperature->XYZ` computes the unnormalized CIEXYZ(1931) values for the spectrum of a black body at temperature x.

  Compute the chromaticities of 6500.K and 5000.K blackbody radiation:

      (require 'color-space)
      (XYZ->chromaticity (temperature->XYZ 6500))
          ⇒ (0.3135191660557008 0.3236456786200268)

      (XYZ->chromaticity (temperature->XYZ 5000))
          ⇒ (0.34508082841161052 0.3516084965163377)

Function: temperature->chromaticity x ¶

  The positive number x is a temperature in degrees kelvin. `temperature->cromaticity` computes the chromaticity for the spectrum of a black body at temperature x.

  Compute the chromaticities of 6500.K and 5000.K blackbody radiation:

      (require 'color-space)
      (temperature->chromaticity 6500)
          ⇒ (0.3135191660557008 0.3236456786200268)

      (temperature->chromaticity 5000)
          ⇒ (0.34508082841161052 0.3516084965163377)

Function: XYZ->chromaticity xyz ¶

  Returns a two element list: the x and y components of xyz normalized to 1 (= x + y + z).

Function: chromaticity->CIEXYZ x y ¶

  Returns the list of x, and y, 1 - y - x.

Function: chromaticity->whitepoint x y ¶

  Returns the CIEXYZ(1931) values having luminosity 1 and chromaticity x and y.

Many color datasets are expressed in xyY format; chromaticity with CIE luminance (Y). But xyY is not a CIE standard like CIEXYZ, CIELAB, and CIELUV. Although chrominance is well defined, the luminance component is sometimes scaled to 1, sometimes to 100, but usually has no obvious range. With no given whitepoint, the only reasonable course is to ascertain the luminance range of a dataset and normalize the values to lie from 0 to 1.

Function: XYZ->xyY xyz ¶

  Returns a three element list: the x and y components of XYZ normalized to 1, and CIE luminance Y.

Function: xyY->XYZ xyY ¶

Function: xyY:normalize-colors colors ¶

  colors is a list of xyY triples. `xyY:normalize-colors` scales each chromaticity so it sums to 1 or less; and divides the Y values by the maximum Y in the dataset, so all lie between 0 and 1.

Function: xyY:normalize-colors colors n ¶

  If n is positive real, then `xyY:normalize-colors` divides the Y values by n times the maximum Y in the dataset.

  If n is an exact non-positive integer, then `xyY:normalize-colors` divides the Y values by the maximum of the Ys in the dataset excepting the -n largest Y values.

  In all cases, returned Y values are limited to lie from 0 to 1.

Why would one want to normalize to other than 1? If the sun or its reflection is the brightest object in a scene, then normalizing to its luminance will tend to make the rest of the scene very dark. As with photographs, limiting the specular highlights looks better than darkening everything else.

The results of measurements being what they are, `xyY:normalize-colors` is extremely tolerant. Negative numbers are replaced with zero, and chromaticities with sums greater than one are scaled to sum to one.

#### 5.11.4 Color Difference Metrics ¶

`(require 'color-space)`

The low-level metric functions operate on lists of 3 numbers, lab1, lab2, lch1, or lch2.

`(require 'color)`

The wrapped functions operate on objects of type color, color1 and color2 in the function entries.

Function: L*a*b*:DE* lab1 lab2 ¶

  Returns the Euclidean distance between lab1 and lab2.

Function: CIE:DE* color1 color2 white-point ¶
Function: CIE:DE* color1 color2 ¶

  Returns the Euclidean distance in L*a*b* space between color1 and color2.

Function: L*a*b*:DE*94 lab1 lab2 parametric-factors ¶
Function: L*a*b*:DE*94 lab1 lab2 ¶
Function: CIE:DE*94 color1 color2 parametric-factors ¶
Function: CIE:DE*94 color1 color2 ¶

  Measures distance in the L*a*b* color-space. The three axes are individually scaled in their contributions to the total distance.

  `DE*94` is not symmetrical in its arguments. lab1 is the “reference” color and lab2 is the “sample” color.

  The CIE has defined reference conditions under which the metric with default parameters can be expected to perform well. These are:

  - The specimens are homogeneous in colour.
  - The colour difference (CIELAB) is <= 5 units.
  - They are placed in direct edge contact.
  - Each specimen subtends an angle of >4 degrees to the assessor, whose colour vision is normal.
  - They are illuminated at 1000 lux, and viewed against a background of uniform grey, with L* of 50, under illumination simulating D65.

  The parametric-factors argument is a list of 3 quantities kL, kC and kH. parametric-factors independently adjust each colour-difference term to account for any deviations from the reference viewing conditions. Under the reference conditions explained above, the default is kL = kC = kH = 1.

The Color Measurement Committee of The Society of Dyers and Colorists in Great Britain created a more sophisticated color-distance function for use in judging the consistency of dye lots. With CMC:DE* it is possible to use a single value pass/fail tolerance for all shades.

Function: CMC-DE lch1 lch2 parametric-factors ¶
Function: CMC-DE lch1 lch2 l c ¶
Function: CMC-DE lch1 lch2 l ¶
Function: CMC-DE lch1 lch2 ¶
Function: CMC:DE* color1 color2 l c ¶
Function: CMC:DE* color1 color2 ¶

  `CMC:DE` is a L*C*h metric. The parametric-factors argument is a list of 2 numbers l and c. l and c parameterize this metric. 1 and 1 are recommended for perceptibility; the default, 2 and 1, for acceptability.

#### 5.11.5 Color Conversions ¶

This package contains the low-level color conversion and color metric routines operating on lists of 3 numbers. There is no type or range checking.

`(require 'color-space)`

Constant: CIEXYZ:D65 ¶

  Is the color of 6500.K (blackbody) illumination. D65 is close to the average color of daylight.

Constant: CIEXYZ:D50 ¶

  Is the color of 5000.K (blackbody) illumination. D50 is the color of indoor lighting by incandescent bulbs.

Constant: CIEXYZ:A ¶
Constant: CIEXYZ:B ¶
Constant: CIEXYZ:C ¶
Constant: CIEXYZ:E ¶

  CIE 1931 illuminants normalized to 1 = y.

Function: color:linear-transform matrix row ¶

Function: CIEXYZ->RGB709 xyz ¶
Function: RGB709->CIEXYZ srgb ¶

Function: CIEXYZ->L*u*v* xyz white-point ¶
Function: CIEXYZ->L*u*v* xyz ¶
Function: L*u*v*->CIEXYZ L*u*v* white-point ¶
Function: L*u*v*->CIEXYZ L*u*v* ¶

  The white-point defaults to CIEXYZ:D65.

Function: CIEXYZ->L*a*b* xyz white-point ¶
Function: CIEXYZ->L*a*b* xyz ¶
Function: L*a*b*->CIEXYZ L*a*b* white-point ¶
Function: L*a*b*->CIEXYZ L*a*b* ¶

  The XYZ white-point defaults to CIEXYZ:D65.

Function: L*a*b*->L*C*h L*a*b* ¶
Function: L*C*h->L*a*b* L*C*h ¶

Function: CIEXYZ->sRGB xyz ¶
Function: sRGB->CIEXYZ srgb ¶

Function: CIEXYZ->xRGB xyz ¶
Function: xRGB->CIEXYZ srgb ¶

Function: sRGB->xRGB xyz ¶
Function: xRGB->sRGB srgb ¶

Function: CIEXYZ->e-sRGB n xyz ¶
Function: e-sRGB->CIEXYZ n srgb ¶

Function: sRGB->e-sRGB n srgb ¶
Function: e-sRGB->sRGB n srgb ¶

  The integer n must be 10, 12, or 16. Because sRGB and e-sRGB use the same RGB709 chromaticities, conversion between them is simpler than conversion through CIEXYZ.

Do not convert e-sRGB precision through `e-sRGB->sRGB` then `sRGB->e-sRGB` – values would be truncated to 8-bits!

Function: e-sRGB->e-sRGB n1 srgb n2 ¶

  The integers n1 and n2 must be 10, 12, or 16. `e-sRGB->e-sRGB` converts srgb to e-sRGB of precision n2.

#### 5.11.6 Color Names ¶

`(require 'color-names)`

Rather than ballast the color dictionaries with numbered grays, `file->color-dictionary` discards them. They are provided through the `grey` procedure:

Function: grey k ¶

  Returns `(inexact->exact (round (* k 2.55)))`, the X11 color grey<k>.

A color dictionary is a database table relating canonical color-names to color-strings (see External Representation).

The column names in a color dictionary are unimportant; the first field is the key, and the second is the color-string.

Function: color-name:canonicalize name ¶

  Returns a downcased copy of the string or symbol name with ‘`_`’, ‘`-`’, and whitespace removed.

Function: color-name->color name table1 table2 … ¶

  table1, table2, … must be color-dictionary tables. `color-name->color` searches for the canonical form of name in table1, table2, … in order; returning the color-string of the first matching record; #f otherwise.

Function: color-dictionaries->lookup table1 table2 … ¶

  table1, table2, … must be color-dictionary tables. `color-dictionaries->lookup` returns a procedure which searches for the canonical form of its string argument in table1, table2, …; returning the color-string of the first matching record; and #f otherwise.

Function: color-dictionary name rdb base-table-type ¶

  rdb must be a string naming a relational database file; and the symbol name a table therein. The database will be opened as base-table-type. `color-dictionary` returns the read-only table name in database name if it exists; #f otherwise.

Function: color-dictionary name rdb ¶

  rdb must be an open relational database or a string naming a relational database file; and the symbol name a table therein. `color-dictionary` returns the read-only table name in database name if it exists; #f otherwise.

Function: load-color-dictionary name rdb base-table-type ¶
Function: load-color-dictionary name rdb ¶

  rdb must be a string naming a relational database file; and the symbol name a table therein. If the symbol base-table-type is provided, the database will be opened as base-table-type. `load-color-dictionary` creates a top-level definition of the symbol name to a lookup procedure for the color dictionary name in rdb.

  The value returned by `load-color-dictionary` is unspecified.

#### Dictionary Creation ¶

`(require 'color-database)`

Function: file->color-dictionary file table-name rdb base-table-type ¶
Function: file->color-dictionary file table-name rdb ¶

  rdb must be an open relational database or a string naming a relational database file, table-name a symbol, and the string file must name an existing file with colornames and their corresponding xRGB (6-digit hex) values. `file->color-dictionary` creates a table table-name in rdb and enters the associations found in file into it.

Function: url->color-dictionary url table-name rdb base-table-type ¶
Function: url->color-dictionary url table-name rdb ¶

  rdb must be an open relational database or a string naming a relational database file and table-name a symbol. `url->color-dictionary` retrieves the resource named by the string url using the wget program; then calls `file->color-dictionary` to enter its associations in table-name in url.

This section has detailed the procedures for creating and loading color dictionaries. So where are the dictionaries to load?

http://people.csail.mit.edu/jaffer/Color/Dictionaries.html

Describes and evaluates several color-name dictionaries on the web. The following procedure creates a database containing two of these dictionaries.

Function: make-slib-color-name-db ¶

  Creates an alist-table relational database in library-vicinity containing the Resene and saturate color-name dictionaries.

  If the files `resenecolours.txt`, `nbs-iscc.txt`, and `saturate.txt` exist in the library-vicinity, then they used as the source of color-name data. Otherwise, `make-slib-color-name-db` calls url->color-dictionary with the URLs of appropriate source files.

#### The Short List ¶

`(require 'saturate)`

Function: saturate name ¶

  Looks for name among the 19 saturated colors from Approximate Colors on CIE Chromaticity Diagram:

  reddish orange | orange | yellowish orange | yellow
  greenish yellow | yellow green | yellowish green | green
  bluish green | blue green | greenish blue | blue
  purplish blue | bluish purple | purple | reddish purple
  red purple | purplish red | red

  (http://people.csail.mit.edu/jaffer/Color/saturate.pdf). If name is found, the corresponding color is returned. Otherwise #f is returned. Use saturate only for light source colors.

Resene Paints Limited, New Zealand’s largest privately-owned and operated paint manufacturing company, has generously made their Resene RGB Values List available.

`(require 'resene)`

Function: resene name ¶

  Looks for name among the 1300 entries in the Resene color-name dictionary (http://people.csail.mit.edu/jaffer/Color/resene.pdf). If name is found, the corresponding color is returned. Otherwise #f is returned. The Resene RGB Values List is an excellent source for surface colors.

If you include the Resene RGB Values List in binary form in a program, then you must include its license with your program:

> Resene RGB Values List
> For further information refer to http://www.resene.co.nz
> Copyright Resene Paints Ltd 2001

> Permission to copy this dictionary, to modify it, to redistribute it, to distribute modified versions, and to use it for any purpose is granted, subject to the following restrictions and understandings.

> 1. Any text copy made of this dictionary must include this copyright notice in full.
> 2. Any redistribution in binary form must reproduce this copyright notice in the documentation or other materials provided with the distribution.
> 3. Resene Paints Ltd makes no warranty or representation that this dictionary is error-free, and is under no obligation to provide any services, by way of maintenance, update, or otherwise.
> 4. There shall be no use of the name of Resene or Resene Paints Ltd in any advertising, promotional, or sales literature without prior written consent in each case.
> 5. These RGB colour formulations may not be used to the detriment of Resene Paints Ltd.

#### 5.11.7 Daylight ¶

`(require 'daylight)`

This package calculates the colors of sky as detailed in:
http://www.cs.utah.edu/vissim/papers/sunsky/sunsky.pdf
A Practical Analytic Model for Daylight
A. J. Preetham, Peter Shirley, Brian Smits

Function: solar-hour julian-day hour ¶

  Returns the solar-time in hours given the integer julian-day in the range 1 to 366, and the local time in hours.

  To be meticulous, subtract 4 minutes for each degree of longitude west of the standard meridian of your time zone.

Function: solar-declination julian-day ¶

Function: solar-polar declination latitude solar-hour ¶

  Returns a list of theta_s, the solar angle from the zenith, and phi_s, the solar azimuth. 0 <= theta_s measured in degrees. phi_s is measured in degrees from due south; west of south being positive.

In the following procedures, the number 0 <= theta_s <= 90 is the solar angle from the zenith in degrees.

Turbidity is a measure of the fraction of scattering due to haze as opposed to molecules. This is a convenient quantity because it can be estimated based on visibility of distant objects. This model fails for turbidity values less than 1.3.

        _______________________________________________________________
    512|-:                                                             |
       | * pure-air                                                    |
    256|-:**                                                           |
       | : ** exceptionally-clear                                      |
    128|-:   *                                                         |
       | :    **                                                       |
     64|-:      *                                                      |
       | :       ** very-clear                                         |
     32|-:         **                                                  |
       | :           **                                                |
     16|-:             *** clear                                       |
       | :               ****                                          |
      8|-:                  ****                                       |
       | :                     **** light-haze                         |
      4|-:                         ****                                |
       | :                             ******                          |
      2|-:                                  ******** haze         thin-|
       | :                                          ***********    fog |
      1|-:----------------------------------------------------*******--|
       |_:____.____:____.____:____.____:____.____:____.____:____.____:_|
         1         2         4         8        16        32        64
                  Meterorological range (km) versus Turbidity

Function: sunlight-spectrum turbidity theta_s ¶

  Returns a vector of 41 values, the spectrum of sunlight from 380.nm to 790.nm for a given turbidity and theta_s.

Function: sunlight-chromaticity turbidity theta_s ¶

  Given turbidity and theta_s, `sunlight-chromaticity` returns the CIEXYZ triple for color of sunlight scaled to be just inside the RGB709 gamut.

Function: zenith-xyy turbidity theta_s ¶

  Returns the xyY (chromaticity and luminance) at the zenith. The Luminance has units kcd/m^2.

Function: overcast-sky-color-xyy turbidity theta_s ¶

  turbidity is a positive real number expressing the amount of light scattering. The real number theta_s is the solar angle from the zenith in degrees.

  `overcast-sky-color-xyy` returns a function of one angle theta, the angle from the zenith of the viewing direction (in degrees); and returning the xyY value for light coming from that elevation of the sky.

Function: clear-sky-color-xyy turbidity theta_s phi_s ¶
Function: sky-color-xyy turbidity theta_s phi_s ¶

  turbidity is a positive real number expressing the amount of light scattering. The real number theta_s is the solar angle from the zenith in degrees. The real number phi_s is the solar angle from south.

  `clear-sky-color-xyy` returns a function of two angles, theta and phi which specify the angles from the zenith and south meridian of the viewing direction (in degrees); returning the xyY value for light coming from that direction of the sky.

  `sky-color-xyY` calls `overcast-sky-color-xyY` for turbidity <= 20; otherwise the `clear-sky-color-xyy` function.

#### Footnotes

##### (5)

Readers may recognize these color string formats from Xlib. X11’s color management system was doomed by its fiction that CRT monitors’ (and X11 default) color-spaces were linear RGBi. Unable to shed this legacy, the only practical way to view pictures on X is to ignore its color management system and use an sRGB monitor. In this implementation the device-independent RGB709 and sRGB spaces replace the device-dependent RGBi and RGB spaces of Xlib.

##### (6)

A comprehensive encoding of transforms between CIEXYZ and device color spaces is the International Color Consortium profile format, ICC.1:1998-09:

> The intent of this format is to provide a cross-platform device profile format. Such device profiles can be used to translate color data created on one device into another device’s native color space.