Color8Impl.mesa
Mik Lamming - July 15, 1983 4:35 pm
DIRECTORY
ColorMap,
ColorMapImpl,
ColorPackagePrivate,
ConvertUnsafe,
Graphics,
GraphicsOps,
JaMFnsDefs,
Map,
Real,
Rope,
TJaMGraphics;
Color8Impl: CEDAR PROGRAM
IMPORTS ColorMap, ColorMapImpl, ColorPackagePrivate, ConvertUnsafe, Graphics, GraphicsOps, JaMFnsDefs, Map, Real, TJaMGraphics
SHARES ColorMapImpl = BEGIN
table: Map.ColorTable;
palette: Map.PalTable;
Init: PROCEDURE [] = TRUSTED {
JaMFnsDefs.Register["LoadMap"L, JLoadMap];
JaMFnsDefs.Register["ShowRawImage"L, JShowRawImage];
JaMFnsDefs.Register["RestoreMap"L, JRestoreMap];
JaMFnsDefs.Register["RotateMap"L, JRotateMap];
JaMFnsDefs.Register["RotateColors"L, JRotateColors];
};
JLoadMap: PROCEDURE [] = TRUSTED {
s:LONG STRING ← [50];
JaMFnsDefs.PopString[s];
LoadMap[ConvertUnsafe.ToRope[s]];
};
LoadMap: PROCEDURE [file:Rope.ROPE] = TRUSTED {
[table, palette] ← Map.Restore[file];
ColorPackagePrivate.SetNewColorMapProc[PalMapper];
SetUpMap[palette];
};
RestoreMap: PROCEDURE [] = TRUSTED {
ColorPackagePrivate.SetNewColorMapProc[ColorMapImpl.MyGetIndex];
ColorMap.StandardMap[];
};
JRestoreMap: PROCEDURE [] = TRUSTED {
RestoreMap[];
};
JShowRawImage: PROCEDURE [] = TRUSTED {
s:LONG STRING ← [50];
paint: PROC [dc: Graphics.Context] = TRUSTED {
Graphics.DrawImage[self:dc, image:GraphicsOps.NewAisImage[ConvertUnsafe.ToRope[s]], raw:TRUE];
};
JaMFnsDefs.PopString[s];
TJaMGraphics.Painter[paint];
};
PalMapper: ColorPackagePrivate.ColorMapProc = TRUSTED {
RETURN [Map.GetIndex[r,g,b, table]];
};
SetUpMap: PROCEDURE [p:Map.PalTable] = TRUSTED {
FOR palix:CARDINAL IN [0..p.size) DO
ColorMap.SetRGBColor[palix, p[palix].r, p[palix].g, p[palix].b];
ENDLOOP;
};
ToRange: PROC[v: REAL] RETURNS[REAL] = INLINE { IF v IN[0..1] THEN RETURN[v]
ELSE ERROR };
-- ensures that v is in [0..1]; raises BoundsFault if not
HSVToRGB: PROC[h,s,v: REAL] RETURNS[r,g,b: REAL] = {
hue: REAL ← ToRange[h];
saturation: REAL ← ToRange[s];
value: REAL ← ToRange[v];
 ihue: INTEGER;
 fhue,m,n,k: REAL;
 hue ← hue*6;
 ihue ← Real.FixI[hue]; --integer hue
 fhue ← hue-ihue; --fractional hue
IF ihue=6 THEN ihue ← 0;
 m ← value*(1-saturation);
 n ← value*(1-(saturation*fhue));
 k ← value*(1-(saturation*(1-fhue)));
SELECT ihue FROM
  0 => RETURN[value,k,m];
  1 => RETURN[n,value,m];
  2 => RETURN[m,value,k];
  3 => RETURN[m,n,value];
  4 => RETURN[k,m,value];
  5 => RETURN[value,m,n];
  ENDCASE => RETURN[0,0,0];
};


RGBToHSV: PROC[r,g,b: REAL] RETURNS[h,s,v: REAL] = {
max,min,rc,gc,bc: REAL;
r ← ToRange[r]; g ← ToRange[g]; b ← ToRange[b];
 min ← MIN[MIN[r,g],b]; --amount of white
 v ← max ← MAX[MAX[r,g],b]; --maximum "brightness"
IF max#0 THEN s ← (max-min)/max
ELSE s ← 0;
IF s=0 THEN RETURN[0,0,v]; --gray
 rc ← (max - r)/(max - min);
 gc ← (max - g)/(max - min);
 bc ← (max - b)/(max - min);
IF r=max THEN h�-gc
ELSE IF g=max THEN h𡤂+rc-bc
ELSE IF b=max THEN h𡤄+gc-rc;
 h ← h / 6.0;
IF h<0 THEN h←h+1;
};
RotateColors: PROCEDURE [n:INTEGER] = TRUSTED {
lr,lg,lb,h,s,v:REAL;
WHILE n>0 DO
FOR i:CARDINAL DECREASING IN [0..40] DO -- rotate colors
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
h ← i / 40.0 ;
s ← 1.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP; -- NB hue is now 0
FOR pix:CARDINAL IN [0..palette.size) DO -- restore the colors
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
s ← 1.0; v ← 0.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
FOR i:CARDINAL IN [0..20] DO -- restore values
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
v ← v * i/20.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
n ← n - 1;
ENDLOOP;
};
RotateMap: PROCEDURE [n:INTEGER] = TRUSTED {
lr,lg,lb,h,s,v:REAL;
WHILE n>0 DO
FOR i:CARDINAL IN [0..20] DO -- maximise saturations
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
s ← MIN[s + i / 20.0, 1.0] ;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
FOR i:CARDINAL DECREASING IN [0..20] DO -- reduce the saturations to 0
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
s ← i/20.0 ;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
FOR i:CARDINAL IN [0..10] DO -- threshold values around 0.5
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
v ← IF v>0.5 THEN MIN[v+i*0.05, 1.0] ELSE MAX[v-i*0.05, 0.0] ;
s ← 0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
FOR i:CARDINAL DECREASING IN [0..10] DO -- restore values
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
v ← IF v>0.5 THEN MIN[v+i*0.05, 1.0] ELSE MAX[v-i*0.05, 0.0] ;
s ← 0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
FOR pix:CARDINAL IN [0..palette.size) DO -- go red
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
h ← 1.0 ;
s ← 0.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
FOR i:CARDINAL IN [0..20] DO -- maximise saturations
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
s ← i / 20.0 ;
h ← 1.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
FOR i:CARDINAL DECREASING IN [0..40] DO -- rotate colors
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
h ← i / 40.0 ;
s ← 1.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP; -- NB hue is now 0
FOR i:CARDINAL DECREASING IN [0..20] DO -- reduce the value to 0
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
h ← 0.0;
v ← v * i/20.0;
s ← 1.0 ;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
FOR pix:CARDINAL IN [0..palette.size) DO -- restore the colors
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
s ← 1.0; v ← 0.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
FOR i:CARDINAL IN [0..20] DO -- restore values
FOR pix:CARDINAL IN [0..palette.size) DO
OPEN palette[pix];
[h,s,v] ← RGBToHSV[r,g,b];
v ← v * i/20.0;
[lr,lg,lb] ← HSVToRGB[h,s,v];
ColorMap.SetRGBColor[pix, lr,lg,lb];
ENDLOOP;
ENDLOOP;
n ← n - 1;
ENDLOOP;
};
JRotateMap: PROCEDURE [] = TRUSTED {
RotateMap[1];
};
JRotateColors: PROCEDURE [] = TRUSTED {
RotateColors[1];
};
Init[];
END.