ColorTrixPixImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, July 11, 1986 12:20:36 pm PDT
DIRECTORY ColorTrixBasics, ColorTrixPix, ImagerSample, ImagerPixelMap, PixelMapOps, Process, Random, Real;
ColorTrixPixImpl: CEDAR PROGRAM
IMPORTS ColorTrixBasics, ImagerSample, ImagerPixelMap, PixelMapOps, Process, Random, Real
EXPORTS ColorTrixPix
~ BEGIN
PixelMap:   TYPE ~ ImagerPixelMap.PixelMap;
Color Display Modification Procedures:
Dither: PUBLIC PROC [pm: PixelMap, intensity: CARDINAL] ~ {
w: ImagerPixelMap.DeviceRectangle ← ImagerPixelMap.Window[pm];
IF intensity = 0 AND pm.refRep.lgBitsPerPixel = 3 THEN {
FOR y: INTEGER IN [w.sMin..w.sMin+w.sSize) DO
Process.CheckForAbort[];
FOR x: INTEGER IN [w.fMin..w.fMin+w.fSize) DO
pval: CARDINAL ~ ColorTrixBasics.GetPixel[pm, x, y];
v: CARDINAL ~ IF Random.ChooseInt[, 0, 255] > pval THEN 0 ELSE 255;
ImagerPixelMap.Fill[pm, [y, x, 1, 1], v];
ENDLOOP;
ENDLOOP;
RETURN;
};
FOR y: INTEGER IN [w.sMin..w.sMin+w.sSize) DO
Process.CheckForAbort[];
IF pm.refRep.lgBitsPerPixel = 4
THEN FOR x: INTEGER IN [w.fMin..w.fMin+w.fSize) DO
r: CARDINALIF Random.ChooseInt[, 0, 255] > intensity THEN 0 ELSE 255*256;
g: CARDINALIF Random.ChooseInt[, 0, 255] > intensity THEN 0 ELSE 255;
ImagerPixelMap.Fill[pm, [y, x, 1, 1], r+g];
ENDLOOP
ELSE FOR x: INTEGER IN [w.fMin..w.fMin+w.fSize) DO
v: CARDINALIF Random.ChooseInt[, 0, 255] > intensity THEN 0 ELSE 255;
ImagerPixelMap.Fill[pm, [y, x, 1, 1], v];
ENDLOOP;
ENDLOOP;
};
RampH: PUBLIC PROC [pm: PixelMap] ~ {
w: ImagerPixelMap.DeviceRectangle ~ pm.Window;
inc: REAL ← 255.0/Real.Float[w.fSize-1];
Action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
FOR y: INTEGER IN [w.sMin..w.sMin+w.sSize) DO
ival: CARDINAL ← Real.Round[(y-w.sMin)*inc];
ival ← 256*ival+ival;          -- for 8 or 16 bit pixel maps
Process.CheckForAbort[];
FOR x: INTEGER IN [0..w.fSize) DO line.samples[x] ← ival; ENDLOOP;
PixelMapOps.PutF[pm, y, w.fMin, line, 0, 0, w.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, Action];
};
RampV: PUBLIC PROC [pm: PixelMap] ~ {
w: ImagerPixelMap.DeviceRectangle ~ pm.Window;
inc: REAL ← 255.0/Real.Float[w.fSize-1];
Action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED {
FOR x: INTEGER IN [0..w.fSize) DO
v: CARDINAL ← Real.Round[x*inc];
line.samples[x] ← 256*v+v;        -- for 8 or 16 bit pixel maps
ENDLOOP;
FOR y: INTEGER IN [w.sMin..w.sMin+w.sSize) DO
Process.CheckForAbort[];
PixelMapOps.PutF[pm, y, w.fMin, line, 0, 0, w.fSize, null, null];
ENDLOOP;
};
ImagerSample.DoWithScratchBuffer[1, pm.fSize, Action];
};
Pie: PUBLIC PROC [pm: PixelMap] ~ {
Init: PROC ~ {
val: INT ← 0; dval: INT ← 1; ddval: INT ~ 2;
factor: REAL ← ratio*ratio;
FOR i: INTEGER IN [0..512] DO sq[i] ← val; val ← val + dval; dval ← dval + ddval; ENDLOOP;
FOR i: INTEGER IN [0..maxVal+1] DO threshs[i] ← Real.Round[factor*sq[i]]; ENDLOOP;
};
Scan: PROC [y: CARDINAL] ~ {
pval: CARDINAL ← Real.Round[MIN[255.0, MAX[1.0, REAL[y]/ratio]]];
thresh: INT ← threshs[pval]-sq[y];
FOR x: INTEGER IN [0..dx] DO
WHILE sq[x] > thresh AND pval < maxVal DO
pval ← pval+1;
thresh ← threshs[pval]-sq[y];
ENDLOOP;
IF pval = maxVal THEN {
FOR xx: INTEGER IN [dx+x..pm.fSize) DO line.samples[xx] ← rgMaxVal; ENDLOOP;
FOR xx: INTEGER IN [0..dx-x] DO line.samples[xx] ← rgMaxVal; ENDLOOP;
EXIT;
};
line.samples[dx+x] ← line.samples[dx-x] ← IF bits16 THEN pval+256*pval ELSE pval;
ENDLOOP;
PixelMapOps.PutF[pm, cy+y, pm.fMin, line, 0, 0, pm.fSize, null, null];
PixelMapOps.PutF[pm, cy-y, pm.fMin, line, 0, 0, pm.fSize, null, null];
};
line: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pm.fSize];
dx: INTEGER ~ MIN[511, (pm.fSize+1)/2-1];
dy: INTEGER ~ MIN[511, (pm.sSize+1)/2-1];
cx: INTEGER ~ pm.fMin+dx;
cy: INTEGER ~ pm.sMin+dy;
maxVal: CARDINAL ~ 255;
rgMaxVal: CARDINAL ~ maxVal+256*maxVal;
sq: ARRAY [0..512] OF INT;
threshs: ARRAY [0..maxVal+1] OF INT;
ratio: REAL ← Real.RoundI[dx+1]/256.0;
bits16: BOOL ← pm.refRep.lgBitsPerPixel = 4;
Init[];
FOR y: INTEGER IN [0..dy] DO Process.CheckForAbort[]; Scan[y]; ENDLOOP;
IF pm.sSize MOD 2 = 0
THEN ImagerPixelMap.Fill[pm, [pm.sMin+pm.sSize-1, pm.fMin, 1, pm.fSize], rgMaxVal];
IF pm.fSize MOD 2 = 0
THEN ImagerPixelMap.Fill[pm, [pm.sMin, pm.fMin+pm.fSize-1, pm.sSize, 1], rgMaxVal];
ImagerSample.ReleaseScratchBuffer[line];
};
END.