File: ReadAISImpl.mesa
Author: Eric Bier on June 17, 1983 10:40 am
Last edited by Bier on June 23, 1983 3:45 pm
DIRECTORY
AIS,
ConvertUnsafe,
IO,
MessageWindow,
ReadAIS,
Rope,
UnsafeStorage;
ReadAISImpl: PROGRAM
IMPORTS AIS, ConvertUnsafe, IO, MessageWindow, Rope, UnsafeStorage
EXPORTS ReadAIS =
BEGIN
Raster: TYPE = AIS.Raster;
RasterPart: TYPE = AIS.RasterPart;
Placement: TYPE = AIS.Placement;
PlacementPart: TYPE = AIS.PlacementPart;
Photometry: TYPE = AIS.Photometry;
PhotometryPart: TYPE = AIS.PhotometryPart;
MyRaster: TYPE = REF MyRasterPart;
MyRasterPart: TYPE = ReadAIS.MyRasterPart;
MyPlacement: TYPE = REF MyPlacementPart;
MyPlacementPart: TYPE = ReadAIS.MyPlacementPart;
MyPhotometry: TYPE = REF MyPhotometryPart;
MyPhotometryPart: TYPE = ReadAIS.MyPhotometryPart;
MyAISInfo: TYPE = REF MyAISInfoPart;
MyAISInfoPart: TYPE = ReadAIS.MyAISInfoPart;
Read: PUBLIC PROC [filename: Rope.ROPE] RETURNS [info: MyAISInfo, success: BOOL] = {
zone: UNCOUNTED ZONE ← UnsafeStorage.NewUZone[];
oldRaster: Raster ← zone.NEW[RasterPart];
oldPlacement: Placement ← zone.NEW[PlacementPart];
oldPhotometry: Photometry ← zone.NEW[PhotometryPart];
placementExists, photometryExists, commentExists: BOOL;
raster: MyRaster;
placement: MyPlacement; photometry: MyPhotometry; comment: Rope.ROPE;
fileString: LONG STRING ← [30];
commentString: LONG STRING ← [256];
f: AIS.FRef;
ConvertUnsafe.AppendRope[fileString, filename];
success ← TRUE;
f ← AIS.OpenFile[fileString, FALSE
!AIS.Error => {IF type = fileNotFound THEN {
MessageWindow.Append[" File Not Found"]}
ELSE {MessageWindow.Append["File Problem"]};
success ← FALSE; CONTINUE}];
IF NOT success THEN RETURN;
AIS.ReadRaster[f, oldRaster];
raster ← CopyOldRaster[oldRaster];
placementExists ← AIS.ReadPlacement[f, oldPlacement];
IF placementExists THEN placement ← CopyOldPlacement[oldPlacement];
photometryExists ← AIS.ReadPhotometry[f, oldPhotometry];
IF photometryExists THEN photometry ← CopyOldPhotometry[oldPhotometry];
commentExists ← AIS.ReadComment[f, commentString];
IF commentExists THEN comment ← ConvertUnsafe.ToRope[commentString];
info ← NEW[MyAISInfoPart ← [raster, placementExists, placement, photometryExists, photometry, commentExists, comment]];
UnsafeStorage.FreeUZone[zone];
}; -- end of Read
ResolutionFromInfo: PUBLIC PROC [info: MyAISInfo] RETURNS [resolution: REAL] = {
fileString: LONG STRING ← [30];
commentStream: IO.STREAM;
IF NOT info.commentExists THEN {
resolution ← 72.0;
RETURN};
commentStream ← IO.CreateInputStreamFromRope[info.comment];
ReadRope[commentStream, "res: "];
resolution ← ReadReal[commentStream];
};
SamplesFromInfo: PUBLIC PROC [info: MyAISInfo] RETURNS [samplesX, samplesY: NAT] = {
samplesX ← info.raster.scanLength;
samplesY ← info.raster.scanCount;
};
CopyOldRaster: PROC [oldRaster: Raster] RETURNS [raster: MyRaster] = {
raster ← NEW[MyRasterPart];
raster.scanCount ← oldRaster.scanCount;
raster.scanLength ← oldRaster.scanLength;
raster.scanMode ← oldRaster.scanMode;
raster.bitsPerPixel ← oldRaster.bitsPerPixel;
raster.linesPerBlock ← oldRaster.linesPerBlock;
raster.paddingPerBlock ← oldRaster.paddingPerBlock;
};
CopyOldPlacement: PROC [oldPlacement: Placement] RETURNS [placement: MyPlacement] = {
placement ← NEW[MyPlacementPart];
placement.xLeft ← oldPlacement.xLeft;
placement.yBottom ← oldPlacement.yBottom;
placement.xWidth ← oldPlacement.xWidth;
placement.yHeight ← oldPlacement.yHeight;
};
CopyOldPhotometry: PROC [oldPhotometry: Photometry] RETURNS [photometry: MyPhotometry] = {
photometry ← NEW[MyPhotometryPart];
photometry.signal ← oldPhotometry.signal;
photometry.sense ← oldPhotometry.sense;
photometry.scaleType ← oldPhotometry.scaleType;
photometry.pointA ← oldPhotometry.pointA;
photometry.pointB ← oldPhotometry.pointB;
photometry.pointC ← oldPhotometry.pointC;
photometry.spotType ← oldPhotometry.spotType;
photometry.spotWidth ← oldPhotometry.spotWidth;
photometry.spotLength ← oldPhotometry.spotLength;
photometry.sampleMin ← oldPhotometry.sampleMin;
photometry.sampleMax ← oldPhotometry.sampleMax;
photometry.histogramLength ← oldPhotometry.histogramLength;
};

FilenameMinusExtension: PUBLIC PROC [wholeName: Rope.ROPE] RETURNS [firstPart: Rope.ROPE] = {
wholeStream: IO.STREAMIO.RIS[wholeName];
firstPart ← IO.GetToken[wholeStream, PeriodBreakProc];
};
PeriodBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
'. => RETURN[sepr];
ENDCASE => RETURN[other];
};
CreateRaster: PUBLIC PROC [
scanCount: CARDINAL, -- number of scan lines
scanLength: CARDINAL, -- number of pixels per scan line
scanMode: AIS.ScanMode, -- scanning directions
bitsPerPixel: [0..16], -- number of bits per pixel
linesPerBlock: INTEGER ← -1, -- for blocked AIS files. -1=no blocks
paddingPerBlock: CARDINAL --in words
] RETURNS [raster: MyRaster] = {
raster ← NEW[MyRasterPart ← [scanCount, scanLength, scanMode, bitsPerPixel, linesPerBlock, paddingPerBlock]];
};
CreateFile: PUBLIC PROC [fileString: LONG STRING, raster: Raster, commentString: LONG STRING, overwrite: BOOLEANFALSE, attributeLength: CARDINAL ← 0, resolution: REAL] RETURNS[f: AIS.FRef] = {
f ← AIS.CreateFile[fileString, raster, overwrite];
AIS.WriteComment[f, commentString];
};
OpenFile: PUBLIC PROC [name: Rope.ROPE, write: BOOLEANFALSE] RETURNS [f: AIS.FRef, resolution: REAL] = {
comment: Rope.ROPE;
fileString: LONG STRING ← [30];
commentString: LONG STRING ← [256];
commentStream: IO.STREAM;
commentExists: BOOL;
ConvertUnsafe.AppendRope[fileString, name];
f ← AIS.OpenFile[fileString, write];
commentExists ← AIS.ReadComment[f, commentString];
IF NOT commentExists THEN {
resolution ← 72.0;
RETURN};
comment ← ConvertUnsafe.ToRope[commentString];
commentStream ← IO.CreateInputStreamFromRope[comment];
ReadRope[commentStream, "res: "];
resolution ← ReadReal[commentStream];
};
Resolution: PUBLIC PROC [filename: Rope.ROPE] RETURNS [resolution: REAL] = {
f: AIS.FRef;
comment: Rope.ROPE;
fileString: LONG STRING ← [30];
commentString: LONG STRING ← [256];
commentStream: IO.STREAM;
commentExists: BOOL;
ConvertUnsafe.AppendRope[fileString, filename];
f ← AIS.OpenFile[fileString, FALSE];
commentExists ← AIS.ReadComment[f, commentString];
IF NOT commentExists THEN {
resolution ← 72.0;
AIS.CloseFile[f];
RETURN};
comment ← ConvertUnsafe.ToRope[commentString];
commentStream ← IO.CreateInputStreamFromRope[comment];
ReadRope[commentStream, "res: "];
resolution ← ReadReal[commentStream];
AIS.CloseFile[f];
};
ReadRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = {
 Removes the given rope from the top of the stream. Used to remove formatting words and phrases from 3d files. We are not interested in these strings but only in the data in between them.
 Signals RopeNotOnTop if some other rope is on top.
 c: CHAR;
FOR i: NAT IN[1..Rope.Length[rope]] DO
  c ← IO.GetChar[f];
  IF NOT c = Rope.Fetch[rope,i-1] THEN
    SIGNAL RopeNotOnTop [IO.GetIndex[f], Rope.FromChar[c], rope];
ENDLOOP;
 };
RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE;
ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = {
 Reads digits up to the next ], <CR>, <SPACE> or <COMMA>. Leaves these terminators on the stream.
 realRope: Rope.ROPEIO.GetToken[f, RealBreakProc];
IF Rope.Find[realRope, ".", 0, FALSE] = -1 THEN realRope ← Rope.Concat[realRope, ".0"];
 r ← IO.GetReal[IO.RIS[realRope]];
 };
RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
'], ', => RETURN [break];
IO.CR =>RETURN [break];
IO.SP => RETURN [break];
ENDCASE => RETURN [other];
};
TestComment: PROC [filename: Rope.ROPE] = {
fileString: LONG STRING ← [30];
commentString: LONG STRING ← [30];
rasterPart: AIS.RasterPart ← [10, 10, rd, 8, -1, 65535];
f: AIS.FRef;
ConvertUnsafe.AppendRope[fileString, filename];
ConvertUnsafe.AppendRope[commentString, "Hello, I am a comment"];
f ← AIS.CreateFile[fileString, @rasterPart, TRUE, 0];
AIS.WriteComment[f, commentString];
AIS.CloseFile[f];
};
END.