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.STREAM ← IO.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:
BOOLEAN ←
FALSE, 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:
BOOLEAN ←
FALSE]
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.ROPE ← IO.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];
};