JaMIColorImpl:
CEDAR MONITOR
IMPORTS ColorFns, JaM, ImagerBackdoor, ImagerColor, NamedColors, RealFns
EXPORTS JaMIPrivate = {
OPEN J: JaM, P: JaMIPrivate;
ROPE: TYPE = Rope.ROPE;
maxIndex: INTEGER ← MaxIndex[];
TurnOnColor: PROC[state: JaM.State] = {
nbits: INTEGER ← J.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: BOOLEAN ¬ J.PopBool[state];
IF onLeft THEN screenpos ¬ left ELSE screenpos ¬ right;
};
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: REAL ← MAX[MIN[1,J.PopReal[state]],0];
g: REAL ← MAX[MIN[1,J.PopReal[state]],0];
r: REAL ← MAX[MIN[1,J.PopReal[state]],0];
index: INTEGER ← J.PopInt[state];
index ← MAX[MIN[maxIndex,index],0];
[] ← ColorMap.SetRGBColor[index,r,g,b];
};
SetHSVColorMap: 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];
index: INTEGER ← J.PopInt[state];
index ← MAX[MIN[maxIndex,index],0];
[] ← ColorMap.SetHSVColor[index,h,s,v];
};
GetMapValue: PROC [state: JaM.State] = {
index: INTEGER ← J.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];
};
ColorFromName:
PROC [r: Rope.
ROPE]
RETURNS [c: ImagerColor.ConstantColor] ~ {
RETURN [ImagerColor.ColorFromRGB[
ColorFns.RGBFromHSL[NamedColors.RopeToHSL[r]]
]];
};
PopColor:
PROC [self: JaM.State]
RETURNS [ImagerColor.OpConstantColor] ~
TRUSTED {
x: JaM.Any ~ JaM.Pop[self];
WITH x
SELECT
FROM
x: ImagerColor.Color => RETURN[LOOPHOLE[x]];
x: ImagerColor.ConstantColor => RETURN[LOOPHOLE[x]];
x: ImagerColor.OpConstantColor => RETURN[x];
ENDCASE => ERROR JaM.Error[WrongType];
};
Red: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Red"]]};
Green: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Green"]]};
Blue: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Blue"]]};
Magenta: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Magenta"]]};
Cyan: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Cyan"]]};
Yellow: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Vivid Yellow"]]};
Black: PROC [state: JaM.State] = {PushColor[state, ColorFromName["Black"]]};
White: PROC [state: JaM.State] = {PushColor[state, ColorFromName["White"]]};
InvertedColor:
PROC [state: JaM.State] = {
PushColor[state, ImagerBackdoor.invert]
};
Gray: PROC [state: JaM.State] = {PushColor[state, ImagerColor.ColorFromGray[.5]]};
PushColor:
PROC [self:
J.State, x: ImagerColor.ConstantColor] ~ {
IF x#NIL THEN J.Push[self, x]
ELSE ERROR J.Error[WrongType];
};
IColor:
PROC [state: JaM.State] = {
gray: REAL ¬ J.PopReal[state];
gray ¬ MIN[MAX[0,gray],1];
JaM.Push[state, ImagerColor.ColorFromGray[gray]];
};
RGBColor:
PROC [state: JaM.State] = {
b: REAL ¬ MAX[MIN[1,J.PopReal[state]],0];
g: REAL ¬ MAX[MIN[1,J.PopReal[state]],0];
r: REAL ¬ MAX[MIN[1,J.PopReal[state]],0];
JaM.Push[state, ImagerColor.ColorFromRGB[rgb: [r,g,b]]];
};
CMYKColor:
PROC [state: JaM.State] = {
k: REAL = MAX[MIN[1,J.PopReal[state]],0];
y: REAL = MAX[MIN[1,J.PopReal[state]],0];
m: REAL = MAX[MIN[1,J.PopReal[state]],0];
c: REAL = MAX[MIN[1,J.PopReal[state]],0];
JaM.Push[state, ImagerColor.ColorFromCMYK[[c,m,y,k]]];
};
CMYColor:
PROC [state: JaM.State] = {
y: REAL = MAX[MIN[1,J.PopReal[state]],0];
m: REAL = MAX[MIN[1,J.PopReal[state]],0];
c: REAL = MAX[MIN[1,J.PopReal[state]],0];
JaM.Push[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromCMY[[c,m,y]] ]];
};
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 = ColorFns.RGBFromHSV[[h, s, v]];
JaM.Push[state, ImagerColor.ColorFromRGB[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 = ColorFns.RGBFromHSL[[h, s, l]];
JaM.Push[state, ImagerColor.ColorFromRGB[rgb]];
};
HSLFromColor:
PROC [state: JaM.State] = {
color: ImagerColor.OpConstantColor = PopColor[state];
rgb: ImagerColor.RGB ¬ ImagerColor.RGBFromColor[color];
hsl: ColorTypes.HSL ¬ ColorFns.HSLFromRGB[rgb];
JaM.PushReal[state,hsl.H];
JaM.PushReal[state,hsl.S];
JaM.PushReal[state,hsl.L];
};
HSVFromColor:
PROC [state: JaM.State] = {
color: ImagerColor.OpConstantColor = PopColor[state];
rgb: ImagerColor.RGB ¬ ImagerColor.RGBFromColor[color];
hsv: ColorFns.HSV ¬ ColorFns.HSVFromRGB[rgb];
J.PushReal[state,hsv.H];
J.PushReal[state,hsv.S];
J.PushReal[state,hsv.V];
};
RGBFromColor:
PROC [state: JaM.State] = {
color: ImagerColor.OpConstantColor = PopColor[state];
rgb: ImagerColor.RGB ¬ ImagerColor.RGBFromColor[color];
JaM.PushReal[state,rgb.R];
JaM.PushReal[state,rgb.G];
JaM.PushReal[state,rgb.B];
};
GetColorFromName:
PROC [state: JaM.State] = {
name: ROPE ¬ JaM.PopRope[state];
PushColor[state, ColorFromName[name]];
};
FindColor:
PROC [state: JaM.State] = {
name: ROPE ¬ JaM.PopRope[state];
PushColor[state, ImagerColor.Find[name]];
};
Vec3: TYPE = RECORD[v0, v1, v2: REAL];
GetVec3:
PROC[state: JaM.State]
RETURNS[v: Vec3] = {
v.v2 ¬ JaM.PopReal[state];
v.v1 ¬ JaM.PopReal[state];
v.v0 ¬ JaM.PopReal[state];
};
Mix3:
PROC[state: JaM.State]
RETURNS[v: Vec3] = {
pb: REAL ¬ JaM.PopReal[state];
pa: REAL ¬ JaM.PopReal[state];
b: Vec3 ¬ GetVec3[state];
a: Vec3 ¬ GetVec3[state];
v.v0 ¬ MIN[MAX[a.v0*pa+b.v0*pb, 0],1];
v.v1 ¬ MIN[MAX[a.v1*pa+b.v1*pb, 0],1];
v.v2 ¬ MIN[MAX[a.v2*pa+b.v2*pb, 0],1];
};
Interp3:
PROC[state: JaM.State]
RETURNS[v: Vec3] = {
d: REAL ¬ JaM.PopReal[state];
b: Vec3 ¬ GetVec3[state];
a: Vec3 ¬ GetVec3[state];
v.v0 ¬ (1-d)*a.v0+d*b.v0;
v.v1 ¬ (1-d)*a.v1+d*b.v1;
v.v2 ¬ (1-d)*a.v2+d*b.v2;
};
MixRGB:
PROC[state: JaM.State] = {
rgb: ImagerColor.RGB;
[[rgb.R, rgb.G, rgb.B]] ¬ Mix3[state];
PushColor[state, ImagerColor.ColorFromRGB[rgb]];
};
MixHSL:
PROC[state: JaM.State] = {
hsl: ColorFns.HSL;
[[hsl.H, hsl.S, hsl.L]] ¬ Mix3[state];
PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSL[hsl]]];
};
MixHSV:
PROC[state: JaM.State] = {
hsv: ColorFns.HSV;
[[hsv.H, hsv.S, hsv.V]] ¬ Mix3[state];
PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSV[hsv]]];
};
MixCMY:
PROC[state: JaM.State] = {
cmy: ColorFns.CMY;
[[cmy.C, cmy.M, cmy.Y]] ¬ Mix3[state];
PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromCMY[cmy]]];
};
InterpRGB:
PROC[state: JaM.State] = {
rgb: ImagerColor.RGB;
[[rgb.R, rgb.G, rgb.B]] ¬ Interp3[state];
PushColor[state, ImagerColor.ColorFromRGB[rgb]];
};
InterpHSL:
PROC[state: JaM.State] = {
hsl: ColorFns.HSL;
[[hsl.H, hsl.S, hsl.L]] ¬ Interp3[state];
PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSL[hsl]]];
};
InterpHSV:
PROC[state: JaM.State] = {
hsv: ColorFns.HSV;
[[hsv.H, hsv.S, hsv.V]] ¬ Interp3[state];
PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromHSV[hsv]]];
};
InterpCMY:
PROC[state: JaM.State] = {
cmy: ColorFns.CMY;
[[cmy.C, cmy.M, cmy.Y]] ¬ Interp3[state];
PushColor[state, ImagerColor.ColorFromRGB[ColorFns.RGBFromCMY[cmy]]];
};
BlackCursor: PROC [state: JaM.State] = {
[] ← Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreBlack]};
WhiteCursor: PROC [state: JaM.State] = {
[] ← Terminal.SetColorCursorPresentation[Terminal.Current[], onesAreWhite]};
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: REAL ¬ IF r < rMin THEN drMax ELSE RealFns.Log[arg: 1.0/r,base: 10];
dg: REAL ¬ IF g < gMin THEN dgMax ELSE RealFns.Log[arg: 1.0/g,base: 10];
db: REAL ¬ IF 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,".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,".cmykcolor", CMYKColor];
J.Register[state,".cmycolor", CMYColor];
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,".colorfromname", GetColorFromName];
J.Register[state,".findcolor", FindColor];
J.Register[state,".mixRGB", MixRGB];
J.Register[state,".mixHSL", MixHSL];
J.Register[state,".mixHSV", MixHSV];
J.Register[state,".mixCMY", MixCMY];
J.Register[state,".interpRGB", InterpRGB];
J.Register[state,".interpHSL", InterpHSL];
J.Register[state,".interpHSV", InterpHSV];
J.Register[state,".interpCMY", InterpCMY];
J.Register[state,".getcolor", GetColor];
};
}.