Color representations
XYZ:
TYPE ~
RECORD [X, Y, Z:
REAL];
CIE tristimulus values; by convention, X, Y, and Z range from 0 to approximately 1, although all combinations in this range do not correspond with physically realizable colors.
Corresponding chromaticity coordinates are x = X/(X+Y+Z) y = Y/(X+Y+Z) z = Z/(X+Y+Z)
Chromaticity:
TYPE ~
RECORD [x, y:
REAL];
CIE chromaticity; x and y are IN [0..1]. On the CIE chromaticity diagram, all points that correspond to physically realizable colors lie within the horseshoe-shaped spectrum locus.
illuminantD50: Chromaticity ~ [x: 0.xxx, y: 0.yyy];
illuminantD65: Chromaticity ~ [x: 0.xxx, y: 0.yyy];
illuminantC: Chromaticity ~ [x: 0.310, y: 0.317];
Chromaticity of CIE standard illuminant C (daylight).
ChromaticityFromXYZ:
PROC [
XYZ]
RETURNS [Chromaticity];
Derives [x, y] from [X, Y, Z].
XYZFromChromaticity:
PROC [c: Chromaticity, Y:
REAL]
RETURNS [
XYZ];
Derives [X, Y, Z] from [x, y, Y].
Row3: TYPE ~ ARRAY [0..3) OF REAL;
Matrix3:
TYPE ~
ARRAY [0..3)
OF
ARRAY [0..3)
OF
REAL;
RGBCalibration: TYPE ~ REF RGBCalibrationRep;
RGBCalibrationRep:
TYPE ~
RECORD [
type: ATOM, -- identifying name
red: Chromaticity, -- CIE chromaticity of red phosphor
green: Chromaticity, -- CIE chromaticity of green phosphor
blue: Chromaticity, -- CIE chromaticity of blue phosphor
white: Chromaticity, -- CIE chromaticity of white (RGB[1, 1, 1])
maxY: REAL, -- maximum luminance, typically 1
matrixRGBtoXYZ: Matrix3, -- A row vector with [red, green, blue] components, multiplied on the right by the matrix, yields a row vector with [X, Y, Z] components.
matrixXYZtoRGB: Matrix3 -- The inverse.
];
An RGBCalibration specifies the relationship between RGB and CIE for a given device.
GetDefaultCalibration:
PROC
RETURNS [RGBCalibration];
Returns a "reasonable" calibration for a typical color monitor.
CreateCalibration:
PROC [type:
ATOM, red, green, blue: Chromaticity,
white: Chromaticity, maxY:
REAL ← 1]
RETURNS [RGBCalibration];
Creates a new RGB calibration.
RGB:
TYPE ~
RECORD [R, G, B:
REAL];
Red, green, and blue, as for a color monitor or scanner; R, G, and B range from 0 to 1.
XYZFromRGB:
PROC [rgb:
RGB, calibration: RGBCalibration ←
NIL]
RETURNS [
XYZ];
Converts RGB to XYZ; if calibration=NIL, uses the default calibration.
RGBFromXYZ:
PROC [xyz:
XYZ, calibration: RGBCalibration ←
NIL]
RETURNS [
RGB];
Converts XYZ to RGB; if calibration=NIL, uses the default calibration.
May return values outside [0..1] if the color is outside the device's gamut.
RGBMaxY:
PROC [c: Chromaticity, calibration: RGBCalibration ←
NIL]
RETURNS [Y:
REAL];
For the given CIE chromaticity, returns the maximum Y attainable with RGB.
[x, y, Y] is inside the device's gamut iff Y<=RGBMaxY[[x, y], calibration].
YIQ:
TYPE ~
RECORD [Y, I, Q:
REAL];
YIQ is the scheme used for color television; see Foley and van Dam, section 17.4.3.
Y, I, and Q range from 0 to 1; Y is luminance, roughly corresponding to XYZ.Y/100.
Y = .30*R+.59*G+.11*B I = .60*R-.28*G-.32*B Q = .21*R-.52*G+.31*B
YIQFromRGB: PROC [RGB] RETURNS [YIQ];
RGBFromYIQ:
PROC [
YIQ]
RETURNS [
RGB];
Conversion between RGB and YIQ.
HSV:
TYPE ~
RECORD [H, S, V:
REAL];
Hue, Saturation, Value; H, S, and V range from 0 to 1.
If V=0 (black), H and S are irrelevant. If S=0 (achromatic), H is irrelevant.
The HSV space is a hexcone; see Foley and van Dam, section 17.4.4.
HSVFromRGB: PROC [RGB] RETURNS [HSV];
RGBFromHSV:
PROC [
HSV]
RETURNS [
RGB];
Conversion between RGB and HSV.
HSL:
TYPE ~
RECORD [H, S, L:
REAL];
Hue, Saturation, Lightness; H, S, and L range from 0 to 1.
If L=0 (black) or L=1 (white), H and S are irrelevant. If S=0 (achromatic), H is irrelevant.
The HSL space is a double hexcone; see Foley and van Dam, section 17.4.5 (they call it HLS).
HSLFromRGB: PROC [RGB] RETURNS [HSL];
RGBFromHSL:
PROC [
HSL]
RETURNS [
RGB];
Conversion between RGB and HSL.
Making color operators
SampleTableProc:
TYPE ~
PROC [Sample]
RETURNS [
REAL];
NewColorOperatorGrayLinear:
PROC [sWhite, sBlack:
REAL, sampleTableSize: Sample ← 0, sampleTableProc: SampleTableProc ←
NIL]
RETURNS [ColorOperator];
... colorModelOperators/Xerox/GrayLinear, as specified in the Raster Encoding Standard.
The resulting ColorOperator maps a single sample s0 into MakeGray[f], where:
s ← IF sampleTableSize=0 THEN s0 ELSE sampleMap[s0];
f ← MIN[MAX[(s-sWhite)/(sBlack-sWhite), 0.0], 1.0];
NewColorOperatorGrayDensity:
PROC [sWhite, sBlack, dBlack:
REAL, sampleTableSize: Sample ← 0, sampleTableProc: SampleTableProc ←
NIL]
RETURNS [ColorOperator];
... colorModelOperators/Xerox/GrayDensity, as specified in the Raster Encoding Standard.
The resulting ColorOperator maps a single sample s0 into MakeGray[f], where:
s ← IF sampleTableSize=0 THEN s0 ELSE sampleMap[s0];
d ← ((s-sWhite)/(sBlack-sWhite))*dBlack;
f ← MIN[MAX[1-10**d, 0.0], 1.0]; -- 10**d means 10 to the power d
NewColorOperatorGrayVisual:
PUBLIC
PROC [sWhite, sBlack:
REAL, sampleTableSize: Sample ← 0, sampleTableProc: SampleTableProc ←
NIL]
RETURNS [ColorOperator];
... colorModelOperators/Xerox/GrayVisual, as specified in the Raster Encoding Standard.
The resulting ColorOperator maps a single sample s0 into MakeGray[f], where:
s ← IF sampleTableSize=0 THEN s0 ELSE sampleMap[s0];
L ← (s-sBlack)/(sWhite-sBlack);
Y ← IF L<=0.09 THEN L/0.09 ELSE ((L+0.16)/0.25)**3; -- x**3 means x cubed
f ← MIN[MAX[1-0.01*Y, 0.0], 1.0];
NewColorOperatorMap:
PROC [maxSampleValue: Sample, map:
PROC [Sample]
RETURNS [ConstantColor]]
RETURNS [ColorOperator];
... colorModelOperators/Xerox/Map, as specified in the Raster Encoding Standard.
The resulting ColorOperator maps a single sample s0 into the ConstantColor map[s0].
NewColorOperatorBuildMap:
PROC [colorOperator: ColorOperator, maxSampleValue: Sample, map:
PROC [Sample]
RETURNS [Sample]]
RETURNS [ColorOperator];
... colorModelOperators/Xerox/BuildMap, as specified in the Raster Encoding Standard.
The resulting ColorOperator maps a single sample s0 into the ConstantColor obtained by applying colorOperator to map[s0]
SampleEncoding: TYPE ~ REF SampleEncodingRep ← NIL;
SampleEncodingRep: TYPE ~ RECORD [SEQUENCE size: NAT OF REAL];
Pixel3Encoding: TYPE ~ ARRAY [0..3) OF SampleEncoding;
identityPixel3Encoding: Pixel3Encoding ~ ALL[NIL];
MakeSampleEncoding:
PROC [size:
NAT ← 0, sampleTableProc: SampleTableProc ←
NIL]
RETURNS [SampleEncoding];
NewColorOperatorCalibrated:
PROC [encoding: Pixel3Encoding ← identityPixel3Encoding, matrix: Matrix3, hints: Atom.PropList]
RETURNS [ColorOperator];
... a color model for calibrated color. The parameters specify a mapping from a 3-sample pixel to a set CIE tristimulus values as follows: first, each sample is looked up in its SampleEncoding table to yield a real number (if the table is NIL, the sample is simply converted to a real number without scaling). Then the resulting row vector is postmultiplied by the matrix to yield a row vector containing the [X, Y, Z] tristimulus values, normalized so that the maximum attainable Y component is 1.
The hints may be used by some implementations to control details of the color rendition.
NewColorOperatorRGB:
PROC [maxIn: Sample]
RETURNS [ColorOperator];
... a color model for uncalibrated red, green, blue separations; expects samplesPerPixel=3. For each separation, 0 ~ minimum intensity, maxIn ~ maximum intensity.
NewColorOperatorCMY:
PROC [maxIn: Sample]
RETURNS [ColorOperator];
... a color model for uncalibrated cyan, magenta, yellow separations; expects samplesPerPixel=3. For each separation, 0 ~ no ink, maxIn ~ full ink coverage.
NewColorOperatorCMYK:
PROC [maxIn: Sample]
RETURNS [ColorOperator];
... a simple color model for cyan, magenta, yellow, black separations; expects samplesPerPixel=4. For each separation, 0 ~ no ink, maxIn ~ full ink coverage.
ColorValue: TYPE ~ [0..256);
ColorValueTriple: TYPE ~ PACKED ARRAY [0..3) OF ColorValue; -- red, green, blue
ColorMapProc: TYPE ~ PROC [Sample] RETURNS [ColorValueTriple];
NewColorOperatorColorMap:
PROC [maxIn: Sample, map: ColorMapProc]
RETURNS [ColorOperator];
... a color operator corresponding to the color map in certain display devices (although still device independent). Each ColorValueTriple is interpreted according to the color operator obtained from NewColorOperatorRGB[ColorValue.LAST].
NewColorOperatorAlpha:
PROC [colorOperator: ColorOperator, maxAlphaIn: Sample]
RETURNS [ColorOperator];
Adds an alpha (transparency) channel to the supplied color operator; the result will have one more sample per pixel. The additional sample will be the highest-indexed, and will range over [0..maxAlphaIn]. Some devices may not support the alpha channel. The alpha sample interpretation is linear, with 0 ~ fully transparent and 1 ~ opaque.