DIRECTORY Args, CedarProcess, ColorTrixMap, Commander, Controls, ImagerPixelMap, Interminal, IO, Process, Random, Real, Rope, Terminal, ViewerClasses; ColorTrixMapCommandsImpl: CEDAR PROGRAM IMPORTS Args, CedarProcess, ColorTrixMap, Commander, Controls, IO, Process, Random, Real, Rope ~ { OuterData: TYPE ~ Controls.OuterData; Cmap: TYPE ~ ColorTrixMap.Cmap; CmSave: Commander.CommandProc ~ { arg: Rope.ROPE _ Args.GetRope[cmd]; IF arg = NIL THEN RETURN[$Failure, "Save requires a filename as argument"]; ColorTrixMap.Save[ColorTrixMap.Read[], arg]; }; CmLoad: Commander.CommandProc ~ { arg: Rope.ROPE _ Args.GetRope[cmd]; IF arg = NIL THEN RETURN[$Failure, "Filename required as argument"]; IF NOT ColorTrixMap.Load[arg] THEN RETURN[$Failure, "Can't read file."]; }; CmMono: Commander.CommandProc ~ {ColorTrixMap.Mono[]}; CmGamma: Commander.CommandProc ~ { arg: Args.Arg _ Args.ArgReal[cmd]; IF arg.ok THEN ColorTrixMap.Gamma[arg.real] ELSE [] _ Controls.OuterViewer[ name: "Gamma", controls: LIST[Controls.NewControl[name: "gamma", type: horiz, min: 0.0, max: 5.0, init: 2.2, x: 60, y: 10, w: 200, h: 20, detents: LIST[[, 2.2]], proc: Gammaler]]]; }; Gammaler: Controls.ControlProc ~ { IF control.mouse.state = up THEN ColorTrixMap.Gamma[control.val]; }; CmRamp: Commander.CommandProc ~ { args: ARRAY[0..8) OF Args.Arg; FOR i: INT IN [0..8) DO args[i] _ Args.ArgIntRange[cmd, i, 0, 255]; IF NOT args[i].ok THEN RETURN[$Failure, "bad arguments"]; ENDLOOP; ColorTrixMap.Ramp[args[0].int, args[1].int, args[2].int, args[3].int, args[4].int, args[5].int, args[6].int, args[7].int]; }; CmPrint: Commander.CommandProc ~ { cm: Cmap _ ColorTrixMap.Read[]; FOR i: INT IN [0..256) DO cmd.out.PutF["%3g:\t%3g\t%3g\t%3g\n", IO.int[i], IO.int[cm[0][i]], IO.int[cm[1][i]], IO.int[cm[2][i]]]; ENDLOOP; }; CmOnly: Commander.CommandProc ~ { a: Rope.ROPE _ Args.GetRope[cmd]; IF a = NIL THEN RETURN[$Failure, "Only requires an argument"]; SELECT TRUE FROM a.Equal["red"] => ColorTrixMap.PrimaryOnly[red]; a.Equal["green"] => ColorTrixMap.PrimaryOnly[green]; a.Equal["blue"] => ColorTrixMap.PrimaryOnly[blue]; ENDCASE => RETURN[$Failure, "argument one of: red, green, blue."]; }; CmTents: Commander.CommandProc ~ { a: Args.Arg _ Args.ArgInt[cmd]; IF a.ok THEN ColorTrixMap.Tents[a.int] ELSE RETURN[$Failure, "argument needed."]; }; CmSin: Commander.CommandProc ~ { a: Args.Arg; v: ARRAY[0..2] OF REAL; IF Args.NArgs[cmd] < 1 THEN RETURN[$Failure, "argument(s) needed."]; FOR i: NAT IN[0..2] DO a _ Args.ArgReal[cmd, i]; IF NOT a.ok AND i = 0 THEN RETURN[$Failure, "bad argument."]; v[i] _ IF a.ok THEN a.real ELSE v[i-1]; ENDLOOP; ColorTrixMap.Sin[v[0], v[1], v[2]]; }; CmGauss: Commander.CommandProc ~ {ColorTrixMap.Gauss[]}; CmColor: Commander.CommandProc ~ { i, r, g, b: Args.Arg; IF NOT (i _ Args.ArgIntRange[cmd, 0, 0, 255]).ok THEN RETURN[$Failure, "bad arguments"]; IF NOT (r _ Args.ArgIntRange[cmd, 1, 0, 255]).ok THEN RETURN[$Failure, "bad arguments"]; IF NOT (g _ Args.ArgIntRange[cmd, 2, 0, 255]).ok THEN RETURN[$Failure, "bad arguments"]; IF NOT (b _ Args.ArgIntRange[cmd, 3, 0, 255]).ok THEN RETURN[$Failure, "bad arguments"]; ColorTrixMap.WriteEntry[i.int, r.int, g.int, b.int]; }; Restore: Controls.ClickProc ~ { ColorTrixMap.Write[NARROW[NARROW[clientData, OuterData].data]]; }; RestoreAndQuit: Controls.ClickProc ~ { Controls.EndViewer[NARROW[parent, Controls.Viewer].parent]; Process.Pause[Process.MsecToTicks[100]]; ColorTrixMap.Write[NARROW[NARROW[clientData, OuterData].data]]; }; CmCycle: Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; cm: Cmap _ ColorTrixMap.Copy[cmSave]; outer: Controls.Viewer _ Controls.OuterViewer[ name: "Cycle", entries: LIST[["Restore", Restore]], controls: LIST[Controls.NewControl[type: horiz, report: FALSE, x: 60, y: 10, w: 200, h: 20, min: -25.0, max: 25.0, init: 0.0, detents: LIST[[, 0.0]]]], data: cmSave]; TRUSTED {Process.Detach[FORK Cycler[NARROW[outer.data], cm]]}; }; Cycler: PROC [data: Controls.OuterData, cm: Cmap] ~ { CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO abs: REAL _ ABS[data.val]; n: INT _ MAX[1, Real.RoundI[abs]]; IF data.val = 0.0 THEN {Process.Pause[Process.MsecToTicks[100]]; LOOP}; ColorTrixMap.Write[ColorTrixMap.Cycle[cm, IF data.val > 0 THEN n ELSE -n]]; IF abs > 0.01 THEN Process.Pause[Process.MsecToTicks[Real.Round[100.0/abs]]]; ENDLOOP; }; CmNBits: Commander.CommandProc ~ { a: Args.Arg _ Args.ArgInt[cmd]; IF NOT a.ok THEN RETURN[$Failure, "argument needed."]; ColorTrixMap.NBits[ColorTrixMap.Read[], a.int]; }; CmScale: Commander.CommandProc ~ { a: Args.Arg _ Args.ArgReal[cmd]; IF NOT a.ok THEN RETURN[$Failure, "argument needed."]; ColorTrixMap.Scale[ColorTrixMap.Read[], a.real]; }; CmAdd: Commander.CommandProc ~ { a: Args.Arg _ Args.ArgInt[cmd]; IF NOT a.ok THEN RETURN[$Failure, "argument needed."]; ColorTrixMap.Add[ColorTrixMap.Read[], a.int]; }; CmCompose: Commander.CommandProc ~ { cm1, cm2: Cmap; ok1: BOOL _ ColorTrixMap.Load[Args.GetRope[cmd, 0], cm1 _ ColorTrixMap.NewCmap[]]; ok2: BOOL _ ColorTrixMap.Load[Args.GetRope[cmd, 1], cm2 _ ColorTrixMap.NewCmap[]]; IF NOT ok1 OR NOT ok2 THEN RETURN[$Failure, "bad color map name(s)."]; ColorTrixMap.Compose[cm1, cm2]; }; CmInterp: Commander.CommandProc ~ { cmLoad: Cmap _ ColorTrixMap.NewCmap[]; a: Args.Arg _ Args.ArgReal[cmd, 0]; IF NOT a.ok OR NOT ColorTrixMap.Load[Args.GetRope[cmd, 1], cmLoad] THEN RETURN[$Failure, "bad argument(s)."]; ColorTrixMap.Interp[a.real, cmLoad, ColorTrixMap.Read[]]; }; CmScramble: Commander.CommandProc ~ {ColorTrixMap.Scramble[ColorTrixMap.Read[]]}; CmRandom: Commander.CommandProc ~ {ColorTrixMap.Rand[]}; CmShift: Commander.CommandProc ~ { arg: Args.Arg _ Args.ArgInt[cmd]; cmSave: Cmap _ ColorTrixMap.Read[]; IF arg.ok THEN ColorTrixMap.Write[ColorTrixMap.Cycle[ColorTrixMap.Read[], arg.int]] ELSE [] _ Controls.OuterViewer[ name: "Shift", controls: LIST[Controls.NewControl[type: circ, report: FALSE, x: 60, y: 10, w: 80, h: 80, min: 0.0, max: 255.0, init: 0.0, detents: LIST[[, 0.0]], proc: Shifter, data: cmSave]]]; }; Shifter: Controls.ControlProc ~ { cmSave: Cmap _ NARROW[control.data]; cm: Cmap _ ColorTrixMap.ObtainCmap[]; [] _ ColorTrixMap.Copy[cmSave, cm]; ColorTrixMap.Write[ColorTrixMap.Cycle[cm, Real.Round[control.val]]]; ColorTrixMap.ReleaseCmap[cm]; }; CmSpeckle: Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: Controls.Viewer _ Controls.OuterViewer[ name: "Speckle", entries: LIST[ ["Quit", Controls.Quit], ["Restore", Restore], ["Restore&Quit", RestoreAndQuit]], controls: LIST[Controls.NewControl[type: horiz, report: FALSE, x: 60, y: 10, w: 200, h: 20, min: 1.0, max: 0.0, init: 0.5]], data: cmSave]; TRUSTED {Process.Detach[FORK Speckler[NARROW[outer.data]]]}; }; Speckler: PROC [data: Controls.OuterData] ~ { RandInt: PROC RETURNS [INTEGER] ~ {RETURN[Random.ChooseInt[max: 255]]}; CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO Process.Pause[Process.MsecToTicks[Real.Round[100.0*data.val]]]; ColorTrixMap.WriteEntry[RandInt[], RandInt[], RandInt[], RandInt[]]; ENDLOOP; }; CmFlash: Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: ViewerClasses.Viewer _ Controls.OuterViewer[ name: "Flash", entries: LIST[ ["Quit", Controls.Quit], ["Restore", Restore], ["Restore&Quit", RestoreAndQuit]], controls: LIST[Controls.NewControl[type: horiz, report: FALSE, x: 60, y: 10, w: 200, h: 20, min: 1.0, max: 0.0, init: 0.5]], data: cmSave]; TRUSTED {Process.Detach[FORK Flasher[NARROW[outer.data]]]}; }; Flasher: PROC [data: Controls.OuterData] ~ { CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO ColorTrixMap.Rand[]; Process.Pause[Process.MsecToTicks[Real.Round[1000.0*data.val]]]; ENDLOOP; }; CmRipple: Commander.CommandProc ~ { outer: ViewerClasses.Viewer _ Controls.OuterViewer[ name: "Ripple", controls: LIST[ Controls.NewControl[type:horiz,report:FALSE,x:60,y:10,w:200,h:20,min:0.0,max:1.0,init:0.5], Controls.NewControl[type:horiz,report:FALSE,x:60,y:40,w:200,h:20,min:0.0,max:1.0,init:0.5], Controls.NewControl[type:horiz,report:FALSE,x:60,y:70,w:200,h:20,min:0.0,max:1.0,init:0.5], ]]; TRUSTED {Process.Detach[FORK Rippler[NARROW[outer.data]]]}; }; Rippler: PROC [data: Controls.OuterData] ~ { vals: ARRAY [0..2] OF REAL _ ALL[0.0]; cs: ARRAY [0..2] OF Controls.ControlData; incs: ARRAY [0..2] OF INTEGER _ ALL[1]; cs[0] _ data.controls.first; cs[1] _ data.controls.rest.first; cs[2] _ data.controls.rest.rest.first; CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO FOR i: NAT IN[0..2] DO IF vals[i] < 0.25 THEN incs[i] _ 1 ELSE IF vals[i] > 25.0 THEN incs[i] _ -1; vals[i] _ vals[i]+incs[i]*cs[i].val; ENDLOOP; ColorTrixMap.Sin[vals[0], vals[1], vals[2]]; ENDLOOP; }; rec: TYPE ~ RECORD [data: SEQUENCE num: NAT OF Cmap]; CmBlend: Commander.CommandProc ~ { ncm: NAT _ 0; outer: Controls.Viewer; cm: REF rec _ NEW[rec[Args.NArgs[cmd]]]; FOR a: NAT IN[0..Args.NArgs[cmd]) DO Process.CheckForAbort[]; IF ColorTrixMap.Load[Args.GetRope[cmd, a], cm.data[ncm] _ ColorTrixMap.NewCmap[]] THEN ncm _ ncm+1 ELSE cmd.out.PutF["Can't read %g\n", IO.rope[Args.GetRope[cmd, a]]]; ENDLOOP; IF ncm = 0 THEN RETURN; outer _ Controls.OuterViewer[ name: "Color Map Blender", controls: LIST[Controls.NewControl[type: horiz, report: FALSE, x: 60, y: 10, w: 200, h: 20, min: 0.01, max: 1.0, init: 0.1]]]; TRUSTED {Process.Detach[FORK Blender[NARROW[outer.data], cm, ncm]]}; }; Blender: PROC [d: Controls.OuterData, cm: REF rec, ncm: NAT] ~ { inc: INTEGER _ 1; n0, n1: INTEGER _ 0; WHILE NOT d.destroyed DO Process.CheckForAbort[]; IF (n1 _ n0+inc) = -1 OR n1 = ncm THEN {inc _ -inc; n1 _ n0+inc}; FOR t: REAL _ 0, t+d.val WHILE t <= 1.0 DO ColorTrixMap.Interp[t, cm.data[n0], cm.data[n1]]; ENDLOOP; n0 _ n1; ENDLOOP; }; CmSnake: Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: Controls.Viewer _ Controls.OuterViewer[ name: "Snake", entries: LIST[ ["Quit", Controls.Quit], ["Restore", Restore], ["Restore&Quit", RestoreAndQuit]], data: cmSave]; TRUSTED {Process.Detach[FORK Snaker[NARROW[outer.data]]]}; }; Snaker: PROC [data: Controls.OuterData] ~ { r, g, b: REAL; cm: Cmap _ ColorTrixMap.Read[]; CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO [r, g, b] _ GetSnake[]; [] _ ColorTrixMap.Cycle[cm, 1]; ColorTrixMap.SetEntry[cm, 1, Real.RoundI[255*r], Real.RoundI[255*g], Real.RoundI[255*b]]; ColorTrixMap.Write[cm]; ENDLOOP; }; r, g, b: Section; Section: TYPE ~ RECORD [count: INTEGER _ 0, p, d: REAL _ 0.0]; GetSnake: PROC RETURNS [REAL, REAL, REAL] ~ { RandomReal: PROC RETURNS [REAL] ~ { RETURN[(1.0/1024.0)*REAL[Random.ChooseInt[min: 1, max: 1024]]]; }; NewSection: PROC [p: REAL] RETURNS[s: Section] ~ { s.p _ p; s.count _ Random.ChooseInt[min: 5, max: 30]; s.d _ (RandomReal[]-p)/REAL[s.count]; }; IF (r.count _ r.count-1) <= 0 THEN r _ NewSection[r.p]; IF (g.count _ g.count-1) <= 0 THEN g _ NewSection[g.p]; IF (b.count _ b.count-1) <= 0 THEN b _ NewSection[b.p]; r.p _ MAX[0.0, MIN[1.0, r.p+r.d]]; g.p _ MAX[0.0, MIN[1.0, g.p+g.d]]; b.p _ MAX[0.0, MIN[1.0, b.p+b.d]]; RETURN[r.p, g.p, b.p]; }; Commander.Register["CmSave", CmSave, "\nCmSave ."]; Commander.Register["CmLoad", CmLoad, "\nCmLoad ."]; Commander.Register["CmMono", CmMono, "\nPut linear ramp in color map."]; Commander.Register["CmGamma", CmGamma, "\nGamma correct the color map."]; Commander.Register["CmRamp", CmRamp, "\nCmRamp "]; Commander.Register["CmPrint", CmPrint, "\nPrint the color map."]; Commander.Register["CmOnly", CmOnly, "\nCmOnly ."]; Commander.Register["CmTents", CmTents, "\nCmTents ."]; Commander.Register["CmSin", CmSin, "\nCmSin ."]; Commander.Register["CmGauss", CmGauss, "\nPut Gaussian curve in color map."]; Commander.Register["CmColor", CmColor, "\nCmColor ."]; Commander.Register["CmCycle", CmCycle, "\nCycle the color map."]; Commander.Register["CmNBits", CmNBits, "\nCMNBits ."]; Commander.Register["CmScale", CmScale, "\nCmScale ."]; Commander.Register["CmAdd", CmAdd, "\nCmAdd ."]; Commander.Register["CmCompose", CmCompose, "\nCmCompose ."]; Commander.Register["CmInterp", CmInterp, "\nCmInterp ."]; Commander.Register["CmScramble", CmScramble, "\nScramble the color map."]; Commander.Register["CmRandom", CmRandom, "\nRandomize the color map."]; Commander.Register["CmShift", CmShift, "\nRotate the color map."]; Commander.Register["CmSpeckle", CmSpeckle, "\nSpeckle the color map."]; Commander.Register["CmFlash", CmFlash, "\nRandomly change the color map."]; Commander.Register["CmBlend", CmBlend, "\nCmBlend [-s #]."]; Commander.Register["CmRipple", CmRipple, "\nRipple through some sine waves."]; Commander.Register["CmSnake", CmSnake, "\nSnake through color space."]; }. ŒColorTrixMapCommandsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bloomenthal, May 14, 1986 0:49:16 am PDT Κ l˜šœ™Jšœ Οmœ1™šžœžœž˜Jšœ0˜0Jšœ4˜4Jšœ2˜2Icedaršžœžœ1˜B—Jšœ˜J˜—š œ˜"Jšœ˜Jšžœžœžœžœ˜QJšœ˜J˜—š œ˜ Jšœ ˜ Jšœžœžœžœ˜Jšžœžœžœ"˜Dšžœžœžœž˜Jšœ˜Jš žœžœžœžœžœ˜=Jšœžœžœžœ˜'Jšžœ˜—Jšœ#˜#Jšœ˜J˜—š œ1˜8J˜—š œ˜"Jšœ˜Jšžœžœ+žœžœ˜XJšžœ+žœžœ˜XJšžœ+žœžœ˜XJšžœ+žœžœ˜XJšœ4˜4J˜J˜—š œ˜Jšœžœžœ˜?Jšœ˜J˜—š œ˜&Jšœžœ"˜;Jšœ(˜(Jšœžœžœ˜?Jšœ˜J˜—š œ˜"Jšœ#˜#J˜%šœ.˜.Jšœ˜Jšœ žœ˜$Jšœ žœ*žœJžœ ˜—Jšœ˜—Jšžœžœžœ˜>J˜—J˜šΟnœžœ)˜5Jšœ%˜%šžœžœž˜Jšœžœžœ ˜Jšœžœžœ˜"Jšžœžœžœ'ž˜GJšœ*žœ žœžœ˜KJšžœ žœ;˜MJšžœ˜—Jšœ˜—J˜š œ˜"Jšœ˜Jšžœžœžœžœ˜6Jšœ/˜/Jšœ˜J˜—š œ˜"Jšœ ˜ Jšžœžœžœž œ˜6Jšœ0˜0Jšœ˜J˜—š œ˜ Jšœ˜Jšžœžœžœžœ˜6Jšœ-˜-Jšœ˜J˜—š  œ˜$Jšœ˜JšœžœI˜RJšœžœI˜RJš žœžœžœžœžœžœ%˜FJšœ˜Jšœ˜J˜—š œ˜#Jšœ&˜&Jšœ#˜#šžœžœžœžœ0˜BJšžœžœ˜*—Jšœ9˜9Jšœ˜J˜—š  œG˜QJ˜—š œ0˜8J˜—š œ˜"Kšœ!˜!Jšœ#˜#šžœ˜ JšžœE˜Išžœ˜Jšœ˜Jšœ žœ)žœHžœ*˜²——J˜J˜—š‘œ˜!Jšœžœ˜$J˜%J˜#JšœD˜DJ˜Jšœ˜J˜—š  œ˜$Jšœ#˜#šœ.˜.Jšœ˜šœ žœ˜Jšœ˜Jšœ˜Jšœ"˜"—Jšœ žœ*žœ?˜|Jšœ˜—Jšžœžœ žœ˜J˜š ‘œžœžœžœžœžœ˜-š‘ œžœžœžœ˜#Jšžœžœ'˜?J˜—š‘ œžœžœžœ˜2J˜Jšœ,˜,Jšœžœ ˜%J˜—Jšžœžœ˜7Jšžœžœ˜7Jšžœžœ˜7Jšœžœžœ˜"Jšœžœžœ˜"Jšœžœžœ˜"Jšžœ˜Jšœ˜—J˜JšœC˜CJšœC˜CJšœH˜HJšœI˜IJšœK˜KJšœA˜AJšœC˜CJšœC˜CJšœ?˜?JšœM˜MJšœP˜PJšœA˜AJšœB˜BJšœ?˜?Jšœ<˜