ImagerAISUtilImpl.mesa
Copyright (C) 1984, Xerox Corporation. All rights reserved.
Michael Plass, January 3, 1985 4:01:34 pm PST
DIRECTORY Basics, ImagerPixelMaps, ImagerBasic, AIS, Rope, Scaled, ImagerTransform, ImagerAISUtil;
ImagerAISUtilImpl: CEDAR PROGRAM
IMPORTS Basics, ImagerPixelMaps, AIS, Scaled, ImagerTransform
EXPORTS ImagerAISUtil
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
PixelMapFromAIS: PUBLIC PROC [aisName: ROPE] RETURNS [pixelMap: ImagerPixelMaps.PixelMap, raster: AIS.Raster] ~ TRUSTED {
ais: AIS.FRef ← AIS.OpenFile[aisName];
window: AIS.WRef ← AIS.OpenWindow[ais];
lgBitsPerPixel: [0..4] ← SELECT (raster ← AIS.ReadRaster[ais]).bitsPerPixel FROM
0, 1 => 0,
2 => 1,
4 => 2,
8 => 3,
16 => 4,
ENDCASE => ERROR;
lineMap: ImagerPixelMaps.PixelMap ← ImagerPixelMaps.Create[lgBitsPerPixel, [0, 0, 1, raster.scanLength]];
lineBufferDesc: AIS.Buffer ← [length: lineMap.refRep.words, addr: lineMap.refRep.pointer];
pixelMap ← ImagerPixelMaps.Create[lgBitsPerPixel, [0, 0, raster.scanCount, raster.scanLength]];
FOR i: NAT IN [0..raster.scanCount) DO
AIS.UnsafeReadLine[window, lineBufferDesc, i];
pixelMap.Transfer[lineMap];
lineMap.sOrigin ← lineMap.sOrigin + 1;
ENDLOOP;
AIS.CloseWindow[window];
AIS.CloseFile[ais];
};
TransformationFromScanMode: PROC [scanMode: AIS.ScanMode, lines, pixelsPerLine: INT] RETURNS [ImagerTransform.Transformation] ~ {
pixelDeltaX: REALSELECT scanMode FROM
ru, rd => 1,
lu, ld => -1,
ENDCASE => 0;
pixelDeltaY: REALSELECT scanMode FROM
ul, ur => 1,
dr, dl => -1,
ENDCASE => 0;
lineDeltaX: REALSELECT scanMode FROM
dr, ur => 1,
ul, dl => -1,
ENDCASE => 0;
lineDeltaY: REALSELECT scanMode FROM
ru, lu => 1,
ld, rd => -1,
ENDCASE => 0;
t: ImagerTransform.TransformationRec ← [
a: lineDeltaX,
b: pixelDeltaX,
c: MAX[-(pixelDeltaX*pixelsPerLine + lineDeltaX*lines), 0],
d: lineDeltaY,
e: pixelDeltaY,
f: MAX[-(pixelDeltaY*pixelsPerLine + lineDeltaY*lines), 0]
];
RETURN [ImagerTransform.FromRec[t]]
};
AISToColor: PUBLIC PROC [aisName: Rope.ROPE] RETURNS [ImagerBasic.SampledColor] ~ {
pixelArray: ImagerBasic.PixelArray ← NEW[ImagerBasic.PixelArrayRep];
color: ImagerBasic.SampledColor ← NEW[ImagerBasic.ColorRep.sampled];
pixelMap: ImagerPixelMaps.PixelMap; raster: AIS.Raster;
[pixelMap, raster] ← PixelMapFromAIS[aisName];
IF ABS[pixelMap.sOrigin]+ABS[pixelMap.sMin]+ABS[pixelMap.fOrigin]+ABS[pixelMap.fMin] # 0 THEN ERROR;
pixelArray.xPixels ← pixelMap.sSize;
pixelArray.yPixels ← pixelMap.fSize;
pixelArray.m ← TransformationFromScanMode[raster.scanMode, pixelMap.sSize, pixelMap.fSize];
pixelArray.maxSampleValue ← Basics.BITSHIFT[1, Basics.BITSHIFT[1, pixelMap.refRep.lgBitsPerPixel]]-1;
pixelArray.samplesPerPixel ← 1;
pixelArray.get ←
SELECT pixelMap.refRep.lgBitsPerPixel FROM
0 => GetBitPixels,
3 => GetBytePixels,
ENDCASE => GetPixels;
pixelArray.data ← NEW[ImagerPixelMaps.PixelMap ← pixelMap];
color.transparent ← FALSE;
color.pa ← pixelArray;
color.m ← ImagerTransform.Rotate[0];
color.colorOperator ← IF raster.bitsPerPixel = 0 THEN $SampledBlack ELSE $Intensity;
RETURN [color];
};
GetBitPixels: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ {
pixelArrayRef: REF ImagerPixelMaps.PixelMap ~ NARROW[self.data];
pixelArray: ImagerPixelMaps.PixelMap ~ pixelArrayRef^;
IF layer#0 THEN ERROR;
FOR i: NAT IN [0..nSamples) DO
WHILE yStart.Floor < 0 DO
yStart ← yStart.PLUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE yStart.Floor >= pixelArray.fSize DO
yStart ← yStart.MINUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE xStart.Floor < 0 DO
xStart ← xStart.PLUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
WHILE xStart.Floor >= pixelArray.sSize DO
xStart ← xStart.MINUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
buffer[i] ← pixelArray.GetBit[xStart.Floor, yStart.Floor];
xStart ← xStart.PLUS[xDelta];
yStart ← yStart.PLUS[yDelta];
ENDLOOP;
};
GetBytePixels: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ {
pixelArrayRef: REF ImagerPixelMaps.PixelMap ~ NARROW[self.data];
pixelArray: ImagerPixelMaps.PixelMap ~ pixelArrayRef^;
IF layer#0 THEN ERROR;
IF xDelta = Scaled.zero THEN TRUSTED {
p: LONG POINTER TO RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF [0..256)];
WHILE xStart.Floor < 0 DO
xStart ← xStart.PLUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
WHILE xStart.Floor >= pixelArray.sSize DO
xStart ← xStart.MINUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
p ← pixelArray.refRep.pointer + Basics.LongMult[(xStart.Floor - pixelArray.sOrigin), pixelArray.refRep.rast];
FOR i: NAT IN [0..nSamples) DO
WHILE yStart.Floor < 0 DO
yStart ← yStart.PLUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE yStart.Floor >= pixelArray.fSize DO
yStart ← yStart.MINUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
buffer[i] ← p[yStart.Floor - pixelArray.fOrigin];
yStart ← yStart.PLUS[yDelta];
ENDLOOP;
}
ELSE {
FOR i: NAT IN [0..nSamples) DO
WHILE yStart.Floor < 0 DO
yStart ← yStart.PLUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE yStart.Floor >= pixelArray.fSize DO
yStart ← yStart.MINUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE xStart.Floor < 0 DO
xStart ← xStart.PLUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
WHILE xStart.Floor >= pixelArray.sSize DO
xStart ← xStart.MINUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
buffer[i] ← pixelArray.Get8Bits[xStart.Floor, yStart.Floor];
xStart ← xStart.PLUS[xDelta];
yStart ← yStart.PLUS[yDelta];
ENDLOOP;
};
};
GetPixels: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ {
pixelArrayRef: REF ImagerPixelMaps.PixelMap ~ NARROW[self.data];
pixelArray: ImagerPixelMaps.PixelMap ~ pixelArrayRef^;
IF layer#0 THEN ERROR;
FOR i: NAT IN [0..nSamples) DO
WHILE yStart.Floor < 0 DO
yStart ← yStart.PLUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE yStart.Floor >= pixelArray.fSize DO
yStart ← yStart.MINUS[Scaled.FromInt[pixelArray.fSize]];
ENDLOOP;
WHILE xStart.Floor < 0 DO
xStart ← xStart.PLUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
WHILE xStart.Floor >= pixelArray.sSize DO
xStart ← xStart.MINUS[Scaled.FromInt[pixelArray.sSize]];
ENDLOOP;
buffer[i] ← pixelArray.GetPixel[xStart.Floor, yStart.Floor];
xStart ← xStart.PLUS[xDelta];
yStart ← yStart.PLUS[yDelta];
ENDLOOP;
};
END.