TransformTest.mesa
Last Edited by: Hiller, September 7, 1984 0:46:07 am PDT
Copyright (C) 1984 by Xerox Corporation. All rights reserved.
DIRECTORY       
ConstantColors  USING[IntensityToColor, NameToColor],
FilteredTransforms USING [Transform, xyRectangle],
Filters    USING [SetFilter],
Imager    USING [Context, Create, MaskRectangle, MaskVector, MoveTo, Trajectory, MaskStroke, ConicTo, Pair, SetColor],
ImagerAISUtil  USING[ AISToColor],
ImagerBasic   USING [IntRectangle],
ImagerColorAIS  USING [GetAISFile, PutAISFile, PutFastAISFile],
ImagerColorTestMain USING [GetDisplayContext, GetDisplayData, LineTest, LoadGrey8BitMap, SetDevice],
ImagerDisplay  USING [DisplayData],
ImagerPixelMaps  USING [Clear, PixelMap, Rotate],
ImagerPixelMapsExtras USING [SetPixel],
Matrix3d,
Real     USING [RoundI],
RealFns    USING [SinDeg],
Rope     USING [ROPE];
TransformTest: CEDAR PROGRAM
IMPORTS ConstantColors, FilteredTransforms, Filters, Imager, ImagerColorAIS, ImagerPixelMaps, ImagerColorTestMain, Matrix3d
-- ImagerPixelMapsExtras, Real, RealFns, ImagerAISUtil
= BEGIN
CurrentMatrix: Matrix3d.Matrix4by4;
contexts: ARRAY [0..10) OF Imager.Context ← ALL[NIL];
contextCount: NAT ← 0;
PI: REAL = 3.14159265;
box has its fields in the same order as xyRectangle: xMin, yMin, xSize, ySize. Create a new context; does not attach it to the screen. This returns a number; from this time forward this context will be referred to as contexts[n]. In all procedures that take a context as argument, the default context is the one that is attached to the screen (produced by SetDevice).
CreateContext: PUBLIC PROC[ deviceType: ATOM, box: ImagerBasic.IntRectangle]
RETURNS[ NAT] ~ {
context: Imager.Context;
data: ImagerDisplay.DisplayData;
refBox: REF ImagerBasic.IntRectangle ← NEW[ImagerBasic.IntRectangle];
refPinned: REF BOOLEANNEW[BOOLEANFALSE];  -- don't pin this pixelmap
creationList: LIST OF REF ANYLIST[refBox, refPinned];
refBox.x ← box.x; refBox.y ← box.y; refBox.w ← box.w; refBox.h ← box.h;
context ← Imager.Create[deviceType, creationList];
contexts[contextCount] ← context;
contextCount ← contextCount + 1;
NameColor[ "Black"];
Imager.MaskRectangle[context, 0, 0, .26, .2];  -- initialize compositeClipper
data ← NARROW[context.data, ImagerDisplay.DisplayData];
ImagerPixelMaps.Clear[ data[0]];     -- clear image (it would be nice if this could be done with MaskRectangle, but I don't want to have to figure out how to convert pixels to meters, or whatever the !@#$@#$~%~* thing is.
RETURN[ contextCount - 1];  -- tell 'em where you put it
};
SetupStandard: PROC = {
SetDevice[$Gray8bpp,[0,0,0,0]];
ImagerColorTestMain.GetDisplayContext[].state.T ← Imager.Rotate[0];
};
AISStandard: PROC [file: Rope.ROPE, scale: REAL ← 1.0] ~ {
color: ImagerBasic.SampledColor ← ImagerAISUtil.AISToColor[file];
context: Imager.Context ← ImagerColorTestMain.GetDisplayContext[];
color.m ← Imager.Scale[scale];
Imager.SetColor[context, color];
Imager.MaskRectangle[context, 0,0, 1000, 1000];
};
NameColor: PROC [color: Rope.ROPE, context: Imager.Context ← NIL] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
Imager.SetColor[context, ConstantColors.NameToColor[color]]};
NameIntensity: PROC [ intensity: REAL, context: Imager.Context ← NIL] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
Imager.SetColor[context, ConstantColors.IntensityToColor[intensity]]};
LoadGrey8BitMap: PROC [] ~ {
ImagerColorTestMain.LoadGrey8BitMap[]};
FillRectangle: PROC [ x, y, w, h: REAL, context: Imager.Context ← NIL] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
Imager.MaskRectangle[context, x, y, w, h]};
DrawLine: PROC [ pt1, pt2: Imager.Pair, width: REAL, context: Imager.Context ← NIL] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
Imager.MaskVector[context, pt1, pt2, width]};
LineTest: PROC[ color: CARDINAL, length, times: NAT] ~ {
ImagerColorTestMain.LineTest[ color, length, times]};
SetDevice: PROC[ deviceType: ATOM, box: ImagerBasic.IntRectangle] ~ {
ImagerColorTestMain.SetDevice[ deviceType, box]};
GetAISFile: PUBLIC PROC[ fileName: Rope.ROPE, context: Imager.Context ← NIL, xOffSet, yOffSet: INTEGER ← 0] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
ImagerColorAIS.GetAISFile[context, fileName, xOffSet, yOffSet]};
PutAISFile: PUBLIC PROC[ fileName: Rope.ROPE, context: Imager.Context ← NIL] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
ImagerColorAIS.PutAISFile[ context, fileName]};
PutFastAISFile: PUBLIC PROC[ fileName: Rope.ROPE, context: Imager.Context ← NIL] ~ {
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
ImagerColorAIS.PutFastAISFile[ context, fileName]};
SetWindow: PUBLIC PROC[ w: FilteredTransforms.xyRectangle, image: Imager.Context ← NIL] ~ {
data: ImagerDisplay.DisplayData;
IF image = NIL THEN
data ← ImagerColorTestMain.GetDisplayData[]
ELSE
data ← NARROW[image.data, ImagerDisplay.DisplayData];
data.compositeClipper.first.sMin ← data[0].sMin ← w.yMin;
data.compositeClipper.first.fMin ← data[0].fMin ← w.xMin;
data.compositeClipper.first.sSize ← data[0].sSize ← w.ySize;
data.compositeClipper.first.fSize ← data[0].fSize ← w.xSize;
};
scaling of an image within the plane of the screen
ScaleImage: PUBLIC PROC[ scaleX, scaleY: REAL,
   moveX, moveY: REAL ← 0.0,
   image, newImage: Imager.Context ← NIL] ~ TRUSTED {
data, newData: ImagerDisplay.DisplayData;
screen, newScreen: ImagerPixelMaps.PixelMap;
CurrentMatrix ← Matrix3d.Identity[];
CurrentMatrix ← Matrix3d.Scale[ CurrentMatrix, scaleX, scaleY, 1];
IF image = NIL THEN {
data ← ImagerColorTestMain.GetDisplayData[];
screen ← data[0]}
ELSE {
data ← NARROW[image.data, ImagerDisplay.DisplayData];
screen ← data[0]};
IF newImage = NIL THEN {
newData ← ImagerColorTestMain.GetDisplayData[];
newScreen ← newData[0]}
ELSE {
newData ← NARROW[newImage.data, ImagerDisplay.DisplayData];
newScreen ← newData[0]};
FilteredTransforms.Transform[ screen, newScreen, CurrentMatrix, moveX, moveY, 1];
};
rotation of an image in the plane of the screen
RotateImage: PUBLIC PROC[ angle: REAL,
   moveX, moveY: REAL ← 0.0,
   image, newImage: Imager.Context ← NIL] ~ TRUSTED {
data, newData: ImagerDisplay.DisplayData;
screen, newScreen: ImagerPixelMaps.PixelMap;
CurrentMatrix ← Matrix3d.Identity[];
CurrentMatrix ← Matrix3d.LocalRotateAboutZAxis[ CurrentMatrix, angle];
IF image = NIL THEN {
data ← ImagerColorTestMain.GetDisplayData[];
screen ← data[0]}
ELSE {
data ← NARROW[image.data, ImagerDisplay.DisplayData];
screen ← data[0]};
IF newImage = NIL THEN {
newData ← ImagerColorTestMain.GetDisplayData[];
newScreen ← newData[0]}
ELSE {
newData ← NARROW[newImage.data, ImagerDisplay.DisplayData];
newScreen ← newData[0]};
FilteredTransforms.Transform[ screen, newScreen, CurrentMatrix, moveX, moveY, 1];
};
any transform you can depict using a 4x4 matrix (focal length defaults to the length of the longest side of the input image)
TransformImage: PUBLIC PROC[
    moveX, moveY: REAL ← 0.0,
    focalLength: REAL ← 0.0,
    m: Matrix3d.Matrix4by4,
    image, newImage: Imager.Context ← NIL] ~ {
data, newData: ImagerDisplay.DisplayData;
screen, newScreen: ImagerPixelMaps.PixelMap;
IF image = NIL THEN {
data ← ImagerColorTestMain.GetDisplayData[];
screen ← data[0]}
ELSE {
data ← NARROW[image.data, ImagerDisplay.DisplayData];
screen ← data[0]};
IF newImage = NIL THEN {
newData ← ImagerColorTestMain.GetDisplayData[];
newScreen ← newData[0]}
ELSE {
newData ← NARROW[newImage.data, ImagerDisplay.DisplayData];
newScreen ← newData[0]};
IF focalLength = 0.0 THEN focalLength ← MAX[ screen.sSize - screen.sMin, screen.fSize - screen.fMin];
FilteredTransforms.Transform[ screen, newScreen, m, moveX, moveY, focalLength];
};
Filter 0 is sinc x, cut off at the first zero crossing. Filter 1 is sinc x * sinc x/2, cut off at the second zero crossing. Filter 0 is about twice as fast; filter 1 produces a better image. The initial default filter is filter 0.
SetFilter: PUBLIC PROC[ i: [0..2)] ~ {
Filters.SetFilter[i]};
ShowFilter: PUBLIC PROC[ i: [0..7)] ~ {
data: ImagerDisplay.DisplayData;
screen: ImagerPixelMaps.PixelMap;
data ← ImagerColorTestMain.GetDisplayData[];
screen ← data[0];
Filters.ShowFilter[ i, screen];
};
ShowSinc: PUBLIC PROC[ w, h: REAL, color: [0..256)] ~ {
displayData: ImagerDisplay.DisplayData ← ImagerColorTestMain.GetDisplayData[];
screen: ImagerPixelMaps.PixelMap ← displayData[0];
center: INTEGER ← (screen.fSize - screen.fMin)/2 + screen.fMin;
FOR i: INTEGER IN [screen.fMin..center) DO
x: REAL ← (i-center) / (center * 1.0);
ImagerPixelMapsExtras.SetPixel[ screen, (screen.sSize - 1) - 50, i, 150];
ImagerPixelMapsExtras.SetPixel[ screen,  -- axis
   (screen.sSize - 1) - (50 + Real.RoundI[ h*RealFns.SinDeg[ w * 360 * x] / (w * 2*PI * x)]),
   i,
   color];
ENDLOOP;
ImagerPixelMapsExtras.SetPixel[ screen, (screen.sSize - 1) - 50, center, 150];
ImagerPixelMapsExtras.SetPixel[ screen,  -- axis
   (screen.sSize - 1) - (50 + Real.RoundI[ h]),
   center,
   color];
FOR i: INTEGER IN (center..screen.fSize) DO
x: REAL ← (i-center) / (center * 1.0);
ImagerPixelMapsExtras.SetPixel[ screen, (screen.sSize - 1) - 50, i, 150];
ImagerPixelMapsExtras.SetPixel[ screen,  -- axis
   (screen.sSize - 1) - (50 + Real.RoundI[ h*RealFns.SinDeg[ w * 360 * x] / (w * 2*PI * x)]),
   i,
   color];
ENDLOOP;
};
Rotate90: PUBLIC PROC[ filename: Rope.ROPE, context: Imager.Context ← NIL] ~ {
data: ImagerDisplay.DisplayData;
screen: ImagerPixelMaps.PixelMap;
IF context = NIL THEN
context ← ImagerColorTestMain.GetDisplayContext[];
data ← NARROW[context.data, ImagerDisplay.DisplayData];
screen ← data[0];
data[0] ← ImagerPixelMaps.Rotate[ screen];
PutAISFile[ filename];
data[0] ← screen;
};
DiagLineTest: PUBLIC PROC[ f: REAL ← .15] ~ {
displayData: ImagerDisplay.DisplayData ← ImagerColorTestMain.GetDisplayData[];
map: ImagerPixelMaps.PixelMap ← displayData[0];
FOR i: INTEGER IN [-25..25] DO
DrawLine[ [0.004, 0.004 * i], [ .15, f + 0.004 * i], .001];
ENDLOOP
};
CurveTest: PUBLIC PROC[ scale: REAL ← 1] ~ {
displayData: ImagerDisplay.DisplayData ← ImagerColorTestMain.GetDisplayData[];
map: ImagerPixelMaps.PixelMap ← displayData[0];
pos: REAL ← 0.;
FOR i: INTEGER IN [0..60) DO
pos: REAL ← pos + scale*(0.004 - 0.00005 * i);
t: Imager.Trajectory ← Imager.MoveTo[[pos, 0.005*scale]];
Imager.MaskStroke[ ImagerColorTestMain.GetDisplayContext[],
       Imager.ConicTo[t, [0.15*scale + pos, 0.095*scale],
             [pos, 0.185*scale], .5],
       scale*(.001 - 0.00001 * i)];
ENDLOOP
};
Grid: PUBLIC PROC[ scale: REAL ← 1.0] ~ {
displayData: ImagerDisplay.DisplayData ← ImagerColorTestMain.GetDisplayData[];
map: ImagerPixelMaps.PixelMap ← displayData[0];
pos: REAL ← 0.;
FOR i: INTEGER IN [0..11] DO
DrawLine[[i*scale*.02+.005, .005], [i*scale*.02+.005, 8*scale*.02+.005], 0];
ENDLOOP;
FOR i: INTEGER IN [0..8] DO
DrawLine[[.005, i*scale*.02+.005], [11*scale*.02+.005, i*scale*.02+.005], 0];
ENDLOOP;
};
END.