CDMEBESScanImpl.mesa
.. module to scan a MEBES file and tell you about it.
Copyright © 1986 by Xerox Corporation. All rights reserved.
McCreight, September 24, 1986 10:53:28 am PDT
DIRECTORY BasicTime, CDMEBES, CDMEBESScan, FS, IO, Rope;
CDMEBESScanImpl: CEDAR PROGRAM IMPORTS BasicTime, FS, IO, Rope EXPORTS CDMEBESScan =
BEGIN OPEN CDMEBESScan;
ScanMebesPatternFile: PUBLIC PROC [ fileName: Rope.ROPE ] RETURNS [ did: DropInDescriptor ← NIL ] =
BEGIN
s: IO.STREAMNIL;
BEGIN ENABLE UNWIND => GOTO Punt;
moDayYr, name: Rope.ROPE;
ReadMDYName: PROC =
BEGIN
nameWords: CARDINAL;
nameText: REF TEXT;
mdyText: REF TEXTNEW[TEXT[6]];
IF s.GetBlock[mdyText] # 6 THEN ERROR;
moDayYr ← Rope.FromRefText[mdyText];
nameWords ← ReadMebesWord[s];
nameText ← NEW[TEXT[2*nameWords]];
IF s.GetBlock[nameText] # 2*nameWords THEN ERROR;
IF nameText[nameText.length-1] = '\000 THEN nameText.length ← nameText.length-1;
name ← Rope.FromRefText[nameText];
END;
nHeaderFields, startDrawing, extraFields: Byte;
pixelSize: Meters;
size: CDMEBES.MEBESPosition; -- pixels
field2WordCnt: CARDINAL ← 0;
stripeHeight: INT ← 255;
stripe, segment: INT ← 1;
maxStripes: CARDINAL ← 0;
s ← FS.StreamOpen[fileName];
nHeaderFields ← ReadMebesByte[s];
startDrawing ← ReadMebesByte[s];
SELECT startDrawing FROM
3, 6 => { -- Mode 1/2
pixelSize ← 1500.0E-9/startDrawing -- meters -- ;
size.x ← ReadMebesWord[s];
size.y ← ReadMebesWord[s];
ReadMDYName[];
extraFields ← nHeaderFields-1;
};
5 => { -- extended or reticle mode
patFileBlockCount: CARDINAL;
pixelSize ← (REAL[ReadMebesDoubleWord[s] -- (10^-6)*(2^-28) meters -- ])*1.0E-6/(16384.0*16384.0);
stripeHeight ← ReadMebesWord[s];
size.x ← ReadMebesDoubleWord[s];
size.y ← ReadMebesDoubleWord[s];
ReadMDYName[];
field2WordCnt ← ReadMebesWord[s];
IF field2WordCnt > 0 THEN {
patFileBlockCount ← ReadMebesWord[s];
IF s.GetLength[] # patFileBlockCount*blockSize THEN ERROR NotMEBESFormat;
field2WordCnt ← field2WordCnt-1;
}
ELSE ERROR NotMEBESFormat;
extraFields ← nHeaderFields-2;
};
ENDCASE => ERROR NotMEBESFormat;
did ← NEW[DropInDescriptorRec[MAX[field2WordCnt/2, 1]+1]];
did.fileName ← fileName;
did.created ← FS.GetInfo[FS.OpenFileFromStream[s]].created;
did.lastChecked ← BasicTime.Now[];
did.pixelSize ← pixelSize;
did.sizeX ← pixelSize*size.x;
did.sizeY ← pixelSize*size.y;
did.clip ← [x1: 0, y1: 0, x2: size.x, y2: size.y];
did.stripeHeight ← stripeHeight;
maxStripes ← (size.y+stripeHeight-1)/stripeHeight;
IF field2WordCnt > 0 THEN { -- reticle mode
IF (field2WordCnt MOD 2) # 0 THEN ERROR NotMEBESFormat;
FOR i: NAT IN [1..field2WordCnt/2] DO
did[i] ← NEW[StripeDirectory[maxStripes+1]];
did[i].nStripes ← 0;
did[i][0].firstBlock ← ReadMebesWord[s];
did[i][0].firstWordWithinBlock ← ReadMebesWord[s];
ENDLOOP;
}
ELSE { -- mode 1/2 or extended
did[1] ← NEW[StripeDirectory[maxStripes+1]];
did[1].nStripes ← 0;
};
FOR i: INT IN [0..extraFields) DO -- read across extraneous fields
wc: CARDINAL = ReadMebesWord[s];
FOR j: CARDINAL IN [0..wc) DO
[] ← ReadMebesWord[s];
ENDLOOP;
ENDLOOP;
segment ← stripe ← 1;
DO
NoteStripePos: PROC [] = {
WHILE did[segment].nStripes < stripe DO -- fill in empty space with defaults
did[segment].nStripes ← did[segment].nStripes+1;
did[segment][did[segment].nStripes] ← [];
ENDLOOP;
did[segment][stripe] ← [
firstBlock: (index/blockSize)+1,
firstWordWithinBlock: ((index MOD blockSize)/2)+1
];
};
t1: CARDINAL ← ReadMebesWord[s];
index: INT;
SELECT t1 MOD 100B FROM
16 => s.SetIndex[s.GetIndex[]+6]; -- Manhattan Rectangle
17, 18, 19 => s.SetIndex[s.GetIndex[]+10]; -- Parallelogram, Trapezoid 1/2
20 => s.SetIndex[s.GetIndex[]+12]; -- Trapezoid 3
10 => { -- start of segment
segment ← (t1/256);
IF NOT segment IN [1..did.nSegments] THEN ERROR;
index ← s.GetIndex[]-2; -- to account for word containing t1
stripe ← 0;
NoteStripePos[];
};
2, 7 =>
BEGIN -- start of stripe
index ← s.GetIndex[]-2; -- to account for word containing t1
stripe ← (IF (t1 MOD 100) = 7 THEN t1/256 ELSE ReadMebesWord[s]);
NoteStripePos[];
END;
8 => NULL; -- end of stripe
4 => RETURN; -- end of drawing
9 => { -- end of buffer
i: INT = s.GetIndex[]+blockSize-1;
s.SetIndex[i - (i MOD blockSize)];
};
ENDCASE => ERROR NotMEBESFormat;
ENDLOOP;
EXITS Punt => NULL;
END; -- of ENABLE block
IF s # NIL THEN { s.Close[]; s ← NIL };
END;
ReadMebesByte: PUBLIC PROC [ s: IO.STREAM ] RETURNS [byte: Byte] =
TRUSTED BEGIN
byte ← LOOPHOLE[s.GetChar[]];
END;
ReadMebesWord: PUBLIC PROC [ s: IO.STREAM ] RETURNS [ c: CARDINAL ] =
TRUSTED BEGIN
IF s.UnsafeGetBlock[[base: LOOPHOLE[LONG[@c]], startIndex: 0, count: 2]] # 2 THEN ERROR;
END;
ReadMebesDoubleWord: PUBLIC PROC [ s: IO.STREAM ] RETURNS [ lc: LONG CARDINAL ] =
BEGIN
tc: CARDINAL = ReadMebesWord[s];
lc ← 65536*tc+ReadMebesWord[s];
END;
NotMEBESFormat: PUBLIC ERROR = CODE;
END.