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:
BOOL ←
TRUE] ~ {
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:
BOOL ←
TRUE] ~ {
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];
};