ImageProcs.mesa
Copyright © 1988 by Xerox Corporation. All rights reserved.
Last Edited by: Crow, March 14, 1988 5:58:01 pm PST
DIRECTORY
Basics     USING [ BITAND ],
Real     USING [ Round ],
RealFns    USING [ Sin, Cos, Power ],
CedarProcess   USING [ DoWithPriority ],
ThreeDBasics  USING [ Context ],
ImagerPixel   USING [ GetPixels, NewPixels, PixelBuffer, PutPixels ];
ImageProcs: CEDAR PROGRAM
IMPORTS Basics, CedarProcess, ImagerPixel, Real, RealFns
= BEGIN
Internal Declarations
Context: TYPE ~ ThreeDBasics.Context;
Sqr: PROCEDURE [number: REAL] RETURNS [REAL] ~ INLINE { RETURN[number * number]; };
Sgn: PROCEDURE [number: REAL] RETURNS [REAL] ~ INLINE {
IF number < 0. THEN RETURN[-1.] ELSE RETURN[1.];
};
Procedures for Making texture and test images
MakeStripes: PUBLIC PROC[context: REF Context, numStripes, min, max, power: REAL] ~ {
width: INTEGER ← Real.Round[context.viewPort.w];
height: INTEGER ← Real.Round[context.viewPort.h];
factor: REAL ← ( numStripes * 2. * 3.1416 ) / width;
maxValue: REAL ← 255.0;
scanSeg: ImagerPixel.PixelBuffer ← ImagerPixel.NewPixels[context.pixels.samplesPerPixel, width];
ImagerPixel.GetPixels[
self: context.pixels, pixels: scanSeg,
initIndex: [f: 0, s: 0], count: width
];
FOR x: NAT IN [ 0 .. width ) DO
sineValue: REAL ← RealFns.Sin[ factor * x ];
sineValue ← RealFns.Power[ABS[sineValue], power] * Sgn[sineValue];
scanSeg[0][x] ← Real.Round[maxValue * (((sineValue + 1.) / 2.0) * (max - min) + min)];
ENDLOOP;
FOR y: NAT IN [ 0 .. height ) DO
ImagerPixel.PutPixels[ self: context.pixels, pixels: scanSeg,
       initIndex: [f: 0, s: y], count: width ];
ENDLOOP;
};
MakeStretchedSpots: PUBLIC PROC[context: REF Context,
           spotsAcross, min, max, power: REAL,
           stretched: BOOLEANFALSE] ~ {
Action: PROC ~ {
width: INTEGER ← Real.Round[context.viewPort.w];
height: INTEGER ← Real.Round[context.viewPort.h];
maxValue: REAL ← 255.0;
factor: REAL ← (spotsAcross * 2 * 3.1416) / Real.Round[context.viewPort.w];
scanSeg: ImagerPixel.PixelBuffer ← ImagerPixel.NewPixels[context.pixels.samplesPerPixel, width];
ImagerPixel.GetPixels[
self: context.pixels, pixels: scanSeg,
initIndex: [f: 0, s: 0], count: width
];
FOR y: NAT IN [ 0 .. height ) DO
spread: REAL
IF stretched THEN
RealFns.Cos[ 3.1416 * (y - Real.Round[context.viewPort.h] / 2.0) /
              (Real.Round[context.viewPort.h]) ]
ELSE 1.0;
sineY: REAL ← RealFns.Cos[ factor * y ];
sineY ← RealFns.Power[ABS[sineY], power] * Sgn[sineY];
FOR x: NAT IN [ 0 .. width ) DO
sineX: REAL ← RealFns.Cos[ spread * factor * (x - Real.Round[context.viewPort.w]/2.0) ];
sineX ← RealFns.Power[ABS[sineX], power] * Sgn[sineX];
scanSeg[0][x] ← Real.Round[
maxValue * (((sineX * sineY + 1.) / 2.0) * (max - min) + min) ];
ENDLOOP;
ImagerPixel.PutPixels[ self: context.pixels, pixels: scanSeg,
       initIndex: [f: 0, s: y], count: width ];
ENDLOOP;
};
CedarProcess.DoWithPriority[background, Action];    -- be nice to other processess
};
MakeBarTest: PUBLIC PROC[context: REF Context] ~ {
width: INTEGER ← Real.Round[context.viewPort.w];
height: INTEGER ← Real.Round[context.viewPort.h];
startY: INTEGER ← 0;
lines: INTEGER ← height/6;
half: INTEGER ← width/2;
quarter: INTEGER ← width/4;
eighth: INTEGER ← width/8;
scanSeg: ImagerPixel.PixelBuffer ← ImagerPixel.NewPixels[context.pixels.samplesPerPixel, width];
ImagerPixel.GetPixels[
self: context.pixels, pixels: scanSeg,
initIndex: [f: 0, s: 0], count: width
];
FOR x: NAT IN [ 0 .. width/8 ) DO
scanSeg[0][x] ← scanSeg[0][x+half] ← IF Basics.BITAND[x, 1] # 0 THEN 255 ELSE 0;
scanSeg[0][x+eighth] ← scanSeg[0][x+half+eighth] ← IF Basics.BITAND[x, 2] # 0 THEN 255 ELSE 0;
scanSeg[0][x+quarter] ← scanSeg[0][x+half+quarter] ← IF Basics.BITAND[x, 4] # 0 THEN 255 ELSE 0;
scanSeg[0][x+quarter+eighth] ← scanSeg[0][x+half+quarter+eighth] ← IF Basics.BITAND[x, 8] # 0 THEN 255 ELSE 0;
ENDLOOP;
FOR i: NAT IN [ 0 .. 3 ) DO    -- Fill lower half of image
FOR y: NAT IN [ startY .. startY+lines ) DO
ImagerPixel.PutPixels[ self: context.pixels, pixels: scanSeg,
       initIndex: [f: 0, s: y], count: width ];
ENDLOOP;
startY ← startY+lines;
FOR x: NAT IN [ 0 .. width/8 ) DO    -- Shift line to left by 1/8
temp: CARD16 ← scanSeg[0][x];
scanSeg[0][x] ← scanSeg[0][x+half] ← scanSeg[0][x+eighth];
scanSeg[0][x+eighth] ← scanSeg[0][x+half+eighth] ← scanSeg[0][x+quarter];
scanSeg[0][x+quarter] ← scanSeg[0][x+half+quarter] ← scanSeg[0][x+quarter+eighth];
scanSeg[0][x+quarter+eighth] ← scanSeg[0][x+half+quarter+eighth] ← temp;
ENDLOOP;
ENDLOOP;
FOR x: NAT IN [ 0 .. width/2 ) DO    -- reverse line
scanSeg[0][x] ← scanSeg[0][width-1 - x];  
scanSeg[0][width-1 - x] ← scanSeg[0][width-1 - x - half] ← scanSeg[0][x+half];
scanSeg[0][x+half] ← scanSeg[0][x];
ENDLOOP;
FOR i: NAT IN [ 0 .. 3 ) DO    -- Fill upper half of image
FOR y: NAT IN [ startY .. startY+lines ) DO
ImagerPixel.PutPixels[ self: context.pixels, pixels: scanSeg,
       initIndex: [f: 0, s: y], count: width ];
ENDLOOP;
startY ← startY+lines;
FOR x: NAT IN [ 0 .. width/8 ) DO    -- Shift line to left by 1/8
temp: CARD16 ← scanSeg[0][x];
scanSeg[0][x] ← scanSeg[0][x+half] ← scanSeg[0][x+eighth];
scanSeg[0][x+eighth] ← scanSeg[0][x+half+eighth] ← scanSeg[0][x+quarter];
scanSeg[0][x+quarter] ← scanSeg[0][x+half+quarter] ← scanSeg[0][x+quarter+eighth];
scanSeg[0][x+quarter+eighth] ← scanSeg[0][x+half+quarter+eighth] ← temp;
ENDLOOP;
ENDLOOP;
};
END.