JaMIColorImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
last edited by Maureen Stone August 14, 1984 6:25:02 pm PDT
Tim Diebert: August 1, 1985 1:55:30 pm PDT
Last edited by: Mik Lamming - June 20, 1986 11:24:24 am PDT
Alfred Permuy July 1, 1986 2:38:54 pm PDT
DIRECTORY
ImagerColor,
ImagerColorDefs USING [ConstantColor],
ImagerColorPrivate,
RealFns USING [AlmostZero, Log, Power],
JaMIPrivate,
JaM USING [Any, Error, Pop, PopInt, PopReal, Register, PopBool, PushReal, State, Push],
Terminal USING [Current, GetColorMode, SetColorCursorPresentation, ColorMode],
WindowManager USING[StartColorViewers, StopColorViewers, ScreenPos];
JaMIColorImpl: CEDAR MONITOR
IMPORTS JaM, ImagerColor, ImagerColorPrivate, WindowManager, Terminal, RealFns
EXPORTS JaMIPrivate = {
OPEN J: JaM, P: JaMIPrivate;
maxIndex: INTEGER ← MaxIndex[];
TurnOnColor: PROC[state: JaM.State] = {
nbits: INTEGERJ.PopInt[state];
SELECT nbits FROM
0 => WindowManager.StopColorViewers[];
1 => WindowManager.StartColorViewers[screenpos,1];
2 => WindowManager.StartColorViewers[screenpos,2];
4 => WindowManager.StartColorViewers[screenpos,4];
8 => WindowManager.StartColorViewers[screenpos,8];
24 => WindowManager.StartColorViewers[screenpos,24];
ENDCASE;
maxIndex ← MaxIndex[];
};
MaxIndex: PROC RETURNS[max: CARDINAL] = {
mode: Terminal.ColorMode ← Terminal.GetColorMode[Terminal.Current[]];
max ←
IF NOT mode.full THEN SELECT mode.bitsPerPixelChannelA FROM
1 => 1, 2 => 3, 4 => 15, 8 => 255, ENDCASE => 0
ELSE 0;
};
TurnOffColor: PROC [state: JaM.State] = {WindowManager.StopColorViewers[]};
screenpos: WindowManager.ScreenPos ← left;
OnLeft: PROC [state: JaM.State] = {
onLeft: BOOLEANJ.PopBool[state];
IF onLeft THEN screenpos ← left ELSE screenpos ← right;
};
Rainbow: PROCEDURE [state: JaM.State] = {
fully saturated rainbow in the even values. grays in the odd values
i: NAT ← 2;
scaler: REAL ← 1.0/maxIndex;
ColorMap.StandardMap[]; --odd values are gray
UNTIL i>maxIndex DO
ColorMap.SetHSVColor[i,i*scaler,1,1];
i ← i+2;
ENDLOOP;
};
GrayMap: PROCEDURE [state: JaM.State] = {ColorMap.GrayMap[]};
StandardMap: PROCEDURE [state: JaM.State] = {ColorMap.StandardMap[]};
SetGamma: PROC [state: JaM.State] = {ColorMap.SetGamma[J.PopReal[state]]};
GetGamma: PROC [state: JaM.State] = {J.PushReal[state, ColorMap.GetGamma[]]};
SetRGBColorMap: PROC [state: JaM.State] = {
b: REALMAX[MIN[1,J.PopReal[state]],0];
g: REALMAX[MIN[1,J.PopReal[state]],0];
r: REALMAX[MIN[1,J.PopReal[state]],0];
index: INTEGERJ.PopInt[state];
index ← MAX[MIN[maxIndex,index],0];
[] ← ColorMap.SetRGBColor[index,r,g,b];
};
SetHSVColorMap: PROC [state: JaM.State] = {
v: REALMAX[MIN[1,J.PopReal[state]],0];
s: REALMAX[MIN[1,J.PopReal[state]],0];
h: REALMAX[MIN[1,J.PopReal[state]],0];
index: INTEGERJ.PopInt[state];
index ← MAX[MIN[maxIndex,index],0];
[] ← ColorMap.SetHSVColor[index,h,s,v];
};
GetMapValue: PROC [state: JaM.State] = {
index: INTEGERJ.PopInt[state];
r,g,b: REAL;
[r,g,b] ← ColorMap.GetColor[MAX[MIN[maxIndex,index],0]];
J.PushReal[state,r/255.0];
J.PushReal[state,g/255.0];
J.PushReal[state,b/255.0];
};
PopColor: PROC [self: JaM.State] RETURNS [ImagerColor.ConstantColor] ~ TRUSTED {
x: JaM.Any ~ JaM.Pop[self];
WITH x SELECT FROM
x: ImagerColor.Color => RETURN[LOOPHOLE[x]];
x: ImagerColor.ConstantColor => RETURN[x];
ENDCASE => ERROR JaM.Error[WrongType];
};
Red: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Red]]};
Green: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Green]]};
Blue: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Blue]]};
Magenta: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Magenta]]};
Cyan: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Cyan]]};
Yellow: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Yellow]]};
Black: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$Black]]};
White: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromAtom[$White]]};
InvertedColor: PROC [state: JaM.State] = {
PushColor[state, ImagerColor.ColorFromAtom[$Invert]]
};
Gray: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromGray[.5]]};
PushColor: PROC [self: J.State, x: ImagerColorDefs.ConstantColor] ~ {
IF x#NIL THEN J.Push[self, x]
ELSE ERROR J.Error[WrongType];
};
IColor: PROC [state: JaM.State] = {
gray: REALJ.PopReal[state];
gray ← MIN[MAX[0,gray],1];
JaM.Push[state, ImagerColor.ColorFromGray[gray]];
};
RGBColor: PROC [state: JaM.State] = {
b: REALMAX[MIN[1,J.PopReal[state]],0];
g: REALMAX[MIN[1,J.PopReal[state]],0];
r: REALMAX[MIN[1,J.PopReal[state]],0];
JaM.Push[state, ImagerColor.ColorFromRGB[rgb: [r,g,b]]];
};
HSVColor: PROC [state: JaM.State] = {
v: REAL = MAX[MIN[1,J.PopReal[state]],0];
s: REAL = MAX[MIN[1,J.PopReal[state]],0];
h: REAL = MAX[MIN[1,J.PopReal[state]],0];
rgb: ImagerColor.RGB = ImagerColor.RGBFromHSV[[h, s, v]];
JaM.Push[state, ImagerColor.ColorFromRGB[rgb: rgb]];
};
HSLColor: PROC [state: JaM.State] = {
l: REAL = MAX[MIN[1,J.PopReal[state]],0];
s: REAL = MAX[MIN[1,J.PopReal[state]],0];
h: REAL = MAX[MIN[1,J.PopReal[state]],0];
rgb: ImagerColor.RGB = ImagerColor.RGBFromHSL[[h, s, l]];
JaM.Push[state, ImagerColor.ColorFromRGB[rgb: rgb]];
};
HSLFromColor: PROC [state: JaM.State] = {
color: ImagerColor.ConstantColor = PopColor[state];
h,s,l: REAL;
r, g, b: REAL;
r← ImagerColorPrivate.ComponentFromColor[color, $Red];
g← ImagerColorPrivate.ComponentFromColor[color, $Green];
b← ImagerColorPrivate.ComponentFromColor[color, $Blue];
[[h, s, l]] ← ImagerColor.HSLFromRGB[[r, g, b]];
JaM.PushReal[state,h];
JaM.PushReal[state,s];
JaM.PushReal[state,l];
};
HSVFromColor: PROC [state: JaM.State] = {
h,s,v: REAL;
color: ImagerColor.ConstantColor = PopColor[state];
r, g, b: REAL;
r← ImagerColorPrivate.ComponentFromColor[color, $Red];
g← ImagerColorPrivate.ComponentFromColor[color, $Green];
b← ImagerColorPrivate.ComponentFromColor[color, $Blue];
[[h, s, v]] ← ImagerColor.HSVFromRGB[[r, g, b]];
J.PushReal[state,h];
J.PushReal[state,s];
J.PushReal[state,v];
};
RGBFromColor: PROC [state: JaM.State] = {
color: ImagerColor.ConstantColor = PopColor[state];
r,g,b: REAL;
r← ImagerColorPrivate.ComponentFromColor[color, $Red];
g← ImagerColorPrivate.ComponentFromColor[color, $Green];
b← ImagerColorPrivate.ComponentFromColor[color, $Blue];
JaM.PushReal[state,r];
JaM.PushReal[state,g];
JaM.PushReal[state,b];
};
BlackCursor: PROC [state: JaM.State] = {
[] ← Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreBlack]};
WhiteCursor: PROC [state: JaM.State] = {
[] ← Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreWhite]};
SetDisplayAtom: PROC [state: JaM.State] = {
bits: INT ← JaM.PopInt[state];
atom: ATOM ← JaM.RopeToAtom[JaM.PopRope[state]];
type: ImagerBridgeExtras.DisplayAtom ← SELECT bits FROM
1 => lf, 2 => bits2, 4 => bits4, 8 => bits8, 24 => bits24, ENDCASE => ERROR;
ImagerBridgeExtras.SetDisplayAtom[type, atom];
};
drMax: REAL ← 1.385;
dgMax: REAL ← 1.032;
dbMax: REAL ← 1.13;
rMin: REAL ← 0.041;
gMin: REAL ← 0.09;
bMin: REAL ← 0.074;
RGBForVtec: PROC [state: JaM.State] = {
b: REAL ← JaM.PopReal[state];
g: REAL ← JaM.PopReal[state];
r: REAL ← JaM.PopReal[state];
a value of 0 is an infinite density. need infinity and zero values to keep values in bounds
dr: REALIF r < rMin THEN drMax ELSE RealFns.Log[arg: 1.0/r,base: 10];
dg: REALIF g < gMin THEN dgMax ELSE RealFns.Log[arg: 1.0/g,base: 10];
db: REALIF b < bMin THEN dbMax ELSE RealFns.Log[arg: 1.0/b,base: 10];
newDr, newDg, newDb: REAL;
newDr ← dr*0.8038-dg*0.1154-db*0.0999;
newDg ← dr*(-0.5522)+dg*1.1776-db*0.119;
newDb ← dr*0.1035-dg*0.7085+db*0.9906;
JaM.PushReal[state, ClipRange[RealFns.Power[base: 10, exponent: -1*newDr]]];
JaM.PushReal[state, ClipRange[RealFns.Power[base: 10, exponent: -1*newDg]]];
JaM.PushReal[state, ClipRange[RealFns.Power[base: 10, exponent: -1*newDb]]];
};
ClipRange: PROC [v: REAL] RETURNS[REAL] = {
RETURN[MIN[MAX[0,v],1]];
};
Defuzz: PROC [v: REAL] RETURNS[REAL] = {
IF RealFns.AlmostZero[v,-10] THEN v ← 0;
IF RealFns.AlmostZero[v-1.0,-10] THEN v ← 1;
RETURN[v];
};
Initialization starts here
RegisterColor: PUBLIC PROC[state: JaM.State] = {
J.Register[state, ".displayatom", SetDisplayAtom];
J.Register[state,".turnoncolor",TurnOnColor];
J.Register[state,".turnoffcolor",TurnOffColor];
J.Register[state,".onleft",OnLeft];
J.Register[state,".rainbow",Rainbow];
J.Register[state,".graymap",GrayMap];
J.Register[state,".standardmap",StandardMap];
J.Register[state,".setgamma",SetGamma];
J.Register[state,".getgamma",GetGamma];
J.Register[state,".setrgbmap",SetRGBColorMap];
J.Register[state,".sethsvmap", SetHSVColorMap];
J.Register[state,".getmapvalue", GetMapValue];
J.Register[state,".red", Red];
J.Register[state,".green", Green];
J.Register[state,".blue", Blue];
J.Register[state,".magenta", Magenta];
J.Register[state,".cyan", Cyan];
J.Register[state,".yellow", Yellow];
J.Register[state,".black", Black];
J.Register[state,".white", White];
J.Register[state,".gray", Gray];
J.Register[state,".invertedcolor", InvertedColor];
J.Register[state,".icolor", IColor];
J.Register[state,".rgbcolor", RGBColor];
J.Register[state,".hsvcolor", HSVColor];
J.Register[state,".hslcolor", HSLColor];
J.Register[state,".hsvfromcolor", HSVFromColor];
J.Register[state,".rgbfromcolor", RGBFromColor];
J.Register[state,".hslfromcolor", HSLFromColor];
J.Register[state,".rgbforvtec", RGBForVtec];
J.Register[state,".blackcursor", BlackCursor];
J.Register[state,".whitecursor", WhiteCursor];
J.Register[state,".getcolor", GetColor];
};
}.