DIRECTORY Args, CedarProcess, ColorTrixDispatch, ColorTrixMap, Commander, Controls, ImagerPixelMap, ImagerTerminal, Interminal, InterminalBackdoor, IO, Process, Random, Real, RealFns, Rope, Terminal, ViewerClasses; ColorTrixMapCommandsImpl: CEDAR PROGRAM IMPORTS Args, CedarProcess, ColorTrixDispatch, ColorTrixMap, Controls, ImagerTerminal, InterminalBackdoor, IO, Process, Random, Real, RealFns, Rope ~ BEGIN OuterData: TYPE ~ Controls.OuterData; Cmap: TYPE ~ ColorTrixMap.Cmap; ROPE: TYPE ~ Rope.ROPE; standardButtonList: Controls.ButtonList _ LIST[ ["Quit", Controls.Quit], ["Restore", Restore], ["Restore&Quit", RestoreAndQuit]]; Destroy: Controls.DestroyProc ~ { ColorTrixMap.ReleaseCmap[NARROW[NARROW[outerData, OuterData].data]]; }; 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]]; }; CmSave: PUBLIC 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: PUBLIC 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: PUBLIC Commander.CommandProc ~ {ColorTrixMap.Mono[]}; Gammaler: Controls.ControlProc ~ { IF control.mouse.button = right OR control.mouse.state = up THEN ColorTrixMap.Gamma[control.value]; }; CmGamma: PUBLIC Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; arg: Args.Arg _ Args.ArgReal[cmd]; IF arg.ok THEN ColorTrixMap.Gamma[arg.real] ELSE [] _ Controls.OuterViewer[ name: "Gamma", column: right, buttons: standardButtonList, controls: LIST[Controls.NewControl[name: "gamma", type: hSlider, min: 0.0, max: 5.0, init: 2.2, x: 60, y: 10, w: 200, h: 20, detents: LIST[[, 2.2]], proc: Gammaler]], data: cmSave]; }; CmDither: PUBLIC Commander.CommandProc ~ { ImagerTerminal.SetStandardColorMap[InterminalBackdoor.terminal]; }; CmRamp: PUBLIC 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: PUBLIC 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: PUBLIC 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: PUBLIC Commander.CommandProc ~ { a: Args.Arg _ Args.ArgInt[cmd]; IF a.ok THEN ColorTrixMap.Tents[a.int] ELSE RETURN[$Failure, "argument needed."]; }; CmSin: PUBLIC 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: PUBLIC Commander.CommandProc ~ {ColorTrixMap.Gauss[]}; CmColor: PUBLIC 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]; }; Cycler: PROC [data: Controls.OuterData, cm: Cmap] ~ { control: Controls.Control _ data.controls.first; CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO abs: REAL _ ABS[control.value]; n: INT _ MAX[1, Real.RoundI[abs]]; IF control.value = 0.0 THEN {Process.Pause[Process.MsecToTicks[100]]; LOOP}; ColorTrixMap.Write[ColorTrixMap.Cycle[cm, IF control.value > 0 THEN n ELSE -n]]; IF abs > 0.01 THEN Process.Pause[Process.MsecToTicks[Real.Round[100.0/abs]]]; ENDLOOP; }; CmCycle: PUBLIC Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; cm: Cmap _ ColorTrixMap.Copy[cmSave]; outer: Controls.Viewer _ Controls.OuterViewer[ name: "Cycle", column: right, buttons: standardButtonList, controls: LIST[Controls.NewControl[type: hSlider, 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]]}; }; NBitser: Controls.ControlProc ~ { cm: Cmap _ ColorTrixMap.ObtainCmap[]; ColorTrixMap.Mono[cm]; ColorTrixMap.NBits[cm, Real.Round[control.value]]; ColorTrixMap.ReleaseCmap[cm]; }; CmNBits: PUBLIC Commander.CommandProc ~ { arg: Args.Arg _ Args.ArgInt[cmd]; IF arg.ok THEN ColorTrixMap.NBits[ColorTrixMap.Read[], arg.int] ELSE [] _ Controls.OuterViewer[ name: "CmNBits", column: right, buttons: standardButtonList, controls: LIST[Controls.NewControl[type: hSlider, x: 60, y: 10, w: 80, h: 20, min: 1.0, max: 8.0, init: 8.0, truncate: TRUE, proc: NBitser]], data: ColorTrixMap.Read[]]; }; CmScale: PUBLIC Commander.CommandProc ~ { a: Args.Arg _ Args.ArgReal[cmd]; IF NOT a.ok THEN RETURN[$Failure, "argument needed."]; ColorTrixMap.Scale[ColorTrixMap.Read[], a.real]; }; CmAdd: PUBLIC Commander.CommandProc ~ { a: Args.Arg _ Args.ArgInt[cmd]; IF NOT a.ok THEN RETURN[$Failure, "argument needed."]; ColorTrixMap.Add[ColorTrixMap.Read[], a.int]; }; CmCompose: PUBLIC 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: PUBLIC 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: PUBLIC Commander.CommandProc ~ {ColorTrixMap.Scramble[ColorTrixMap.Read[]]}; CmRandom: PUBLIC Commander.CommandProc ~ {ColorTrixMap.Rand[]}; Shifter: Controls.ControlProc ~ { cm: Cmap _ ColorTrixMap.ObtainCmap[]; shift: INTEGER _ Real.Round[control.valuePrev]-Real.Round[control.value]; ColorTrixMap.Write[ColorTrixMap.Cycle[ColorTrixMap.Read[cm], shift]]; ColorTrixMap.ReleaseCmap[cm]; }; ShiftRestore: Controls.ClickProc ~ { outerData: OuterData _ NARROW[clientData]; ColorTrixMap.Write[NARROW[outerData.data]]; Controls.Reset[outerData.controls.first]; }; CmShift: PUBLIC Commander.CommandProc ~ { arg: Args.Arg _ Args.ArgInt[cmd]; cm: Cmap _ ColorTrixMap.Read[]; IF arg.ok THEN ColorTrixMap.Write[ColorTrixMap.Cycle[ColorTrixMap.Read[], arg.int]] ELSE [] _ Controls.OuterViewer[ name: "Shift", column: right, buttons: LIST[["Restore", ShiftRestore], ["Restore&Quit", RestoreAndQuit]], destroyProc: Destroy, controls: LIST[Controls.NewControl[type: dial, 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: cm]], data: cm]; }; 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.controls.first.value]]]; ColorTrixMap.WriteEntry[RandInt[], RandInt[], RandInt[], RandInt[]]; ENDLOOP; }; CmSpeckle: PUBLIC Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: Controls.Viewer _ Controls.OuterViewer[ name: "Speckle", column: right, buttons: standardButtonList, controls: LIST[Controls.NewControl[ type: hSlider, 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]]]}; }; Flasher: PROC [data: Controls.OuterData] ~ { CedarProcess.SetPriority[background]; WHILE NOT data.destroyed DO ColorTrixMap.Rand[]; Process.Pause[Process.MsecToTicks[Real.Round[1000.0*data.controls.first.value]]]; ENDLOOP; }; CmFlash: PUBLIC Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: ViewerClasses.Viewer _ Controls.OuterViewer[ name: "Flash", column: right, buttons: standardButtonList, controls: LIST[Controls.NewControl[type: hSlider, 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]]]}; }; Rippler: PROC [data: Controls.OuterData] ~ { cmOut: Cmap _ ColorTrixMap.ObtainCmap[]; vals: ARRAY [0..2] OF REAL _ ALL[0.0]; cs: ARRAY [0..2] OF Controls.Control; 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]; 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].value; ENDLOOP; ColorTrixMap.Sin[vals[0], vals[1], vals[2], cmOut]; IF data.destroyed THEN EXIT; ColorTrixMap.Write[cmOut]; ENDLOOP; ColorTrixMap.ReleaseCmap[cmOut]; }; CmRipple: PUBLIC Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: ViewerClasses.Viewer _ Controls.OuterViewer[ name: "Ripple", column: right, buttons: standardButtonList, controls: LIST[ Controls.NewControl[type:hSlider,report:FALSE,x:60,y:10,w:200,h:20,min:0.,max:1.,init:0.5], Controls.NewControl[type:hSlider,report:FALSE,x:60,y:40,w:200,h:20,min:0.,max:1.,init:0.5], Controls.NewControl[type:hSlider,report:FALSE,x:60,y:70,w:200,h:20,min:0.,max:1.,init:0.5]], data: cmSave]; TRUSTED {Process.Detach[FORK Rippler[NARROW[outer.data]]]}; }; rec: TYPE ~ RECORD [data: SEQUENCE num: NAT OF Cmap]; 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.controls.first.value WHILE t <= 0.5*3.1415926535 DO IF d.destroyed THEN EXIT; ColorTrixMap.Interp[RealFns.Sin[t], cm.data[n0], cm.data[n1]]; ENDLOOP; n0 _ n1; ENDLOOP; }; CmBlend: PUBLIC Commander.CommandProc ~ { ncm: NAT _ 0; outer: Controls.Viewer; cmSave: Cmap _ ColorTrixMap.Read[]; 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", column: right, buttons: standardButtonList, controls: LIST[Controls.NewControl[type: hSlider, report: FALSE, x: 60, y: 10, w: 200, h: 20, min: 0.01, max: 1.0, init: 0.1]], data: cmSave]; TRUSTED {Process.Detach[FORK Blender[NARROW[outer.data], cm, ncm]]}; }; 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; }; CmSnake: PUBLIC Commander.CommandProc ~ { cmSave: Cmap _ ColorTrixMap.Read[]; outer: Controls.Viewer _ Controls.OuterViewer[ name: "Snake", column: right, buttons: standardButtonList, data: cmSave]; TRUSTED {Process.Detach[FORK Snaker[NARROW[outer.data]]]}; }; 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]; }; CmContours: PUBLIC Commander.CommandProc ~ { ok: BOOL; nCyclesArg, powerArg: Args.Arg; twoPI: REAL ~ 2.0*3.1415926535; halfPI: REAL ~ 0.5*3.1415926535; [ok, nCyclesArg, powerArg] _ Args.ArgsGet[cmd, "-power%r-ncycles%r"]; IF ok THEN { nCycles: REAL ~ IF nCyclesArg.ok THEN nCyclesArg.real ELSE 4.0; power: REAL ~ 1.0/(IF powerArg.ok THEN powerArg.real ELSE 6.0); FOR n: NAT IN [0..255] DO cmapValue: INT; t: REAL ~ REAL[n]/255.0; intensity: REAL _ 0.5+0.5*RealFns.Sin[(nCycles*twoPI+halfPI)*RealFns.Power[t, power]]; intensity _ t+(1.0-t)*intensity; cmapValue _ Real.RoundI[intensity*255.0]; ColorTrixMap.WriteEntry[n, cmapValue, cmapValue, cmapValue]; ENDLOOP; ColorTrixMap.JustWritten[]; }; }; CmToOthers: PUBLIC Commander.CommandProc ~ { source: Rope.ROPE ~ Args.GetRope[cmd]; i0dst, i1dst, isrc: INT _ -1; SELECT TRUE FROM Rope.Equal[source, "red", FALSE] => {isrc _ 0; i0dst _ 1; i1dst _ 2}; Rope.Equal[source, "grn", FALSE] => {isrc _ 1; i0dst _ 0; i1dst _ 2}; Rope.Equal[source, "blu", FALSE] => {isrc _ 2; i0dst _ 0; i1dst _ 1}; ENDCASE; IF isrc # -1 THEN { cmap: ColorTrixMap.Cmap _ ColorTrixMap.Read[]; FOR n: NAT IN [0..255] DO cmap[i0dst][n] _ cmap[i1dst][n] _ cmap[isrc][n]; ENDLOOP; ColorTrixMap.Write[cmap]; ColorTrixMap.JustWritten[]; }; }; cmSaveUsage: ROPE ~ "Cm Save ."; cmLoadUsage: ROPE ~ "Cm Load ."; cmMonoUsage: ROPE ~ "Cm Mono: set the color map to a linear ramp."; cmGammaUsage: ROPE ~ "Cm Gamma [value]: if no argument, interactive."; cmDitherUsage: ROPE ~ "Cm Dither: set color to Imager.StandardMap."; cmRampUsage: ROPE ~ "Cm Ramp ."; cmPrintUsage: ROPE ~ "Cm Print: print the color map contents."; cmOnlyUsage: ROPE ~ "Cm Only ."; cmTentsUsage: ROPE ~ "Cm Tents ."; cmSinUsage: ROPE ~ "Cm Sin ."; cmGaussUsage: ROPE ~ "Cm Gauss: put a gaussian in color map."; cmColorUsage: ROPE ~ "Cm Color : Set color map entry i."; cmCycleUsage: ROPE ~ "Cm Cycle: interactively cycle color map."; cmNBitsUsage: ROPE ~ "Cm NBits [nBits]: if no argument, interactive."; cmScaleUsage: ROPE ~ "Cm Scale ."; cmAddUsage: ROPE ~ "Cm Add ."; cmComposeUsage: ROPE ~ "Cm Compose : result _ c2[c1]."; cmInterpUsage: ROPE ~ "Cm Interp ."; cmScrambleUsage: ROPE ~ "Cm Scramble: randomly interchange entries."; cmRandomUsage: ROPE ~ "Cm Random: randomize the color map."; cmShiftUsage: ROPE ~ "Cm Shift [n]: in no argument, interactive."; cmSpeckleUsage: ROPE ~ "Cm Speckle: randomly set single entries."; cmFlashUsage: ROPE ~ "Cm Flash: interactively randomize color map."; cmBlendUsage: ROPE ~ "Cm Blend : continuously blend."; cmRippleUsage: ROPE ~ "Cm Ripple: interactively ripple sine waves."; cmSnakeUsage: ROPE ~ "Cm Snake: snake through color space."; cmToOthersUsage: ROPE ~ "Cm ToOthers one component to other two."; cmContoursUsage: ROPE ~ "Cm Contours [-power ] [-ncycles ] show contours."; ColorTrixDispatch.RegisterCmOp["Save", CmSave, cmSaveUsage]; ColorTrixDispatch.RegisterCmOp["Load", CmLoad, cmLoadUsage]; ColorTrixDispatch.RegisterCmOp["Mono", CmMono, cmMonoUsage]; ColorTrixDispatch.RegisterCmOp["Gamma", CmGamma, cmGammaUsage]; ColorTrixDispatch.RegisterCmOp["Dither", CmDither, cmDitherUsage]; ColorTrixDispatch.RegisterCmOp["Ramp", CmRamp, cmRampUsage]; ColorTrixDispatch.RegisterCmOp["Print", CmPrint, cmPrintUsage]; ColorTrixDispatch.RegisterCmOp["Only", CmOnly, cmOnlyUsage]; ColorTrixDispatch.RegisterCmOp["Tents", CmTents, cmTentsUsage]; ColorTrixDispatch.RegisterCmOp["Sin", CmSin, cmSinUsage]; ColorTrixDispatch.RegisterCmOp["Gauss", CmGauss, cmGaussUsage]; ColorTrixDispatch.RegisterCmOp["Color", CmColor, cmColorUsage]; ColorTrixDispatch.RegisterCmOp["Cycle", CmCycle, cmCycleUsage]; ColorTrixDispatch.RegisterCmOp["NBits", CmNBits, cmNBitsUsage]; ColorTrixDispatch.RegisterCmOp["Scale", CmScale, cmScaleUsage]; ColorTrixDispatch.RegisterCmOp["Add", CmAdd, cmAddUsage]; ColorTrixDispatch.RegisterCmOp["Compose", CmCompose, cmComposeUsage]; ColorTrixDispatch.RegisterCmOp["Interp", CmInterp, cmInterpUsage]; ColorTrixDispatch.RegisterCmOp["Scramble", CmScramble, cmScrambleUsage]; ColorTrixDispatch.RegisterCmOp["Random", CmRandom, cmRandomUsage]; ColorTrixDispatch.RegisterCmOp["Shift", CmShift, cmShiftUsage]; ColorTrixDispatch.RegisterCmOp["Speckle", CmSpeckle, cmSpeckleUsage]; ColorTrixDispatch.RegisterCmOp["Flash", CmFlash, cmFlashUsage]; ColorTrixDispatch.RegisterCmOp["Blend", CmBlend, cmBlendUsage]; ColorTrixDispatch.RegisterCmOp["Ripple", CmRipple, cmRippleUsage]; ColorTrixDispatch.RegisterCmOp["Snake", CmSnake, cmSnakeUsage]; ColorTrixDispatch.RegisterCmOp["ToOthers", CmToOthers, cmToOthersUsage]; ColorTrixDispatch.RegisterCmOp["Contours", CmContours, cmContoursUsage]; END. ΎColorTrixMapCommandsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bloomenthal, January 16, 1987 11:59:00 pm PST Miscellany Commands Usage Messages Start Code Κύ˜šœ™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˜—š‘œžœ0˜?J˜—š‘œžœ˜)Jšœ˜Jšžœžœ+žœžœ˜XJšžœžœ+žœžœ˜XJšžœžœ+žœžœ˜XJšžœžœ+žœžœ˜XJšœ4˜4J˜—J˜š œžœ)˜5J˜0Jšœ%˜%šžœžœž˜Jšœžœžœ˜Jšœžœžœ˜"Jšžœžœ+žœ˜LJšœ*žœžœžœ˜PJšžœ žœ;˜MJšžœ˜—Jšœ˜J˜—š‘œžœ˜)Jšœ#˜#J˜%šœ.˜.Jšœ˜J˜J˜Jšœ žœ,žœJžœ ˜™Jšœ˜—Jšžœžœžœ˜>J˜—J˜š œ˜!J˜%Jšœ˜Jšœ2˜2J˜Jšœ˜J˜—š‘œžœ˜)Lšœ!˜!šžœ˜ Jšžœ1˜5šžœ˜Jšœ˜J˜J˜Jšœ žœižœ˜Jšœ˜——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˜—š‘ œžœF˜XJ˜—š‘œžœ/˜?J˜—š œ˜!Jšœ%˜%Jšœžœ;˜IJšœE˜ELšœ˜Jšœ˜J˜—š‘ œ˜$Jšœžœ ˜*Jšœžœ˜+J˜)Jšœ˜J˜—š‘œžœ˜)Lšœ!˜!Jšœ˜šžœ˜ JšžœE˜Išžœ˜Jšœ˜J˜Jšœ žœ>˜KJ˜Jšœ žœ)žœHžœ%˜­Jšœ ˜ ——J˜J˜—š‘œžœ˜-Jš  œžœžœžœžœ˜GJšœ%˜%šžœžœž˜JšœP˜PJ˜DJšžœ˜—J˜J˜—š‘ œžœ˜+Jšœ#˜#šœ.˜.Jšœ˜J˜J˜šœ žœ˜#Jšœžœ?˜[—Jšœ˜—Jšžœžœ žœ˜˜>Jšžœ˜—Jšœ˜Jšžœ˜—J˜J˜—š‘œžœ˜)Jšœžœ˜ Jšœ˜Jšœ#˜#Lšœžœžœ˜(L˜šžœžœžœž˜$Jšœ˜šžœO˜QLšžœ ˜Lšžœ!žœ˜D—Lšžœ˜—Jšžœ žœžœ˜šœ˜Jšœ˜J˜J˜Jšœ žœ,žœ@˜Jšœ˜—Jšžœžœ žœ˜DJ˜—J™š œžœ˜+Jšœ žœ˜Jšœ˜Jšœ%˜%šžœžœž˜Jšœ˜Jšœ˜JšœY˜YJ˜Jšžœ˜ —Jšœ˜J˜—š‘œžœ˜)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šœžœ˜ J˜Jšœžœ˜Jšœžœ˜ J˜Ešžœžœ˜ Jš œ žœžœžœžœ˜?Jš œžœžœ žœžœ˜?šžœžœžœ ž˜Jšœ žœ˜Jšœžœžœ ˜Jšœ žœG˜VJ˜ Jšœ)˜)Jšœ<˜Jšœžœ0˜DJšœžœ.˜DJšœžœ2˜FJšœžœ£œ ˜FJšœžœ1˜FJšœžœ*˜>Jšœžœ?˜UJšœžœB˜X—š’ ™ Jšœ@˜@Jšœ@˜@Jšœ@˜@JšœA˜AJšœD˜DJšœ@˜@JšœC˜CJšœ@˜@JšœC˜CJšœ=˜=JšœC˜CJšœC˜CJšœC˜CJšœC˜CJšœC˜CJšœ=˜=JšœG˜GJšœD˜DJšœJ˜JJšœD˜DJšœC˜CJšœG˜GJšœC˜CJšœC˜CJšœD˜DJšœC˜CJšœJ˜JJšœJ˜J—Jšžœ˜J˜J˜—…—EΤX