ColorTrixCommandsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, January 17, 1987 0:12:17 am PST
DIRECTORY Args, ColorTrixBasics, ColorTrixDispatch, ColorTrixFile, ColorTrixMap, ColorTrixMod, ColorTrixPalette, ColorTrixPix, Commander, FileNames, ImagerPixelMap, IO, PixelMapOps, Rope, Terminal, ViewerClasses;
ColorTrixCommandsImpl: CEDAR PROGRAM
IMPORTS Args, ColorTrixBasics, ColorTrixDispatch, ColorTrixFile, ColorTrixMap, ColorTrixMod, ColorTrixPalette, ColorTrixPix, FileNames, ImagerPixelMap, IO, PixelMapOps, Rope
~ BEGIN
ROPE:     TYPE ~ Rope.ROPE;
PixelMap:    TYPE ~ ColorTrixBasics.PixelMap;
PixelMapMisc:  TYPE ~ ColorTrixBasics.PixelMapMisc;
DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle;
Cmap:      TYPE ~ ColorTrixMap.Cmap;
palOn:    BOOLFALSE;
File IO Commands
CtView: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
name, center, clear, cmap, aisX, aisY, aisW, aisH, dum: Args.Arg;
[ok, name, center, clear, cmap, aisX, aisY, aisW, aisH, dum, dum, dum, dum]
← Args.ArgsGet[cmd, "%s-center%b-clear%b-cmap%s-a%iiii-w%iiii"];
IF NOT ok
THEN RETURN[$Failure, NIL]
ELSE {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
x: CARDINALIF aisX.ok THEN aisX.int ELSE 0;
y: CARDINALIF aisY.ok THEN aisY.int ELSE 0;
w: CARDINALIF aisW.ok THEN aisW.int ELSE LAST[CARDINAL];
h: CARDINALIF aisH.ok THEN aisH.int ELSE LAST[CARDINAL];
IF cmap.ok AND NOT ColorTrixMap.Load[cmap.rope]
THEN RETURN[$Failure, Rope.Concat["Can't load ", cmap.rope]];
IF clear.ok AND clear.bool THEN {
IF pmMisc.bpp = 8
THEN ColorTrixBasics.FillPm[pmMisc.bw, 0]
ELSE ColorTrixBasics.FillRGBPm[pmMisc, 0, 0, 0];
};
msg 𡤌olorTrixFile.ViewFile[pmMisc, name.rope, center.ok AND center.bool, x, y, w, h];
IF msg # NIL THEN RETURN[$Failure, msg];
};
};
CtSave: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
name, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, name, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "%s-w%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
ColorTrixFile.WritePmMiscToAIS[pmMisc, FileNames.ResolveRelativePath[name.rope]];
};
Window Commands
CtSetWindow: PUBLIC Commander.CommandProc ~ {
IF Args.NArgs[cmd] > 0
THEN {
ok: BOOL;
x, y, w, h: Args.Arg;
[ok, x, y, w, h] ← Args.ArgsGet[cmd, "%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
ColorTrixDispatch.SetGlobalWindow[[y.int, x.int, h.int, w.int]];
};
};
CtResetWindow: PUBLIC Commander.CommandProc ~ {
ColorTrixDispatch.SetGlobalWindow[ColorTrixDispatch.GetInitialWindow[]];
};
CtPrintWindow: PUBLIC Commander.CommandProc ~ {
w: DeviceRectangle ~ ColorTrixDispatch.GetGlobalWindow[];
cmd.out.PutF["global window is (x, y, w, h): [%g, %g, %g, %g].\n",
IO.int[w.fMin], IO.int[w.sMin], IO.int[w.fSize], IO.int[w.sSize]];
};
Clearing/Drawing Commands
CtClear: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
rVal, gVal, bVal: CARDINAL;
rArg, gArg, bArg, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, dum, dum, dum, dum, rArg, gArg, bArg] ← Args.ArgsGet[cmd, "-w%iiii[iii"];
IF NOT ok THEN RETURN[$Failure, NIL];
rVal ← MIN[255, IF rArg.ok THEN INTEGER[rArg.int] ELSE 0];
gVal ← MIN[255, IF gArg.ok THEN INTEGER[gArg.int] ELSE rVal];
bVal ← MIN[255, IF bArg.ok THEN INTEGER[bArg.int] ELSE gVal];
SELECT pmMisc.bpp FROM
8 => ColorTrixBasics.FillPm[pmMisc.bw, rVal];
24 => ColorTrixBasics.FillRGBPm[pmMisc, rVal, gVal, bVal]
ENDCASE => NULL;
};
CtLine: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
x0, y0, x1, y1, r, g, b, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, x0, y0, x1, y1, r, g, b, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "[iiiiiii-w%iiii"];
IF NOT (ok AND x0.ok AND y0.ok AND x1.ok AND y1.ok AND r.ok)
THEN RETURN[$Failure, "Bad argument(s)."];
SELECT pmMisc.bpp FROM
8 => ColorTrixBasics.PutLine[pmMisc.bw, x0.int, y0.int, x1.int, y1.int, r.int];
24 => {
IF NOT (g.ok AND b.ok) THEN RETURN[$Failure, NIL];
ColorTrixBasics.PutRGBLine[pmMisc, x0.int, y0.int, x1.int, y1.int, r.int, g.int, b.int];
};
ENDCASE => NULL;
};
CtRamp: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
v, h, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, v, h, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "-v%b-h%b-w%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
SELECT pmMisc.bpp FROM
8 => IF h.bool
THEN ColorTrixPix.RampH[pmMisc.bw]
ELSE ColorTrixPix.RampV[pmMisc.bw];
24 => {
IF h.bool THEN ColorTrixPix.RampH[pmMisc.rg] ELSE ColorTrixPix.RampV[pmMisc.rg];
IF h.bool THEN ColorTrixPix.RampH[pmMisc.b] ELSE ColorTrixPix.RampV[pmMisc.b];
};
ENDCASE => NULL;
};
CtPie: PUBLIC Commander.CommandProc ~ {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
SELECT pmMisc.bpp FROM
8 => ColorTrixPix.Pie[pmMisc.bw];
24 => {
ColorTrixPix.Pie[pmMisc.rg];
ColorTrixPix.Pie[pmMisc.b];
};
ENDCASE => NULL;
};
CtDither: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
dum, arg: Args.Arg;
[ok, arg, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "[i-w%iiii"];
IF NOT ok
THEN RETURN[$Failure, NIL]
ELSE {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
value: CARDINALIF arg.ok THEN arg.int ELSE 0;
SELECT pmMisc.bpp FROM
8 => ColorTrixPix.Dither[pmMisc.bw, value];
24 => {
ColorTrixPix.Dither[pmMisc.rg, value];
ColorTrixPix.Dither[pmMisc.b, value];
};
ENDCASE => NULL;
};
};
CtGrid: PUBLIC Commander.CommandProc ~ {
InnerGrid: PROC [pm: PixelMap] ~ {
FOR i: NAT ← 0, i+spacing WHILE i < pm.fSize DO
FOR j: NAT ← 0, j+1 WHILE j < pm.sSize DO
ImagerPixelMap.Fill[pm, [j, i, lineWidth, lineWidth], pVal];
ENDLOOP;
ENDLOOP;
FOR j: NAT ← 0, j+spacing WHILE j < pm.sSize DO
FOR i: NAT ← 0, i+1 WHILE i < pm.fSize DO
ImagerPixelMap.Fill[pm, [j, i, lineWidth, lineWidth], pVal];
ENDLOOP;
ENDLOOP;
};
ok: BOOL;
pVal, spacing, lineWidth: CARDINAL;
pValArg, spacingArg, lineWidthArg, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, pValArg, spacingArg, lineWidthArg, dum, dum, dum, dum]
← Args.ArgsGet[cmd, "-pVal%i-spacing%i-lineWidth%i-w%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
pVal ← IF pValArg.ok THEN pValArg.int ELSE 0;
pVal ← 256*pVal+pVal;
spacing ← IF spacingArg.ok THEN spacingArg.int ELSE 40;
lineWidth ← IF lineWidthArg.ok THEN lineWidthArg.int ELSE 1;
SELECT pmMisc.bpp FROM
8 => InnerGrid[pmMisc.bw];
24 => {
InnerGrid[pmMisc.rg];
InnerGrid[pmMisc.b];
};
ENDCASE => NULL;
};
CtCheck: PUBLIC Commander.CommandProc ~ {
InnerCheck: PROC [pm: PixelMap] ~ {
sense: BOOLTRUE;
FOR y: NAT ← 0, y+spacing WHILE y < pm.sSize DO
FOR x: NAT ← 0, x+spacing WHILE x < pm.fSize DO
IF sense THEN ImagerPixelMap.Fill[pm, [y, x, spacing, spacing], pVal];
sense ← NOT sense;
ENDLOOP;
sense ← NOT sense;
ENDLOOP;
};
ok: BOOL;
pVal, spacing: CARDINAL;
pValArg, spacingArg, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, pValArg, spacingArg, dum, dum, dum, dum]
← Args.ArgsGet[cmd, "-pVal%i-spacing%i-w%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
pVal ← IF pValArg.ok THEN pValArg.int ELSE 0;
pVal ← 256*pVal+pVal;
spacing ← IF spacingArg.ok THEN spacingArg.int ELSE 40;
SELECT pmMisc.bpp FROM
8 => InnerCheck[pmMisc.bw];
24 => {
InnerCheck[pmMisc.rg];
InnerCheck[pmMisc.b];
};
ENDCASE => NULL;
};
Palette Commands
CtPal: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
n, smooth: Args.Arg;
pm: PixelMap ← ColorTrixBasics.GetColorDisplayPm[];
[ok, n, smooth] ← Args.ArgsGet[cmd, "[i-smooth%b"];
IF NOT ok THEN RETURN[$Failure, NIL];
ColorTrixPalette.Pal[pm, IF n.ok THEN n.int ELSE 5, smooth.ok AND smooth.bool];
palOn ← TRUE;
};
CtUnPal: PUBLIC Commander.CommandProc ~ {
IF palOn THEN ColorTrixPalette.UnPal[ColorTrixBasics.GetColorDisplayPm[]];
palOn ← FALSE;
};
Processing Commands
CtLum: PUBLIC Commander.CommandProc ~ {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
SELECT pmMisc.bpp FROM
8 => ColorTrixMod.Lum[pmMisc.bw];
24 => {
ColorTrixMod.Lum[pmMisc.rg];
ColorTrixMod.Lum[pmMisc.b];
};
ENDCASE => NULL;
};
CtPseudoToRGB: PUBLIC Commander.CommandProc ~ {
name: Rope.ROPE ~ Args.GetRope[cmd];
IF name = NIL
THEN RETURN[$Failure, "Usage: CtPsuedoToRGB <base name>"]
ELSE {
pm: ColorTrixBasics.PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
IF pm.bpp # 8
THEN RETURN[$Failure, "Color display should be in 8bpp"]
ELSE {
cmap: ColorTrixMap.Cmap ← ColorTrixMap.Read[];
base: Rope.ROPE ~ FileNames.ResolveRelativePath[name];
table: ColorTrixMod.Table ← NEW[ColorTrixMod.TableRep];
temp: ImagerPixelMap.PixelMap ←
ImagerPixelMap.Create[3, ImagerPixelMap.Window[pm.bw]];
SaveOneFile: PROC [color: Rope.ROPE, i: NAT] ~ {
IO.PutF[cmd.out, "%g . . . ", IO.rope[color]];
ImagerPixelMap.Transfer[temp, pm.bw];
FOR n: NAT IN [0..255) DO table[n] ← cmap[i][n]; ENDLOOP;
ColorTrixMod.Indirect[temp, table];
PixelMapOps.StoreAIS[Rope.Cat[base, "-", color, ".ais"], [temp, FALSE, NIL]];
};
IO.PutRope[cmd.out, "writing "];
SaveOneFile["red", 0];
SaveOneFile["grn", 1];
SaveOneFile["blu", 2];
IO.PutRope[cmd.out, "done!\n"];
};
};
};
CtDif: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
x0, y0, x1, y1, x2, y2, w, h: Args.Arg;
[ok, x0, y0, x1, y1, x2, y2, w, h] ← Args.ArgsGet[cmd, "%iiiiiiii"];
IF NOT ok
THEN RETURN[$Failure, "Bad argument(s)."]
ELSE {
pm: PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
SELECT pm.bpp FROM
8 => ColorTrixMod.Dif[pm.bw, x0.int, y0.int, x1.int, y1.int, x2.int, y2.int, w.int, h.int];
24 => {
ColorTrixMod.Dif[pm.rg, x0.int, y0.int, x1.int, y1.int, x2.int, y2.int, w.int, h.int];
ColorTrixMod.Dif[pm.b, x0.int, y0.int, x1.int, y1.int, x2.int, y2.int, w.int, h.int];
};
ENDCASE;
};
};
CtPVal: PUBLIC Commander.CommandProc ~ {
n: NAT ← 0;
new, old: Args.Arg;
list: REF List ← NIL;
nArgs: NAT ← Args.NArgs[cmd];
List: TYPE ~ RECORD[first: NAT, rest: REF List];
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
WHILE n < nArgs DO
IF Args.GetRope[cmd, n].Equal["-w"] THEN {n ← n+5; LOOP};
IF new.ok THEN {
IF NOT (old ← Args.ArgInt[cmd, n]).ok THEN RETURN[$Failure, "Bad old value."];
list ← NEW[List ← [old.int, list]];
}
ELSE IF NOT (new ← Args.ArgInt[cmd, n]).ok THEN RETURN[$Failure, "Bad new value."];
n ← n+1;
ENDLOOP;
IF list # NIL THEN SELECT pmMisc.bpp FROM
8 => ColorTrixMod.PVal[pmMisc.bw, new.int, list];
24 => {
ColorTrixMod.PVal[pmMisc.rg, new.int, list];
ColorTrixMod.PVal[pmMisc.b, new.int, list];
};
ENDCASE => NULL;
};
Manipulations Commands
CtCopy: PUBLIC Commander.CommandProc ~ {
InnerCopy: PROC [pm: PixelMap] ~ {
src: PixelMap ~ ImagerPixelMap.Clip[pm, [y0.int, x0.int, h0.int, w0.int]];
dst: PixelMap ~ ImagerPixelMap.Clip[pm, [y1.int, x1.int, h1.int, w1.int]];
ImagerPixelMap.Transfer[dst, ImagerPixelMap.ShiftMap[src, y1.int-y0.int, x1.int-x0.int]];
};
ok: BOOL;
x0, y0, w0, h0, x1, y1, w1, h1: Args.Arg;
[ok, x0, y0, w0, h0, x1, y1, w1, h1] ← Args.ArgsGet[cmd, "%iiiiii[ii"];
IF NOT ok
THEN RETURN[$Failure, NIL]
ELSE {
pmMisc: PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
IF NOT w1.ok THEN w1.int ← w0.int;
IF NOT h1.ok THEN h1.int ← h0.int;
SELECT pmMisc.bpp FROM
8 => InnerCopy[pmMisc.bw];
24 => {
InnerCopy[pmMisc.rg];
InnerCopy[pmMisc.b];
};
ENDCASE => NULL;
};
};
CtLeft: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
dum, arg: Args.Arg;
[ok, arg, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "%i-w%iiii"];
IF NOT ok OR NOT arg.ok
THEN RETURN[$Failure, NIL]
ELSE {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
SELECT pmMisc.bpp FROM
8 => ColorTrixMod.Left[pmMisc.bw, arg.int];
24 => {
ColorTrixMod.Left[pmMisc.rg, arg.int];
ColorTrixMod.Left[pmMisc.b, arg.int];
};
ENDCASE => NULL;
};
};
CtUp: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
dum, arg: Args.Arg;
[ok, arg, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "%i-w%iiii"];
IF NOT ok OR NOT arg.ok
THEN RETURN[$Failure, NIL]
ELSE {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
SELECT pmMisc.bpp FROM
8 => ColorTrixMod.Up[pmMisc.bw, arg.int];
24 => {
ColorTrixMod.Up[pmMisc.rg, arg.int];
ColorTrixMod.Up[pmMisc.b, arg.int];
};
ENDCASE => NULL;
};
};
CtNegate: PUBLIC Commander.CommandProc ~ {
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
SELECT pmMisc.bpp FROM
8 => ColorTrixMod.Negate[pmMisc.bw];
24 => {
ColorTrixMod.Negate[pmMisc.rg];
ColorTrixMod.Negate[pmMisc.b];
};
ENDCASE => NULL;
};
CtReflect: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
v, h, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, v, h, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "-v%b-h%b-w%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
IF h.bool
THEN SELECT pmMisc.bpp FROM
8 => ColorTrixMod.ReflectH[pmMisc.bw];
24 => {
ColorTrixMod.ReflectH[pmMisc.rg];
ColorTrixMod.ReflectH[pmMisc.b];
};
ENDCASE => NULL
ELSE SELECT pmMisc.bpp FROM
8 => ColorTrixMod.ReflectV[pmMisc.bw];
24 => {
ColorTrixMod.ReflectV[pmMisc.rg];
ColorTrixMod.ReflectV[pmMisc.b];
};
ENDCASE => NULL;
};
CtMirror: PUBLIC Commander.CommandProc ~ {
MirrorH: PROC [pmMisc: PixelMapMisc, leftToRight: BOOL] ~ {
SELECT pmMisc.bpp FROM
8 => ColorTrixMod.MirrorH[pmMisc.bw];
24 => {
ColorTrixMod.MirrorH[pmMisc.rg];
ColorTrixMod.MirrorH[pmMisc.b];
};
ENDCASE => NULL;
};
MirrorV: PROC [pmMisc: PixelMapMisc, leftToRight: BOOL] ~ {
SELECT pmMisc.bpp FROM
8 => ColorTrixMod.MirrorV[pmMisc.bw];
24 => {
ColorTrixMod.MirrorV[pmMisc.rg];
ColorTrixMod.MirrorV[pmMisc.b];
};
ENDCASE => NULL;
};
ok: BOOL;
l, r, t, b, dum: Args.Arg;
pmMisc: PixelMapMisc ← ColorTrixDispatch.GetWindowedPmMisc[cmd];
[ok, l, r, t, b, dum, dum, dum, dum] ← Args.ArgsGet[cmd, "-l%b-r%b-t%b-b%b-w%iiii"];
IF NOT ok THEN RETURN[$Failure, NIL];
SELECT TRUE FROM
l.bool => MirrorV[pmMisc, TRUE];
r.bool => MirrorV[pmMisc, FALSE];
t.bool => MirrorH[pmMisc, TRUE];
b.bool => MirrorH[pmMisc, FALSE];
ENDCASE => MirrorH[pmMisc, FALSE];
};
Usage Messages
File IO
ctViewUsage: ROPE ~
"Ct View <ais or interpress file>
 Display the named image file on the color display.
 The complete file name should be given unless the image
 is 24 bits, in which case only the base name should be given.
 Images are un-scaled, those larger than 1024 by 768 are clipped.
  Options:
  -center   center the image on the color display
  -cmap <file>  load the specified color map
  -w <x y w h> display image in this window
  -a <x y w h> if ais file, read data from this window.";
  
ctSaveUsage: ROPE ~
"Ct Save <name> [-w <x y w h>]
 Save the entire color display image to disk.
 If 24 bits, '-red.ais', '-grn.ais', '-blu.ais' are
 appended to name for the appropriate file.";
Windows
ctSetWindowUsage:  ROPE ~ "Ct SetWindow <x y w h>: set the color display window.";
ctResetWindowUsage: ROPE ~ "Ct Reset: reset the window.";
ctPrintWindowUsage: ROPE ~ "Ct Print: print the window.";
Clearing/Drawing
ctClearUsage:    ROPE ~ "Ct Clear [r[gb]] [-w<xywh>]: clear the color display.";
ctLineUsage:    ROPE ~ "Ct Line x0 y0 x1 y1 r[gb] [-w<xywh>]: draw a line";
ctRampUsage:   ROPE ~ "Ct Ramp [-h|-v] [-w<xywh>]: draw a horiz. or vert. ramp.";
ctPieUsage:    ROPE ~ "Ct Pie [-w<xywh>]: draw a circular ramp.";
ctGridUsage:    ROPE ~ "[-pVal<INT>][-spacing<INT>][-lineWidth<INT>][-w<xywh>].";
ctCheckUsage:   ROPE ~ "Ct Check [-pVal<INT>][-spacing<INT>][-w<xywh>].";
Palette
ctPalUsage:    ROPE ~ "Ct Pal [INT: nrows] [-smooth]: display palette.";
ctUnPalUsage:   ROPE ~ "Ct UnPal: remove palette.";
Processing
ctPseudoToRGBUsage: ROPE ~
"Ct PsuedoToRGBUsage <name>:
 creates name-red, -grn, -blu.ais from pseudo color image.";
ctLumUsage:    ROPE ~ "Ct Lum [-w<xywh>]: convert pseudo-colors to luminance.";
ctPValUsage:    ROPE ~ "Ct PVal <newVal> <oldVal> [oldVal] . . . [-w<xywh>].";
ctDifUsage:    ROPE ~ "Ct Dif <x0 y0 x1 y1 x2 y2 w h> Display |dif| of windows.";
ctDitherUsage:   ROPE ~
"Ct Dither [value] [-w<xywh>]: dither the picture.
 If no value specified, dither the existing image;
 otherwise, create a dithered flat field of intensity <value>.";
Manipulation
ctCopyUsage:    ROPE ~ "Ct Copy <xywh (src) xy[wh] (dest)>: copy src to dest.";
ctLeftUsage:    ROPE ~ "Ct Left <INT> [-w<xywh>]: shift image left.";
ctUpUsage:    ROPE ~ "Ct Up <INT> [-w<xywh>]: shift image up.";
ctNegateUsage:   ROPE ~ "Ct Negate [-w<xywh>]: negate the image.";
ctReflectUsage:   ROPE ~ "Ct Reflect <-h|-v> [-w<xywh>]: reflect the image.";
ctMirrorUsage:   ROPE ~ "Ct Mirror <-l|-r|-t|-b> [-w<xywh>]: mirror the image.";
Start Code
ColorTrixDispatch.RegisterCtOp["View",   CtView,   ctViewUsage];
ColorTrixDispatch.RegisterCtOp["Save",   CtSave,   ctSaveUsage];
ColorTrixDispatch.RegisterCtOp["SetWindow", CtSetWindow, ctSetWindowUsage];
ColorTrixDispatch.RegisterCtOp["ResetWindow", CtResetWindow, ctResetWindowUsage];
ColorTrixDispatch.RegisterCtOp["PrintWindow", CtPrintWindow, ctPrintWindowUsage];
ColorTrixDispatch.RegisterCtOp["Clear",   CtClear,   ctClearUsage];
ColorTrixDispatch.RegisterCtOp["Line",   CtLine,   ctLineUsage];
ColorTrixDispatch.RegisterCtOp["Ramp",   CtRamp,   ctRampUsage];
ColorTrixDispatch.RegisterCtOp["Pie",    CtPie,    ctPieUsage];
ColorTrixDispatch.RegisterCtOp["Dither",   CtDither,   ctDitherUsage];
ColorTrixDispatch.RegisterCtOp["Grid",   CtGrid,   ctGridUsage];
ColorTrixDispatch.RegisterCtOp["Check",   CtCheck,   ctCheckUsage];
ColorTrixDispatch.RegisterCtOp["Pal",    CtPal,    ctPalUsage];
ColorTrixDispatch.RegisterCtOp["UnPal",   CtUnPal,   ctUnPalUsage];
ColorTrixDispatch.RegisterCtOp["Lum",   CtLum,   ctLumUsage];
ColorTrixDispatch.RegisterCtOp["PseudoToRGB", CtPseudoToRGB, ctPseudoToRGBUsage];
ColorTrixDispatch.RegisterCtOp["Dif",    CtDif,    ctDifUsage];
ColorTrixDispatch.RegisterCtOp["PVal",   CtPVal,   ctPValUsage];
ColorTrixDispatch.RegisterCtOp["Copy",   CtCopy,   ctCopyUsage];
ColorTrixDispatch.RegisterCtOp["Left",   CtLeft,   ctLeftUsage];
ColorTrixDispatch.RegisterCtOp["Up",    CtUp,    ctUpUsage];
ColorTrixDispatch.RegisterCtOp["Negate",   CtNegate,   ctNegateUsage];
ColorTrixDispatch.RegisterCtOp["Reflect",   CtReflect,   ctReflectUsage];
ColorTrixDispatch.RegisterCtOp["Mirror",   CtMirror,   ctMirrorUsage];
END.