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: 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;
};
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: 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];
};
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: 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]]];
};
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: 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,".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];
};
}.