ColorTrixModImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, December 13, 1986 7:05:42 pm PST
DIRECTORY ColorTrixBasics, ColorTrixMod, ColorTrixMap, ImagerSample, ImagerPixelMap, PrincOps, PixelMapOps, Process, Real;
ColorTrixModImpl: CEDAR PROGRAM
IMPORTS ColorTrixBasics, ColorTrixMap, ImagerSample, ImagerPixelMap, PixelMapOps, Process, Real
EXPORTS ColorTrixMod
~ BEGIN
PixelMap:  TYPE ~ ImagerPixelMap.PixelMap;
Color Display Modification Procedures:
Indirect: PUBLIC PROC [pm: 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];
IF pm.refRep.lgBitsPerPixel = 4
THEN FOR x: NAT IN [0..pm.fSize) DO
rg: CARDINAL ← sample[x];
r: CARDINAL ← table[rg/256];
g: CARDINAL ← table[rg MOD 256];
sample[x] ← 256*r+g;
ENDLOOP
ELSE 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];
};
Dif: PUBLIC PROC [pm: PixelMap, x0, y0, x1, y1, x2, y2, w, h: NAT] ~ {
src0: PixelMap ~ ImagerPixelMap.Clip[pm, [y0, x0, h, w]];
src1: PixelMap ~ ImagerPixelMap.Clip[pm, [y1, x1, h, w]];
dif: PixelMap ~ ImagerPixelMap.Clip[pm, [y2, x2, h, w]];
FOR y: INT IN [0..h) DO
FOR x: INT IN [0..w) DO
src0Value: INTEGER ~ ColorTrixBasics.GetPixel[src0, x+src0.fMin, y+src0.sMin];
src1Value: INTEGER ~ ColorTrixBasics.GetPixel[src1, x+src1.fMin, y+src1.sMin];
ColorTrixBasics.PutPixel[dif, x+dif.fMin, y+dif.sMin, ABS[src0Value-src1Value]];
ENDLOOP;
ENDLOOP;
};
Up: PUBLIC PROC [pm: PixelMap, shift: INTEGER] ~ {
t: PixelMap;
startClip, secondShift: INTEGER;
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: PixelMap, shift: INTEGER] ~ {
t: PixelMap;
startClip, secondShift: INTEGER;
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: PixelMap] ~ {
ImagerPixelMap.Transfer[pm, pm, [null, complement]];
};
ReflectH: PUBLIC PROC [pm: 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;
ImagerSample.ReleaseScratchBuffer[line1];
ImagerSample.ReleaseScratchBuffer[line1];
};
ReflectV: PUBLIC PROC [pm: 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: CARDINAL ← sample[x];
xx: CARDINAL ← 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: 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: 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];
};
Lum: PUBLIC PROC [pm: 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[0.30*cm[0][i]+0.59*cm[1][i]+0.11*cm[2][i]]]];
ENDLOOP;
ColorTrixMap.Mono[];
Indirect[pm, table];
};
PVal: PUBLIC PROC [pm: 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];
};
END.
Reflect: PUBLIC PROC [p: PixelMapCD] ~ {
ImagerPixelMap.Transfer[p, ImagerPixelMap.ShiftMap[ImagerPixelMap.Reflect[p], p.sSize, 0]];
};
Lum: PUBLIC PROC [pm: PixelMapCD] ~ {
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: PixelMapCD ← 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: PixelMapCD ← 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];
};