DIRECTORY ImagerPixelArray USING [PixelArray], ImagerSample USING [PixelBuffer, PixelMap, PixelProc, Sample, SampleBuffer, SampleMap], ImagerTransformation USING [Transformation], Rope USING [ROPE]; ImagerColor: CEDAR DEFINITIONS ~ BEGIN Transformation: TYPE ~ ImagerTransformation.Transformation; Sample: TYPE ~ ImagerSample.Sample; SampleBuffer: TYPE ~ ImagerSample.SampleBuffer; SampleMap: TYPE ~ ImagerSample.SampleMap; PixelProc: TYPE ~ ImagerSample.PixelProc; PixelBuffer: TYPE ~ ImagerSample.PixelBuffer; PixelMap: TYPE ~ ImagerSample.PixelMap; PixelArray: TYPE ~ ImagerPixelArray.PixelArray; ROPE: TYPE ~ Rope.ROPE; XYZ: TYPE ~ RECORD [X, Y, Z: REAL]; Chromaticity: TYPE ~ RECORD [x, y: REAL]; illuminantC: Chromaticity ~ [x: 0.310, y: 0.317]; ChromaticityFromXYZ: PROC [XYZ] RETURNS [Chromaticity]; XYZFromChromaticity: PROC [c: Chromaticity, Y: REAL] RETURNS [XYZ]; 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]) YMax: REAL, -- maximum luminance, typically 100 impl: REF RGBCalibrationImplRep -- implementation data (matrices relating RGB and XYZ) ]; RGBCalibrationImplRep: TYPE; GetDefaultCalibration: PROC RETURNS [RGBCalibration]; CreateCalibration: PROC [type: ATOM, red, green, blue: Chromaticity, white: Chromaticity, YMax: REAL _ 100] RETURNS [RGBCalibration]; RGB: TYPE ~ RECORD [R, G, B: REAL]; XYZFromRGB: PROC [rgb: RGB, calibration: RGBCalibration _ NIL] RETURNS [XYZ]; RGBFromXYZ: PROC [xyz: XYZ, calibration: RGBCalibration _ NIL] RETURNS [RGB]; RGBMaxY: PROC [c: Chromaticity, calibration: RGBCalibration _ NIL] RETURNS [Y: REAL]; YIQ: TYPE ~ RECORD [Y, I, Q: REAL]; YIQFromRGB: PROC [RGB] RETURNS [YIQ]; RGBFromYIQ: PROC [YIQ] RETURNS [RGB]; HSV: TYPE ~ RECORD [H, S, V: REAL]; HSVFromRGB: PROC [RGB] RETURNS [HSV]; RGBFromHSV: PROC [HSV] RETURNS [RGB]; HSL: TYPE ~ RECORD [H, S, L: REAL]; HSLFromRGB: PROC [RGB] RETURNS [HSL]; RGBFromHSL: PROC [HSL] RETURNS [RGB]; Color: TYPE ~ REF ColorRep; ColorRep: TYPE ~ RECORD [ SELECT tag: * FROM constant => [ colorOperator: ColorOperator, pixel: SEQUENCE size: NAT OF Sample ], sampled => [ -- the result of MakeSampledColor pa: PixelArray, -- the array of pixels um: Transformation, -- transforms from color to device coordinates colorOperator: ColorOperator -- maps pixels into constant colors ], sampledBlack => [ -- the result of MakeSampledBlack pa: PixelArray, -- the array of pixels (must be 1 bit per pixel) um: Transformation, -- transforms from color to device coordinates clear: BOOL -- are zero bits transparent? ], special => [ -- XOR, stipples, and the like type: ATOM, data: REF, substitute: Color -- use this if you don't recognize type ], ENDCASE ]; ConstantColor: TYPE ~ REF ColorRep.constant; SampledColor: TYPE ~ REF ColorRep.sampled; SampledBlack: TYPE ~ REF ColorRep.sampledBlack; SpecialColor: TYPE ~ REF ColorRep.special; ColorOperator: TYPE ~ REF ColorOperatorRep; ColorOperatorRep: TYPE ~ RECORD [ chromatic: BOOL, samplesPerPixelIn: NAT, class: REF ColorOperatorClassRep, data: REF ]; ColorOperatorClassRep: TYPE; ColorOutput: TYPE ~ REF ColorOutputRep; ColorOutputRep: TYPE ~ RECORD [ type: ATOM, samplesPerPixelOut: NAT, impl: REF ColorOutputImplRep ]; ColorOutputImplRep: TYPE; TupleProc: TYPE ~ PROC [i: NAT] RETURNS [REAL]; TranslateProc: TYPE ~ PROC [pixelsIn: PixelBuffer, pixelsOut: PixelBuffer]; Apply: PROC [self: ColorOperator, pixel: PixelProc] RETURNS [ConstantColor]; TupleFromPixel: PROC [self: ColorOperator, output: ColorOutput, pixelIn: PixelProc, tupleAction: PROC [tupleOut: TupleProc]]; PixelFromPixel: PROC [self: ColorOperator, output: ColorOutput, pixelIn: PixelProc, maxOut: PixelProc, pixelAction: PROC [pixelOut: PixelProc]]; TranslatePixels: PROC [self: ColorOperator, output: ColorOutput, maxIn: PixelProc, maxOut: PixelProc, translateAction: PROC [translate: TranslateProc]]; Translate: PROC [self: ColorOperator, output: ColorOutput, pa: PixelArray, maxOut: PixelProc] RETURNS [PixelMap]; ColorFromGray: PROC [f: REAL] RETURNS [ConstantColor]; ColorFromXYZ: PROC [xyz: XYZ] RETURNS [ConstantColor]; ColorFromRGB: PROC [rgb: RGB, calibration: RGBCalibration _ NIL] RETURNS [ConstantColor]; ColorFromYIQ: PROC [yiq: YIQ, calibration: RGBCalibration _ NIL] RETURNS [ConstantColor]; ColorFromHSV: PROC [hsv: HSV, calibration: RGBCalibration _ NIL] RETURNS [ConstantColor]; ColorFromHSL: PROC [hsl: HSL, calibration: RGBCalibration _ NIL] RETURNS [ConstantColor]; TupleFromColor: PROC [self: ConstantColor, output: ColorOutput, tupleAction: PROC [tupleOut: TupleProc]]; PixelFromColor: PROC [self: ConstantColor, output: ColorOutput, maxOut: PixelProc, pixelAction: PROC [pixelOut: PixelProc]]; GrayFromColor: PROC [color: ConstantColor] RETURNS [REAL]; MakeSampledBlack: PROC [pa: PixelArray, um: Transformation, clear: BOOL _ FALSE] RETURNS [SampledBlack]; MakeSampledColor: PROC [pa: PixelArray, um: Transformation, colorOperator: ColorOperator] RETURNS [SampledColor]; END. 6ImagerColor.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Doug Wyatt, March 6, 1986 9:59:30 pm PST Color representations CIE tristimulus values; by convention, X, Y, and Z range from 0 to about 100. Corresponding chromaticity coordinates are x = X/(X+Y+Z) y = Y/(X+Y+Z) z = Z/(X+Y+Z) 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. Chromaticity of CIE standard illuminant C (daylight). Derives [x, y] from [X, Y, Z]. Derives [X, Y, Z] from [x, y, Y]. An RGBCalibration specifies the relationship between RGB and CIE for a given device. Returns a "reasonable" calibration for a typical color monitor. Creates a new RGB calibration. Red, green, and blue, as for a color monitor or scanner; R, G, and B range from 0 to 1. Converts RGB to XYZ; if calibration=NIL, uses the default calibration. 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. 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 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 Conversion between RGB and YIQ. 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. Conversion between RGB and HSV. 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). Conversion between RGB and HSL. The Color type Color operators Applies a color operator to a single pixel to produce a constant color. Making constant colors Constant gray; f is the fraction of absorptance, from 0 (background) to 1 (black). Imager.MakeGray is identical; see MAKEGRAY in the Interpress standard, section 4.7.1. CIE tristimulus values, X, Y, Z, in the range 0 to approximately 100. Red, Green, Blue, in the range 0 to 1. If calibration=NIL, the color is uncalibrated. Returns Interpress-style gray, a fraction of absorptance from 0 (background) to 1 (black). Making sampled colors Κ2˜codešœ™Kšœ Οmœ7™BKšœ(™(—K™šΟk ˜ Kšœžœ˜$Kšœ žœE˜WKšœžœ˜,Kšœžœžœ˜—K˜KšΠbl œžœž ˜šœž˜K˜Kšœžœ'˜;Kšœžœ˜#Kšœžœ˜/Kšœ žœ˜)Kšœ žœ˜)Kšœ žœ˜-Kšœ žœ˜'Kšœ žœ˜/Kšžœžœžœ˜—head™šžœžœžœ žœ˜#KšœM™MKšœV™VK˜—šœžœžœžœ˜)Kšœžœ”™΄K™—šœ1˜1K™5—K˜šΟnœžœžœžœ˜7Kšœ™K˜—š  œžœžœžœžœ˜CKšœ!™!K™—K˜Kšœžœžœ˜-šœžœžœ˜"KšœžœΟc˜Kšœ‘#˜6Kšœ‘%˜:Kšœ‘$˜8Kšœ‘Πck‘ ˜@Kšœžœ‘#˜/Kšœžœ‘6˜VKšœ˜—šœžœ˜KšœT™TK™—š œžœžœ˜5K™?K™—š  œžœžœ>žœžœ˜†K™K™—K˜šžœžœžœ žœ˜#KšœW™WK™—š   œžœžœ žœžœžœ˜MKšœ$žœ™FK™—š   œžœžœ žœžœžœ˜MKšœ$žœ™FKšœL™LK˜—š  œžœ1žœžœžœ˜UKšœJ™JKšœK™KK™—K˜šžœžœžœ žœ˜#KšœS™SKšœR™RK™CK™—Kš   œžœžœžœžœ˜%š   œžœžœžœžœ˜%Kšœ™—K˜šžœžœžœ žœ˜#Kšœ6™6IprocšœN™NMšœB™BK˜—Kš   œžœžœžœžœ˜%š   œžœžœžœžœ˜%Kšœ™—K˜šžœžœžœ žœ˜#Kšœ:™:Mšœ5‘œ'™]Mšœ\™\K˜—Kš   œžœžœžœžœ˜%š   œžœžœžœžœ˜%Kšœ™K™——™Kšœžœžœ ˜šœ žœžœ˜šžœž˜šœ ˜ Kšœ˜Kšœžœžœžœ˜#Kšœ˜—šœ ‘!˜.Kšœ‘˜&Kšœ‘.˜BKšœ‘#˜@K˜—šœ‘!˜3Kšœ‘0˜@Kšœ‘.˜BKšœžœ‘˜)K˜—šœ ‘˜+Kšœžœ˜ Kšœžœ˜ Kšœ‘'˜9Kšœ˜—Kšž˜—K˜K˜—Kšœžœžœ˜,Kšœžœžœ˜*Kšœžœžœ˜/Kšœžœžœ˜*—™Kšœžœžœ˜+šœžœžœ˜!Kšœ žœ˜Kšœžœ˜Kšœžœ˜!Kšœž˜ K˜—šœžœ˜K˜—Kšœ žœžœ˜'šœžœžœ˜Kšœžœ˜ Kšœžœ˜Kšœžœ˜Kšœ˜—šœžœ˜K˜—š œ žœžœžœžœžœ˜/K˜—šœžœžœ1˜KK˜—K˜š œžœ)žœ˜LK™GK™—K˜š œžœNžœ˜~K˜—š œžœažœ˜‘K˜—š œžœcžœ˜™K˜—š  œžœOžœ ˜qK˜——™š  œžœžœžœ˜6K™RKšœ"žœ+™UK˜—š  œžœžœžœ˜6K™EK™—š   œžœžœ žœžœ˜YKšœ7žœ™VK™—Kš   œžœžœ žœžœ˜YKš   œžœžœ žœžœ˜Yš   œžœžœ žœžœ˜YK™—K˜š œžœ:žœ˜jK˜—š œžœMžœ˜}K˜—K˜š  œžœžœžœ˜:K™ZK˜——™š  œžœ-žœžœžœ˜iK˜—š œžœDžœ˜rK˜——K˜Kšžœ˜—…—~&ζ