<> <> <> 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.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 ], , or . 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]; }; END.