ColorTrixModImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, January 17, 1986 0:07:49 am PST
DIRECTORY ColorTrixMod, ColorTrixMap, ImagerSample, ImagerPixelMap, PrincOps, PixelMapOps, Process, Real;
ColorTrixModImpl: CEDAR PROGRAM
IMPORTS ColorTrixMap, ImagerSample, ImagerPixelMap, PixelMapOps, Process, Real
EXPORTS ColorTrixMod
~ {
Color Display Modification Procedures:
Up: PUBLIC PROC [pm: ImagerPixelMap.PixelMap, shift: INT] ~ {
startClip, secondShift: INT;
t: ImagerPixelMap.PixelMap;
IF shift = 0 THEN RETURN;
IF shift > 0 THEN {startClip ← 0; secondShift ← pm.sSize-shift};
IF shift < 0 THEN {startClip ← pm.sSize+shift; secondShift ← -pm.sSize-shift};
t ← ImagerPixelMap.Copy[ImagerPixelMap.Clip[pm, [startClip, 0, ABS[shift], pm.fSize]]];
ImagerPixelMap.Transfer[pm, ImagerPixelMap.ShiftMap[pm, -shift, 0]];
ImagerPixelMap.Transfer[pm, ImagerPixelMap.ShiftMap[t, secondShift, 0]];
};
Left: PUBLIC PROC [pm: ImagerPixelMap.PixelMap, shift: INT] ~ {
startClip, secondShift: INT;
t: ImagerPixelMap.PixelMap;
IF shift = 0 THEN RETURN;
IF shift > 0 THEN {startClip ← 0; secondShift ← pm.fSize-shift};
IF shift < 0 THEN {startClip ← pm.fSize+shift; secondShift ← -pm.fSize-shift};
t ← ImagerPixelMap.Copy[ImagerPixelMap.Clip[pm, [0, startClip, pm.sSize, ABS[shift]]]];
ImagerPixelMap.Transfer[pm, ImagerPixelMap.ShiftMap[pm, 0, -shift]];
ImagerPixelMap.Transfer[pm, ImagerPixelMap.ShiftMap[t, 0, secondShift]];
};
Negate: PUBLIC PROC [pm: ImagerPixelMap.PixelMap] ~ {
ImagerPixelMap.Transfer[pm, pm, [null, complement]];
};
ReflectH: PUBLIC PROC [pm: ImagerPixelMap.PixelMap] ~ {
line1: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pm.fSize];
line2: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pm.fSize];
FOR dy: NAT IN [0..pm.sSize/2] DO
y: NAT ← pm.sMin+dy;
yy: NAT ← pm.sMin+pm.sSize-1-dy;
Process.CheckForAbort[];
PixelMapOps.GetF[pm, y, pm.fMin, line1, 0, 0, pm.fSize];
PixelMapOps.GetF[pm, yy, pm.fMin, line2, 0, 0, pm.fSize];
PixelMapOps.PutF[pm, y, pm.fMin, line2, 0, 0, pm.fSize, null, null];
PixelMapOps.PutF[pm, yy, pm.fMin, line1, 0, 0, pm.fSize, null, null];
ENDLOOP;
};
ReflectV: PUBLIC PROC [pm: ImagerPixelMap.PixelMap] ~ {
action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
sample: ImagerSample.UnsafeSamples ~ ImagerSample.GetPointer[line, 0, 0, pm.fSize];
xRight: NAT ← pm.fSize-1;
FOR y: INT IN [pm.sMin..pm.sMin+pm.sSize) DO
Process.CheckForAbort[];
PixelMapOps.GetF[pm, y, pm.fMin, line, 0, 0, pm.fSize];
FOR x: NAT IN [0..pm.fSize/2] DO
t: NAT ← sample[x];
xx: NAT ← xRight-x;
sample[x] ← sample[xx];
sample[xx] ← t;
ENDLOOP;
PixelMapOps.PutF[pm, y, pm.fMin, line, 0, 0, pm.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};
MirrorH: PUBLIC PROC [pm: ImagerPixelMap.PixelMap, topToBottom: BOOLTRUE] ~ {
action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
y1, y2: NAT;
FOR dy: NAT IN [0..pm.sSize/2] DO
Process.CheckForAbort[];
IF topToBottom
THEN {y1 ← pm.sMin+dy; y2 ← pm.sMin+pm.sSize-1-dy}
ELSE {y1 ← pm.sMin+pm.sSize-1-dy; y2 ← pm.sMin+dy};
PixelMapOps.GetF[pm, y1, pm.fMin, line, 0, 0, pm.fSize];
PixelMapOps.PutF[pm, y2, pm.fMin, line, 0, 0, pm.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};
MirrorV: PUBLIC PROC [pm: ImagerPixelMap.PixelMap, leftToRight: BOOLTRUE] ~ {
action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
sample: ImagerSample.UnsafeSamples ~ ImagerSample.GetPointer[line, 0, 0, pm.fSize];
xRight: NAT ← pm.fSize-1;
FOR y: INT IN [pm.sMin..pm.sMin+pm.sSize) DO
Process.CheckForAbort[];
PixelMapOps.GetF[pm, y, pm.fMin, line, 0, 0, pm.fSize];
IF leftToRight
THEN FOR x: NAT IN [0..pm.fSize/2] DO sample[xRight-x] ← sample[x]; ENDLOOP
ELSE FOR x: NAT IN [0..pm.fSize/2] DO sample[x] ← sample[xRight-x]; ENDLOOP;
PixelMapOps.PutF[pm, y, pm.fMin, line, 0, 0, pm.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};
Indirect: PUBLIC PROC [pm: ImagerPixelMap.PixelMap, table: ColorTrixMod.Table] ~ {
action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
sample: ImagerSample.UnsafeSamples ~ ImagerSample.GetPointer[line, 0, 0, pm.fSize];
FOR y: INT IN [pm.sMin..pm.sMin+pm.sSize) DO
Process.CheckForAbort[];
PixelMapOps.GetF[pm, y, pm.fMin, line, 0, 0, pm.fSize];
FOR x: NAT IN [0..pm.fSize) DO sample[x] ← table[sample[x]]; ENDLOOP;
PixelMapOps.PutF[pm, y, pm.fMin, line, 0, 0, pm.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};
Lum: PUBLIC PROC [pm: ImagerPixelMap.PixelMap] ~ {
table: ColorTrixMod.Table ← NEW[ColorTrixMod.TableRep];
cm: ColorTrixMap.Cmap ← ColorTrixMap.Read[];
FOR i: INT IN [0..256) DO
table[i] ← MIN[255, MAX[0, Real.RoundI[.30*cm[0][i] + .59*cm[1][i] + .11*cm[2][i]]]];
ENDLOOP;
ColorTrixMap.Mono[];
Indirect[pm, table];
};
PVal: PUBLIC PROC [pm: ImagerPixelMap.PixelMap, new: NAT, old: LIST OF NAT] ~ {
table: ColorTrixMod.Table ← NEW[ColorTrixMod.TableRep];
IF old = NIL THEN RETURN;
FOR i: NAT IN [0..256) DO table[i] ← i; ENDLOOP;
new ← MIN[255, MAX[0, INTEGER[new]]];
FOR o: LIST OF NAT ← old, o.rest WHILE o # NIL DO
table[MIN[255, MAX[0, INTEGER[o.first]]]] ← new;
ENDLOOP;
Indirect[pm, table];
};
}.
Reflect: PUBLIC PROC [p: ImagerPixelMap.PixelMap] ~ {
ImagerPixelMap.Transfer[p, ImagerPixelMap.ShiftMap[ImagerPixelMap.Reflect[p], p.sSize, 0]];
};
Lum: PUBLIC PROC [pm: ImagerPixelMap.PixelMap] ~ {
buf: ARRAY [0..256) OF NAT;
cm: ColorMap.Cmap ← ColorMap.Read[];
By keeping buf outside of action, action runs ~30% faster because less stack mgt. necessary
action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
sample: ImagerSample.UnsafeSamples ~ ImagerSample.GetPointer[line, 0, 0, pm.fSize];
FOR y: INT IN [pm.sMin..pm.sMin+pm.sSize) DO
Process.CheckForAbort[];
PixelMapOps.GetF[pm, y, pm.fMin, line, 0, 0, pm.fSize];
FOR x: NAT IN [0..pm.fSize) DO sample[x] ← buf[sample[x]]; ENDLOOP;
PixelMapOps.PutF[pm, y, pm.fMin, line, 0, 0, pm.fSize, null, null];
ENDLOOP;
};
FOR i: INT IN [0..256) DO
buf[i] ← MIN[255, MAX[0, Real.RoundI[.30*cm[0][i] + .59*cm[1][i] + .11*cm[2][i]]]];
ENDLOOP;
ColorMap.Write[ColorMap.Mono[]];
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};
PerLine: PUBLIC PROC [perLineProc: ColorDisplayCase.PerLineProc] ~ {
pm: ImagerPixelMap.PixelMap ← ImagerOps.PixelMapFromFrameBuffer [Terminal.GetColorFrameBufferA[InterminalBackdoor.terminal]];
action: PROC [sampleBuffer: ImagerSample.SampleBuffer] ~ TRUSTED {
bounds: ImagerPixelMap.DeviceRectangle ~ pm.Window;
sample: ImagerSample.UnsafeSamples ~ GetPointer[sampleBuffer, 0, 0, bounds.fSize];
maxVal: ImagerSample.Sample ~ CARDINAL[Basics.BITSHIFT[1, Basics.BITSHIFT[1, pm.refRep.lgBitsPerPixel]]-1];
FOR s: INT IN [bounds.sMin..bounds.sMin+bounds.sSize) DO
Process.CheckForAbort[];
PixelMapOps.GetF[pm, s, bounds.fMin, sampleBuffer, 0, 0, bounds.fSize];
perLineProc[sample, bounds.fSize];
PixelMapOps.PutF[pm, s, bounds.fMin, sampleBuffer, 0, 0, bounds.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};
PerPixel: PUBLIC PROC [perPixelProc: ColorDisplayCase.PerPixelProc] ~ {
pm: ImagerPixelMap.PixelMap ← ImagerOps.PixelMapFromFrameBuffer [Terminal.GetColorFrameBufferA[InterminalBackdoor.terminal]];
action: PROC [sampleBuffer: ImagerSample.SampleBuffer] ~ TRUSTED {
bounds: ImagerPixelMap.DeviceRectangle ~ pm.Window;
sample: ImagerSample.UnsafeSamples ~ GetPointer[sampleBuffer, 0, 0, bounds.fSize];
maxVal: ImagerSample.Sample ~ CARDINAL[Basics.BITSHIFT[1, Basics.BITSHIFT[1, pm.refRep.lgBitsPerPixel]]-1];
FOR s: INT IN [bounds.sMin..bounds.sMin+bounds.sSize) DO
Process.CheckForAbort[];
PixelMapOps.GetF[pm, s, bounds.fMin, sampleBuffer, 0, 0, bounds.fSize];
FOR j: NAT IN [0..bounds.fSize) DO
sample[j] ← MAX[MIN[INT[perPixelProc[sample[j]]], maxVal], 0];
ENDLOOP;
PixelMapOps.PutF[pm, s, bounds.fMin, sampleBuffer, 0, 0, bounds.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, action];
};